Sign in to follow this  
EngineCoder

[SOLVED] Problems when moving from GL_STENCIL_TEST to GL_STENCIL_TEST_TWO_SIDE_EXT

Recommended Posts

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]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this