渲染到窗口帧缓冲区和 FBO 以保存全尺寸纹理图像

Posted

技术标签:

【中文标题】渲染到窗口帧缓冲区和 FBO 以保存全尺寸纹理图像【英文标题】:Render to window framebuffer and FBO to save full scale texture image 【发布时间】:2013-11-26 20:19:59 【问题描述】:

我想将图像处理 OpenGL 着色器程序的输出保存到图像文件中,并将结果显示在屏幕上。我知道如何使用glReadPixels() 保存窗口帧缓冲区。但是,屏幕的分辨率小于图像的尺寸。

如果我渲染到 FBO,是否需要在保存并取消绑定 FBO 后再次调用 glDrawArrays() 才能在屏幕上看到结果?或者是否可以告诉窗口帧缓冲区从 FBO 渲染而无需再次运行着色器程序?

【问题讨论】:

【参考方案1】:

要将渲染图像保存在 RBO 中,您可以通过调用 glReadBuffer 来设置 OpenGL 将从哪个缓冲区读取像素来直接读取像素。在您的特定情况下,将读取缓冲区设置为 GL_COLOR_ATTACHMENT<i> 应该可以解决问题。详情请见glDrawBuffer man page。

为了在 FBO 中显示图像:是的,您需要进行额外的渲染传递以将 FBO 的图像复制到默认帧缓冲区中。您可以将 FBO 绑定为纹理,并按照您的建议渲染几何图形以在屏幕上获取图像,或者您可以使用glBlitFramebuffer 来简化复制和图像过滤。

【讨论】:

我假设您的“否”答复是对我问题的第二部分。因此,在渲染到附加到 FBO 的纹理后,我确实需要再次调用glDrawArrays(),以便在屏幕上显示结果。所以,我应该渲染到 FBO,使用我渲染到的颜色附件调用 glReadBuffer(),然后调用 glReadPixels() 来保存结果。之后,我将不得不再次调用glDrawArrays()(在更改视口尺寸之后)将纹理渲染到屏幕上。 对不起;编辑以解决您的其他问题。有不同的方法可以完成您的要求,但基本上,您处于正确的轨道上,您需要(以某种方式)复制 - 通过使用纹理和着色器进行渲染,或对帧缓冲区进行 blitting - 来自 FBO 的位到默认帧缓冲区。 感谢您的澄清。我已经用第二个渲染通道实现了它,它工作得很好。我有全尺寸保存的图像,屏幕输出被缩放到窗口尺寸。【参考方案2】:

如果我渲染到 FBO,是否需要在保存并取消绑定 FBO 后再次调用 glDrawArrays() 才能在屏幕上看到结果?

你应该使用glBlitFramebuffer (...),这个函数的目的是将一个帧缓冲区(读取缓冲区)复制到另一个(绘制缓冲区)。如果你没有做一些不寻常的事情,比如绘制一个整数纹理附件,那么你的 FBO 的绘制缓冲区应该与你的默认帧缓冲区(窗口)兼容。

还有一些与过滤方法和您要复制的图像类型相关的额外注意事项(例如,深度缓冲区不能使用线性插值),但由于您在这里讨论“全尺寸”,我想您对 @987654323 感兴趣@无论如何。

【讨论】:

+1 用于解释如何执行 blitting 以及可能出现的问题。学到了一些新东西。谢谢。

以上是关于渲染到窗口帧缓冲区和 FBO 以保存全尺寸纹理图像的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL(FBO)中的普通后台缓冲区+渲染到深度纹理

WebGL入门(四十一)-使用帧缓冲区对象(FBO)实现将渲染结果作为纹理绘制到另一个物体上

OpenGL:使用 FBO 和视口偏移问题渲染到纹理

纹理可以绑定到多个 fbo 吗?

是否可以将默认渲染缓冲区附加到 FBO?

为 fbo 提供预先存在的纹理以在其上绘制