Coping from FBO's stencil to main stencil buffer ?

Hi,

I have FBO with depth and stencil only - as render buffers - (GL_DEPTH24_STENCIL8_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_STENCIL_ATTACHMENT_EXT…etc) and everything is ok.

Now I need to copy stencil from FBO to main stencil buffer - but it does not work. So I tryied copy depth from FBO to main depth buffer and it also does not work. My code:


glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
//clear depth and stencil buffer, draw writing to stencil and depth...

glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, fbo);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
glBlitFramebufferEXT(0,0,w,h,0,0,w,h, GL_(DEPTH or STENCIL)_BUFFER_BIT, GL_NEAREST);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
//draw using stencill...

Is it possible to do this ? What I am doing wrong ?

Are you doing it on ATI card?
Then read this: http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=282189#Post282189

I notice you are binding the draw buffer to 0. Is this because you want to copy to the system depth buffer? (you call that the main framebuffer).
Well…in that case you can not. BlitFramebuffer only copies between FBO objects, and the system backbuffer is not one of them.
Anyway, you should ditch the backbuffer and just use an FBO.

This is SO WRONG. Of course you are allowed to blit into the window framebuffer 0!

But, there are certain special rules. You cannot “enumerate” the attachments of FBO 0. Because of this you cannot determine the internal format enum that the driver is using for the window FBO. Therefore it is not possible for you to create an FBO with 100% identical pixelformat (for color, depth and stencil buffer).

There are certain cases where glBlitFramebuffer requires that both, source and destination FBO must have identical format and/or number of multisamples. If these requirements are not met, you’ll get GL_INVALID_OPERATION when trying to blit.

OTOH, these are the rules:

  1. Non-multisampled color buffers can be blit between different formats,they will be converted. Blitting non-multisampled colors into FBO 0 works in general.

If the source and destination buffers are multisampled, they must have the same number of samples.
Blitting which involves multisampling generally requires that both FBOs must have identical color formats. But, you cannot reliably create an FBO with identical color format as FBO 0, because you cannot determine the internal format of FBO 0.

  1. If you blit stencil or depth values, source and destination buffer must have the identical format. If you are blittig into FBO 0, its depth/stencil format cannot be determined 100% reliable, so in general you are not able to do this. In this case, I suggest rendering a quad over the whole window which is reading from a depth texture (bound to the source FBO) and writng these depth values into gl_FragDepth. You are not able to transfer stencil values into FBO 0.

In general, I’ve seen that nVidia cards are more forgiving when trying to blit into FBO 0. You’ll get GL_INVALID_OPERATION on ATI’s much easier - in this case refer to the specs and see if you broke one of the rules.

This is SO WRONG. Of course you are allowed to blit into the window framebuffer 0!
[/QUOTE]

Read the original post dude!
He wants to blit stencil into the system backbuffer. This can not be done. OK I could have been more general about blitting colour…but he wanted to know about stencil in particular.

I just wanted to correct the false statement you can’t blit into FBO 0, before the word spreads and another myth is born :wink:

In meantime I’ve come to an idea how to transport offscreen stencil values into window back buffer.

First, use glReadPixels() to read back the FBO depth/stencil values into a PBO (format: GL_DEPTH_STENCIL, type: GL_UNSIGNED_INT_24_8). For a multisampled FBO, a resolve-blit is needed first.
Then, upload that buffer into an RGBA8 texture (format: GL_RGBA, type: GL_UNSIGNED_INT_8_8_8_8), using glTex(Sub)Image2D.
Now render a fullscreen quad, reading that texture. The stencil value should now be availabe in the alpha channel of the texture (encoded in 0.0-1.0 range).
Finally, use ARB_shader_stencil_export to write this value (*255.0) into the destination stencil buffer.

I haven’t tried it… but it should work.

Thanks, everyone

Well, when I have started using FBO with depth, stencil and also color attachment (not using it) it start to work :slight_smile:
(main/system buffer is 24bit color, 24 depth, 8 stencil).

For tests, I have also created two FBOs: one with color, depth, stencil and second: with depth and stencil only (glDrawBuffer was GL_NONE before glCheckFramebufferStatusEXT). Both were “framebuffer complete”. Formats were the same.
glBlitFramebufferEXT with GL_STENCIL_BUFFER_BIT in this case also return GL_INVALID_FRAMEBUFFER_OPERATION (blitting from second to first). When second FBO has color attachment everything is ok.
I have GeForce card.