OpenGL图形编程3二维观察与三维变换(陈永强)ppt课件.ppt

上传人:小飞机 文档编号:2003941 上传时间:2022-12-30 格式:PPT 页数:46 大小:365KB
返回 下载 相关 举报
OpenGL图形编程3二维观察与三维变换(陈永强)ppt课件.ppt_第1页
第1页 / 共46页
OpenGL图形编程3二维观察与三维变换(陈永强)ppt课件.ppt_第2页
第2页 / 共46页
OpenGL图形编程3二维观察与三维变换(陈永强)ppt课件.ppt_第3页
第3页 / 共46页
OpenGL图形编程3二维观察与三维变换(陈永强)ppt课件.ppt_第4页
第4页 / 共46页
OpenGL图形编程3二维观察与三维变换(陈永强)ppt课件.ppt_第5页
第5页 / 共46页
点击查看更多>>
资源描述

《OpenGL图形编程3二维观察与三维变换(陈永强)ppt课件.ppt》由会员分享,可在线阅读,更多相关《OpenGL图形编程3二维观察与三维变换(陈永强)ppt课件.ppt(46页珍藏版)》请在三一办公上搜索。

1、1,OpenGL图形编程,武汉纺织大学数学与计算机学院,授课教师:陈永强 教授,2,3. OpenGL二维观察与三维变换,3.1二维观察3.2三维变换,3,3,3. 1OpenGL二维观察,实现二维观察的步骤:3.1.1指定矩阵堆栈3.1.2指定裁剪窗口3.1.3指定视区,4,4,3.1.1指定矩阵堆栈,指定当前操作的是投影矩阵堆栈glMatrixMode(GL_PROJECTION);初始化,即指定当前操作的矩阵堆栈的栈顶元素为单位矩阵。 glLoadIdentity();,5,5,3.1.2指定裁剪窗口,定义二维裁剪窗口gluOtho2D(xwmin, xwmax, ywmin, ywma

2、x);其中,双精度浮点数xwmin, xwmax, ywmin, ywmax分别对应裁剪窗口的左、右、下、上四条边界。默认的裁剪窗口,四条边界分别为wxl=-1.0, wxr=1.0,wyt=-1.0,wyb=1.0。,6,6,3.1.3指定视区,指定视区glViewPort(xvmin,yvmin,vpWidth,vpHeighht);xvmin和yvmin指定了对应于屏幕上显示窗口中的矩形视区的左下角坐标,单位为像素。整型值vpWidth和vpHeighht则指定了视区的宽度和高度。默认的视区大小和位置与显示窗口保持一致。,7,3. 1OpenGL二维观察,例子教材【程序6-2】,8,8,

3、3.2.1变换种类3.2.2模型视图矩阵3.2.3矩阵操作3.2.4矩阵堆栈3.2.5投影变换3.2.6剪切变换,3.2OpenGL中的变换,9,9,视图变换:指定观察者或摄影机的位置;模型变换:在场景中移动对象;模型视图变换:描述视图变换与模型变换的对偶性;投影变换:对视见空间进行修剪和改变大小;视见区变换:对窗口的最终输出进行缩放;,3.2.1变换种类,10,10,视图变换:指定观察者或摄影机的位置;视图变换是第一个应用到场景上的变换。它用于确定场景的有利位置。默认情况下,观察点位于原点,顺着z轴的负向看。视图变换使你可以将观察点放置在任何期望的位置上,从任何方向进行观察。确定视图变换相当

4、于在场景中放置一部摄像机并确定其指向。 在工作时间表上,必须先指定视图变换再指定其他任何变换。,3.2.1变换种类,11,11,模型变换:在场景中移动对象;模型变换用于处理模型和模型内的特定对象。这些变换把对象移动到合适的位置,旋转它们,并对它们进行缩放。模型变换实际上就是几何变换。,3.2.1变换种类,12,12,模型视图变换:描述视图变换与模型变换的对偶性;从内部效果和它们对场景最终外观的效果来说,视图变换和模型变换是相同的,把这两者分开完全是为了程序员的方便,向后移动对象和向前移动参考系之间并没有本质差别。术语“模型视图”表示你可以把这类变换视为模型变换或视图变换,但实际上并无区别,因此

5、称它为模型视图变换。,3.2.1变换种类,13,13,投影变换:对视见空间进行修剪和改变大小;投影变换应用到最终的模型视图方向。投影实际上定义了视见空间并建立了修剪平面。更明确一些,投影变换指定已完成场景如何转换成屏幕上的最终图象。常用的投影变换包括 正投影和透视投影。,3.2.1变换种类,14,14,视见区变换:对窗口的最终输出进行缩放;把场景的一个二维投影映射到屏幕上某处的窗口。这个到物理窗口坐标的映射是最后完成的一项变换,它称为视见区变换。,3.2.1变换种类,15,15,在计算机图形学中,所有的变换都是通过矩阵乘法来实现的,即将物体顶点构成的齐次坐标矩阵乘以三维变换矩阵就得到了变换后的

6、物体顶点的齐次坐标矩阵,这样只要求出物体的三维变换矩阵,就可以得到变换后的物体。在OpenGL中,对象的坐标变换也通过矩阵来实现的(虽然并不一定要自己定义矩阵)。通常,在OpenGL中使用了两个重要的矩阵:模型视图矩阵和投影矩阵,其中模型视图矩阵用于物体的模型视图变换,投影矩阵用于投影变换。,3.2.1变换种类,16,16,有了模型视图矩阵和投影矩阵,在OpenGL中从未加工的顶点数据到屏幕坐标的过程就包括如下步骤: 1. 将顶点坐标转换为规范化齐次坐标矩阵; 2. 将顶点的规范化齐次坐标矩阵乘以模型视图矩阵,生成变换后的顶点齐次坐标矩阵; 3. 将变换后的顶点齐次坐标矩阵乘以投影矩阵,生成修

7、剪坐标矩阵,这样就有效地排除了视见空间之外的所有数据。4. 由修剪坐标除以w坐标,得到规格化的设备坐标。注意,在变换过程中,模型视图矩阵和投影视图矩阵都有可能改变坐标的 w 值。 5. 坐标三元组被视见区变换影射到一个2D平面。这也是一个矩阵变换,但在OpenGL中不能直接指定或修改它,系统会根据指定给 glViewport 的值在内部设置它。,3.2.1变换种类,17,17,模型视图矩阵用于指定场景的视图变换和几何变换,模型视图矩阵是一个44的矩阵,它代表了用来放置和定位对象的经过变换的坐标系。在计算机图形学中,物体进行的几何变换可以分解成多个基本几何变换,而三维几何变换矩阵是多个基本几何变

8、换矩阵相乘的结果。OpenGL提供了一些函数用于把任意矩阵设置成当前操作的矩阵(模型视图矩阵或投影矩阵)。,3.2.2模型视图矩阵,18,18,glfloat m = 1.0f, 0.0f,3.0f,0.0f, 0.0f,1.0f,0.0f,1.0f, 0.0f,0.0f,1.0f,1.0f, 0.0f,0.0f,0.0f,1.0f, ;glMatrixMode(GL_MODELVIEW); glLoadMatrixf(m); 这段程序中,先声明了一个数组来保存 44 矩阵的值,注意这里矩阵按列优先顺序保存,这意味着先从上往下遍历每一列;然后使用glLoadMatrix函数将定义的矩阵设置为当

9、前操作的矩阵。,3.2.2模型视图矩阵,19,19,如果需要执行变换,即把定义的矩阵乘到模型视图矩阵中。可以使用函数 glMultmatrix,其函数原型如下: void glMultMatrixfd(const TYPE *m); 参数 m 为一个以列优先顺序保存16个连续值的数组。,3.2.2模型视图矩阵,20,20,平移 旋转 比例,3.2.2模型视图矩阵,21,21,平移void glTranslatefd(TYPE x,TYPE y,TYPE z);参数x,y,z就是目标分别沿三个轴的正向平移的偏移量。这个函数用这三个偏移量生成的矩阵完成乘法。当参数是(0.0,0.0,0.0)时,生

10、成的矩阵是单位矩阵,此时对物体没有影响。,3.2.2模型视图矩阵,22,22,旋转void glRotatefd(TYPE angle,TYPE x,TYPE y,TYPE z );函数中第一个参数是表示目标沿从原点到指定点(x,y,z)的方向矢量逆时针旋转的角度,后三个参数则是指定旋转方向矢量的坐标。这个函数表示用这四个参数生成的矩阵完成乘法。当角度参数是 0.0 时,表示对物体没有影响。,3.2.2模型视图矩阵,23,23,比例void glScalefd(TYPE x,TYPE y,TYPE z);三个参数值就是目标分别沿三个轴向缩放的比例因子。这个函数用这三个比例因子生成的矩阵完成乘法

11、。这个函数能完成沿相应的轴对目标进行拉伸、压缩和反射三项功能。当参数是(1.0,1.0,1.0)时,对物体没有影响。当其中某个参数为负值时,表示将对目标进行相应轴的反射变换,且这个参数不为1.0,则还要进行相应轴的缩放变换。最好不要令三个参数值都为零,这将导致目标沿三轴都缩为零。,3.2.2模型视图矩阵,24,3.2.2模型视图矩阵,视图变换函数(定义观察坐标系)void gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez, GLdouble centerx,GLdouble centery,GLdouble centerz,GLdouble

12、 upx,GLdouble upy,GLdouble upz);视点位置:(eyex, eyey, eyez)参考点位置:(centerx, centery, centerz)向上矢量方向:(upx, upy, upz),25,3.2.2模型视图矩阵,例子红皮书cube.c model.c,26,26,3.2.3矩阵操作,矩阵堆栈选择 glMatrixMode(GLenum mode);参数mode用于确定将哪个矩阵堆栈用于矩阵操作。GL_MODELVIEW:模型视图矩阵堆栈GL_PROJECTION:投影矩阵堆栈GL_TEXTURE:纹理矩阵堆栈,27,27,3.2.3矩阵操作,通过上述的高

13、级矩阵函数,可以很方便地实现变换。问题:在调用函数时,修改的是当前的模型视图矩阵。新的矩阵随后将成为当前的模型视图矩阵并影响此后绘制的图形。这样模型视图矩阵函数在调用时,就会造成效果的积累。,28,28,3.2.3矩阵操作,效果积累一段代码: /沿 x 轴正向移动 10 个单位 glTranslatef(10.0f, 0.0f, 0.0f); glutSolidSphere(1.0f, 15, 15); /沿 y 轴正向移动 10 个单位 glTranslatef(0.0f, 10.0f, 0.0f); glutSolidSphere(1.0f); 这段代码绘制了两个球,第一个绘制的球的球心沿

14、x轴正向移动了10个单位,而第二球不仅沿y轴正向移动10个单位,也沿x轴正向移动10个单位。这就是效果积累。,29,3.2.3矩阵操作,单位矩阵glTranslatef(10.0f, 0.0f, 0.0f);glutSolidSphere(1.0f, 15, 15);glTranslatef(0.0f, 10.0f, 0.0f);glutSolidSphere(1.0f , 15, 15);想要第二个球只沿 y 轴正向移动 10 个单位,一种简单的方法是把模型矩阵复位,即通过给模型视图矩阵加载上单位矩阵来复位原点。,glMatrixMode(GL_MODELVIEW); glLoadIdent

15、ity( );,30,30,3.2.4矩阵堆栈,实际上,在创建、装入、相乘模型变换和投影变换矩阵时,都已用到堆栈操作。一般说来,矩阵堆栈常用于构造具有继承性的模型,即由一些简单目标构成复杂模型。而在构造复杂模型时,常常需要保存中间的变化状态,以便在进行一些变换后能够恢复。,31,31,3.2.4矩阵堆栈,OpenGL为模型视图矩阵和投影矩阵各维护着一个“矩阵堆栈”,可以把当前矩阵压到堆栈中保存它,然后对当前矩阵进行修改。把矩阵弹出堆栈即可恢复。使用的函数如下: void glPushMatrix(void); void glPopMatrix(void);,32,32,3.2.4矩阵堆栈,函数

16、 glPushMatrix 用于将当前矩阵压入当前矩阵堆栈,常用于保存当前变换矩阵。函数 glPopMatrix 用于将最后一个(最顶上的)矩阵弹出当前矩阵堆栈,常用于恢复当前变换矩阵原先的状态,如果曾经调用 glPushMatrix 把它保存起来的话。,33,33,3.2.4矩阵堆栈,堆栈是有深度的,如果超出了堆栈深度或当堆栈为空时试图弹出一个矩阵值,都会发生错误。可以用下面的函数获取堆栈深度的最大值: glGet(GL_MAX_MODELVIEW_STACK_DEPTH); glGet(GL_MAX_PROJECTION_STACK_DEPTH);,34,34,3.2.5投影变换,Open

17、GL中只提供了两种投影方式,一种是平行投影(正射投影),另一种是透视投影。在投影变换之前必须指定当前处理的是投影变换矩阵: glMatrixMode(GL_PROJECTION);glLoadIdentity();,35,35,3.2.5投影变换,平行投影视景体是一个矩形的平行管道,也就是一个长方体,其特点是无论物体距离相机多远,投影后的物体大小尺寸不变。 OpenGL中平行投影函数共有两个: glOrtho gluOrtho2D,36,36,3.2.5投影变换,void glOrtho (GLdouble left,GLdouble right, GLdouble bottom,GLdoub

18、le top, GLdouble near,GLdouble far);函数的操作是创建一个正射投影矩阵,并且用这个矩阵乘以当前矩阵。近裁剪平面是一个矩形,矩形左下角点三维空间坐标是(left,bottom,-near),右上角点是(right,top,-near);远裁剪平面也是一个矩形,左下角点空间坐标是(left,bottom,-far),右上角点是(right,top,-far)。所有的near和far值同时为正或同时为负。如果没有其他变换,正射投影的方向平行于Z 轴,且视点朝向Z负轴。这意味着物体在视点前面时far和near都为负值,物体在视点后面时far和near都为正值。,37,

19、37,3.2.5投影变换,void gluOrtho2D (GLdouble left,GLdouble right, GLdouble bottom,GLdouble top);一个特殊的正射投影函数,主要用于二维图像到二维屏幕上的投影。其near和far缺省值分别为-1.0和1.0,所有二维物体的Z坐标都为0.0。裁剪面是一个左下角点为(left,bottom)、右上角点为(right,top)的矩形。,38,3.2.5投影变换,透视投影透视投影的特点是距离视点近的物体大,距离视点远的物体小,远到极点即为消失,成为灭点。它的视景体类似于一个顶部和底部都被切除掉的棱椎,也就是棱台。OpenG

20、L透视投影函数也有两个: glFrustum gluPerspective,39,3.2.5投影变换,void glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);此函数创建一个透视投影矩阵,并且用这个矩阵乘以当前矩阵。参数只定义近裁剪平面的左下角点和右上角点的三维空间坐标,即(left,bottom,-near)和(right,top,-near);最后一个参数far是远裁剪平面的Z负值,其左下角点和右上角点空间坐标由函数根据透视投影原理自动

21、生成。near和far表示离视点的远近,它们总为正值。,40,void gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble near, GLdouble far);它也创建一个对称透视视景体,但它的参数定义于前面的不同,其操作是创建一个对称的透视投影矩阵,并且用这个矩阵乘以当前矩阵。参数fovy定义视野在X-Z平面(垂直方向上的可见区域)的角度,范围是0.0, 180.0;参数aspect是投影平面的纵横比(宽度与高度的比值);参数near和far分别是远近裁剪面沿Z负轴到视点的距离。,3.2.5投影变换,41,3.2.5投影变换,

22、42,3.2.6剪切变换,在 OpenGL 中,除了利用投影变换中视景体定义的六个裁剪平面(上、下、左、右、前、 后)外,还可继续再定义一个或多个附加裁剪平面,对场景进一步进行裁减,以去掉场景中无关的目标。,43,3.2.6剪切变换,附加平面裁剪函数为: void glClipPlane(GLenum plane,Const GLdouble *equation); 这个函数定义一个附加的裁剪平面。其中参数equation指向一个包含四个双精度浮点数 的数组,这四个系数分别是裁剪平面 Ax+By+Cz+D=0 的 A、B、C、D 值。因此,由这四个 系数就能确定一个裁剪平面。参数 plane 是符号常数 GL_CLIP_PLANEi (i=0,1,.),用于指定裁剪面号。,44,3.2.6剪切变换,注意:在调用附加裁剪函数之前,必须先启动 glEnable(GL_CLIP_PLANEi),使得当前 所定义的裁剪平面有效;当不再调用某个附加裁剪平面时,可用 glDisable(GL_CLIP_PLANEi) 关闭相应的附加裁剪功能。,45,3.2.6剪切变换,例子红皮书clip.c,46,3.2OpenGL中的变换,综合例子红皮书planet.c robot.c,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号