opengl 为什么没有输出到帧缓冲区的纹理?

jbose2ul  于 2022-11-29  发布在  其他
关注(0)|答案(1)|浏览(210)

代码如下:

int main(){
    //init gl environment
    //...

    //create textures for pass 1

    GLuint normal_color_output;
    glCreateTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &normal_color_output);
    glTextureStorage2DMultisample(normal_color_output, 8, GL_RGBA32F, 1000, 800, GL_TRUE);
    GLuint high_color_output;
    glCreateTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &high_color_output);
    glTextureStorage2DMultisample(high_color_output,8, GL_R11F_G11F_B10F, 1000, 800,GL_TRUE);

    //init framebuffer

    GLuint render_buffer;
    glCreateRenderbuffers(1, &render_buffer);
    glNamedRenderbufferStorageMultisample(render_buffer, 8, GL_DEPTH24_STENCIL8, 1000, 800);
    GLuint framebuffer;
    glCreateFramebuffers(1, &framebuffer);
    glNamedFramebufferTexture(framebuffer, GL_COLOR_ATTACHMENT0, normal_color_output,0);
    glNamedFramebufferTexture(framebuffer, GL_COLOR_ATTACHMENT1, high_color_output, 0);
    glNamedFramebufferRenderbuffer(framebuffer, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, render_buffer);
    const GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0,GL_COLOR_ATTACHMENT1};
    glNamedFramebufferDrawBuffers(framebuffer, 2, drawbuffers);
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

    //init another framebuffer
    //What I want to do is trying to achieve implementing my own msaa color resolve solution.

    GLuint mix_framebuffer;
    glCreateFramebuffers(1, &mix_framebuffer);
    GLuint mix_renderbuffer;
    glCreateRenderbuffers(1, &mix_renderbuffer);
    glNamedRenderbufferStorage(mix_renderbuffer, GL_DEPTH24_STENCIL8, 1000, 800);
    GLuint normal_antialiasing_texture, hdr_antialiasing_texture;
    glCreateTextures(GL_TEXTURE_2D, 1, &normal_antialiasing_texture);
    glTextureStorage2D(normal_antialiasing_texture, 1, GL_RGBA32F, 1000, 800);
    glCreateTextures(GL_TEXTURE_2D, 1, &hdr_antialiasing_texture);
    glTextureStorage2D(hdr_antialiasing_texture, 1, GL_RGBA32F, 1000, 800);
    glNamedFramebufferTexture(mix_framebuffer, GL_COLOR_ATTACHMENT0, normal_antialiasing_texture, 0);
    glNamedFramebufferTexture(mix_framebuffer, GL_COLOR_ATTACHMENT1, hdr_antialiasing_texture, 0);
    glNamedFramebufferDrawBuffers(mix_framebuffer,2, drawbuffers);
    glNamedFramebufferRenderbuffer(mix_framebuffer, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mix_renderbuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, mix_framebuffer);

    //....
    //draw commands
    while (!glfwWindowShouldClose(window)) {
        // pass 1
        glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
        glUseProgram(program);
        glUniformMatrix4fv(3, 1, GL_FALSE, glm::value_ptr(camera.GetViewMat()));
        model.Render(program);
        glPointSize(20.f);
        glUseProgram(light_shader);// I draw a point to show the light's position
        glUniformMatrix4fv(0, 1, GL_FALSE, glm::value_ptr(camera.GetViewMat()));
        glDrawArrays(GL_POINTS, 0, 1);

        //pass 2
        glBindFramebuffer(GL_FRAMEBUFFER, mix_framebuffer);
        glUseProgram(mix_program);
        glBindTextureUnit(0, normal_color_output);
        glBindTextureUnit(1, high_color_output);
        glClear(GL_COLOR_BUFFER_BIT);
        glNamedFramebufferDrawBuffers(mix_framebuffer, 2, drawbuffers);
        glDrawArrays(GL_POINTS, 0, 1);
        //...
    }
}

我使用几何着色器来建模一个正方形,代码如下:

//mix_gs.glsl
#version 450 core

layout(points) in;
layout(triangle_strip) out;
layout(max_vertices = 4) out;

void main(){
    gl_Position = vec4(-1,1,-1,1);
    EmitVertex();
    gl_Position = vec4(-1,-1,-1,1);
    EmitVertex();
    gl_Position = vec4(1,1,-1,1);
    EmitVertex();
    gl_Position = vec4(1,-1,-1,1);
    EmitVertex();
    EndPrimitive();
}

下面是mix_fs.glsl:

#version 450 core

layout(location = 0)out vec4 color;
layout(location = 1)out vec4 hdr_color;
layout(binding = 0) uniform sampler2DMS color_sdms;
layout(binding = 1) uniform sampler2DMS hdr_sdms;
void main(){
/*
    for(int i=0;i<8;i++){
        color += texelFetch(color_sdms,ivec2(gl_FragCoord.xy),i);
        hdr_color += vec4(texelFetch(hdr_sdms,ivec2(gl_FragCoord.xy),i).xyz,1);
    }
    */
    color = vec4(1,0,0,1);//I just output a color
    hdr_color = vec4(0,1,0,1);
}

我在第二次绘制过程中发现了一个问题,gl无法输出任何颜色到绑定到mix_framebuffer的纹理。
下面是RenderDoc中的调试信息:绘制通道1纹理输出:x1c 0d1x绘制通道2的几何输出:

绘制通道2纹理输入:

绘制通道2纹理输出:

你可以看到,draw-pass 1的输出被成功地传递到draw-pass 2的管道,但是没有输出到draw-pass 2的纹理。我不知道为什么。

bwleehnv

bwleehnv1#

如果你连素色都看不出来,首先我建议你检查一下它是怎么被丢弃的。没有那么多选择:

  • glColorMask。很可能不是您的情况,因为pass 1有效;
  • 错误的面剔除和多边形缠绕顺序(顺时针,逆时针)。通过你的几何着色器,它看起来像顺时针;
  • 混合选项;
  • 深度模板状态。我看到您使用glNamedRenderbufferStorage(mix_renderbuffer, GL_DEPTH24_STENCIL8, 1000, 800);。什么是深度模板设置?

如果上面的一切看起来都很好,有任何glGetError消息吗?如果没有问题,尝试删除MRT以进行调试,并在第二次传递中输出唯一的颜色。如果可以工作,可能是MRT +深度缓冲区设置中的一些错误。

相关问题