this is the code for shadows , terrain ( draw world) , buildings , light source
glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); // Reset The Current Modelview Matrix
gluLookAt(objCamera.mPos.x, objCamera.mPos.y, objCamera.mPos.z,
objCamera.mView.x, objCamera.mView.y, objCamera.mView.z,
objCamera.mUp.x, objCamera.mUp.y, objCamera.mUp.z);
glRotatef(rotWorld,-1.0, 0.0, 0.0);
// Turn off writing to the Color Buffer and Depth Buffer
// We want to draw to the Stencil Buffer only
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE);
// Enable the Stencil Buffer
glEnable(GL_STENCIL_TEST);
// Set 1 into the stencil buffer
glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
// Draw the floor
DrawWorld();
// Turn on Color Buffer and Depth Buffer
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);
// Only write to the Stencil Buffer where 1 is set
glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
// Keep the content of the Stencil Buffer
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
// Draw the floor
DrawWorld();
glPushMatrix();
glColor4f(0.0, 0.0, 0.0, 0.3f);
// Disable light
glDisable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
// Enable blending
glEnable(GL_BLEND);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
// Calculate the projected shadow
shadowmatrix(floorShadow, groundplane, lightPosition);
glMultMatrixf((float *)floorShadow);
DrawBuildings();
glTranslatef(7,7,1.0);
glScalef(0.1,0.1,0.1);
Draw_Model();
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glEnable(GL_LIGHTING);
glPopMatrix();
glPushMatrix();
// Dissable Stencil Buffer
glDisable(GL_STENCIL_TEST);
glTranslatef(7,7,1.0);
glScalef(0.1,0.1,0.1);
Draw_Model();
glPopMatrix();
glPushMatrix();
glDisable(GL_STENCIL_TEST);
DrawBuildings();
glPopMatrix();
glPushMatrix();
glDisable(GL_LIGHTING);
glColor3f(1,0,0);
glBegin(GL_POINTS);
glVertex3f(lightPosition[0],lightPosition[1],lightPosition[2]);
glEnd();
glEnable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glPopMatrix();
glPushMatrix();
glTranslatef(lightPosition[0],lightPosition[1],lightPosition[2]);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Lt0spec); // Make sphere glow
glutSolidSphere(1.3, 20, 20);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Noemit); // Turn off emission
if ( LightIsPositional==1 ) {
glLightfv(GL_LIGHT0, GL_POSITION, zeroPos ); // Position is transformed by ModelView matrix
}
else {
glLightfv(GL_LIGHT0, GL_POSITION, dirI ); // Direction is transformed by ModelView matrix
}
glPopMatrix();
void shadowmatrix(float shadowMat[4][4], float groundplane[4], float lightpos[4])
{
// Find the dot product between the light position vector and the ground plane normal
float dot = groundplane[X] * lightpos[X] + groundplane[Y] * lightpos[Y] + groundplane[Z] * lightpos[Z] + groundplane[W] * lightpos[W];
shadowMat[0][0] = dot - lightpos[X] * groundplane[X];
shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y];
shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z];
shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W];
shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X];
shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y];
shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z];
shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W];
shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X];
shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y];
shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z];
shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W];
shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X];
shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y];
shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z];
shadowMat[3][3] = dot - lightpos[W] * groundplane[W];
}