我们在之前使用了很多缓冲了:颜色缓冲、深度缓冲、模板缓冲。这些缓冲结合起来叫做帧缓冲,
其实也能从名字理解,每一帧屏幕都需要不断更新画面,对应的缓冲也需要更新。
不过上面这些都是在默认的缓冲里面做的,现在我们可以自定义帧缓冲方式。
创建帧缓冲
和之前的VBO一样,我们生成VBO需要通过glGenBuffer,帧缓冲也一样
unsigned int fbo;
glGenFramebuffers(1, &fbo);//生成
glBindFramebuffer(GL_FRAMEBUFFER, fbo);//绑定
不过还不能用,一个完整的帧缓冲需要满足以下的条件:
- 附加至少一个缓冲(颜色、深度或模板缓冲)。
- 至少有一个颜色附件(Attachment)。
- 所有的附件都必须是完整的(保留了内存)。
- 每个缓冲都应该有相同的样本数。
在完成了所有附加之后可以调用一个检查函数来检查是否完整。
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
// 执行胜利的舞蹈
不过还记得我们有个默认的帧缓冲吗,我们自定义的叫做离屏渲染off-screen rendering,要保证所有的渲染操作在主窗口中有视觉效果,我们需要再次激活默认帧缓冲,将它绑定到0
。
glBindFramebuffer(GL_FRAMEBUFFER, 0);
。。。glDeleteFramebuffers(1, &fbo);
用完之后记得删除。
添加一个纹理附件
和之前创建一个纹理差不多
unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
这里注意,没有给纹理的data参数传东西。也就是分配了内存但是没有填充他。而填充纹理将会在我们渲染到帧缓冲中进行。同样注意我们并不关心环绕方式或多级渐远纹理,我们在大多数情况下都不会需要它们。
创建完最后一件事就是附加到帧缓冲上。
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
渲染缓冲对象附件
渲染缓冲对象(Renderbuffer Object)是在纹理之后引入到OpenGL中,作为一个可用的帧缓冲附件类型的,所以在过去纹理是唯一可用的附件。和纹理图像一样,渲染缓冲对象是一个真正的缓冲,即一系列的字节、整数、像素等。渲染缓冲对象附加的好处是,它会将数据储存为OpenGL原生的渲染格式,它是为离屏渲染到帧缓冲优化过的。
渲染缓冲对象直接将所有的渲染数据储存到它的缓冲中,不会做任何针对纹理格式的转换,让它变为一个更快的可写储存介质。然而,渲染缓冲对象通常都是只写的,所以