使用glBlitFramebuffer显示纹理

时间:2015-03-25 11:37:24

标签: opengl

我正在尝试实现一个简单的多通道渲染方案。我首先将场景的多重采样版本blit到FBO beforeEffectsContext.fbo。如果我然后将其blit到应用程序提供的FB它工作正常。但是我想在场景上做另一次传球来模糊它。因此,我将COLOR_ATTACHMENT0中的纹理绑定在beforeEffectsContext.fbo中,对其进行采样,绘制一个四边形,并将模糊效果添加到另一个帧缓冲区blurContext.fbo

如果我知道使用相同的四边形和纹理采样方法在屏幕上显示blurContext.fbo的颜色附件的内容,它就会起作用,我会得到一个模糊的场景。

但如果我尝试在此步骤中使用glBlitFramebuffer(),我会得到一个黑色的屏幕。问题似乎在于我对blitting过程和FBO的误解。

blurContext.fbo的初始化代码:

// BeforeEffects Framebuffer
glGenFramebuffers(1, &renderContext->beforeEffectsContext.fbo);
glBindFramebuffer(GL_FRAMEBUFFER, renderContext->beforeEffectsContext.fbo);

glGenTextures(1, &renderContext->beforeEffectsContext.colorAttachment);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, renderContext->beforeEffectsContext.colorAttachment);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 600, 0, GL_RGBA, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderContext->beforeEffectsContext.colorAttachment, 0);

// Blur Framebuffer
glGenFramebuffers(1, &renderContext->blurContext.fbo);
glBindFramebuffer(GL_FRAMEBUFFER, renderContext->blurContext.fbo);

glGenTextures(1, &renderContext->blurContext.colorAttachment);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, renderContext->blurContext.colorAttachment);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 600, 0, GL_RGBA, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderContext->blurContext.colorAttachment, 0);

渲染:

// Draw to the MSampled scene to the BeforeEffects framebuffer
glBindFramebuffer(GL_READ_FRAMEBUFFER, renderContext->multiSamplingContext.fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, renderContext->beforeEffectsContext.fbo);
glBlitFramebuffer(0, 0, 800, 600, 0, 0, 800, 600, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);

// Sample the texture attached to the beforeEffects FBO and draw to the blur FBO
glBindTexture(GL_TEXTURE_2D, renderContext->beforeEffectsContext.colorAttachment);
glBindFramebuffer(GL_FRAMEBUFFER, renderContext->blurContext.fbo);
glViewport(0, 0, 800, 600);

glUseProgram(renderContext->blurProgramContext.program);
glBindVertexArray(renderContext->vaoBlur);

glDrawArrays(GL_QUADS, 0, 4);

glUseProgram(0);
glBindVertexArray(0);

// Blit the content of the blur FBO to the app-provided Framebuffer (doesn't work, black screen)
glBindFramebuffer(GL_READ_FRAMEBUFFER, renderContext->blurContext.fbo);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_DRAW_BUFFER, 0);
glViewport(0, 0, 800, 600);
glBlitFramebuffer(0, 0, 800, 600, 0, 0, 800, 600, GL_COLOR_BUFFER_BIT,
    GL_NEAREST);

1 个答案:

答案 0 :(得分:5)

在绑定默认帧缓冲区(0)以进行绘制的行中,您将目标设置为GL_DRAW_BUFFER。根据{{​​3}},设置绘制帧缓冲区的正确枚举是GL_DRAW_FRAMEBUFFER。如果添加对glGetError的调用,您可能会看到GL_INVALID_ENUM错误。