#include #include // function prototypes void display(void); void reshape(int width, int height); void keyboard(unsigned char key, int x, int y); void init(void); void shadowMatrixPointLight(float matrix[4][4], float groundPlane[4], float lightPosition[4]); void drawFloor(void); void drawCube(void); // global yuck float pointLightPosition[]={-3.0f,2.0f,0.0f,1.0f}; int main(int argc, char **argv) { // set up window glutInitWindowSize(400, 400); glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutCreateWindow("Shadow Demo"); // register callback functions glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); // initalize opengl parameters init(); // loop until something happens glutMainLoop(); return 0; } void init() { // initialize viewing system glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, 1.0, 1.0, 100.0); glMatrixMode(GL_MODELVIEW); // initialize shade model to smooth glShadeModel(GL_SMOOTH); // initialize background color to white glClearColor(1.0,1.0,1.0,0.0); // initialize stencil value glClearStencil(0.0); // enable depth buffering glEnable(GL_DEPTH_TEST); // create some ambient light float ambient[]={0.5f,.5f,.5f}; glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); // create a point light float pointLightColor[]={1.0f,1.0f,1.0f,1.0f}; glLightfv(GL_LIGHT0, GL_POSITION, pointLightPosition); glLightfv(GL_LIGHT0, GL_DIFFUSE, pointLightColor); glLightfv(GL_LIGHT0, GL_SPECULAR, pointLightColor); // enable lighting and the point light glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); // set polygon mode glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); } void reshape(int width, int height) { glViewport(0,0,width,height); } void display() { // initialize modelview matrix glLoadIdentity(); gluLookAt(0.0,3.0,10.0,0.0,0.0,0.0,0.0,1.0,0.0); // clear buffers glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |GL_STENCIL_BUFFER_BIT); // draw a floor // // you need to set up stencil buffer for shadow on floor // float floorDiffuse[]={1.0f, 0.0f, 0.0f}; float floorAmbient[]={1.0f, 0.0f, 0.0f}; glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, floorDiffuse); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, floorAmbient); drawFloor(); // draw a cube float cubeDiffuse[]={0.0f, 0.0f, 0.8f}; float cubeAmbient[]={0.0f, 0.0f, 0.8f}; glMaterialfv(GL_FRONT, GL_DIFFUSE, cubeDiffuse); glMaterialfv(GL_FRONT, GL_AMBIENT, cubeAmbient); drawCube(); // draw a shadow // set up stencil buffer // set up blending // set color to black with alpha = 1/2 // set up polygon offset // build the projection matrix //float shadowMatrix[4][4]; //float groundPlane[4]={0.0f,1.0f, 0.0f, 0.0f}; //shadowMatrixPointLight(shadowMatrix, groundPlane, pointLightPosition); // now draw the shadow //glMultMatrixf((GLfloat *) shadowMatrix); //drawCube(); //restore parameters // swap buffers glutSwapBuffers(); } void keyboard(unsigned char key, int mouseX, int mouseY) { } /* Create a matrix that will project the desired shadow. */ void shadowMatrixPointLight(GLfloat shadowMat[4][4], GLfloat groundplane[4], GLfloat lightpos[4]) { GLfloat dot; /* Find dot product between light position vector and ground plane normal. */ dot = groundplane[0] * lightpos[0] + groundplane[1] * lightpos[1] + groundplane[2] * lightpos[2] + groundplane[3] * lightpos[3]; shadowMat[0][0] = dot - lightpos[0] * groundplane[0]; shadowMat[1][0] = 0.f - lightpos[0] * groundplane[1]; shadowMat[2][0] = 0.f - lightpos[0] * groundplane[2]; shadowMat[3][0] = 0.f - lightpos[0] * groundplane[3]; shadowMat[0][1] = 0.f - lightpos[1] * groundplane[0]; shadowMat[1][1] = dot - lightpos[1] * groundplane[1]; shadowMat[2][1] = 0.f - lightpos[1] * groundplane[2]; shadowMat[3][1] = 0.f - lightpos[1] * groundplane[3]; shadowMat[0][2] = 0.f - lightpos[2] * groundplane[0]; shadowMat[1][2] = 0.f - lightpos[2] * groundplane[1]; shadowMat[2][2] = dot - lightpos[2] * groundplane[2]; shadowMat[3][2] = 0.f - lightpos[2] * groundplane[3]; shadowMat[0][3] = 0.f - lightpos[3] * groundplane[0]; shadowMat[1][3] = 0.f - lightpos[3] * groundplane[1]; shadowMat[2][3] = 0.f - lightpos[3] * groundplane[2]; shadowMat[3][3] = dot - lightpos[3] * groundplane[3]; } void drawFloor(void) { // draw a floor glPushMatrix(); glTranslatef(-2.5f,0.0f,-3.0f); glNormal3f(0.0,1.0,0.0); for (int i=0;i<5; i++) { glTranslatef(0.0f,0.0f,1.0f); glBegin(GL_QUAD_STRIP); for (int j=0; j<6 ;j++) { glVertex3f((float) j, 0.0f, 0.0f); glVertex3f((float) j, 0.0f, 1.0f); } glEnd(); } glPopMatrix(); } void drawCube(void) { glPushMatrix(); glTranslatef(0.0f,0.5f,0.0f); glutSolidCube( 1.0); glPopMatrix(); }