视图(3dmax相机视图)变换是不是必须的

Android OpenGL ES 2.0绘图:应用投影和相机视图 - 推酷
Android OpenGL ES 2.0绘图:应用投影和相机视图
在OpenGL ES环境中,投影和相机视图让绘制对象以更接近于人们肉眼所看到的实物对象的样子显示。这项仿真技术是通过对绘制对象的坐标进行精确的数学变换而实现的。
投影:这种变换是根据所在GLSurfaceView的宽和高调整绘制对象的坐标。 如果没有此变换,对象会被不规则比例的视图所扭曲变形。通常一个投影变换只有当创建OpenGLView或你的renderer类的 onSurfaceChange()方法发生变化时才被计算,更多关于OpenGL ES预测和坐标映射的信息,请参阅代码Mapping Coordinates for Drawn Objects。
相机视图:这种变换是基于一个虚拟相机的位置来调整绘制对象的坐标。需要主要的 是,OpenGL ES并没有定义一个真实的相机对象,而是提供了一些工具方法变换绘制对象的显示来模拟一个相机。一个相机视图变换可能在创建GLSurfaceView时 被计算一次,或根据用户行为或应用程序功能动态地改变。
这一节将描述如何创建一个投影和一个相机视图,并将它们应用于你的GLSurfaceView的形状绘制过程中。
一、定义一个投影
一个投影变换的数据是在GLSurfaceView.Renderer类的 onSurfaceChanged()方法中计算得到的。下面的示例代码演示了根据传入GLSurfaceView的宽和高计算比例,并使用Matrix 类frustumM()方法来填充一个投影变换:
[java]&view&plaincopyprint?&
&onSurfaceChanged(GL10&unused,&
&height)&{&
GLES20.glViewport(
,&width,&height);&
&ratio&=&(
)&width&/&&
//&在onDrawFrame()方法中,将投影矩阵应用到对象的坐标
Matrix.frustumM(mProjMatrix,&
,&-ratio,&ratio,&-
这段代码填充了一个投影矩阵:mProjMatrix,可以把它与一个相机视图变换在onDrawFrame()方法中结合起来使用。
注:如果只是一个投影变换应用到你的绘制对象中,通常会导致什么也看不到。一般来说,你必须再申请一个相机视图变换才能看到屏幕上的东东。
二、定义一个相机视图
[java]&view&plaincopyprint?&
&onDrawFrame(GL10&unused)&{&
//&设置相机的位置(视图矩阵)
Matrix.setLookAtM(mVMatrix,&
,&0f,&0f,&0f,&0f,&
//&计算投影和视图变换
Matrix.multiplyMM(mMVPMatrix,&
,&mProjMatrix,&
,&mVMatrix,&
//&绘制形状
mTriangle.draw(mMVPMatrix);&
三、应用投影和相机视图变换
[java]&view&plaincopyprint?&
[]&mvpMatrix)&{&
//&传递计算出的变换矩阵
//&获得形状的变换矩阵的handle
mMVPMatrixHandle&=&GLES20.glGetUniformLocation(mProgram,&
&uMVPMatrix&
//&应用投影和视图变换
GLES20.glUniformMatrix4fv(mMVPMatrixHandle,&
,&mvpMatrix,&
//&绘制三角形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES,&
,&vertexCount);&
已发表评论数()
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
排版有问题
没有分页内容
视频无法显示
图片无法显示图形学第三次实验_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
图形学第三次实验
上传于||暂无简介
阅读已结束,如果下载本文需要使用
想免费下载本文?
下载文档到电脑,查找使用更方便
还剩18页未读,继续阅读
你可能喜欢【OpenGL编程指南】之视图和模型变换 - 弈名 - 博客园
照相机比喻
视图变换&&确定照相机位置;
模型变换&&安排场景,确定物体位置;
投影变换&&选择照相机镜头,调整放大倍数;
视口变换&&确定照片的大小;
通用变换函数
  void glMatrixMode(GLenum mode);  指定模型视图、投影或纹理矩阵是否将被修改,值可以为GL_MODELVIEW,GL_PROJECTION或GL_TEXTURE;
  void glLoadIdentiy(void);  加载单位矩阵,用于清除当前矩阵,将其归零;
  void glLoadMatrix(cont Type *m);  将当前矩阵的16个值设置为m指定的值;
  void glMultMatrix(const Type *m);  与当前矩阵相乘;
  矩阵乘法要注意是使用行主序还是列主序,若使用行主序,则调用glLoadTransposeMatrix()和glMultTransposeMatrix()方法。
  所有视图变换和模型变换都是用一个4*4矩阵表示的,不同的变换顺序其结果差异很大,如下图所示,先旋转和先矩阵差异很大。
  在实际编码时,一定要注意矩阵相乘的顺序和实际变换的顺序正好相反。
  void&glTranslate{fd} (TYPE x, TYPE y, TYPE z);  很简单,不再细述。
  void glRotate{fd}(TYPE angle, TYPE x,&TYPE y, TYPE z);
  glRotatef(45.0, 0.0, 0.0, 1.0)的效果相当于沿Z轴旋转45度。
  void glScale{fd}(TYPE x, TYPE y, TYPE z);  由x,y,z因子拉伸,收缩和反射。下图显示了glScalef(2.0, -0.5, 1.0)的效果。
  视图变换用于修改观察点的位置和方向,一般由移动和旋转组成,视图变换函数必须在调用任何模型变换之前被调用,以确保模型变换首先作用于物体。
使用移动和旋转
  当使用模型变换函数模拟视图变换时,其做法相当于在场景中的物体保持静止的前提下按照预想的方式移动观察点。
使用gluLookAt
  void gluLookAt(GLdouble eyex,&GLdouble eyey,&GLdouble eyez,&GLdouble ceterx,&GLdouble certery,&GLdouble centerz,&GLdouble upx,&GLdouble upy,&GLdouble upz);  观察点由eye指定的,center指定了视线上的任意一点,up表示哪个方向是朝上的。
阅读(...) 评论()
Copyright & 弈名
Powered by:
模板提供:OpenGL照相机模型及变换_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
OpenGL照相机模型及变换
上传于||文档简介
&&关​于​“​O​p​e​n​G​L​模​型​视​图​变​换​,​投​影​变​换​及​视​口​变​换​”​的​详​细​介​绍​请​登​录​“​CD​N​论​坛​”
大小:445.50KB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢实验5 OpenGL模型视图变换 - 慢步前行 - 博客园
1.实验目的:
理解掌握OpenGL程序的模型视图变换。
2.实验内容:
(1)阅读实验原理,运行示范实验代码,理解掌握OpenGL程序的模型视图变换;
(2)根据示范代码,尝试完成实验作业;
3.实验原理:
我们生活在一个三维的世界&&如果要观察一个物体,我们可以:
1、从不同的位置去观察它(人运动,选定某个位置去看)。(视图变换)
2、移动或者旋转它,当然了,如果它只是计算机里面的物体,我们还可以放大或缩小它(物体运动,让人看它的不同部分)。(模型变换)
3、如果把物体画下来,我们可以选择:是否需要一种&近大远小&的透视效果。另外,我们可能只希望看到物体的一部分,而不是全部(指定看的范围)。(投影变换)
4、我们可能希望把整个看到的图形画下来,但它只占据纸张的一部分,而不是全部(指定在显示器窗口的那个位置显示)。(视口变换)
这些,都可以在OpenGL中实现。
从&相对移动&的观点来看,改变观察点的位置与方向和改变物体本身的位置与方向具有等效性。在OpenGL中,实现这两种功能甚至使用的是同样的函数。
由于模型和视图的变换都通过矩阵运算来实现,在进行变换前,应先设置当前操作的矩阵为&模型视图矩阵&。设置的方法是以GL_MODELVIEW为参数调用glMatrixMode函数,像这样:
glMatrixMode(GL_MODELVIEW);
该语句指定一个4&4的建模矩阵作为当前矩阵。
通常,我们需要在进行变换前把当前矩阵设置为单位矩阵。把当前矩阵设置为单位矩阵的函数为:
glLoadIdentity();
我们在进行矩阵操作时,有可能需要先保存某个矩阵,过一段时间再恢复它。当我们需要保存时,调用glPushMatrix()函数,它相当于把当前矩阵压入堆栈。当需要恢复最近一次的保存时,调用glPopMatrix()函数,它相当于从堆栈栈顶弹出一个矩阵为当前矩阵。OpenGL规定堆栈的容量至少可以容纳32个矩阵,某些OpenGL实现中,堆栈的容量实际上超过了32个。因此不必过于担心矩阵的容量问题。
通常,用这种先保存后恢复的措施,比先变换再逆变换要更方便,更快速。
注意:模型视图矩阵和投影矩阵都有相应的堆栈。使用glMatrixMode来指定当前操作的究竟是模型视图矩阵还是投影矩阵。
在代码中,视图变换必须出现在模型变换之前,但可以在绘图之前的任何时候执行投影变换和视口变换。
1.display()程序中绘图函数潜在的重复性强调了:在指定的视图变换之前,应该使用glLoadIdentity()函数把当前矩阵设置为单位矩阵。
2.在载入单位矩阵之后,使用gluLookAt()函数指定视图变换。如果程序没有调用gluLookAt(),那么照相机会设定为一个默认的位置和方向。在默认的情况下,照相机位于原点,指向Z轴负方向,朝上向量为(0,1,0)。
3.一般而言,display()函数包括:视图变换 + 模型变换 + 绘制图形的函数(如glutWireCube())。display()会在窗口被移动或者原来先遮住这个窗口的东西被一开时,被重复调用,并经过适当变换,保证绘制的图形是按照希望的方式进行绘制。
4.在调用glFrustum()设置投影变换之前,在reshape()函数中有一些准备工作:视口变换 + 投影变换 + 模型视图变换。由于投影变换,视口变换共同决定了场景是如何映射到计算机的屏幕上的,而且它们都与屏幕的宽度,高度密切相关,因此应该放在reshape()中。reshape()会在窗口初次创建,移动或改变时被调用。
OpenGL中矩阵坐标之间的关系
物理坐标*模型视图矩阵*投影矩阵*透视除法*规范化设备坐标&&〉窗口坐标
(1)视图变换函数gluLookAt(0.0,0.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0,)设置照相机的位置
把照相机放在(0,0,5),镜头瞄准(0,0,0),朝上向量定为(0,1,0)朝上向量为照相机指定了一个唯一的方向。如果没有调用gluLookAt,照相机就设定一个默认的位置和方向,在默认情况下,照相机位于原点,指向Z轴的负方向,朝上向量为(0,1,0)
glLoadIdentity()函数把当前矩阵设置为单位矩阵。
(2)使用模型变换的目的是设置模型的位置和方向
(3)投影变换,指定投影变换类似于为照相机选择镜头,可以认为这种变换的目的是确定视野,并因此确定哪些物体位于视野之内以及他们能够被看到的程度。
除了考虑视野之外,投影变换确定物体如何投影到屏幕上,OpenGL提供了两种基本类型的投影,1、透视投影:远大近小;2、正投影:不影响相对大小,一般用于建筑和CAD应用程序中
(4)视口变换
视口变换指定一个图象在屏幕上所占的区域
(5)绘制场景
4.示范代码: 太阳系
#include &GL/glut.h&
#include &stdlib.h&
static int year = 0, day = 0;
void init(void)
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
void display(void)
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
glPushMatrix();
glutWireSphere(1.0, 20, 16); /* draw sun */
glRotatef ((GLfloat) year, 0.0, 1.0, 0.0);
glTranslatef (2.0, 0.0, 0.0);
glRotatef ((GLfloat) day, 0.0, 1.0, 0.0);
glutWireSphere(0.2, 10, 8); /* draw smaller planet */
glPopMatrix();
glutSwapBuffers();
void reshape (int w, int h)
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
void keyboard (unsigned char key, int x, int y)
switch (key) {
day = (day + 10) % 360;
glutPostRedisplay();
day = (day - 10) % 360;
glutPostRedisplay();
year = (year + 5) % 360;
glutPostRedisplay();
year = (year - 5) % 360;
glutPostRedisplay();
int main(int argc, char** argv)
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMainLoop();
代码说明:
上面所描述的这个程序绘制一个简单的太阳系,其中有一颗行星和一颗太阳,它们是用同一个球体绘制函数绘制的。为了编写这个程序,需要使用glRtate*()函数让这颗行星绕太阳旋转,并且绕自身的轴旋转。还需要使用glTranslate*()函数让这颗行星远离太阳系原点,移动到它自己的轨道上。记住,可以在glutWireSphere()函数中使用适当的参数,在绘制两个球体时指定球体的大小。
为了绘制这个太阳系,首先需要设置一个投影变换和一个视图变换。在这个例子中,可以使用glutPerspective()和gluLookat().
绘制太阳比较简单,因为它应该位于全局固定坐标系统的原点,也就是球体函数进行绘图的位置。因此,绘制太阳时并不需要移动,可以使用glRotate*()函数绕一个任意的轴旋转。绘制一颗绕太阳旋转的行星要求进行几次模型变换。这颗行星需要每天绕自己的轴旋转一周,每年沿着自己的轨道绕太阳旋转一周。
为了确定模型变换的顺序,可以从局部坐标系统的角度考虑。首先,调用初始的glRotate*()函数对局部坐标系统进行旋转,这个局部坐标系统最初与全局固定坐标系统是一致的。接着,可以调用glTranslate*()把局部坐标系统移动到行星轨道上的一个位置。移动的距离应该等于轨道的半径。因此,第一个glRotate*()函数实际上确定了这颗行星从什么地方开始绕太阳旋转(或者说,从一年的什么时候开始)。
第二次调用glRotate*()使局部坐标轴进行旋转,因此确定了这颗行星在一天中的时间。当调用了这些函数变换之后,就可以绘制这颗行星了。
5. 实验作业:
(1)尝试在太阳系中增加一颗卫星,一颗行星。提示:使用glPushMatrix()和glPopMatrix()在适当的时候保存和恢复坐标系统的位置。如果打算绘制几颗卫星绕同一颗行星旋转,需要在移动每颗卫星的位置之前保存坐标系统,并在绘制每颗卫星之后恢复坐标系统。
(2)尝试把行星的轴倾斜。}

我要回帖

更多关于 opengl视图变换 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信