显示列表:
不管数据描述的是几何体还是像素,都可以被存储在显示列表中,供现在或以后使用;也可以不将数据存储在显示列表中,而是立刻对数据进行处理,这被称为直接模式.显示列表被执行时,其中存储的数据被发送出去,就像在应用程序中用直接模式发送一样.
求值程序:
所 有的几何图元最终都是使用顶点描述的.参数化曲面和曲线最初可能是由控制点和多项式函数(基函数)描述的.求值程序提供了一种根据控制点导出描述曲面的顶 点的方法.这种方法是一种多项式映射(polynomial mapping),能够根据控制点生成面法线、纹理坐标和空间坐标值.
顶点操作:
对于顶点数据,接焉的处理步骤是"顶点操作":将顶点转换为图元.对于有些类型的顶点(如空间坐标),使用4*4的浮点数矩阵对其进行变换.三维空间坐标被投影到屏幕.
如果启用了高级特性,这个阶段需要完成的工作更多.如果使用了纹理映射,将可能生成纹理坐标,并对其进行变换.如果光照功能被启用,将执行光照计算:根据变换后的顶点、面法线和其他光照信息计算颜色值.
图元装配:
这个阶段的处理结果是完整的几何图元:变换和裁剪后的顶点以及相关的颜色、深度、纹理坐标值和光栅化准则.
像素操作:
首先将系统内存的像素数组进行拆封:从某种格式转换为合适数目的分量.接下来对数据进行缩放、偏移和像素映射.然后将得到的数据进行截取,并将其写入纹理内存或发送给光栅化操作进行处理.
如果是从帧缓存中读取像素数据,则对其执行像素转换(缩放、偏移、映射和截取)操作.然后将其封装成合适的格式,并存储到系统内存的数组中.
纹理装配:
如果使用了多个纹理图像,最好将它们存储到纹理对象中,这样可以方便在它们之间进行切换.
光栅化:
将几何数据和像素数据转换为片元.每个片元都对应于帧缓存中的一个像素.将顶点连接成直线或计算填充多边形内部的像素时,需要考虑直线和多边形的点画模式、线宽、点的大小、着色模式以及用于支持反走样的覆盖率计算.这个阶段确定了每个片元的颜色和深度值.
将片元值写入帧缓存之前,将执行一系列的操作,它们可能修改甚至丢弃片元.这些操作都可以被启用和禁用.
第 一个操作可以是纹理映射:对于每个片元,从纹理内存中选择一个纹素,并将其应用于该片元.接下来,可执行雾计算;然后是裁剪测试、alpha测试、模板测 试和深度测试(深度缓存用于隐藏面消除).然后执行混合、拌动、逻辑运算和屏蔽.最后,处理后的片元被绘制到合适的缓存中,并变成像素.
当我们把要绘制的三角形传给OpenGL之后,OpenGL还要做许多工作以完成3D空间到屏幕的投影。这一系列的过程被称为OpenGL的渲染流水线。一般地,OpenGL的渲染流程如下:
2.2.1 视图变换
当一个场景确定之后,如果我们想移动某个物体,或者要实现场景内的漫游,就必须进行模型视图的变换。模型视图变换可以根据需要,移动或旋转一个或多个物 体。例如,如果我们想在3D空间中沿着Z轴向前走的话,只需要把所有物体向-Z方向移动n个单位即可。如果我们要向左看,就应该把所有物体沿着Y轴渲染向 右旋转N个角度。下图演示了这个过程。
2.2.2 背面隐藏
在一些封闭的3D物体中,朝着物体内部的面总是不可见的。对于这些永远不可见的平面,我们可以使用背面隐藏忽略对它的绘制以提高渲染速度。为了实现背面隐 藏,我们在绘制三角形的时候必须注意三角形的绕法。一般的,OpenGL默认为逆时针缠绕的面是正面。如下图所示的三角形中,如果把顶点按照 V1->V3->V2的顺序传给OpenGL,那么OpenGL就会认为这个三角形朝着屏幕的面是正面。
使用背面隐藏,就要求我们在把图形传给OpenGL的时候要始终遵守正面使用逆时针绕法的规定。要开启背面隐藏的功能,只需调用函数:
glEnable(GL_CULL_FACE);
当然,我们也可以改变OpenGL的设置,决定是对物体的正面还是背面进行隐藏。调用如下函数:
glCullFace(GL_FRONT);
来隐藏正面,也可调用
glCullFace(GL_BACK);
来隐藏背面。
2.2.3 光照渲染
如果你开启了光照渲染,并且为每个顶点指定了它的法线,在此过程中,OpenGL将根据顶点的法线和光源的位置及性质重新计算顶点的颜色。使用光照效果可以大大提高画面的真实性。我们将在第六章中讲到光照。
2.2.4 剪裁
剪裁就是把那些不在视见空间,或者一半在可视空间中的物体剔除或剪裁,以保证不该出现在屏幕上的图形就不出现。
2.2.5 投影
要把一个3D空间中的物体显示在屏幕上,就要进行投影。投影又有两种方式:平行投影和透视投影。在平行投影中,远处的物体和近处的物体是一样大的,这种投 影主要运用在计算机辅助设计(CAD)上,由于这种投影没有立体感,所以一般情况下使用透视投影。在透视投影中,远处的物体会变得较小,因此在透视投影 中,可视空间是一个平头截体(或台体)。下图表明了投影变换的原理。
2.2.6 视见空间变换
当3D空间中的图形经过投影成为2D图形之后,我们还要把图形缩放到窗口或屏幕上。这个过程被称为视见空间变换。对于一般的游戏来说,视见空间应该是整个屏幕或窗体。但是视见空间也可以是它的子集。
2.2.7 光栅化
当2D图形的所有变换都完成之后,就要把它们栅格化以显示在屏幕上,或保存为BMP图片。栅格化其实是把变换得到的2D矢量图转化为位图的过程。
2.2.8 绘制
在这一步中,将由Windows GDI把光栅化的图形显示在屏幕上。