Jump to content

  • Log In with Google      Sign In   
  • Create Account


reusing depth stencil texture in another fbo


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
14 replies to this topic

#1 Yours3!f   Members   -  Reputation: 1282

Like
0Likes
Like

Posted 24 April 2012 - 12:39 PM

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();



Sponsor:

#2 V-man   Members   -  Reputation: 805

Like
0Likes
Like

Posted 25 April 2012 - 05:53 AM

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);

#3 Ashaman73   Crossbones+   -  Reputation: 6956

Like
0Likes
Like

Posted 25 April 2012 - 07:21 AM

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.

#4 Yours3!f   Members   -  Reputation: 1282

Like
0Likes
Like

Posted 25 April 2012 - 09:37 AM

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.



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.


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.


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?

#5 Ashaman73   Crossbones+   -  Reputation: 6956

Like
0Likes
Like

Posted 25 April 2012 - 11:17 PM

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.

#6 Yours3!f   Members   -  Reputation: 1282

Like
0Likes
Like

Posted 27 April 2012 - 11:21 AM


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.


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?

#7 slicer4ever   Crossbones+   -  Reputation: 3413

Like
0Likes
Like

Posted 27 April 2012 - 02:36 PM

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.

#8 Yours3!f   Members   -  Reputation: 1282

Like
0Likes
Like

Posted 28 April 2012 - 02:59 AM

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?

#9 slicer4ever   Crossbones+   -  Reputation: 3413

Like
0Likes
Like

Posted 28 April 2012 - 03:27 AM

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.

#10 Yours3!f   Members   -  Reputation: 1282

Like
0Likes
Like

Posted 28 April 2012 - 10:59 AM

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?

#11 DemonRad   Members   -  Reputation: 290

Like
0Likes
Like

Posted 29 April 2012 - 12:25 AM

if you want the skybox drawn only on pixel in wich it was not drawn you don't need FBO. you can achieve that with early z culling. You have just to draw skybox as last drawcall, just have to keep proper Z test to make z culling work ;-)

Peace and love, now I understand really what it means! Guardian Angels exist! Thanks!


#12 Yours3!f   Members   -  Reputation: 1282

Like
0Likes
Like

Posted 29 April 2012 - 01:29 AM

if you want the skybox drawn only on pixel in wich it was not drawn you don't need FBO. you can achieve that with early z culling. You have just to draw skybox as last drawcall, just have to keep proper Z test to make z culling work ;-)


well the skybox already works, the point is that I need to blur the scene later, and I'd like to save some texture fetches by masking out the skybox.

#13 DemonRad   Members   -  Reputation: 290

Like
0Likes
Like

Posted 29 April 2012 - 02:43 AM

ah :)

Peace and love, now I understand really what it means! Guardian Angels exist! Thanks!


#14 Ashaman73   Crossbones+   -  Reputation: 6956

Like
0Likes
Like

Posted 30 April 2012 - 12:06 AM

well the skybox already works, the point is that I need to blur the scene later, and I'd like to save some texture fetches by masking out the skybox.

Here might be a conceptual issue. When you blur, you most likely use a two pass or a single pass approach. When using a two pass approach(x/y axis), utilizing the stencil buffer could result in interesting effects (you stencil out the target and not the source texels). When using a single pass approach, you have a similar effect and you would have a performance impact (single pass (n*n) vs two pass (2*n) ).

Why not use the alpha channel (or some other) to determine a mask by discarding a pixel once the alpha channel has a value less than X. This is not as fast as a stencil buffer, but it should work on a block base, that is, when all pixels in a certain block (i.e. 16x16 pixel block) are discarded , then it is faster for this block. When using large parts of the image as background, this should performe better than the brute force approach. This way you could even implement a bilateral gauss filter (ignore masked source texels).

And try to utilise linear texture blending to half the number of taps needed for the blurring.

#15 Yours3!f   Members   -  Reputation: 1282

Like
0Likes
Like

Posted 30 April 2012 - 04:07 AM


well the skybox already works, the point is that I need to blur the scene later, and I'd like to save some texture fetches by masking out the skybox.

Here might be a conceptual issue. When you blur, you most likely use a two pass or a single pass approach. When using a two pass approach(x/y axis), utilizing the stencil buffer could result in interesting effects (you stencil out the target and not the source texels). When using a single pass approach, you have a similar effect and you would have a performance impact (single pass (n*n) vs two pass (2*n) ).

Why not use the alpha channel (or some other) to determine a mask by discarding a pixel once the alpha channel has a value less than X. This is not as fast as a stencil buffer, but it should work on a block base, that is, when all pixels in a certain block (i.e. 16x16 pixel block) are discarded , then it is faster for this block. When using large parts of the image as background, this should performe better than the brute force approach. This way you could even implement a bilateralgauss filter (ignore masked source texels).

And try to utilise linear texture blending to half the number of taps needed for the blurring.


Well, I use a separated gausssian blur with linear sampling (http://rastergrid.co...inear-sampling/), and I check the normals, so that the blur is geometry aware. I also implemented masking by checking if the normal vector is a null vector (only checking the source), and this seems to do the trick, but I was seeking for a faster method. So this is kind of the alpha-channel method that you described. But if stencil testing is only needed on the source as you described, than I guess the problem is solved Posted Image

Thanks for the bilateral approach I'll look into that.

Edited by Yours3!f, 30 April 2012 - 04:07 AM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS