1、单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,#,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,#,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,#,2.3 OpenGL,介绍,2.3.1,背景,OpenGL(Open Graphics Library,,开放式图形库,),是以,SGI,的,GL,三维图形库为基础制定的一个,开放式三维图形标准,。,SGI,在,1992,年,7,月发布了,1.0,版。,OpenGL,规范由,ARB(OpenGL Architecture Revie
2、w Board,,,OpenGL,结构评审委员会,),负责管理,目前加入,OpenGL ARB,的成员有,SGI,、,Microsoft,、,Intel,、,IBM,、,SUN,、,Compaq,、,HP,等公司,它们均采用了,OpenGL,图形标准,许多软件厂商以,OpenGL,为基础开发自己的产品,硬件厂商提供对,OpenGL,的支持。,由于,OpenGL,的广泛应用,它已经成为一个工业标准。,OpenGL,独立于硬件设备、窗口系统和操作系统,,使得以,OpenGL,为基础开发的应用程序可以在各种平台间移植。,OpenGL,可以运行在当前各种流行操作系统之上,如,Windows95/98,
3、Windows NT/2000,、,Linux,、,Mac OS,、,Unix,、,OS/2,等。,特别需要指出的是,由于,Microsoft,公司在其,Windows95,或更高版本的操作系统和,Visual,系列高级语言开发环境中捆绑了,OpenGL,标准,使得,OpenGL,在微机中得到了更为普遍的应用。,OpenGL,可以,与各种编程语言紧密接口,。各种流行的编程语言如,C,、,C+,、,Fortran,、,Ada,、,Java,等都可以调用,OpenGL,中的库函数。,2.3.2 OpenGL,的主要功能,绘制模型:,提供了绘制点、线、多边形、球、锥、多面体、茶壶等复杂的三维物体
4、以及贝塞尔、,NURBS,等复杂曲线或曲面的绘制函数。,各种变换,:提供了平移、旋转、变比和镜像四种基本变换以及平行投影和透视投影两种投影变换。通过变换实现三维的物体在二维的显示设备上显示。,着色模式:,提供了,RGBA,模式和颜色索引两种颜色的显示方式。,光照处理:,在自然界我们所见到的物体都是由其材质和光照相互作用的结果,,OpenGL,提供了辐射光,(Emitted Light),、环境光,(Ambient Light),、漫反射光,(Diffuse Light),和镜面光,(Specular Light),。材质是指物体表面对光的反射特性,在,OpenGL,中用光的反射率来表示材质。,
5、纹理映射,(Texture Mapping),:,将真实感的纹理粘贴在物体表面,使物体逼真生动。纹理是数据的简单矩阵排列,数据有颜色数据、亮度数据和,alpha,数据。,位图和图像,:提供了一系列函数来实现位图和图像的操作。位图和图像数据均采用像素的矩阵形式表示。,制作动画:,提供了双缓存,(Double Buffering),技术来实现动画绘制。双缓存即前台缓存和后台缓存,后台缓存用来计算场景、生成画面,前台缓存用来显示后台缓存已经画好的画面。当画完一帧时,交互两个缓存,这样循环交替以产生平滑动画。,选择和反馈:,OpenGL,为支持交互式应用程序设计了选择操作模式和反馈模式。在选择模式下,
6、则可以确定用户鼠标指定或拾取的是哪一个物体,可以决定将把哪些图元绘入窗口的某个区域。而反馈模式,,OpenGL,把即将光栅化的图元信息反馈给应用程序,而不是用于绘图。,此外,,OpenGL,还提供了反走样技术,能够实现深度暗示,(Depth Cue),、运动模糊,(Motion Blur),、雾化,(Fog),等特殊效果。,2.3.3 OpenGL,的绘制流程和原理,点数据,评价器,逐点操作,基元匹配,显示列表,像素数据,像素操作,纹理存储器,光栅化,基片操作,帧缓冲区,OpenGL,指令从左侧进入,OpenGL,,有两类数据,分别是由顶点描述的几何模型和由像素描述的位图、影像等模型,其中后者
7、经过像素操作后直接进入光栅化。评价器,(Evaluator),用于处理输入的模型数据,例如对顶点进行转换、光照,并把图元剪切到视景体中,为下一步光栅化做好准备。显示列表,(Display List),用于存储一部分指令,留待合适时间以便于快速处理。光栅化将图元转化成二维操作,并计算结果图像中每个点的颜色和深度等信息,产生一系列图像的帧缓存描述值,其生成结果称为基片,(Fragment),。基片操作主要的有帧缓存的更新、测试、融合和屏蔽操作,以及基片之间的逻辑操作和抖动,(Dithering),。,2.3.4 VC,开发,OpenGL,绘图程序,第一步:向项目文件中添加,OpenGL,的绘图函数
8、Project|Settings|Link,在,Object/library modules,:中输入,opengl32.lib glu32.lib glaux.lib,第二步:添加头文件,在项目工作区的,FileView,中找到,StdAfx.h,,添加下面的代码:,#include,#include,#include,接下来,在,Visual C+,中,修改视图类成员函数代码实现,OpenGL,绘图的过程如下:,改造,PreCreateWindow,函数:将窗口的客户区设置为,OpenGL,能够支持的风格。具体添加代码如下:,cs.style|=WS_CLIPCHILDREN|WS_CL
9、IPSIBLINGS;,在视图类,添加一个成员变量,HGLRC m_hRC,;,然后改造,OnCreate,函数:定义像素存储格式,并创建一个,OpenGL,操作所必须的绘图上下文,RC,(Rendering Context),。使用一个,PIXELFORMATDESCRIPTOR,结构来指定,像素格式,,使用,wglCreateContext(),函数创建绘图上下文,RC,。,具体添加代码如下:,/,首先定义像素存储格式,PIXELFORMATDESCRIPTOR,pfd,=,sizeof(PIXELFORMATDESCRIPTOR),/pfd,的大小,1,/,结构的版本号,PFD_DRAW
10、TO_WINDOW|/,支持,window,PFD_SUPPORT_OPENGL,/,支持,OpenGL,PFD_TYPE_RGBA,/RGBA,颜色模式,24,/24,位颜色深度缓存,0,0,0,0,0,0,/color bits ignored,0,/no alpha buffer,0,/shift bit ignored,0,/,不使用累积缓存,0,0,0,0,/accum bits ignored,32,/32,位,z,缓冲,0,/,不使用模板缓存,0,/no auxiliary buffer,PFD_MAIN_PLANE,/,选择主层面,0,/,保留,0,0,0/layer mas
11、ks ignored,;,CClientDC dc(this);,int pixelFormat=ChoosePixelFormat(dc.m_hDC,BOOL success=SetPixelFormat(dc.m_hDC,pixelFormat,/,创建绘图上下文,RC,m_hRC,=wglCreateContext(dc.m_hDC);,改造,OnSize,函数:当视图尺寸变化是,应及时将新的客户区尺寸通知,OpenGL,,方能够正确在窗口客户区域显示二维场景,通过命令,glViewPort,完成这项工作。,改造,OnEraseBkgnd,函数:重载视图类的,OnEraseBkgnd,成
12、员,使之返回,TRUE,值可以阻止,Windows,重画窗口背景,因为,OpenGL,自己会设置窗口背景,这样可以防止窗口频繁刷新,(,如移动窗口,),时产生的闪烁现象。,改造,OnDestroy,函数:在,OnDestroy,成员中需要释放,OnCreate,成员中,RC,所占用的资源,命令,wglDeleteContext,可以完成这个工作,但在释放,RC,之前,还需要使用命令,wglMakeCurrent(),断开,RC,与设备描述表,DC,的连接。具体代码如下:,wglMakeCurrent(NULL,NULL);,wglDeleteContext(m_hRC);,改造,OnDraw,
13、根据当前的视点、视距、观看方向等参数,设置合适的,OpenGL,视景体属性,使用户能够看到预期的场景外观。添加的代码如下:,wglMakeCurrent(pDC-m_hDC,m_hRC);,DrawScene();/,用户自定义函数,用来编写,OpenGL,绘制语句的,wglMakeCurrent(pDC-m_hDC,NULL);,在,DrawScene(),函数中编写具体的绘图程序。首先需要设置视点、视距和观看方向等场景参数,然后绘制图元。,glClearColor(0.0,0.0,0.0,0.0);,glClear(GL_COLOR_BUFFER_BIT);,glBegin(GL_LIN
14、ES);/OpenGL,绘制直线命令,glColor3f(1.0,0.0,0.0);/,设置当前颜色为红色,glVertex2f(0,0);,glVertex2f(1,1);,glColor3f(0.0,1.0,0.0);/,设置当前颜色为绿色,glVertex2f(0.2,0);/(,书中程序有误!,),glVertex2f(1.20,1);,glEnd();,glClearColor(0.0,0.0,0.0,0.0);,glClear(GL_COLOR_BUFFER_BIT);,glBegin(GL_TRIANGLES);,glColor3f(1.0,0.0,0.0);/,红色,glVer
15、tex3f(-1.0,0.0,0.0);,glColor3f(0.0,1.0,0.0);/,绿色,glVertex3f(0.0,1.0,0.0);,glColor3f(0.0,0.0,1.0);/,蓝色,glVertex3f(1.0,0.0,0.0);,glEnd();,2.3.5 OpenGL,的缓冲区,OpenGL,进行图形显示需要四个缓冲区:颜色缓存、深度缓存、模板缓存和累计缓存。,颜色缓存:,由红、绿、蓝、,Alpha,位等位平面,(Bitplane),组成的,有前缓存,(Front Buffer),、后缓存,(Back Buffer),、左前,(Front_Left),和右前,(Fr
16、ont_Right),缓存、左后,(Back_Left),和右后,(Back_Right),缓存。左前缓存是必须的颜色缓存。前缓存是可见缓存,后缓存是不可见缓存。前后缓存技术可以实现动画操作。,与颜色缓存相关的主要函数有:,清除颜色缓存:,glClear(GL_COLOR_BUFFER_BIT),,用于清除当前显示缓冲区内容,为开始新的绘制做好准备。,设置清除颜色:,glClearColor(red,green,blue,alpha),,用当前颜色,(red,green,blue,alpha),清除当前显示缓冲区内容,为开始新的绘制做好准备。,屏蔽颜色缓存:,glColorMask(),,分别
17、设置红、绿、蓝、,alpha,的可写属性。,选择颜色缓存:,glDrawBuffer(),,用于对双缓存中一个进行选择。,交换颜色缓存:,swapBuffer(),,交换前后缓存中的颜色,以实现动画,深度缓存:,也叫,Z-buffer,,它记录每个像素点所对应的物体点到视点的距离,由此决定表面的可见性。在进行消隐的时候,,OpenGL,必须知道各物体间的相对位置关系,从而模拟出物体相互遮挡得效果,因此,需要进行深度测试。而深度测试的结果就生成了深度缓存。,与深度缓存相关的,OpenGL,操作主要有:,清除深度缓存:,glClear(GL_DEPTH_BUFFER_BIT),,用于清除当前显示缓
18、冲区内容,为开始新的绘制做好准备;,设置清除值:,glClearDepth(1.0),;,屏蔽深度缓存:,glDepthMask(GL_TRUE),,表示可以写深度缓存;,glDepthMask(GL_FALSE),,表示禁止写深度缓存;,启动和关闭深度测试:,glEnable(GL_DEPTH_TEST),,表示开启深度测试;,glDisable(GL_DEPTH_TEST),,表示禁止深度测试。,确定测试条件:,glDepthFunc(),,根据函数参数确定测试方式,具体的参数说明请参考,OpenGL,手册。,确定深度范围:,glDepthRagne(Glclampd zNear,Glcl
19、ampd zFar),,参数,zNear,和,zFar,分别说明视景体的前景面和后景面向窗口坐标映射的规格化坐标,便于后续使用。,模板缓存和累积缓存主要用于图形的特殊效果绘制。,模板缓存:,存放像素的模板值。可用于控制像素是否被改写,因而其可以禁止在屏幕的某些区域绘图。模板缓存可以用于多种复杂图形的绘制,例如:屏蔽屏幕区域(凸区域或凹区域,因而也可以绘制凹多边形等);遮盖物体;制作物体的交集等。,累积缓存:,是一系列绘制结果的累积,可以用来实现场景的反走样、景深模拟、运动模糊等。例如为了实现全局反走样,可多次绘制场景,每次绘制时轻微移动场景,(,相当于在空间上抖动场景,),,把多次绘制的结果进行累积并最后一次输出,结果场景的边界会变得模糊,从而实现全局反走样。,






