图形学第三次实验.docx

上传人:pu****.1 文档编号:543464091 上传时间:2023-09-22 格式:DOCX 页数:21 大小:706.95KB
返回 下载 相关 举报
图形学第三次实验.docx_第1页
第1页 / 共21页
图形学第三次实验.docx_第2页
第2页 / 共21页
图形学第三次实验.docx_第3页
第3页 / 共21页
图形学第三次实验.docx_第4页
第4页 / 共21页
图形学第三次实验.docx_第5页
第5页 / 共21页
点击查看更多>>
资源描述

《图形学第三次实验.docx》由会员分享,可在线阅读,更多相关《图形学第三次实验.docx(21页珍藏版)》请在金锄头文库上搜索。

1、实验三 几何变换与光照1. 实验目的l 熟悉三维图形显示的基本流程l 熟悉视图变换的设置l 熟悉Windows环境下几何变换的设置与实现l 熟悉光照的设置2. 实验内容在实验一的基础上,增加如下功能:l 利用鼠标的中键(滚轮)实现几何物体的缩放l 利用鼠标的左键实现几何物体的旋转l 利用鼠标右键实现几何物体的平移l 在场景中设置好光照,要求包括:环境光、漫反射光、镜面反射光3. 实验指导在设置场景中的几何变换时,我们需要对三维图形的基本显示流程或者说显示流水线有个基本了解,而后熟悉OpenGL中每种几何变换的实现方法。3.1 三维图形的基本显示流程在计算机绘图中,对场景进行变换的整个过程类似于

2、用一台相机拍摄照片。如图 2.1所示,相机拍摄照片的具体步骤(括号内表示相应的计算机绘图操作)如下:(1) 将相机固定在三脚架上并使相机对准场景(视图变换)(2) 使想要拍摄的场景处于取景框中的合适位置(模型变换)(3) 选择相机镜头或调整放大倍数(投影变换)(4) 决定最终照片尺寸的大小,比如想要得到一张经过放大后的照片(视区变换)(a)照相机(b)计算机环境图 2.1 和照相机类比的计算机显示流程这些步骤与程序中指定的变换顺序相对应,然而这一顺序并不是固定的。在源代码中,视图变换一定要在模型变换之前执行,但是投影变换和视区变换则可以在进行绘图之前的任何时刻进行。图 2.2显示了在计算机中上

3、述操作的顺序。图 2.2 OpenGL的几何变换流水线及各阶段的主要函数既然在计算机中OpenGL的几何变换具有如图 2.2所示的固定流水线,为什么在源代码中,视图变换一定要在模型变换之前执行,但是投影变换和视区变换则可以在绘图之前的任何时刻进行呢?这主要是因为在OpenGL中,维护了一个模型视图矩阵和一个投影矩阵(准确的来说,是维护了一个模型视图矩阵堆栈和一个投影矩阵堆栈,栈顶的矩阵即为当前的变换矩阵),对于物体空间的任意一点,其投影以后的图像坐标由式得到,(2.1)因此,模型视图变换和投影变换在源代码中的先后顺序并不影响程序的结果,视口变换也是一样,它也是单独保存的,规格化后的设备坐标经视

4、区变换后即可得到屏幕坐标,它的顺序也不影响程序的结果。但是,模型变换和视图变换是由一个矩阵来管理的,在OpenGL中,由于各几何变换都是对当前矩阵栈栈顶的矩阵做相应的右乘操作,即,其中为当前矩阵栈栈顶的矩阵,为当前的几何变换,图 2.2中的模型变换和视图变换在源代码中的顺序需要反过来, 即视图变换必须在模型变换之前进行。这一规则对于任一变换序列均适用,即在源代码中的变换序列的顺序需要和实际的变换顺序相反,这主要是由于上述的矩阵操作是右乘操作引起的,如图 2.3所示。图 2.3 源代码中模型视图变换序列的顺序与实际场景中的变换顺序相反原理图对应于几何变换流水线的各个阶段,OpenGL提供了不同的

5、函数以方便用户实现各种变换,如图 2.2所示。3.1.1视图变换在进行视图变换前,需确保当前操作的矩阵是模型视图矩阵,即调用:glMatrixMode(GL_MODELVIEW)。gluLookAt(x0, y0, z0, xRef, yRef, zRef, xUp, yUp, zUp)该函数的作用即确定场景中照相机的位置和方向,也即指定视点坐标系。函数参数所确定的视点坐标系如图 2.4所示,指定了视点坐标系的原点,指定了视点坐标系向上的方向, 指定了视点坐标系的正前方。图 2.4 gluLookAt()所定义的视点坐标系如果不引用gluLookAt()函数,默认的OpenGL参数是3.1.2

6、 模型变换在进行模型变换前,需确保当前操作的矩阵是模型视图矩阵,即调用:glMatrixMode(GL_MODELVIEW)。glTranslated,f(xOffset, yOffset, zOffset)xOffset,yoffset,zOffset分别指明沿x,y,z轴方向的平移量glScaled,f(xScale, yScale, zScale)xScale,yScale,zScale分别指明沿x,y,z轴方向的缩放量glRotated,f(angle, x, y, z)绕轴逆时针方向旋转angle角度,这里需要注意如下两个方面的问题:(1) 旋转角度的单位是度(degree),而不是

7、弧度(radian)(2) 旋转轴必须过坐标原点,如果旋转轴不过原点,需要先将旋转轴平移到坐标原点,而后做相应的逆变换,如图 2.5所示。这里需要说明一下变换顺序的问题,这里我们需要得到的最终变换矩阵应为:在OpenGL中,由于各几何变换(旋转,平移,缩放)都是对当前矩阵栈栈顶的矩阵做相应的右乘操作,即,其中为当前矩阵栈栈顶的矩阵,为当前的几何变换,上述的变换序列在OpenGL中的顺序需要反过来,用代码可以表示为: glTranslated(x0, y0, z0);glRotated(angle, x, y, z);glTranslated(-x0, y0, z0);图 2.5 旋转轴不过坐标

8、原点时的处理3.1.3 投影变换在进行投影变换前,需确保当前操作的矩阵是投影矩阵,即调用:glMatrixMode(GL_PROJECTION)。投影变换包括正交投影和透视投影两种。正交投影变换可以通过如下函数指定:glOrtho(left, right, top, bottom, near, far)其各参数均是在视点坐标系中定义的,其意义如图 2.6所示,near和far值为近、远裁剪面距离视点坐标系原点的距离,两个参数中任意一个负值表明在观察原点的“后面”。若要使得该函数定义的视景体有效,需满足,OpenGL正交投影的默认参数值是,生成一个在视点坐标系中的规范化的立方体,即:glOrth

9、o(-1, 1, -1, 1, -1, 1);图 2.6 glOrtho()函数所定义的视景体(View Volume)透视投影可以通过如下两个函数分别定义:gluPerspective(fovy, ratio, near, far)各参数的几何意义如图 2.7所示,该函数可以定义一个四凌锥的视景体。图 2.7 由gluPerspective()函数指定的透视视景体glFrustum(left, right, top, bottom, near, far)glFrustum()函数中各参数的意义与glOrtho()函数类似,与之不同的是,前四个参数仅用于定义近裁剪面,即参数和分别指定近裁剪面的

10、左下角和右上角的x,y,z坐标;参数near和far分别表示视点与近裁剪面和远裁剪面的距离。图 2.8 由glFrustum()函数指定的透视视景体注意:为了避免视窗中显示的物体与实际的几何物体发生比例失调的现象,投影变换中的长宽比应该与Windows视窗的长宽比保持一致,该操作通常在Windows的WM_SIZE消息的响应函数OnSize()中实现。如果是利用gluPersepctive()函数指定视景体,其实现方式为:void CView:OnSize(UINT nType, int cx, int cy)/ select the full client areaglViewport(0,

11、 0, cx, cy);/ compute the aspect ratio/ this will keep all dimension scales equalGLdouble aspect_ratio = (GLdouble)cx/(GLdouble)cy;gluPerspective(60.0f, aspect_ratio, .1f, 200.0f);如果是利用glOrth()或者glFrustum()函数指定的视景体,其实现方式为:void CView:OnSize(UINT nType, int cx, int cy)/ TODO: Add your message handler

12、code hereif ( 0 = cx | 0 = cy )return;/ select the full client areaglViewport(0, 0, cx, cy);/ compute the aspect ratio/ this will keep all dimension scales equaldouble xExt = 1.0, yExt = 1.0;if(cx cy)xExt = cx / cy;elseyExt = cy / cx;glOrtho(-xExt, xExt, -yExt, yExt, 1.0f, 1000.0f);/glFrustum(-xExt,

13、 xExt, -yExt, yExt, 1.0f, 1000.0f);3.2 几何变换在MFC文档/视图结构中的实现位置对于几何变换流水线中的各个阶段,在MFC的文档/视图结构中,又该在什么时机进行设置呢?投影变换、视图变换和视区变换,由于与Windows的窗口大小相关,通常写在WM_SIZE消息的响应函数OnSize()中,模型变换则在具体绘制函数中实现,因而放置在WM_PAINT消息的响应函数OnDraw()中,如图 2.9所示。图 2.9 各几何变换在MFC中的实现位置以下是一个OnSize()函数的典型实现过程。void CView:OnSize(UINT nType, int cx,

14、 int cy)CView:OnSize(nType, cx, cy);/ TODO: Add your message handler code hereif ( 0 = cx | 0 = cy )return; /视区变换/ select the full client areaglViewport(0, 0, cx, cy);/投影变换/ compute the aspect ratio, this will keep all dimension scales equalGLdouble aspect_ratio = (GLdouble)cx/(GLdouble)cy;/ select

15、the projection matrix and clear itglMatrixMode(GL_PROJECTION);glLoadIdentity();/ select the viewing volumegluPerspective(60.0f, aspect_ratio, .1f, 200.0f); /模型视图变换,以视图变换开始/ switch back to the modelview matrix and clear itglMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(0, 0, 2, 0, 0, 0, 0, 1, 0);注意:在进行模型视图变换之前,需要将矩阵模式切换到模型视图变换矩阵状态,在进行投影变换之前,则需将阵阵模式切换到投影矩阵状态,其实现方式分别为:glM

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 社会民生

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号