Clearing the depthbuffer according to values in stencil buffer

Started by
5 comments, last by _the_phantom_ 18 years, 3 months ago
Hi list, I've been messing around with the OpenGL Stencil buffer today and it stroke me how it's not possible to clear the depthbuffer ONLY in places where the Stencil buffer has a specific value. It seems to me, the depth buffer can only be cleared in a whole, is that correct or am I overlooking something? I tried this code, but the depth buffer always gets cleared completely:

GL11.glEnable(GL11.GL_STENCIL_TEST);
GL11.glStencilFunc(GL11.GL_ALWAYS, 2, 0xFFFFFFFF);
GL11.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_REPLACE);
renderMyStuffHere();
		
GL11.glStencilFunc(GL11.GL_EQUAL, 2, 0xFFFFFFFF);
GL11.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_KEEP);
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT); //This should clear the Depthbuffer where the Stencil value is 2, but it doesn't.

GL11.glDisable(GL11.GL_STENCIL_TEST);
Can anyone shed some light on this please? I would be much obliged.
Advertisement
Clear means just that, clear. You can't control anything about the clear.

The only way you can pull off what you're trying to do is to use a pixel shader that writes out the desired depth, and a screen size quad.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
You can use the scissor test to control the area of the framebuffer to clear. This only restricts it to a rectangular area smaller than (or equal to) the framebuffer size, however.
clear, as in, glClear, No way , AFAIK. A workaround would be to draw a full screen quad at a depth == your clear value and enable stencil testing.
Thanks, those are all valid solutions (which I looked into aswell) though the area I want to clear in the Depth buffer is 99% of the time not rectangular, so using the Scissor test is out of the question.

So, besides using a shader, this is simply not possible in OpenGL?
This seems a bit weird to me because the Stencil en Depth-buffer share the same buffer in memory, and the Stencil buffer cán be modified at will.
Quote:Original post by HolyFish
So, besides using a shader, this is simply not possible in OpenGL?
Actually, it didn't occur to me that you probably want a constant depth value, in which case you don't need a shader; just drawing a screen size quad at the correct depth will work.

Oh, and don't forget to turn off color writes. That'll get you a potentially massive speed increase (on the order of 100% faster for that pass on NV hardware).
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Quote:Original post by HolyFish
This seems a bit weird to me because the Stencil en Depth-buffer share the same buffer in memory, and the Stencil buffer cán be modified at will.


Not really, not if you consider the operations.

When you clear the hardware just needs todo a write to the memory, either a full write or a masked one if you dont ask the stencil buffer to be cleared (this is why they recommend clearing both at the same time btw).

For what you want you need todo a read-write combo, something which is going to slow things down more than you might realise (DDR ram performs badly when reading from and writing to the same area, it prefers mass batched reads or writes, this is part of the reason for the 10meg scratch render buffer in the XBox360's GPU) and 99.9% of the people out there dont need it, so they arent going to waste the hardware on doing it.

Also, this doesnt take into account the various buffers both ATI and NV use to speed up depth calculations and other tricks they use. A z-clear does more than simply writing to memory, it resets alot of buffers and internal GPU state as well to speed up later depth compares and to allow early-z rejection to work.

This topic is closed to new replies.

Advertisement