Color attachments in FBO

Finally after the wide acceptance of FBO in most hardware i decided to switch my aging shadow map generation code using FBO (i was using p-buffers earlier which was nothing short of being a pain in the neck). Everything worked fine for spot lights and i saw a great performance improvement. However for omni lights (i use cube maps for omni lights) 4 of the faces of the cube map gave proper shadow map whereas the last 2 (in my case pos z and neg z) came out all black. I was using one FBO and attaching the sides of the cube to different color attachments. I rendered to different faces by setting the draw buffer using glDrawBuffer(…) call. If i use 6 different FBO’s the result is correct so there is nothing wrong with my shadow mapping code (it has been tested thoroughly anyways). What i was able to deduce, after performing further tests was that my current hardware (GFX 5700 Ultra, 78.01) doesn’t support more than 4 color attachments in FBOs and that’s the reason why the last 2 attachments of the cube always came out all black. Is this a limitation of the hardware or a driver issue? Secondly is there any glGet…(…) call via which i can determine the number of color attachments that a particular hardware can support for one FBO?

Thanks in advance.

Ok, read the spec and instantly found out that the glGetIntegerv(GL_MAX_DRAWBUFFERS, …) returns 4 and hence the hardware cannot support more than 4 draw buffers. Sorry for fuss.

Okay, i tested the application on a Radeon 9700 pro (latest drivers with FBO support) and everything worked fine. I checked the GL_MAX_DRAWBUFFERS and that was giving me 4 as well :frowning: . I don’t get it, whats the problem here? It seems like an nVidia driver issue to me? Can someone help?

If you’re rendering to a cube map, you shouldn’t be using different color attachments. You should be using the same color attachment but different texture targets for each cube face.

It sounds like you’re doing something like this:

//Wrong:
glFramebufferTexture2DEXT(
    GL_FRAMEBUFFER_EXT, 
    GL_COLOR_ATTACHMENT0_EXT, 
    GL_TEXTURE_2D, 
    texObject, 
    0
  );
...
glFramebufferTexture2DEXT(
    GL_FRAMEBUFFER_EXT, 
    GL_COLOR_ATTACHMENT5_EXT, 
    GL_TEXTURE_2D, 
    texObject, 
    0
  );

Whereas you should be doing something like this:

//Right:
glFramebufferTexture2DEXT(
    GL_FRAMEBUFFER_EXT,
    GL_COLOR_ATTACHMENT0_EXT,
    GL_TEXTURE_CUBE_MAP_POSITIVE_X, 
    texObject, 
    0
  );
...
glFramebufferTexture2DEXT(
    GL_FRAMEBUFFER_EXT, 
    GL_COLOR_ATTACHMENT0_EXT,
    GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 
    texObject, 
    0
  );

Note that each of those six calls should be immediately followed by rendering to that face of the cube. Hence, you also won’t be needing glDrawBuffer() anymore.

But won’t that be inefficient Tom? According to the following presentation (page 29) the most efficient way is to bind different textures to different color attachments and switch between them using glDrawBuffer(…).

Ah, but wait. It just dawned on me that MAX_DRAW_BUFFERS is, of course, irrelevant for the problem at hand. You’re not actually drawing to multiple buffers simultaneously. It’s MAX_COLOR_ATTACHMENTS you need to query. From the sound of things, that value is going to be different for the two cards you tested on.

Thanks Tom, you are a life saver :slight_smile: .