渲染缓冲区对象主要是为了实现屏外渲染(Off-screen Rendering)而设计的。渲染缓冲区对象主要用做FBO的深度缓冲区和模板缓冲区。可以使用glGenRenderbuffersEXT()函数来申请一个或多个闲置的渲染缓冲区对象ID(非负整数)。ID 0被OpenGL所保留。注意,申请了闲置ID之后,OpenGL并没有创建实际的对象,需要调用glBindRenderbufferEXT()函数来绑定并创建实际的对象。如果绑定ID 0,OpenGL会解除先前设定的渲染缓冲区对象。
上文提到过,渲染缓冲区对象实际上是某种二维数组的抽象。在绑定了一个渲染缓冲区对象之后,需要使用glRenderbufferStorage()函数为其分配二维数组存储空间。注意,同一个FBO中的各个二维数组空间的行数(或列数)应该相同。
同FBO类似,可以使用glDeleteRenderbuffersEXT()函数来删除一个渲染缓冲区对象。
挂接
可以使用glFramebufferRenderbufferEXT()函数将渲染缓冲区对象挂接到FBO上;使用glFramebufferTexture2D()。如果挂接的ID为0,则OpenGL将解除先前的绑定。当被绑定纹理对象或渲染缓冲区对象被删除,则他们会被自动从当前正在使用的FBO上解除挂接。如果纹理对象或渲染缓冲区对象被挂接到多个FBO上,他们被删除的时候,只会从当前被绑定的FBO上解除挂接,而不会从未被绑定的FBO上解除绑定。
FBO的完整性
在向FBO输出渲染结果之前,需要测试FBO的完整性。如果FBO不完整,任何渲染操作都会失败。我们可以使用glCheckFramebufferStatusEXT()函数来测试FBO的完整性(此函数不能在glBegin()和glEnd()函数之间调用)。FBO完整性的判别法则如下:
与FBO挂接的二维数组对象的长度和宽度必须不能为0。
如果一个二维数组对象被挂接到FBO的颜色缓冲区挂接点时,二维数组必须具有内部颜色格式(GL_RGBA, GL_DEPTH_COMPONENT, GL_LUMINANCE等)。
如果一个二维数组对象被挂接到FBO的深度缓冲区挂接点时,二维数组必须具有内部深度格式(GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24_EXT等)。
如果一个二维数组对象被挂接到FBO的模板缓冲区挂接点时,二维数组必须具有内部模板格式(GL_STENCIL_INDEX, GL_STENCIL_INDEX8_EXT等)。
FBO至少挂接有一个二维数组缓冲区对象。
同一个FBO上挂接的二维数组对象必须拥有相同的长度和宽度。
所有的颜色缓冲区挂接点上挂接的二维数组对象必须具有相同的内部格式。
FBO的使用
当所有上述的准备工作都完成之后,就可以调用glBindFramebufferEXT()来绑定一个FBO。随后,就可一像操作窗体系统提供的帧缓冲区一样操作当前绑定的FBO了。日常的3D渲染操作这里不再赘述。这里主要强调像素操作的使用。OpenGL提供了glBlitFramebufferEXT()函数进行像素操作。
示例代码
示例代码使用FBO实现渲染到纹理(Render to texture)功能。编译代码需要链接GLEW和SDL两个库。
具体下载目录在 /2014年资料/3月/25日/OpenGL中的FBO对象(附源码)