Multisample FBO and render to depth texture

Hi,

I created a depth-of-field effect that works fine with a non-multisample FBO (no antialiasing). See image here:
http://www.flickr.com/photos/eomine/3498367334/

Now I’m trying to do the same effect with a multisample FBO - to get a nice antialiased image. Problem is, the depth texture is now full of (regularly distributed) black pixels:
http://www.flickr.com/photos/eomine/3498484275/

The glitch occurs in my ATI HD 4850 card (latest driver). I tested it in another PC with a Geforce 8500 and the depth texture looks fine. My HD 4850 is new (~3 months of usage) and I can play games and demos with no problems…

I’d really grateful if someone could help me with this problem.

FBO code:

// create color texture
glGenTextures( 1, &colorTexID );
glBindTexture( GL_TEXTURE_2D, colorTexID );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, APP_WIDTH, APP_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL );

// create depth texture
glGenTextures( 1, &depthTexID );
glBindTexture( GL_TEXTURE_2D, depthTexID );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY );
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, APP_WIDTH, APP_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL );

// unbind
glBindTexture( GL_TEXTURE_2D, 0 );

// multi sampled color buffer
glGenRenderbuffersEXT(1, &colorBufID);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorBufID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, 4, GL_RGBA, APP_WIDTH, APP_HEIGHT);

// multi sampled depth buffer
glGenRenderbuffersEXT(1, &depthBufID);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBufID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, 4, GL_DEPTH_COMPONENT24, APP_WIDTH, APP_HEIGHT);

// unbind
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, 0 );

// create fbo for multi sampled content and attach buffers
glGenFramebuffersEXT(1, &mframeBufID);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mframeBufID);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, colorBufID);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBufID);
//glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colorTexID, 0);
//glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depthTexID, 0);

// create final fbo and attach textures
glGenFramebuffersEXT(1, &frameBufID);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufID);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colorTexID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depthTexID, 0);

// unbind
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );

// before drawing
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, mframeBufID );
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

// … drawing spheres here …

// blit from multisample FBO to final FBO
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
glBindFramebufferEXT( GL_READ_FRAMEBUFFER_EXT, mframeBufID );
glBindFramebufferEXT( GL_DRAW_FRAMEBUFFER_EXT, frameBufID );
glBlitFramebufferEXT( 0, 0, APP_WIDTH, APP_HEIGHT, 0, 0, APP_WIDTH, APP_HEIGHT, GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT, GL_NEAREST );
glBindFramebufferEXT( GL_READ_FRAMEBUFFER_EXT, 0 );
glBindFramebufferEXT( GL_DRAW_FRAMEBUFFER_EXT, 0 );

Yes, I get same defect on my ATI HD2400 with GL_DEPTH_COMPONENT24 format.
Try using instead GL_DEPTH_COMPONENT32 format. It works fine with me. Also GL_DEPTH_COMPONENT32F works fine.

There is an older thread in these forums with this issue. I can confirm it on Vista and Linux as well (4850, 9.4 drivers).

Does GL_DEPTH_COMPONENT32/32F work for you? Last time I tried this, I got a driver crash inside the FramebufferBlit call - however, I was using the core (GL 3.0) function instead of the EXT one.

I replaced GL_DEPTH_COMPONENT24 with GL_DEPTH_COMPONENT32 (GL_DEPTH_COMPONENT32F was not recognized) and now I get a blank (all black) depth texture.

These are the lines I changed:

glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, APP_WIDTH, APP_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL );

glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, 4, GL_DEPTH_COMPONENT32, APP_WIDTH, APP_HEIGHT);

I noticed that GL_DEPTH_COMPONENT24 yields the same glitched depth texture with a non-multisample FBO too.

So it reminded me I was using GL_DEPTH_COMPONENT16 with the non-multisample version. Problem is, using 16 with multisample resulted in my application crashing on “glBlitFramebufferEXT”.

If I remove the GL_DEPTH_BUFFER_BIT from the blit call, it doesn’t crash but the depth texture is empty again.


FWIW, I’m using GLFW for initializing the window. I’ve played with the parameters in glfwOpenWindow (one of them is the number of depth bits), but it didn’t seem to make a difference.


I’ve found this other thread about this issue - it seems there’s no solution to it?

This is really frustrating… :frowning:

FWIW: I managed to implement my antialiased depth-of-field effect without FBOs. I used glCopyTexImage2D instead:

glEnable( GL_TEXTURE_2D );
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, colorTexID );
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, APP_WIDTH, APP_HEIGHT, 0 );
glActiveTexture( GL_TEXTURE1 );
glBindTexture( GL_TEXTURE_2D, depthTexID );
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 0, 0, APP_WIDTH, APP_HEIGHT, 0 );

And then I send the 2 textures to the fragment shader.

It is simpler and it runs at the same framerate of the non-multisample FBO version: ~44fps at 1280x1024px.

Some images here:
http://www.flickr.com/photos/eomine/sets/72157617756002415/