/* Test of Angel's shadow example */ /* See pgs. 177-178 for his explanations of glVertexPointer, glColorPointer, glDrawElements */ #include #include #include #include "tw.h" #include //variables for the position and angle of "sun" GLfloat angle=0; GLfloat xVal =1.0; GLfloat yVal =0.0; GLfloat zVal =0.0; void sun() { GLfloat lightPosition [] = {xVal,yVal,zVal,1.0}; GLfloat ambient [] = {1,1,1,1}; GLfloat diffuse [] = {1,1,1,1}; GLfloat specular [] = {0.8,0.8,0.8,1}; glLightfv(GL_LIGHT1, GL_POSITION, lightPosition); glLightfv(GL_LIGHT1, GL_AMBIENT, ambient); glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT1, GL_SPECULAR, specular); glShadeModel(GL_SMOOTH); glEnable(GL_LIGHT1); glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); glEnable(GL_LIGHTING); } void drawShape() { glPushMatrix(); glRotatef(45,0,1,0); glutSolidTeapot(4); glPopMatrix(); } void shadowMatrix(GLfloat groundPlane[4], GLfloat lightPos[4]) { GLfloat shadowMat[4][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.0-lightPos[0]*groundPlane[1]; shadowMat[2][0] = 0.0-lightPos[0]*groundPlane[2]; shadowMat[3][0] = 0.0-lightPos[0]*groundPlane[3]; shadowMat[0][1] = 0.0-lightPos[1]*groundPlane[0]; shadowMat[1][1] = dot-lightPos[1]*groundPlane[1]; shadowMat[2][1] = 0.0-lightPos[1]*groundPlane[2]; shadowMat[3][1] = 0.0-lightPos[1]*groundPlane[3]; shadowMat[0][2] = 0.0-lightPos[2]*groundPlane[0]; shadowMat[1][2] = 0.0-lightPos[2]*groundPlane[1]; shadowMat[2][2] = dot-lightPos[2]*groundPlane[2]; shadowMat[3][2] = 0.0-lightPos[2]*groundPlane[3]; shadowMat[0][3] = 0.0-lightPos[3]*groundPlane[0]; shadowMat[1][3] = 0.0-lightPos[3]*groundPlane[1]; shadowMat[2][3] = 0.0-lightPos[3]*groundPlane[2]; shadowMat[3][3] = dot-lightPos[3]*groundPlane[3]; glMultMatrixf((const GLfloat*)shadowMat); } void display(void) { xVal = 20.0*cos(angle); yVal = 20.0*sin(angle); GLfloat light[3]={xVal,yVal,zVal}; /*light position*/ GLfloat m[16]; int i,j; for(i=0;i<16;i++) m[i]=0.0; //matrix to compute teapot's shadow m[0]=m[5]=m[10]=1.0; m[7]=-1.0/light[1]; glClearColor(1,1,1,1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); twCamera(); sun(); glPushMatrix(); glTranslatef(0.0, 3.0, 0.0); twColor(0,0.6,0,128); //color of object drawShape(); glPopMatrix(); glPushMatrix(); glTranslatef(light[0], light[1],light[2]); twColor(0.5,0.5,0,128); glutSolidSphere(0.5,10,10); //sun glMultMatrixf(m); //flattens out the teapot GLfloat ground[4] = {0,1,0,0}; //normal // shadowMatrix(ground,light); glTranslatef(-light[0],-light[1],-light[2]); glDisable(GL_LIGHTING); glColor3f(0.5,0.5,0.5); //color of shadow drawShape(); glPopMatrix(); glFlush(); glutSwapBuffers(); } void timeLapse() { angle+=0.01; if(angle>M_PI) { angle-=M_PI; } glutPostRedisplay(); } void start (unsigned char key, int x, int y) { angle = 0; xVal = 1; yVal = 0; zVal = 0; glutIdleFunc(timeLapse); //necessary after one pauses glutPostRedisplay(); } void keyInit() { twKeyCallback('s', start, "starts animation from beginning"); } int main(int argc, char **argv) { /* need both double buffering and z buffer */ glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); twInitWindowSize(500, 500); twBoundingBox(-10,10,0,20,-5,5); glutCreateWindow("colorcube"); glutDisplayFunc(display); twMainInit(); keyInit(); glutIdleFunc(timeLapse); glutMainLoop(); return 0; }