从一个帧缓冲区读取到另一个帧缓冲区时出现问题

Trouble reading from one frame buffer to another

一段时间以来,我一直在尝试将延迟 shading/rendering 实现到我的引擎中,但是我一直无法真正看到它的最终产品。

为了测试问题可能出在哪里,我设计了一个实验来查看我的目标 FBO 是否真的通过 glBlitFramebuffer() 命令从我的默认 FBO 中读取和读取。

我这样做是为了在我的默认 FBO 自行清除之前,清除颜色设置为 黑色,并且在我的目标 FBO 清除自身之前,清除颜色设置为红色.

结果是当我渲染我的场景时,我看到的都是黑色。

我的问题是:

如果将一个 fbo 设置为 read_framebuffer,并且默认设置为 draw_framebuffer,在“glBlitFramebuffer”操作期间是否也会复制“透明彩色”像素?

如果没有,那么就不知道我的目标 FBO 是否真的被渲染了,因为无论如何都不会复制那个颜色。

如果是,那么我应该看到红色,我不知道我的 FBO 设置有什么问题...


正如我之前所说,我一直在努力研究延迟着色系统。该系统要求我在 FBO 中执行所有操作,然后将其全部渲染回默认 FBO。

由于它不起作用,我简化了它的过程,要么将基本场景直接渲染到默认 FBO(有效),要么将其渲染到目标 FBO 上,然后按照过程将该 FBO 复制回来到默认的 FBO(不起作用)。

我尝试使用的帧缓冲区设置与我一直遵循的教程相同:

glGenFramebuffers(1, &m_fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);
glGenTextures(1, &m_finalTexture);
glBindTexture(GL_TEXTURE_2D, m_finalTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WindowWidth, WindowHeight, 0, GL_RGB, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, m_finalTexture, 0);

我这样渲染我的场景(简化):

//Flush content out of fbo at color attachment 4
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);
glDrawBuffer(GL_COLOR_ATTACHMENT4);
glClear(GL_COLOR_BUFFER_BIT);

//Render scene to m_fbo 
RenderPass();

//Swap default FBO back ("0"), read from target fbo (m_fbo)
//Draw target fbo onto default fbo
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo);
glDrawBuffer(GL_COLOR_ATTACHMENT4);
glReadBuffer(GL_COLOR_ATTACHMENT4);
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR);

我每一步都检查了我的帧缓冲区状态,没有发现任何错误。


我发现了真正的问题,当我完全理解它时,我会在这里更新post并提供更多信息。

此调用顺序无效:

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
...
glDrawBuffer(GL_COLOR_ATTACHMENT4);

GL_COLOR_ATTACHMENT4 不是默认帧缓冲区的有效绘制缓冲区。仅当当前绘制帧缓冲区是 FBO 时才有效。对于默认的帧缓冲区,您需要使用:

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
...
glDrawBuffer(GL_BACK);

这将允许 glBlitFramebuffer() 复制到默认帧缓冲区的后台缓冲区。

一直以来的问题是,如果在主渲染之外完成,我对绑定默认帧缓冲区的调用将无法正常工作 class。 所以我将该行从我的 GBuffer 移出并进入我的主渲染 class 并在调用 GBuffer.FinalPass();

之前执行它