Home | | Syllabus | | Assignments | | Documentation

    Solution to Assignment 6, Problem 1a


    /*
    CSCI384 Assign 6.
    Problem 1a--Flat Shading.
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <GL/glut.h>
    
    
    #define PI 3.14159
    typedef GLfloat point3[3];
    GLfloat spin = 0.0;
    
    void myinit(void)
    {
    	GLfloat mat_specular[] = {1.0, 0.0, 1.0, 1.0};
    	GLfloat mat_diffuse[] = {0.2, 0.0, 0.2, 1.0};
    	GLfloat mat_ambient[] = {0.2, 0.0, 0.2, 1.0};
    	
    	GLfloat light_ambient[] = {1.0, 1.0, 1.0, 1.0};
    	GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0};
    	GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};
    	GLfloat light0_pos[] = {1.0, 2.0, 4.0, 0.0};
    	
    	glLightfv(GL_LIGHT0, GL_POSITION, light0_pos);
    	glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
    	glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
    	glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
    	
    	glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
    	glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    	glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    	
    	glEnable(GL_FLAT);
    	glEnable(GL_LIGHTING);
    	glEnable(GL_LIGHT0);
    
    	glShadeModel(GL_FLAT);
    	glClearColor(1.0, 1.0, 1.0, 1.0);
    	glColor3f(0.0, 0.0, 0.0);
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
    	glOrtho(-250, 250, -250, 250, -250, 250); /*Note, not ortho2D*/
    	glMatrixMode(GL_MODELVIEW);
    }
    void normalize(GLfloat *verts){
    	int i;
    	GLfloat normalFactor;
    	
    	normalFactor = sqrt(verts[0]*verts[0] + verts[1]*verts[1] + verts[2]*verts[2]);
    	for(i = 0; i < 3; i++){
    		verts[i] = verts[i]/normalFactor;
    	}
    }
    void cross(point3 a, point3 b, point3 c, point3 d){
    	d[0] = (b[1] - a[1])*(c[2] - a[2]) - (b[2] - a[2]) * (c[1] - a[1]);
    	d[1] = (b[2] - a[2])*(c[0] - a[0]) - (b[0] - a[0]) * (c[2] - a[2]);
    	d[2] = (b[0] - a[0])*(c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
    	normalize(d);
    	
    }
    void display(void){
    	/*Note 3D points here.  Set up array of 3D vertices*/
    	
    	
    	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} };
    	point3 normals[5];
    	
    	int i;
    	
    	cross(vertices[0], vertices[1], vertices[2], normals[0]);
    	cross(vertices[0], vertices[2], vertices[3], normals[1]);
    	cross(vertices[3], vertices[2], vertices[4], normals[2]);
    	cross(vertices[4], vertices[2], vertices[1], normals[3]);
    	cross(vertices[0], vertices[3], vertices[1], normals[4]);
    	/*Note use of Depth buffer bit for hidden surface removal*/
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    	
    	glLoadIdentity();
    	glRotatef(spin, 0.0, 1.0, 0.0); /*Rotate pyramid*/
    
    	/*Draw pyramid*/
    	glBegin(GL_TRIANGLES);
    	
    		
    		glNormal3fv(normals[0]);
    		for (i=0; i<3; i++){
    			glVertex3fv(vertices[i]);
    		}
    	
    		
    		glNormal3fv(normals[1]);
    
    		glVertex3fv(vertices[0]); /*Second face*/
    		glVertex3fv(vertices[2]);
    		glVertex3fv(vertices[3]);
    	
    		
    		glNormal3fv(normals[2]);
    		glVertex3fv(vertices[3]); /*Third face*/
    		glVertex3fv(vertices[2]);
    		glVertex3fv(vertices[4]);
    	
    		
    		glNormal3fv(normals[3]);
    		glVertex3fv(vertices[4]); /*Fourth face*/
    		glVertex3fv(vertices[2]);
    		glVertex3fv(vertices[1]);
    
    	glEnd();
    	glBegin(GL_QUADS);
    		glNormal3fv(normals[4]);
    		glVertex3fv(vertices[0]);
    		glVertex3fv(vertices[3]);
    		glVertex3fv(vertices[4]);
    		glVertex3fv(vertices[1]);
    	glEnd();
    	glFlush();
    	glutSwapBuffers(); /*Display next buffer*/
    }
    
    /*Function called during idles--spins the pyramid*/
    void spinDisplay(void){
    	spin = spin + 1.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();
    	glutInitWindowSize(500,500);
    	glutInitWindowPosition(50,50);
    	glutCreateWindow("Spinning Triangles"); 
    	glutDisplayFunc(display);
    	glutIdleFunc(spinDisplay); /*Idle function, spins pyramid*/
    	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