opengl帧缓冲(framebuffer)

帧缓冲组成:颜色缓冲、深度缓冲、模板缓冲

应用:离屏渲染、后期处理

完整的帧缓冲:

  • 附加至少一个缓冲(颜色、深度或模板缓冲)颜色附件使用纹理,深度、模板附件使用渲染缓冲对象。
  • 至少有一个颜色附件(Attachment)。还有深度缓冲附件、模板缓冲附件等。
  • 所有的附件都必须是完整的(保留了内存)。
  • 每个缓冲都应该有相同的样本数。

检查帧缓冲是否完整:

if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)         // 执行胜利的舞蹈

创建帧缓冲:

unsigned int fbo;

glGenFramebuffers(1, &fbo);

glBindFramebuffer(GL_FRAMEBUFFER, fbo);

glBindFramebuffer(GL_FRAMEBUFFER, 0);

附件:是一个内存位置,它能作为帧缓冲的一个缓冲。有两种,纹理或渲染缓冲对象(Renderbuffer Object)



纹理:当把一个纹理附加到帧缓冲的时候,所有的渲染指令将会写入到这个纹理中,就像它是一个普通的颜色/深度或模板缓冲一样。

为帧缓冲创建一个纹理:

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);

将纹理附(作为颜色附件)加到帧缓冲上:

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

参数:

  • target:帧缓冲的目标(绘制、读取或者两者皆有)
  • attachment:我们想要附加的附件类型。当前我们正在附加一个颜色附件。注意最后的0意味着我们可以附加多个颜色附件。我们将在之后的教程中提到。
  • textarget:你希望附加的纹理类型
  • texture:要附加的纹理本身
  • level:多级渐远纹理的级别。我们将它保留为0。

将深度或模板附件附加到帧缓冲上:(这里使用纹理,最好使用渲染缓冲对象)

附件类型:

GL_DEPTH_ATTACHMENT

GL_STENCIL_ATTACHMENT

GL_DEPTH_STENCIL_ATTACHMENT

//深度+模板缓冲

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);



渲染缓冲对象:是一个真正的缓冲,即一系列的字节、整数、像素等。渲染缓冲对象附加的好处是,它会将数据储存为OpenGL原生的渲染格式,它是为离屏渲染到帧缓冲优化过的。

        渲染缓冲对象通常都是只写的,所以你不能读取它们(比如使用纹理访问)。当然你仍然还是能够使用glReadPixels来读取它,这会从当前绑定的帧缓冲,而不是附件本身,中返回特定区域的像素。

创建一个渲染缓冲对象:

unsigned int rbo;

glGenRenderbuffers(1, &rbo);

glBindRenderbuffer(GL_RENDERBUFFER, rbo);

将渲染缓冲对象设置为深度和模板渲染缓冲对象:

glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 800, 600);

 将渲染缓冲对象附加到帧缓冲上:

glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 800, 600);

        由于渲染缓冲对象通常都是只写的,它们会经常用于深度和模板附件,因为大部分时间我们都不需要从深度和模板缓冲中读取值,只关心深度和模板测试。我们需要深度和模板值用于测试,但不需要对它们进行采样,所以渲染缓冲对象非常适合它们。当我们不需要从这些缓冲中采样的时候,通常都会选择渲染缓冲对象,因为它会更优化一点。

步骤:

        将场景渲染到纹理,场景每帧更新一次,纹理也每帧更新一次。opengl会对部分物体进行裁剪,每次只渲染了部分场景;当摄像机移动时,投影矩阵会变化,看到的场景也会变化。

        摄像机移动,我们所看到的场景会像直接渲染到默认帧缓冲中一样随之变化,但在这个项目中,本质上我们看到的还是一张图片,只是这张图片会不断更新。

创建并绑定帧缓冲;

附加颜色附件、深度和模板附件;

绑定默认帧缓冲;

绑定新的帧缓冲;

渲染到纹理(为空白的纹理填充颜色,形成一个纹理);

绑定默认帧缓冲;

使用纹理();

处理后渲染到屏幕。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值