user45620
user45620

Reputation: 23

OpenGL ES: Stencilbuffers and culling

I am new to OpenGL and i am trying out few experiments especially with the stencil buffers. In my code, I have set the front and back stencil buffers separately using glStencilFuncSeparate to 0x5 and 0xC respectively(GL_ALWAYS as parameter to the function). glStencilOpSeparate is set for front and back states to GL_REPLACE for dppass. I have also ensured that the depth and the culling are disabled when I setup both the stencil buffers.

Next I try to render a cube with depth, front culling and stencil test enabled. I am now using glStencilFuncSeparate() to draw only the back stencil setup area by comparing against 0x12. As the front face is culled away, I expect only the areas covered by my back stencil buffer whose value is 0x12 to be displayed.

But to my dismay, it displays blank screen. When it give the value for comparision as 0x5(front stencil init val) with cull face as front, I am able to see the portion of the cube.

So it seems to indicate that, the back face of the cube is compared against the front stencil when culling is set to GL_FRONT. All other parameters like StencilClear(value 0x1) looks proper and i somehow cannot understand this behavior.

Setup the stencil

glStencilMaskSeparate(GL_FRONT_AND_BACK, 0xff)
glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 0x5, 0xff)
glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0xc, 0xff)
glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_REPLACE)
glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_REPLACE)
glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE)
glDepthMask(GL_FALSE)
glDrawArrays(GL_TRIANGLES, 0, 6)

Enable culling

glCullFace(GL_FRONT)
glEnable(GL_CULL_FACE)

Draw a cube

glStencilOpSeparate(GL_FRONT,GL_KEEP,GL_KEEP,GL_REPLACE)
glStencilOpSeparate(GL_BACK,GL_KEEP,GL_KEEP,GL_REPLACE)
glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE)
glDepthMask(GL_FALSE)
glDrawArrays(GL_TRIANGLES, 0, 36)

OpenGL version: OpenGL ES 3.1 Mesa 19.0.8, Mesa DRI Intel Haswell Desktop

Could someone please help me understand why the front and back stencil buffers seems swapped with culling mode?

Upvotes: 0

Views: 302

Answers (1)

solidpixel
solidpixel

Reputation: 12069

It sounds like you think there are two different stencil buffers, one for front and one for back. This is incorrect; there is only a single stencil buffer with a single stencil value per pixel.

The glSeparate...() functions simply give you the means to specify separate stencil test/update rules for front and back-facing triangles, but they will write to the same storage location in the framebuffer.

Given you have a cube with the front-face closest to the camera then "surviving" stencil value after your first pass is always going to be the front-facing reference value.

Update: Note that you can "mix" front and back stencil values in the same stencil buffer by using glStencilMaskSeparate() to control which bits can be written, and glStencilFuncSeparate() to control which bits are used when stencil testing.

Upvotes: 1

Related Questions