Search code examples
opengl-4

stencil buffer - understanding glStencilFuncSeparate


An example code looks like this:

glEnable(GL_STENCIL_TEST);
glClearStencil(2);
glClear(GL_STENCIL_BUFFER_BIT);
glStencilFuncSeparate(GL_FRONT, GL_NOTEQUAL, 0, 1);
object.draw();
glDisable(GL_STENCIL_TEST);

Stencil buffer for each pixel has this binary value: 00000010 (8 bits precision) Next, glStencilFuncSeparate make following logic operation: (00000000 & 00000001 = 00000000), (00000010 & 00000001 = 00000000) -> 00000000 != 00000000 so the stencil test is failed and front faces of the object won't be drawn. We can set a mask for example as 2 or 255 and then the test will be passed.

If the Ref argument in glStencilFuncSeparate is 257 then will be clamped to 1. 1.What about the mask argument and clamping ? 2.Presented informations are correct, right ?


Solution

  • You say:

    Stencil buffer for each pixel has this binary value: 00000010 (8 bits precision) Next, glStencilFuncSeparate make following logic operation: (00000000 & 00000001 = 00000000), (00000010 & 00000001 = 00000000) -> 00000000 != 00000000 so the stencil test is failed and front faces of the object won't be drawn.

    which is all correct.

    We can set a mask for example as 2 or 255 and then the test will be passed.

    Yes; any value where the combination of the mask parameter (the fourth parameter to glStencilFunc*) with the pixel's stencil value yields a non-zero answer (provided you don't change the ref parameter (the third parameter to glStencilFunc*) will pass the stencil comparison test.

    If the Ref argument in glStencilFuncSeparate is 257 then will be clamped to 1.

    Actually, no. According to the OpenGL spec and glStencilFunc* reference page, the ref value is clamped to the range [0,  2s - 1], where s is the number of stencil bits, so in your example, the ref value would be clamped to 255.

    1. What about the mask argument and clamping?

    only the s least significant bits of mask are used. The stencil comparison function is really:

    result = (pixel & (mask & (1<<s - 1))) <stencil func> (ref & (mask & (1<<s - 1)))
    

    2. Presented informations are correct, right?

    Almost. Not a bad job at all :-)