opengl - 使用 glBlitFramebuffer 显示纹理

标签 opengl

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

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

但是如果我尝试使用glBlitFramebuffer()相反,在这一步中,我看到黑屏。问题似乎在于我对位 block 传输过程和 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/

相关文章:

macos - 使用 Core Graphics 绘制雾

c++ - 将数据从后台缓冲区复制到前台缓冲区

c++ - 我想将我的计算内容放在辅助线程中,同时将主循环保留在主线程中

c++ - OpenGL 着色器有时可以编译,有时则不能

opengl - 在 OpenGL 中找不到属性变量,可能的优化

visual-studio - OBJ 文件加载器无法正确读取人脸

opengl - 在 gouraud shading 中,什么是 T 型连接问题以及如何使用 OpenGL 进行演示

c++ - OpenGL 渲染大量动态二维圆

linux - 我无法启动程序 Linux Graphics Debugger

java - OpenGL - 使用 GL11 的 OS X