OpenGL:使用多个纹理渲染到 FBO

Posted

技术标签:

【中文标题】OpenGL:使用多个纹理渲染到 FBO【英文标题】:OpenGL: Render to FBO using multiple textures 【发布时间】:2010-10-10 22:27:08 【问题描述】:

我正在尝试使用渲染器。我想要的是将一个颜色缓冲区和一个普通缓冲区写入两个单独的纹理。我弄明白了那部分。

但是,颜色缓冲区应该是两个纹理的组合。这应该可以解决问题:

glActiveTexture(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
g_Tex->Bind();

glActiveTexture(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
g_TexNormal->Bind();

    g_Shader->Enable();
        RenderScene();
    g_Shader->Disable();

glActiveTexture(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);

glActiveTexture(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_2D);

这是片段着色器:(GLSL)

uniform sampler2D tex_diffuse;
uniform sampler2D tex_normal;

void main()

    gl_FragColor = texture2D(tex_diffuse, gl_TexCoord[0].st);
    //gl_FragColor = texture2D(tex_normal, gl_TexCoord[0].st);
   

但是,第二个纹理与第一个相同!附加到GL_TEXTURE0 的任何纹理都是用于两个采样器的纹理。

初始化 FBO:

glGenFramebuffersEXT(1, &g_FBOColor);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_FBOColor);

glGenTextures(1, &g_FBOTexColor);
glBindTexture(GL_TEXTURE_2D, g_FBOTexColor);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, g_FBOTexColor, 0);

glGenTextures(1, &g_FBOTexNormal);
glBindTexture(GL_TEXTURE_2D, g_FBOTexNormal);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, g_FBOTexNormal, 0);

glGenTextures(1, &g_FBOTexDepth);
glBindTexture(GL_TEXTURE_2D, g_FBOTexDepth);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, w, h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, g_FBOTexDepth, 0);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

完整的渲染部分:

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_FBOColor);
glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT);

glViewport(
    0, 0,
    Window::GetSingleton()->GetWidth(), Window::GetSingleton()->GetHeight()
);

GLenum buffers[] =  GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT ;
glDrawBuffers(2, buffers);
//glReadBuffer(GL_COLOR_ATTACHMENT0_EXT | GL_COLOR_ATTACHMENT1_EXT);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glActiveTexture(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
g_Tex->Bind();

glActiveTexture(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
g_TexNormal->Bind();

    g_Shader->Enable();
        RenderScene();
    g_Shader->Disable();

glActiveTexture(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);

glActiveTexture(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_2D);

glPopAttrib();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

提前致谢。

【问题讨论】:

请注意,当绑定它们以进行渲染时,不应调用 glActiveTexture 或 glEnable(GL_TEXTURE_2D)。只有在实际渲染应该显示这些纹理的几何体时才应该使用它们(即渲染到纹理的结果)。 【参考方案1】:

嗯,我想通了。 :)

我的纹理不起作用的原因是我没有设置统一的位置。固定代码:

g_Shader->Enable();

    glActiveTexture(GL_TEXTURE0_ARB);
    glEnable(GL_TEXTURE_2D);
    g_Tex->Bind();
    glUniform1i(glGetUniformLocation(g_Shader->GetProgram(), "tex_diffuse"), 0);

    glActiveTexture(GL_TEXTURE1_ARB);
    glEnable(GL_TEXTURE_2D);
    g_TexNormal->Bind();
    glUniform1i(glGetUniformLocation(g_Shader->GetProgram(), "tex_normal"), 1);

        RenderScene();

    glActiveTexture(GL_TEXTURE1_ARB);
    glDisable(GL_TEXTURE_2D);

    glActiveTexture(GL_TEXTURE0_ARB);
    glDisable(GL_TEXTURE_2D);

g_Shader->Disable();

【讨论】:

以上是关于OpenGL:使用多个纹理渲染到 FBO的主要内容,如果未能解决你的问题,请参考以下文章

带有 FBO 的 OpenGL 阴影映射 - 多个拖尾绘制

OpenGL中分层渲染和多个渲染目标之间的混淆

OpenGL 渲染到纹理 - 黑屏

在 OpenGL ES 2.0 中渲染到纹理时的抗锯齿

尝试渲染到多个纹理以实现延迟渲染。但所有纹理都是平等的

使用 OpenGL C++ 渲染到纹理