reusing depth stencil texture in another fbo

Started by
13 comments, last by Yours3!f 11 years, 12 months ago
Hi,

I'm rendering to a depth stencil texture using a fbo and a rbo. After the rendering is done, I want to use the depth stencil texture in another fbo. I tried attaching the same rbo to the other fbo, and also attaching the texture as a depth stencil attachment to the other fbo, but it didn't work.

So how do I do that? (if its possible)

Here's the code that would render some texture onto the screen where I didn't put 1 into the stencil buffer

//Set up FBO with which I render to the depth and stencil textures
fbo.create();
fbo.bind();

depth_stencil.create();
depth_stencil.valid = true;

depth_stencil.bind();
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_DEPTH24_STENCIL8, ( GLsizei )w, ( GLsizei )h, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0 ); //depth + stencil
depth_stencil.width = w;
depth_stencil.height = h;

rbo.create();
rbo.bind();
rbo.set_storage_format( GL_DEPTH24_STENCIL8, w, h );
rbo.width = w;
rbo.height = h;

rbo.attach_to_frame_buffer( GL_DEPTH_STENCIL_ATTACHMENT, &fbo );
depth_stencil.attach_to_frame_buffer( GL_DEPTH_STENCIL_ATTACHMENT, &fbo );

fbo.check();
fbo.unbind();

//set up another fbo
another_fbo.create();
another_fbo.bind();

GLenum modes[] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers( 1, modes );

another_tex.create(); //create a texture to render to
another_tex.valid = true;

another_tex.bind();
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_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, ( GLsizei )w, ( GLsizei )h, 0, GL_RGBA, GL_FLOAT, 0 );
another_tex.width = w;
another_tex.height = h;

another_tex.attach_to_frame_buffer( GL_COLOR_ATTACHMENT0, &another_fbo );

depth_stencil.attach_to_frame_buffer( GL_DEPTH_STENCIL_ATTACHMENT, &another_fbo );
rbo.attach_to_frame_buffer( GL_DEPTH_STENCIL_ATTACHMENT, &another_fbo );

another_fbo.check();
another_fbo.unbind();

//bind and clear fbo (color depth stencil)
[...]

//render objects placing 1 to the stencil buffer
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

render();

//bind and clear another fbo (only clear color)
[...]

//render full-screen quad with some texture where we didnt render anything
glStencilFunc(GL_NOTEQUAL, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

some_texture.bind();
render_quad();

//unbind another fbo
[...]

//show our work
glDisable(GL_STENCIL_TEST);
another_tex.bind();
render_quad();

Advertisement
What is the problem exactly? If the fbo check isn't working, then you should say what the error message is. If nothing renders to it, then you probably left some gl state on or off and it is causing you trouble. Can you render the same thing to the back buffer?
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);

rbo.attach_to_frame_buffer( GL_DEPTH_STENCIL_ATTACHMENT, &fbo );
depth_stencil.attach_to_frame_buffer( GL_DEPTH_STENCIL_ATTACHMENT, &fbo );

Why are you binding a RBO and a texture to a single FBO at the same attachment point ? I would think, that only the last, in your case depth_stencil, will be taken.


depth_stencil.attach_to_frame_buffer( GL_DEPTH_STENCIL_ATTACHMENT, &another_fbo );
rbo.attach_to_frame_buffer( GL_DEPTH_STENCIL_ATTACHMENT, &another_fbo );

The same here, this time the RBO is the last one, and therefore the first depth_stencil will not be taken.

What is the problem exactly? If the fbo check isn't working, then you should say what the error message is. If nothing renders to it, then you probably left some gl state on or off and it is causing you trouble. Can you render the same thing to the back buffer?


well, let me try to explain what I'm trying to accomplish:
1. render scene geometry with stencil test enabled, and put 1 to the stencil buffer where I draw
2. render the background texture (skybox) where the stencil buffer is 0
3. blur scene where needed (where the stencil buffer is 1)

now in step 1 and 2 I render to FBO #1 that has a D24S8 attached to it.
in step 3 I do a gaussian blur that I render to a texture via FBO #2 ("another fbo") which goes like this:
blur the scene where the stencil buffer is 1 (the geometry) using the D24S8 buffer from FBO #1

my problem is that I don't know how can I attach the D24S8 texture from FBO #1 to FBO #2 and still do stencil testing.
I assumed that I had to attach the same buffers, but that doesn't seem to work.



[quote name='Yours3!f' timestamp='1335292777' post='4934508']
rbo.attach_to_frame_buffer( GL_DEPTH_STENCIL_ATTACHMENT, &fbo );
depth_stencil.attach_to_frame_buffer( GL_DEPTH_STENCIL_ATTACHMENT, &fbo );

Why are you binding a RBO and a texture to a single FBO at the same attachment point ? I would think, that only the last, in your case depth_stencil, will be taken.


depth_stencil.attach_to_frame_buffer( GL_DEPTH_STENCIL_ATTACHMENT, &another_fbo );
rbo.attach_to_frame_buffer( GL_DEPTH_STENCIL_ATTACHMENT, &another_fbo );

The same here, this time the RBO is the last one, and therefore the first depth_stencil will not be taken.
[/quote]

[quote name='Yours3!f' timestamp='1335292777' post='4934508']
rbo.attach_to_frame_buffer( GL_DEPTH_STENCIL_ATTACHMENT, &fbo );
depth_stencil.attach_to_frame_buffer( GL_DEPTH_STENCIL_ATTACHMENT, &fbo );

Why are you binding a RBO and a texture to a single FBO at the same attachment point ? I would think, that only the last, in your case depth_stencil, will be taken.


depth_stencil.attach_to_frame_buffer( GL_DEPTH_STENCIL_ATTACHMENT, &another_fbo );
rbo.attach_to_frame_buffer( GL_DEPTH_STENCIL_ATTACHMENT, &another_fbo );

The same here, this time the RBO is the last one, and therefore the first depth_stencil will not be taken.
[/quote]

umm so that the FBO actually does depth testing and stencil testing, but uses the texture attached to perform the tests. Am I doing that correctly?

umm so that the FBO actually does depth testing and stencil testing, but uses the texture attached to perform the tests. Am I doing that correctly?

Try top attach either the rbo or the texture, but not both.

[quote name='Yours3!f' timestamp='1335368262' post='4934783']
umm so that the FBO actually does depth testing and stencil testing, but uses the texture attached to perform the tests. Am I doing that correctly?

Try top attach either the rbo or the texture, but not both.
[/quote]

Thank you, attaching the rbo only did it. But I have another issue, I render the blurring at half resolution, so I resize the viewport to half the screen size, and back when I'm done. When blurring I can see that it only uses the lower left quater of the stencil buffer because of the half resolution. Now how can I resize the stencil buffer as well, so that it masks the rendering correctly? Is there a "usual" way?
if you want to use the stencil results from a framebuffer, you need to create it as a texture, and attach it to the fbo as a texture, than later, when using the values in another part of the rendering, you simply bind the texture before you draw, and then in the shader do whatever you want with the result.
Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

if you want to use the stencil results from a framebuffer, you need to create it as a texture, and attach it to the fbo as a texture, than later, when using the values in another part of the rendering, you simply bind the texture before you draw, and then in the shader do whatever you want with the result.


I thought about that as well, and that would solve the problem, but isn't the fixed pipeline stencil testing faster?
hmm, i re-read your original problem, and i misunderstood when i originally posted. while doing a shader-tex attachment is a possible option, what you doing is much more efficient, yes.

in short, you were already on the right track, and i carelessly posted, my apologies.
Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

hmm, i re-read your original problem, and i misunderstood when i originally posted. while doing a shader-tex attachment is a possible option, what you doing is much more efficient, yes.

in short, you were already on the right track, and i carelessly posted, my apologies.


well, no problem :)

I actually tried to mask the blurring using the shader based approach, but while rgb contained depth, a contained pure white, meaning all pixels passed the stencil test...
But that is impossible, since the background texture (which gets rendered to where stencil == 0) renders correctly.

I also thought about generating the 2nd level mipmap of the depth-stencil texture (thus generating a half-res texture) and use that for stencil testing, but how could that be done?

This topic is closed to new replies.

Advertisement