Home | | Syllabus | | Assignments | | Documentation

    Solution to Assignment 5, Problem 2


    /*
    CSCI 384 Assign 5.
    Problem 2--shadow of a pyramid.
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <GL/glut.h>
    
    #define PI 3.14159
    
    GLfloat spin= 0.0;
    GLfloat m[16];		/*Shadow projection matrix*/
    GLfloat xLight = 0.0, zLight = 0.0, yLight = 250.0;
    
    void myinit(void)
    {
    	glClearColor(1.0, 1.0, 1.0, 1.0);
    	glColor3f(1.0, 0.0, 0.0);
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
    	glOrtho(-250, 250, -250, 250, -250, 250); /*Note, not ortho2D*/
    	glMatrixMode(GL_MODELVIEW);
    }
    
    /*Set up shadow projection matrix*/
    void initShadowMatrix(void){
    	int i;
    	
    	for (i = 0; i < 16; i++){
    		m[i] = 0.0;
    	}
    	m[0] = m[5] = m[10] = 1.0;
    	m[7] = -1.0/yLight;
    }	
    
    void display(void){
    	/*Note 3D points here.  Set up array of 3D vertices*/
    	typedef GLfloat point3[3];
    	point3 vertices[5] = { {0.0, 0.0, 100.0}, {100.0, 0.0, 0.0}, 
    				{0.0, 100.0, 0.0}, {-100.0, 0.0, 0.0}, 
    				{0.0, 0.0, -100.0} };
    	int i;
    	/*Note use of Depth buffer bit for hidden surface removal*/
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    	
    	/*Draw regular pyramid*/
    	glLoadIdentity();
    	glRotatef(30.0, 1.0, 0.0, 0.0);	/*Rotate a bit so can see x-z plane*/
    	glTranslatef(0.0, 100.0, 0.0);
    	glRotatef(spin, 0.0, 1.0, 0.0);   /*Rotate pyramid*/
    	glScalef(0.75, 0.75, 0.75);
    	/*Draw pyramid*/
    	glBegin(GL_TRIANGLES);
    	glColor3f(1.0, 0.0, 0.0); 
    		for (i=0; i<3; i++){
    			glVertex3fv(vertices[i]);
    		}
    	glColor3f(0.0, 1.0, 0.0);
    		glVertex3fv(vertices[0]); 
    		glVertex3fv(vertices[2]);
    		glVertex3fv(vertices[3]);
    	glColor3f(0.0, 0.0, 1.0);
    		glVertex3fv(vertices[3]); 
    		glVertex3fv(vertices[2]);
    		glVertex3fv(vertices[4]);
    	glColor3f(1.0, 0.0, 1.0);
    		glVertex3fv(vertices[4]); 
    		glVertex3fv(vertices[2]);
    		glVertex3fv(vertices[1]);
    
    	glEnd();
    	glBegin(GL_QUADS);
    		glColor3f(1.0, 1.0, 0.0); 
    		glVertex3fv(vertices[0]);
    		glVertex3fv(vertices[3]);
    		glVertex3fv(vertices[4]);
    		glVertex3fv(vertices[1]);
    	glEnd();
    	
    	glPushMatrix();	/*Save current state*/
    	/*Draw shadow*/
    	glLoadIdentity();
    	glRotatef(30.0, 1.0, 0.0, 0.0);
    	glTranslatef(xLight, yLight, zLight);  /*Translate back*/
    	glMultMatrixf(m);  /*Multiply by shadow projection matrix*/
    	glTranslatef(-xLight, -yLight, -zLight);  /*Translate so lightsource is at origin*/
    	glTranslatef(0.0, 100.0, 0.0);
    	glRotatef(spin, 0.0, 1.0, 0.0); /*Rotate pyramid*/	
    	glScalef(0.75, 0.75, 0.75);
    	glColor3f(0.3, 0.3, 0.3);
    	
    	/*Draw shadow pyramid*/
    	glBegin(GL_TRIANGLES);
    		for (i=0; i<3; i++){
    			glVertex3fv(vertices[i]);
    		}
    	
    		glVertex3fv(vertices[0]); 
    		glVertex3fv(vertices[2]);
    		glVertex3fv(vertices[3]);
    	
    		glVertex3fv(vertices[3]); 
    		glVertex3fv(vertices[2]);
    		glVertex3fv(vertices[4]);
    	
    		glVertex3fv(vertices[4]); 
    		glVertex3fv(vertices[2]);
    		glVertex3fv(vertices[1]);
    
    	glEnd();
    	glBegin(GL_QUADS);
    	
    		 /*Bottom of pyramid*/
    		glVertex3fv(vertices[0]);
    		glVertex3fv(vertices[3]);
    		glVertex3fv(vertices[4]);
    		glVertex3fv(vertices[1]);
    	glEnd();
    	glPopMatrix();
    	glFlush();
    	glutSwapBuffers(); /*Display next buffer*/
    }
    
    void idle(void){
    	spin += 2.0;
    	if (spin > 360.0)
    		spin = spin - 360.0;
    	
    	glutPostRedisplay();
    }
    
    int main(int argc, char** argv)
    {	
    	glutInit(&argc, argv);
    	/*Note the GLUT_DOUBLE and GLUT_DEPTH here*/
    	glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    	myinit();
    	initShadowMatrix();
    	glutInitWindowSize(500,500);
    	glutInitWindowPosition(50,50);
    	glutCreateWindow("Shadow Pyramid"); 
    	glutDisplayFunc(display);
    	glutKeyboardFunc(keys); /*Keyboard function, spins pyramid*/
    	glutIdleFunc(idle);
    	glEnable(GL_DEPTH_TEST); /*For hidden surface removal*/
    	myinit();
    	glutMainLoop();
    	
    	return 0;
    }
    	
    

    Home | | Syllabus | | Assignments | | Documentation


    Constance Royden--croyden@mathcs.holycross.edu
    Computer Science 384
    Date Created: August 17, 1999
    Last Modified: November 5, 2003
    Page Expires: August 17, 2004