使用OpenGL实现视图的变换和投影操作。为了完成这个操作,它可能来自一个单独的函数也可能来自多个函数的组合。视图变换和投影操作应该分开。
定义场景的投影如下:
1 | glMatrixMode(GL_PROJECTION); |
定义场景的视图如下:
1 | glMatrixMode(GL_MODELVIEW); |
定义视点,观察方向以及向上方向使用gluLookAt()函数:
1 | gluLookAt(ex,ey,ez,lx,ly,lz,upx,upy,upz); |
glMatrixMode()用来选择操作模式,投影还是模型视图,然后在定义具体的操作前先调用glLoadIdentity()函数,该函数对紧接的操作初始化,最后调用具体的函数来设置投影或视图变换操作所需的信息,而不与过去的操作数据冲突。
定义窗口和视口:
通过函数定义窗口,这些函数对窗口的大小和位置进行初始化,然后创建窗口。在OpenGL中,创建窗口最简单的方法是使用GLUT工具包,这些函数通常在main()中调用:
1 | glutInitWindowSize(width,height); |
glutCreateWindow()函数返回的是整数值windowHandle,它是窗口的句柄,通过这个句柄可以对这个窗口进行操作,设置为活动窗口,使用glutSetWindow()函数:
1 | glutSetWindow(windowHandle); //设置windowHandle表示的窗口为活动窗口 |
视口通过glViewport函数定义,它指定了窗口中用来显示的左下角坐标和右上角坐标,如果视口比图像窗口小,可以在程序的我初始函数中调用;
glViewport(VPLowerLX,VPLowerLY,VPWidthX,VPHeightY),
可以看到创建属于同一窗口的用于显示两幅独立图像的视口。
设置视图变换的环境
要设置视图变换的环境,必须使用GL_MODEVIEW矩阵来定义单位矩阵,然后指定两个点和一个向量来定义视图变换的环境。
1 | glMatrixMode(GL_MODELVIEW); |
定义视点的步骤如下:
- 绕Z轴旋转,使得向上方向在观察平面上的投影和Y轴对齐
- 进行缩放,使得观察中心位于沿着Z轴负方向上一定距离的点
- 移动变换,使得观察中心位于原点
- 分别绕X轴和Y轴旋转,把 视点放在相对观察中心的正确位置
- 移动变换,把观察中心移到正确位置
视图变换通过把放置在原点的视点变换到所要的位置的逆变换来实现。而glLookAt()函数应该首先出现在display()函数中,它的变换操作如下:
- 把观察中心变换到原点
- 绕X,Y轴旋转,使得视点位于Z轴负方向
- 把视点变换到原点
- 进行缩放,把观察中心变换到(0,0,-1)
- 绕Z轴旋转,使得向上方向与Z轴对齐
定义透视投影
透视透视投影需要指定工作在GL_PROJECTION矩阵,然后设置单位矩阵,最好指定透视变换的属性。顺序如下:
- 观看的范围,用弧度表示宽度
- 高宽比
- zNear的值
- zFar的值
如下代码:
1 | glMatrixMode(GL_PROJECTION) |
也可以是使用函数glFrustum()函数定义透视投影,它的参数是视域体的六个参数,形式如下:
1 | glFrustum(left,right,bottom,near,far); |
定义正交投影
正交投影和透视投影的很相似,除了函数参数以外,要定义正交投影的视域体,只要定义边界就好,使用下main的函数:
1 | glOrtho(xLow,Xhigh,yLow,yHigh,zNear,zFar); |
隐藏面的处理以及设置双缓存
隐藏面的处理不需要我们自己去处理,只要在使用glutInitDisplayMode()函数中指定GLUT_DEPTH,那么就可以处理隐藏面。
1 | glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); |
必须启用深度测试。启用是OpenGL的标准特性,许多系统的功能需要通过调用glEnable函数启用后才能用.
1 | glEnable(GL_DEPTH_TEST); |
如果不想启用可以使用glDisable()函数禁用。深度测试启用后,绘制过程会自动进行。使用glDepthFunc(value)函数可以更改当前的z值。设置双缓存也是在glutInitDisplayMode()函数中指定GLUT_DOUBLE属性,同时在dispaly()函数中是使用glutSwapBuffers()函数用来交换前缓存和后缓存,使得后缓存的内容可以被显示。