OpenGL基本程序结构
用OpenGL编写的程序结构类似于用其他语言编写的程序。实际上,OpenGL是一个丰富的三维图形函数库,编写OpenGL程序并非难事,只需在基本C语言中调用这些函数,用法同Turbo C、Microsoft C等类似,但也有许多不同之处。
本指南所有的程序都是在Windows NT的Microsoft Visual C++集成环境下编译连接的,其中有部分头文件和函数是为这个环境所用的,例如判别操作系统的头文件“glos.h”。此外,为便于各类读者同时快速入门,在短时间内掌握OpenGL编程的基本方法和技巧,指南中例子尽量采用标准ANSI C调用OpenGL函数来编写,而且所有例程都只采用OpenGL附带的辅助库中的窗口系统。此外,这样也便于程序在各平台间移植,尤其往工作站UNIX操作系统移植时,也只需改动头文件等很少很少的部分。下面列出一个简单的OpenGL程序:
例4-1 OpenGL简单例程(Simple.c)
1. #include 2. #include 3. #include "glos.h" 4. 5. void main(void) 6. { 7. auxInitDisplayMode(AUX_SINGLE|AUX_RGBA); 8. auxInitPosition(0,0,500,500); 9. auxInitWindow("simple"); 10. 11. glClearColor(0.0,0.0,0.0,0.0); 12. glClear(GL_COLOR_BUFFER_BIT); 13. 14. glColor3f(1.0,0.0,0.0); 15. glRectf(-0.5,-0.5,0.5,0.5); 16. 17. glFlush(); 18. _sleep(1000); 19. } 这个程序运行结果是在屏幕窗口内画一个红色的方块。 下面具体分析整个程序结构:首先,在程序最开始处是OpenGL头文件: 1. auxInitDisplayMode(AUX_SINGLE|AUX_RGBA); 2. auxInitPosition(0,0,500,500); 3. auxInitWindow("simple"); auxInitDisplayMode(AUX_SINGLE|AUX_RGBA)设置窗口显示模式为RGBA方式,即彩色方式,并且图形缓存为单缓存(SINGLE BUFFER)。auxInitPosition(0, 0, 500, 500)定义窗口的初始位置,前两个参数(0, 0)为窗口的左上角点的屏幕坐标,后两个参数(500,500)为窗口的宽度和高度。auxInitWindow("simple")是窗口初始化,字符参数是窗口名称。 然后是窗口内清屏: 1. glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT); 第一句将窗口清为黑色,第二句将颜色缓冲区清为glClearColor(0.0, 0.0, 0.0, 0.0)命令所设置的颜色,即同窗口背景颜色一致。 再接着是在窗口内画一个物体: 1. glColor3f(1.0,0.0,0.0); 2. glRectf(-0.5,-0.5,0.5,0.5); 很明显,第一句设置物体颜色,函数中前三个参数分别为R、G、B值,最后一个参数是Alpha值,范围都从0至1;第二句绘制一个二维矩形。注意:OpenGL是针对三维图形而言,因此用作OpenGL编程绘制物体必须意识到任何一个物体都是三维的,具有空间性,而显示于屏幕上的物体都是三维物体在二维平面上的投影。 从表面上看,上述程序代码很简单,实际上已经用到了缺省的投影形式(正射投影)。再看glFlush()函数,表示强制绘图完成。最后一句_sleep(1000),参数单位为毫秒,整句意思是保持现有状况一秒钟,然后结束程序运行。这个函数是VC++的库函数。 总而言之,OpenGL程序基本结构为定义窗口、清理窗口、绘制物体、结束运行。 2.1、OpenGL基本理解 OpenGL是一个与硬件图形发生器的软件接口,它包括了100多个图形操作函数,开发者可以利用这些函数来构造景物模型、进行三维图形交互软件的开发。正如上一章所述,OpenGL是一个高性能的图形开发软件包。OpenGL支持网络,在网络系统中用户可以在不同的图形终端上运行程序显示图形。OpenGL作为一个与硬件的图形接口,它不提供与硬件密切相关的设备操作函数,同时,它也不提供描述类似于飞机、汽车、分子形状等复杂形体的图形操作函数。用户必须从点、线、面等最基本的图形单元开始构造自己的三维模型。当然,象OpenInventor那样更高一级的基于OpenGL的三维图形建模开发软件包将提供方便的工具。因此OpenGL的图形操作函数十分基本、灵活。例如OpenGL中的模型绘制过程就多种多样,内容十分丰富,OpenGL提供了以下的对三维物体的绘制方式: •网格线绘图方式(wireframe) 这种方式仅绘制三维物体的网格轮廓线。 •深度优先网格线绘图方式(depth_cued) 用网格线方式绘图,增加模拟人眼看物体一样,远处的物体比近处的物体要暗些。 •反走样网格线绘图方式(antialiased) 用网格线方式绘图,绘图时采用反走样技术以减少图形线条的参差不齐。 •平面消隐绘图方式(flat_shade) 对模型的隐藏面进行消隐,对模型的平面单元按光照程度进行着色但不进行光滑处理。 •光滑消隐绘图方式(smooth_shade) 对模型进行消隐按光照渲染着色的过程中再进行光滑处理,这种方式更接近于现实。 •加阴影和纹理的绘图方式(shadows、textures) 在模型表面贴上纹理甚至于加上光照阴影,使得三维景观象照片一样。 •运动模糊的绘图方式(motion-blured) 模拟物体运动时人眼观察所感觉的动感现象。 •大气环境效果(atmosphere-effects) 在三维景观中加入如雾等大气环境效果,使人身临其境。 •深度域效果(depth-of-effects) 类似于照相机镜头效果,模型在聚焦点处清晰,反之则模糊。 这些三维物体绘图和特殊效果处理方式,说明OpenGL已经能够模拟比较复杂的三维物体或自然景观,这就是我们所面对的OpenGL。 2.2、OpenGL工作流程 整个OpenGL的基本工作流程如下图: 其中几何顶点数据包括模型的顶点集、线集、多边形集,这些数据经过流程图的上部,包括运算器、逐个顶点操作等;图像数据包括象素集、影像集、位图集等,图像象素数据的处理方式与几何顶点数据的处理方式是不同的,但它们都经过光栅化、逐个片元(Fragment)处理直至把最后的光栅数据写入帧缓冲器。在OpenGL中的所有数据包括几何顶点数据和象素数据都可以被存储在显示列表中或者立即可以得到处理。OpenGL中,显示列表技术是一项重要的技术。 OpenGL要求把所有的几何图形单元都用顶点来描述,这样运算器和逐个顶点计算操作都可以针对每个顶点进行计算和操作,然后进行光栅化形成图形碎片;对于象素数据,象素操作结果被存储在纹理组装用的内存中,再象几何顶点操作一样光栅化形成图形片元。 整个流程操作的最后,图形片元都要进行一系列的逐个片元操作,这样最后的象素值BZ送入帧缓冲器实现图形的显示。 2.3、OpenGL图形操作步骤 在上一节中说明了OpenGL的基本工作流程,根据这个流程可以归纳出在OpenGL中进行主要的图形操作直至在计算机屏幕上渲染绘制出三维图形景观的基本步骤: 1)根据基本图形单元建立景物模型,并且对所建立的模型进行数学描述(OpenGL中把:点、线、多边形、图像和位图都作为基本图形单元)。 2)把景物模型放在三维空间中的合适的位置,并且设置视点(viewpoint)以观察所感兴趣的景观。 3)计算模型中所有物体的色彩,其中的色彩根据应用要求来确定,同时确定光照条件、纹理粘贴方式等。 4)把景物模型的数学描述及其色彩信息转换至计算机屏幕上的象素,这个过程也就是光栅化(rasterization)。 在这些步骤的执行过程中,OpenGL可能执行其他的一些操作,例如自动消隐处理等。另外,景物光栅化之后被送入帧缓冲器之前还可以根据需要对象素数据进行操作。