Rendering FBOdepth attachment to main depth buffer

Last month I’ve been playing around a bit with framebuffer objects, and I think they’re very nice, but I can’t seem to find a way to render a depth attachment.

With rendering the attachment I do not mean: rendering it to a quad. That’s easy :slight_smile: What I do mean is that I would like to do the same as for the color buffer, but for depth only. So instead of copying the color attachment to the main framebuffer by using a textured quad, I would very much like to copy the depth attachment of an FBO to the main depth buffer.

I figured this should be possible by using glDrawPixels, but I’d rather be looking for another way because that would be far too slow for (I can’t use PBO to accelerate it).

Anyone? :slight_smile:

What I do mean is that I would like to do the same as for the color buffer, but for depth only.

Well, then do that.

Turn off color writes (glColorMask), turn on depth writes(glDepthMask), and in your fragment shader, copy the depth texture’s value into gl_FragDepth.

I was actually hoping it could be done without fragment shaders as well, but if that’s the only way… guess I’ve got some catching up to do then :slight_smile:


You can do this very fast and easy using GL_EXT_framebuffer_blit

glBlitFramebufferEXT(0, 0, width, height,
                     0, 0, width, height,


Cool, that would be a much better solution indeed, thanks a lot :slight_smile:

I see it’s currently not supported on my card/driver, but I guess I just need a more recent driver to get this extension, is that about right?

(I’m using a Radeon Xpress 200M (mobility))

Yes it is. Updating the drivers is your best (and only) bet :slight_smile:
If it doesn’t show up after that, you’re out of luck.


Thanks again! It seems I’m out of luck, there are no recent drivers for this card. Too bad.

Anyway, I took a fresh dive into the shader stuff and it isn’t really scary anymore. I do wonder why I can’t use gl_MultiTexCoord0 when glTexCoord is used for submitting texture coords, but I guess I should be using multitexturing anyway :slight_smile:

(I’m not even going to ask :slight_smile: it’s pretty obvious that the color and depth attachment from the fbo should be bound to 2 texture units so there’s no need for it)

There are no recent ones for my laptop either. I updated mine with the drivers from laptopvideo2go, but this is only for Nvidia cards…

You should be able to use gl_MultiTexCoord0 instead of gl_TexCoord, note that this is only available in the vertex program.

Well, it’s not that obvious, you could also have used renderbuffers instead of textures :wink:


Thanks, I’ll bookmark that link, my next videocard (or laptop with vidcard) is going to be nVidia again anyway :slight_smile:

Yeah, I’m passing along gl_MultiTexCoord0 to gl_TexCoord[0], which in turn is used as an argument (in a vec2) for texture2D in the fragment program, and assigned to gl_FragColor.

Heh, I was lucky :slight_smile: At first I was using QGLFramebufferObject from Qt4.4, but from looking at the source of Qt I found that QGLFramebufferObject added a renderbuffer when I requested to add a depth buffer to it, while some examples I saw on the web added textures instead. It wasn’t hard to figure out the difference when I noticed that :slight_smile:

I’m currently reading the specs as well. Long read, but I’m afraid that’s the only way to fully learn this stuff.

(and all that just to get buffered regions for my 3d views… pfew :smiley: (because I can’t use buffer region extensions or PBO-accelerated drawpixels) )

By the way, perhaps I should read the specs better, but there’s one more thing I can’t really figure out yet: why is there a need for the separation between renderbuffers and textures? Why doesn’t OpenGL use just the textures only? I mean, fbo’s aren’t even supported in fragment programs, and the image data has to be stored somewhere anyway, right?

(you may slap me around a bit with a large trout when I’ve missed something and someone has found a way to save textures without actually writing out the data to some place and doesn’t depend on dynamic generation of that data)

A renderbuffer is useful for creating a buffers with types which have no corresponding texture format such as a stencil buffer (e.g. STENCIL_INDEX8_EXT).
It’s also useful for creating multisample buffers with glRenderbufferStorageMultisampleEXT.


All right, sounds logical :slight_smile:

I’ve got it working now, but not quite yet…

This is the depth buffer:

Visualized by the following fragment program:

uniform sampler2D colortex;
uniform sampler2D depthtex;

void main(void)
  vec4 tmp = texture2D(depthtex, gl_TexCoord[0].st);
  gl_FragColor = vec4(tmp.r, tmp.r, tmp.r, 1.0);
  gl_FragDepth = tmp.r;

It doesn’t work however… Any depth test is passed. I presume I should do something different than using tmp.r for gl_FragDepth?

I’ve just checked things a bit more thoroughly and it seems that the depth buffer isn’t modified at all :frowning:

Depth mask is enabled, of course.

renderbuffers should always be used (unless u need the output later as a texture then u have no option but to attach a texture to a FBO)
A/ can be faster/use less memory perhaps
B/ they also support AA (textures dont)

Very good points, I’ll keep that in mind, thanks :slight_smile:

As for my problem, I’ve finally found a way to fix most issues with my card and driver: DH Mobility Modder. That allowed me to use the most recent (desktop) drivers.

I can now use PBO’s, VBO’s (finally!) and rectangle textures. The framebuffer blit extension is not listed in the extension string, but the entry point for glBlitFramebufferEXT does seem to exist. It doesn’t work however, don’t know what’s up with that.

Setting values for gl_FragDepth does work in RenderMonkey now (and in addition, shaders are now much much faster), but it does not work in my program yet. I’m probably doing something wrong, but I can’t figure out what it is.

Anyway, I think I’ll try the PBO accelarated drawpixels-approach for reading/writing the depth buffer from the FBO (then I can also switch back to renderbuffers, right?). Should work now, I hope.