Why there is no output to the framebuffer's textures?

69 views Asked by At

Here is the code:

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);
        //...
    }
}

I use geometry shader to model a square, here is the code:

//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();
}

here is the 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);
}

I encount a problem that I find during the draw pass 2, gl cannot outout any color to textures bind to mix_framebuffer.

Here is the debugging info in RenderDoc: draw pass 1 texture output: enter image description here draw pass 2's geometry output: enter image description here draw pass 2 texture input: enter image description here draw pass 2 texture output: enter image description here You can see, draw-pass 1's output was passed to draw-pass2's pipeline successfully, but there is no output to draw-pass2's textures. I don't know why.

1

There are 1 answers

1
rokuz On BEST ANSWER

If you don't see even the plain color, the first I'd recommend to check how it was discarded. There are no so many options:

  • glColorMask. Highly likely it's not your case, since pass 1 works;
  • Wrong face culling and polygon winding order (CW, CCW). By your geometry shader, it looks like CW;
  • Blending options;
  • Depth-stencil state. I see you use glNamedRenderbufferStorage(mix_renderbuffer, GL_DEPTH24_STENCIL8, 1000, 800); What are depth-stencil settings?

If everything above looks good, any glGetError messages? If it's ok, try to remove MRT for a debugging purposes and output the only color in the second pass. If it would work, probably some error in MRT + Depth buffer setup.