FBO技术应该算是OpenGL里很实用的高级技术, 如果你没接触过这个技术那么请看这篇文章, 你就会大致入门了. http://www.gamedev.net/reference/programming/features/fbo1/
我写这篇文章不是重述上面文章里所讲的关于FBO详细使用方法, 我是想说一下我自己对FBO的理解.
首先我们知道OpenGL绘制的流水线最后一道工序就是填充显卡内部的默认帧缓冲区,然后显示器把帧缓冲区中的内容显示到屏幕上. 帧缓冲区应该说是一系列缓冲区的集合,包括颜色缓冲区(对应屏幕上的每个像素的颜色),深度缓冲区,蒙版缓冲区等等.所以从这个原理上讲如果想使用FBO技术进行脱屏绘制,那么就应该另外申请如上的这么些缓冲区,然后把流水线最终的结果填充到自己申请的缓冲区就可以了.
既然明白了上述的基本流程,那么FBO技术基本可以用下图理解(只是理解图)
如上图所示FBO可以看做是一个缓冲区指针的集合, 所以还需另外申请相应的内存空间以保存深度和颜色值(因为一般用不到其他缓冲区,比如蒙版缓冲区,所以这里可以不申请). 而颜色缓冲区有两种方法可以实现, 一种是申请一个RenderBuffer存放每个像素的颜色值 ; 另一种方法就是申请一个纹理内存空间存放颜色值.
FBO到屏幕的过程, 目前我的理解还不是很透彻,只知道一种方法可以实现,那就是使用上面的纹理作为颜色缓冲区之后,纹理保存的内容就应该是最终屏幕上显示的内容,所以可以简单的绘制一个覆盖全窗口的矩形,把上面的纹理贴到矩形上,这样就完成了从FBO到屏幕的转移!
难点解析:
[1]. 渲染到纹理: 意思就是在使用FBO的过程中使用纹理内存作为颜色缓冲区而不是使用RenderBuffer作为颜色缓冲区.
[2]. 如何在FBO和正常的帧缓冲区之间切换?
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); glPushAttrib(GL_VIEWPORT_BIT); glViewport(0,0,width, height); // Render as normal here // output goes to the FBO and it’s attached buffers glPopAttrib(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
如代码所示, glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); 最后一个参数如果是fbo的句柄,那么就表示下面的绘制要使用FBO; 如果最后一个参数是 0 就表示切换到了正常的帧缓冲区(直接绘制到屏幕上的). 或者也可以这样理解,系统允许有多个帧缓冲区,而默认的是使用0号缓冲区.