我正在尝试实现一个简单的多遍渲染方案。我首先将场景的多采样版本转换为FBO beforeEffectsContext.fbo。如果我然后将其绑定(bind)到提供FB的应用程序中,则可以正常工作。但是我想在场景中进行另一遍处理以使其模糊。因此,我将纹理绑定(bind)到COLOR_ATTACHMENT0中的beforeEffectsContext.fbo中,对其进行采样,绘制一个具有模糊效果的四边形,该效果已添加到另一个framebuffer blurContext.fbo中。

如果我知道使用quad和纹理采样的相同方法在屏幕上显示blurContext.fbo的颜色附件的内容,则该方法有效,并且场景模糊。

但是,如果我在此步骤中尝试使用glBlitFramebuffer()代替,则会得到黑色的屏幕。问题似乎出在我对划线程序和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);

最佳答案

在要绑定(bind)用于绘制的默认帧缓冲区(0)的行中,将目标设置为GL_DRAW_BUFFER。根据https://www.opengl.org/sdk/docs/man/html/glBindFramebuffer.xhtml,用于设置绘制帧缓冲区的正确枚举为GL_DRAW_FRAMEBUFFER。如果添加对glGetError的调用,则可能会看到GL_INVALID_ENUM错误。

关于opengl - 使用glBlitFramebuffer显示纹理,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29254574/

10-11 21:04