My z-fail shadow volume rendering works fine, but when I try to convert it to use GL_STENCIL_TEST_TWO_SIDE_EXT my scene renders completely lit.
Old, working code:
// Prior to this code the scene is rendered using ambient lighting.
glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
glDepthMask( GL_FALSE );
glDepthFunc( GL_LEQUAL );
glDisable( GL_TEXTURE_2D );
glDisable( GL_LIGHTING );
glEnable( GL_POLYGON_OFFSET_FILL );
glPolygonOffset( 0.0f, 100.0f );
glEnable( GL_STENCIL_TEST );
// Renders shadow volumes.
for (unsigned int i = 0; i < scene->light.size(); ++i) {
// First pass, renders volume's back faces.
glCullFace( GL_FRONT );
glStencilFunc( GL_ALWAYS, stencilClear, ~0 );
glStencilOp( GL_KEEP, GL_INCR, GL_KEEP ); // stencilClear is 128
glStencilMask( ~0 );
renderAmbient = false;
renderOpaque = true;
activeShadowVolume = i;
glPushMatrix();
renderNode( scene->root ); // Opaque objects.
glPopMatrix();
renderOpaque = false;
glPushMatrix();
renderNode( scene->root ); // Translucent objects.
glPopMatrix();
// Second pass, renders volume's front faces.
glCullFace( GL_BACK );
glStencilOp( GL_KEEP, GL_DECR, GL_KEEP );
renderOpaque = true;
glPushMatrix();
renderNode( scene->root ); // Opaque objects.
glPopMatrix();
renderOpaque = false;
glPushMatrix();
renderNode( scene->root ); // Translucent objects.
glPopMatrix();
}
// Renders the scene normally.
float black[4] = { 0, 0, 0, 1 };
glLightModelfv( GL_LIGHT_MODEL_AMBIENT, black );
glDisable( GL_POLYGON_OFFSET_FILL );
glDepthFunc( GL_EQUAL );
glEnable( GL_BLEND );
glBlendFunc( GL_ONE, GL_ONE );
glStencilFunc( GL_EQUAL, stencilClear, ~0 );
glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
glEnable( GL_TEXTURE_2D );
glEnable( GL_LIGHTING );
renderAmbient = false;
renderOpaque = true;
activeShadowVolume = -1;
glPushMatrix();
renderNode( scene->root ); // Opaque objects.
glPopMatrix();
renderOpaque = false;
glPushMatrix();
renderNode( scene->root ); // Translucent objects.
glPopMatrix();
New code using two-sided stencil test:
...
glEnable( GL_STENCIL_TEST );
glEnable( GL_STENCIL_TEST_TWO_SIDE_EXT );
// Renders shadow volumes.
for (unsigned int i = 0; i < scene->light.size(); ++i) {
aglActiveStencilFaceEXT( GL_FRONT );
glStencilOp( GL_KEEP, GL_DECR, GL_KEEP );
glStencilFunc( GL_ALWAYS, stencilClear, ~0 ); // stencilClear is 128
glStencilMask( ~0 );
aglActiveStencilFaceEXT( GL_BACK );
glStencilOp( GL_KEEP, GL_INCR, GL_KEEP );
glStencilFunc( GL_ALWAYS, stencilClear, ~0 ); // stencilClear is 128
glStencilMask( ~0 );
renderAmbient = false;
renderOpaque = true;
activeShadowVolume = i;
glPushMatrix();
renderNode( scene->root ); // Opaque objects.
glPopMatrix();
renderOpaque = false;
glPushMatrix();
renderNode( scene->root ); // Translucent objects.
glPopMatrix();
}
// Renders the scene normally.
float black[4] = { 0, 0, 0, 1 };
glLightModelfv( GL_LIGHT_MODEL_AMBIENT, black );
glDisable( GL_POLYGON_OFFSET_FILL );
glShadeModel( GL_SMOOTH );
glDepthFunc( GL_EQUAL );
glEnable( GL_BLEND );
glEnable( GL_CULL_FACE );
glBlendFunc( GL_ONE, GL_ONE );
glDisable( GL_STENCIL_TEST_TWO_SIDE_EXT );
glEnable( GL_STENCIL_TEST );
glStencilFunc( GL_EQUAL, stencilClear, ~0 ); // stencilClear is 128
glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
glEnable( GL_TEXTURE_2D );
glEnable( GL_LIGHTING );
renderAmbient = false;
renderOpaque = true;
activeShadowVolume = -1;
glPushMatrix();
renderNode( scene->root ); // Opaque objects.
glPopMatrix();
renderOpaque = false;
glPushMatrix();
renderNode( scene->root ); // Translucent objects.
glPopMatrix();
edit: It's funny, I solved the problem almost right after making this thread. Not the first time. The solution was to put the block with aglActiveStencilFaceEXT( GL_BACK ); abowe the block with aglActiveStencilFaceEXT( GL_FRONT );
Merry Xmas!
[Edited by - EngineCoder on December 22, 2009 1:31:29 PM]