![]() |
|
|
Home | | Syllabus | |
Assignments | |
Documentation
Solution to Assignment 6, Problem 1b
/*
CSCI384 Assign 6.
Problem 1b--Smooth 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[] = {0.0, 0.0, 1.0, 1.0};
GLfloat mat_diffuse[] = {0.0, 0.0, 1.0, 1.0};
GLfloat mat_ambient[] = {0.0, 0.0, 0.2, 1.0};
GLfloat mat_shininess[] = {200.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);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glEnable(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glShadeModel(GL_SMOOTH);
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 vectAvg3(point3 a, point3 b, point3 c, point3 d){
d[0] = (a[0] + b[0] + c[0])/3.0;
d[1] = (a[1] + b[1] + c[1])/3.0;
d[2] = (a[2] + b[2] + c[2])/3.0;
normalize(d);
}
void vectAvg4(point3 a, point3 b, point3 c, point3 d, point3 e){
e[0] = (a[0] + b[0] + c[0] + d[0])/4.0;
e[1] = (a[1] + b[1] + c[1] + d[1])/4.0;
e[2] = (a[2] + b[2] + c[2] + d[2])/4.0;
normalize(e);
}
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], normAvg[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]);
vectAvg3(normals[0], normals[1], normals[4], normAvg[0]);
vectAvg3(normals[0], normals[3], normals[4], normAvg[1]);
vectAvg4(normals[0], normals[1], normals[2], normals[3], normAvg[2]);
vectAvg3(normals[1], normals[2], normals[4], normAvg[3]);
vectAvg3(normals[2], normals[3], normals[4], normAvg[4]);
/*Note use of Depth buffer bit for hidden surface removal*/
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef(spin, 1.0, 0.0, 0.0); /*Rotate pyramid*/
/*Draw pyramid*/
glBegin(GL_TRIANGLES);
glNormal3fv(normals[0]);
for (i=0; i<3; i++){
glNormal3fv(normAvg[i]);
glVertex3fv(vertices[i]);
}
glNormal3fv(normAvg[0]);
glVertex3fv(vertices[0]); /*Second face*/
glNormal3fv(normAvg[2]);
glVertex3fv(vertices[2]);
glNormal3fv(normAvg[3]);
glVertex3fv(vertices[3]);
glNormal3fv(normAvg[3]);
glVertex3fv(vertices[3]); /*Third face*/
glNormal3fv(normAvg[2]);
glVertex3fv(vertices[2]);
glNormal3fv(normAvg[4]);
glVertex3fv(vertices[4]);
glNormal3fv(normAvg[4]);
glVertex3fv(vertices[4]); /*Fourth face*/
glNormal3fv(normAvg[2]);
glVertex3fv(vertices[2]);
glNormal3fv(normAvg[1]);
glVertex3fv(vertices[1]);
glEnd();
glBegin(GL_QUADS);
glNormal3fv(normAvg[0]);
glVertex3fv(vertices[0]);
glNormal3fv(normAvg[3]);
glVertex3fv(vertices[3]);
glNormal3fv(normAvg[4]);
glVertex3fv(vertices[4]);
glNormal3fv(normAvg[1]);
glVertex3fv(vertices[1]);
glEnd();
glFlush();
glutSwapBuffers(); /*Display next buffer*/
}
/*Function called during idles--spins the pyramid*/
void spinDisplay(void){
spin = spin + 0.5;
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
|