I made a very simple scene for testing stencil shadowing: a ball, a cylinder shadow volumn that cross once on the ball.
However, it seems nothing shadowed is drawn. The whole scene remained non-shadowed. What is the fault?
This is the drawing function:
void draw() {
glPushMatrix();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
// apply camera
glTranslated(0,0,-camera.distance);
glRotated(camera.elevation,1,0,0);
glRotated(camera.azimuth,0,1,0);
glTranslated(-camera.x, -camera.y, -camera.z);
// set light
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,1);
glLightfv( GL_LIGHT0, GL_POSITION, light_position );
glLightfv( GL_LIGHT0, GL_AMBIENT, light_ambient );
glLightfv( GL_LIGHT0, GL_DIFFUSE, light_diffuse );
glLightfv( GL_LIGHT0, GL_SPECULAR, light_specular );
// set material
glMaterialfv( GL_FRONT, GL_AMBIENT, mat_ambient );
glMaterialfv( GL_FRONT, GL_DIFFUSE, mat_diffuse );
glMaterialfv( GL_FRONT, GL_SPECULAR, mat_specular );
glMaterialfv( GL_FRONT, GL_EMISSION, mat_emission );
glMaterialf( GL_FRONT, GL_SHININESS, 100 );
// draw objects first time
glDisable(GL_STENCIL_TEST);
gluSphere(quad,10,32,32);
// draw shadow object using depth-fail method
// it should create an stencil mask of 1s on shadowed pixels, and 0s on bright pixels
glPushMatrix();
glRotated(90,0,1,0);
glDisable(GL_LIGHTING);
glEnable(GL_STENCIL_TEST);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
glStencilMask(~0u);
glEnable(GL_CULL_FACE);
// draw the back face of shadow volume
glCullFace(GL_FRONT);
glStencilOp(GL_KEEP,GL_INCR,GL_KEEP);
gluCylinder(quad,4,4,200,32,32);
// draw the front face of shadow volume
glCullFace(GL_BACK);
glStencilOp(GL_KEEP,GL_INCR,GL_KEEP);
gluCylinder(quad,4,4,200,32,32);
glDisable(GL_CULL_FACE);
glPopMatrix();
// draw shadowed scene again
// only draw on pixels which stencil buffer is one
glClear(GL_DEPTH_BUFFER_BIT);
glDepthMask(GL_TRUE);
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
glLightfv(GL_FRONT, GL_DIFFUSE, zeroes);
glLightfv(GL_FRONT, GL_SPECULAR, zeroes);
glStencilFunc(GL_GREATER,0,~0u);
gluSphere(quad,10,32,32);
// draw axis
glDisable(GL_LIGHTING);
glDisable(GL_STENCIL_TEST);
glBegin(GL_LINES);
glColor3f(1,0,0);
glVertex3d(0,0,0);
glVertex3d(100,0,0);
glColor3f(0,1,0);
glVertex3d(0,0,0);
glVertex3d(0,100,0);
glColor3f(0,0,1);
glVertex3d(0,0,0);
glVertex3d(0,0,100);
glEnd();
// finishing works
glPopMatrix();
glFlush();
glutSwapBuffers();
}