Search code examples
c++openglframebufferdepth-bufferpost-processing

Multi-sampling Frame Render Objects and Depth Buffers


I am trying to get multi-sampling working with my Frame Buffer (for post-processing). I can get it almost working by ignoring the Depth Buffer but I get get issues with faces not rendering.

I set up my normal frame buffer like this

glBindTexture(GL_TEXTURE_2D, m_Texture);
    glTexImage2D(
        GL_TEXTURE_2D, 0, GL_RGB, 1280, 720, 0, GL_RGB, GL_UNSIGNED_BYTE, 0
    );

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);


    glFramebufferTexture2D(
        GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_Texture, 0
    );

    // Create color render buffer
    glGenRenderbuffers(1, &m_TexColorBuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, m_TexColorBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, 1280, 720);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_TexColorBuffer);

    // Create depth render buffer (This is optional)
    glGenRenderbuffers(1, &m_RBODepthBuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, m_RBODepthBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 1280, 720);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_RBODepthBuffer);

I then also create a Multi-Sampling frame buffer like this.

glEnable(GL_MULTISAMPLE);
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_Texture);
    glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGB, 1280, 720, GL_FALSE);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_Texture, 0);

    glGenRenderbuffers(1, &m_TexColorBuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, m_TexColorBuffer);
    glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGB, 1280, 720);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_TexColorBuffer);

/*  glGenRenderbuffers(1, &m_RBODepthBuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, m_RBODepthBuffer);
    glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT24, 1280, 720);
    glFramebufferRenderbuffer(
        GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_RBODepthBuffer
    );*/

    glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_Texture, 0);

This code (with the commented out section on the depth buffer) does produce a multi-sampled texture that displayed correctly but without depth I get faces not rendering or normals in the wrong direction (so from angles I am seeing inside the model). But if I uncomment that section then

glCheckFramebufferStatus(GL_FRAMEBUFFER)

returns

36182

followed by

Error 00000506 after convex fill

and ultimately a black screen.

I am using glBlitFramebuffer to copy the multi-sample fbo to a single-sample fbo (which works but with the issues mentioned before).

Really stuck at this point and can't find the solution anywhere!


Solution

  • So I found the answer thanks to some outdated documentation for a random project on source forge.

    My error was GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE

    With that infomation I found what the error meant which is

    GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE is also returned if the value of GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not the same for all attached textures; or, if the attached images are a mix of renderbuffers and textures, the value of GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not GL_TRUE for all attached textures.

    So changing the GL_FALSE at the end of

    glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGB, 1280, 720, GL_FALSE);
    

    to GL_TRUE fixed it. So

    glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGB, 1280, 720, GL_TRUE);