Search code examples
c#openglopentkmultisampling

Multisampled FBO is ignoring depth testing


I have modified my rendering engine to use multisampled textures, except now depth testing is being ignored.

Here's how I'm creating the multisampled FBO,

public MSAA_FBO(int WindowWidth, int WindowHeight)
{
    this.width = WindowWidth;
    this.height = WindowHeight;

    GL.GenFramebuffers(1, out ID);
    GL.BindFramebuffer(FramebufferTarget.Framebuffer, ID);

    // Colour texture
    GL.GenTextures(1, out textureColorBufferMultiSampled);
    GL.BindTexture(TextureTarget.Texture2DMultisample, textureColorBufferMultiSampled);
    GL.TexImage2DMultisample(TextureTargetMultisample.Texture2DMultisample, 4, PixelInternalFormat.Rgb8, WindowWidth, WindowHeight, true);
    GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2DMultisample, textureColorBufferMultiSampled, 0);

    // Depth render buffer
    GL.GenRenderbuffers(1, out RBO);
    GL.BindRenderbuffer(RenderbufferTarget.RenderbufferExt, RBO);
    GL.RenderbufferStorageMultisample(RenderbufferTarget.Renderbuffer, 4, RenderbufferStorage.DepthComponent, WindowWidth, WindowHeight);
    GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, 0);

    var status = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);
    Console.WriteLine("MSAA: " + status);
    GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
}      

performing the resolve,

public void resolveToFBO(FBO outputFBO)
{
    GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, outputFBO.ID);
    GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, this.ID);
    GL.BlitFramebuffer(0, 0, this.width, this.height, 0, 0, outputFBO.width, outputFBO.height, ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit, BlitFramebufferFilter.Nearest);     
}

and rendering the image,

public void MSAAPass(Shader shader)
{
    GL.UseProgram(shader.ID);
    GL.BindFramebuffer(FramebufferTarget.Framebuffer, MSAAbuffer.ID);
    GL.Viewport(0, 0, Width, Height);

    GL.Enable(EnableCap.Multisample);
    GL.ClearColor(System.Drawing.Color.Black);
    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
    GL.Enable(EnableCap.DepthTest);
    GL.Disable(EnableCap.Blend);

    // Uniforms
    Matrix4 viewMatrix = player.GetViewMatrix();
    GL.UniformMatrix4(shader.getUniformID("viewMatrix"), false, ref viewMatrix);

    // Draw all geometry
    DrawScene(shader);

    GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
    MSAAbuffer.resolveToFBO(testBuffer);
}

Solution

  • Your multisampled FBO does not have a depth buffer, hence the depth test will not work. Although you actually created a multisampled renderbuffer with GL_DEPTH_COMPONENT format, you forgot to attach this one as the GL_DEPTH_ATTACHMENT of your FBO. You need to add a glFramebufferRenderbuffer() call in your MSAA_FBO() function.