opengl学习-帧缓冲

2021-04-25  本文已影响0人  小杰66

创建一个帧缓冲

unsigned int fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

完整的帧缓冲组成

  1. 附加至少一个缓冲(颜色、深度或模板缓冲)。
  2. 至少有一个颜色附件(Attachment)。
  3. 所有的附件都必须是完整的(保留了内存)。
  4. 每个缓冲都应该有相同的样本数。

检查帧缓冲是否完整

if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)

激活默认帧缓冲

glBindFramebuffer(GL_FRAMEBUFFER, 0);

删除帧缓冲对象

glDeleteFramebuffers(1, &fbo);

纹理附件

  1. 创建一个纹理
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);
  1. 附加到帧缓冲
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

glFrameBufferTexture2D有以下的参数:

  1. 附加深度缓冲,附件类型设为GL_DEPTH_ATTACHMENT。纹理格式和内部格式类型设为为GL_DEPTH_COMPONENT
  2. 附加模板缓冲,附件类型设为GL_STENCIL_ATTACHMENT,纹理格式设为GL_STENCIL_INDEX
  3. 附加深度模板缓冲,类型设为GL_DEPTH_STENCIL_ATTACHMEN。纹理的每32位数值将包含24位的深度信息和8位的模板信息
glTexImage2D(
  GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 800, 600, 0, 
  GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL
);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texture, 0);

渲染缓冲对象附件

渲染缓冲对象直接将所有的渲染数据储存到它的缓冲中,不会做任何纹理格式的转换,是一个更快的可写储存介质。
渲染缓冲对象通常是只写的,常用于深度和模板附件,因为我们不需要从深度和模板缓冲中读取值,只关心深度和模板测试。

  1. 创建一个渲染缓冲对象
    unsigned int rbo;
    glGenRenderbuffers(1, &rbo);
  2. 绑定渲染缓冲对象
    glBindRenderbuffer(GL_RENDERBUFFER, rbo);
  3. 创建一个深度和模板渲染缓冲对象
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 800, 600);
  4. 附加渲染缓冲对象
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);

如果你不需要从一个缓冲中采样数据,那么使用渲染缓冲对象;
如果你需要从缓冲中采样颜色或深度值等数据,那么选择纹理附件。

渲染到纹理

将场景渲染到一个附加到帧缓冲对象上的颜色纹理中,之后在一个横跨整个屏幕的四边形上绘制这个纹理。
绘制流程为:
1.将新的帧缓冲绑定为激活的帧缓冲,和往常一样渲染场景
2.绑定默认的帧缓冲
3.绘制一个横跨整个屏幕的四边形,将帧缓冲的颜色缓冲作为它的纹理。

//创建并绑定帧缓冲对象
unsigned int framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

//创建纹理图像,作为颜色附件附加到帧缓冲上
unsigned int texColorBuffer;
glGenTextures(1, &texColorBuffer);
glBindTexture(GL_TEXTURE_2D, texColorBuffer);
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);
glBindTexture(GL_TEXTURE_2D, 0);
//附加到当前绑定的帧缓冲对象
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColorBuffer, 0);  

//使用渲染缓冲对象添加一个深度模板附件到帧缓冲中。
unsigned int rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo); 
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 800, 600);  
glBindRenderbuffer(GL_RENDERBUFFER, 0);

//将渲染缓冲对象附加到帧缓冲的深度模板附件
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);

//检查帧缓冲是否是完整
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);

image.png

后期处理

整个场景都被渲染到了一个纹理上,可以通过修改纹理数据创建出各种效果。例如 反相、灰度、 核效果、模糊、 边缘检测等。

上一篇下一篇

猜你喜欢

热点阅读