OpenGL-framebuffers
1.创建一个帧缓冲
到目前为止,我们使用了用于写入颜色值的颜色缓冲、用于写入深度信息的深度缓冲、用于丢弃特定片段的模板缓冲。这些缓冲结合起来叫做帧缓冲。我们目前的工作都是在默认帧缓冲的渲染缓冲上进行,GLFW为我们提供的,但是opengl还允许我们定义自己的缓冲,帮助我们来实现更多的效果。
同其他对象一样,我们通过glGenFramebuffers
来创建帧缓冲对象。
unsigned int fbo;
glGenFramebuffers(1, &fbo);
它的使用方法也和其他对象类似,首先创建帧缓冲对象,把它绑定为active,在使用过后再解绑帧缓冲。我们通过glBindFramebuffer
来绑定帧缓冲。
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
其中GL_FRAMEBUFFER
其实包含了两个目标,它们分别是GL_READ_FRAMEBUFFER
和GL_DRAW_FRAMEBUFFER
即读取目标和写入目标。绑定到读取目标的帧缓冲将会使用在所有像是glReadPixels
的读取操作中,而绑定到写入目标的帧缓冲将会被用作渲染、清除等写入操作的目标。当然我们也可以分别绑定,但是在大部分情况下不需要区分它们。
一个完整的帧缓冲需要满足:
- 附加至少一个缓冲(颜色、深度或模板缓冲)
- 至少有一个颜色附件(Attachment)
- 所有的附件都必须是完整的(保留了内存)
- 每个缓冲都应该有相同的样本数
因此我们还需要为我们刚刚创建的帧缓冲准备一些附件,随后还可以检查帧缓冲是否完全
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
// 执行胜利的舞蹈
else
// 干
之后所有的渲染操作都会渲染到当前绑定帧缓冲的附件中。但是由于我们的帧缓冲不是默认帧缓冲,因此我们还需要再次激活默认帧缓冲,绑定到0
,这种渲染到不同的帧缓冲叫做离屏渲染
glBindFramebuffer(GL_FRAMEBUFFER, 0);
最后还要记得删除我们的帧缓冲对象(注意在创建和删除帧对象时,由于我们可以同时操作多个帧对象,在函数名中Framebuffers
用的也是复数形式)
glDeleteFramebuffers(1, &fbo);
下面我们来讨论如何为创建的帧对象添加附件。
2.纹理附件
为帧缓冲创建纹理和创建普通纹理差不多,这样做的优点在于,所有的渲染操作结果都会被存储在一个纹理图像中,我们可以在着色器中很方便地使用它。