Stencil Buffer

Dear All,

I hope this post is advanced enough to appear here! :slight_smile:

I am trying to do child clipping using stencil buffer,
i.e. if object Obj1 (e.g. a push button) is child of object O2
( e.g. a dialog box), the part of O1 outside Obj2 should be not be drawn.


What I did successfully is:

//init stencil
glEnable(GL_STENCIL_TEST);
glClearStencil(0x0);
glClear(GL_STENCIL_BUFFER_BIT);

//set up stencil for Obj1
glStencilFunc (GL_ALWAYS, 0x1, 0x1);
glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE);

draw_Obj1_the_container(); 
	
//set up stencil for Obj2 - child clipping
glStencilFunc (GL_EQUAL, 0x1, 0x1);
glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
	
draw_Obj2_the_child();	

//turn off the stencil
glDisable(GL_STENCIL_TEST);

What I understand is:

  • Stencil buff is filled with ‘0’
  • When Obj1 is drawn in the color buffer, corresponding slots
    in Stencil are filled with ‘1’
  • While drawing Obj2, for each pixel, the color buffer is filled
    with Obj2 color only if the corresponding slots in Stencil buf
    contain ‘1’ (i.e. inside Obj2)

Is this correct?


1)Whats the relation between color buffer and stencil buffer,
R they filled at the same time? with what values?

  1. Whats the use of ‘mask’ argument for glStencilFunc(…)

  2. why glStencilOp(…) has arguments related to the Depth Buffer?

4)If stencil buffer is Draw/ Dont Draw why it needs multiple bits (mine has 8)

5)How do I implement ‘nested’ stencils, using one bitplane of the stencil
buffer at a time?
In that case, I can have upto 8 levels(mine has 8 bitplanes)

I am doing hierarchical rendering, so Obj2( or any child) doesnt know
about Obj1 (its parent), In this case how a child will know which bitplane
of the stencil buffer is not used by its parent, so that it can use that plane.

  • Chetan

Perhaps glScissor() is what you are looking for…

  1. Whats the use of ‘mask’ argument for glStencilFunc(…)

5)How do I implement ‘nested’ stencils, using one bitplane of the stencil
buffer at a time?

Question 2 answers question 5, in a way.
When rendering your polygon fragment…

say you’ve set up this:
glStencilFunc(GL_EQUAL, 4, 255);

This is the bit arrangment:-
reference : 00000100 (binary of 4)
mask : 11111111 (binary of 255)

Now, as the hardware is drawing your poly, it does this:-
masked reference = reference AND mask
masked stencil pixel = stencil pixel AND mask

You know what a logical AND is don’t you?

So imagine the current value in the stencil pixel is 8.
stencil pixel: 00001000 (binary of 8)
LOGICAL AND
mask : 11111111 (binary of 255)
result = 00001000 (binary of 8)

So the bit arrangement of those two values are now:-
masked reference : 00000100
masked stencil pixel : 00001000

The hardware now compares those two values with whatever operand you specified (=, >, <, >= etc.) which in our case is GL_EQUAL.
So, it does this:
if (masked reference == masked stencil pixel)
{
do a normal depth test
depending on glStencilOp and the result of the depth test, decide what to do to the current stencil pixel value (the one actually in the stencil buffer) based on the ‘zfail’ or ‘zpass’ parameters of glStencilOp
}
else
{
depending on glStencilOp, decide what to do to the current stencil pixel value (the one actually in the stencil buffer) based on the ‘fail’ parameter of glStencilOp
}

Originally posted by 1234!:
Perhaps glScissor() is what you are looking for…

No, GlScissor, is based on pixels i.e. display window co-ordinates and it can cut out only rectangular areas.

  • Chetan

Charming, do you realize how long it took me to produce that explaination?
The least you can do is acknowledge it, you ignorant c*nt.

Originally posted by knackered:
Charming, do you realize how long it took me to produce that explaination?
The least you can do is acknowledge it, you ignorant c*nt.

Hi,

To be frank, I was afraid if I post, a ‘thank u’ message, it will be like spam - against the rules.

Thank you, and sorry for the delay in thanking u !:slight_smile:

Chetan