【发布时间】:2013-11-26 20:19:59
【问题描述】:
我想将图像处理 OpenGL 着色器程序的输出保存到图像文件中,并将结果显示在屏幕上。我知道如何使用glReadPixels() 保存窗口帧缓冲区。但是,屏幕的分辨率小于图像的尺寸。
如果我渲染到 FBO,是否需要在保存并取消绑定 FBO 后再次调用 glDrawArrays() 才能在屏幕上看到结果?或者是否可以告诉窗口帧缓冲区从 FBO 渲染而无需再次运行着色器程序?
【问题讨论】:
我想将图像处理 OpenGL 着色器程序的输出保存到图像文件中,并将结果显示在屏幕上。我知道如何使用glReadPixels() 保存窗口帧缓冲区。但是,屏幕的分辨率小于图像的尺寸。
如果我渲染到 FBO,是否需要在保存并取消绑定 FBO 后再次调用 glDrawArrays() 才能在屏幕上看到结果?或者是否可以告诉窗口帧缓冲区从 FBO 渲染而无需再次运行着色器程序?
【问题讨论】:
要将渲染图像保存在 RBO 中,您可以通过调用 glReadBuffer 来设置 OpenGL 将从哪个缓冲区读取像素来直接读取像素。在您的特定情况下,将读取缓冲区设置为 GL_COLOR_ATTACHMENT<i> 应该可以解决问题。详情请见glDrawBuffer man page。
为了在 FBO 中显示图像:是的,您需要进行额外的渲染传递以将 FBO 的图像复制到默认帧缓冲区中。您可以将 FBO 绑定为纹理,并按照您的建议渲染几何图形以在屏幕上获取图像,或者您可以使用glBlitFramebuffer 来简化复制和图像过滤。
【讨论】:
glDrawArrays(),以便在屏幕上显示结果。所以,我应该渲染到 FBO,使用我渲染到的颜色附件调用 glReadBuffer(),然后调用 glReadPixels() 来保存结果。之后,我将不得不再次调用glDrawArrays()(在更改视口尺寸之后)将纹理渲染到屏幕上。
如果我渲染到 FBO,是否需要在保存并取消绑定 FBO 后再次调用 glDrawArrays() 才能在屏幕上看到结果?
你应该使用glBlitFramebuffer (...),这个函数的目的是将一个帧缓冲区(读取缓冲区)复制到另一个(绘制缓冲区)。如果你没有做一些不寻常的事情,比如绘制一个整数纹理附件,那么你的 FBO 的绘制缓冲区应该与你的默认帧缓冲区(窗口)兼容。
还有一些与过滤方法和您要复制的图像类型相关的额外注意事项(例如,深度缓冲区不能使用线性插值),但由于您在这里讨论“全尺寸”,我想您对 @987654323 感兴趣@无论如何。
【讨论】: