帧缓冲区
几乎每个图形程序的重要目标之一都是在屏幕上绘制图形。屏幕是由一个矩形像素数组组成的,每个像素都可以在图像的某一个点上显示一个某种颜色的微小方块。在光栅化阶段(包括纹理和雾)之后,数据就不再是像素,而是片段。每个片段都具有与像素对应的坐标数据以及颜色值和深度值。
如果顺利通过了这些测试和操作,片段值便可以转换为像素。 如果顺利通过了这些测试和操作,片段值便可以转换为像素。为了绘制这些像素,我们需要知道它们的颜色(即存储在颜色缓冲区中的信息)。当每个像素的数据按照统一的方式存储时,存储所有像素的数据按照统一的方式存储时,存储所有像素的存储空间就叫做缓冲区。不同的缓冲区为每个像素存储的数据量可能不同。但是,在一个特定的缓冲区内,每个像素存储的数据是相同的。为每个像素存储了1位信息的缓冲区又称为位平面(bitplane)。
颜色缓冲区
OpenGL在绘制图元时,先是在一个缓冲区中完成渲染,然后再把渲染结果交换到屏幕上。我们把这两个缓冲区称为前颜色缓冲区(屏幕)和后颜色缓冲区。在默认情况下,OpenGL命令是在后颜色缓冲区进行渲染的。当然,也可以直接在前颜色缓冲区中进行渲染。
若要在前颜色缓冲区中进行渲染,第一种方法是直接告诉OpenGL希望在前颜色缓冲区中进行绘图,可以调用下面这个函数来实现这个目的:
void glDrawBuffer(Glenum mode);
如果参数mode指定为GL_FRONT,OpenGL就会在前颜色缓冲区中进行渲染;
如果参数mode指定为GL_BACK,那么渲染将在后颜色缓冲区中进行。
在前颜色缓冲区进行渲染的第二种方法是在OpenGL被初始化时简单地不要求进行双缓冲区渲染。进行单缓冲区渲染时,如果希望把渲染结果实际绘制到屏幕上,需要调用glFlush()或glFinsh(),这点非常重要。
OpenGL实现除了支持单纯的前颜色缓冲区和后颜色缓冲区之外,还支持其他模式,如用于立体渲染的左和右缓冲区以及辅助缓冲区。
深度缓冲区
与颜色缓冲区不同的是,深度缓冲区中所填充的是深度值而不是颜色值。
为了启用深度缓冲区进行深度测试,只需要调用:
glEnable(GL_DEPTH_TEST);
另外,即使深度缓冲区未被启用,如果深度缓冲区被创建,OpenGL也会把所有写入到颜色缓冲区的颜色片段对应的深度值写入到深度缓冲区中。但是,如果我们希望在进行深度测试时临时禁止把值写入到深度缓冲区,我们可以使用函数:
void glDepthMask(GLboolean mask);
把GL_FALSE作为参数,经禁止写入深度值,但并不禁止用已经写入到深度缓冲区的值进行深度测试。
把GL_TRUE作为参数,可以重新启用深度缓冲区的写入。同时,这也是默认的设置。
模板缓冲区
与颜色缓冲区和深度缓冲区类似,模板缓冲区可以为屏幕上的每个像素点保存一个无符号整数值。这个值的具体意义视程序的具体应用而定。在渲染的过程中,可以用这个值与一个预先设定的参考值相比较,根据比较的结果来决定是否更新相应的像素点的颜色值。这个比较的过程被称为模板测试。模板测试发生在透明度测试(alpha test)之后,深度测试(depth test)之前。如果模板测试通过,则相应的像素点更新,否则不更新。就像使用纸板和喷漆一样精确的混图一样,当启动模板测试时,通过模板测试的片段像素点会被替换到颜色缓冲区中,从而显示出来,未通过的则不会保存到颜色缓冲区中,从而达到了过滤的功能。
累积缓冲区
累积缓冲区允许你把渲染到颜色缓冲区的值,拷贝到累积缓冲区。在多次拷贝操作到累积缓冲区时,可以用不同方式的把颜色缓冲区内容和当前累积缓冲区的内容进行重复混合。当在累积缓冲区完成一幅图像之后,可以拷回颜色缓冲区,然后通过SwapBuffers显示到屏幕上。
累积缓冲区的操作通过void glAccum(GLenum op, GLfloat value);控制。第一个参数表示对累积缓冲区所进行的操作。第二个参数是浮点数用于指定缩放因子。
OpenGL支持的累积缓冲区的操作如下表:
操作 | 描述 |
GL_ACCUM | 把颜色缓冲区的颜色值进行缩放后,累加到累积缓冲区 |
GL_LOAD | 把颜色缓冲区的颜色值进行缩放后,替换掉累积缓冲区的颜色值 |
GL_RETURN | 把累积缓冲区的颜色值缩放后,拷贝回颜色缓冲区 |
GL_MULT | 把累积缓冲区的颜色值缩放后,替换掉原累积缓冲区的颜色值 |
GL_ADD | 把累积缓冲区的颜色值缩放后,累加到累积缓冲区 |
由于累积缓冲区会带来大内存的开销,所以在实时应用程序中比较少用。但在非实时的应用程序中,可以产生实时应用程序无法做到的效果。例如,你可以多次渲染场景,并在每次渲染时进行抖动零点几个像素,这样就可以产生整个场景的反走样的效果,比多重采样的效果还要好。还可以模糊前景或背景,然后清晰的渲染一个物体来模拟,照相机景深的效果。