//Example program of simple lighting with two different materials on a 3D cube //by ZJ Wood for CSC471 #include #include #include #include #include int GW; int GH; int light; //globals for lighting - use a white light and apply materials //light position GLfloat light_pos[4] = {1.0, 1.0, 1.5, 1.0}; //light color (ambiant, diffuse and specular) GLfloat light_amb[4] = {0.6, 0.6, 0.6, 1.0}; GLfloat light_diff[4] = {0.6, 0.6, 0.6, 1.0}; GLfloat light_spec[4] = {0.8, 0.8, 0.8, 1.0}; int mat = 0; //set up some materials typedef struct materialStruct { GLfloat ambient[4]; GLfloat diffuse[4]; GLfloat specular[4]; GLfloat shininess[1]; } materialStruct; materialStruct RedFlat = { {0.3, 0.0, 0.0, 1.0}, {0.9, 0.0, 0.0, 1.0}, {0.0, 0.0, 0.0, 1.0}, {0.0} }; materialStruct GreenShiny = { {0.0, 0.3, 0.0, 1.0}, {0.0, 0.9, 0.0, 1.0}, {0.2, 1.0, 0.2, 1.0}, {8.0} }; //sets up a specific material void materials(materialStruct materials) { glMaterialfv(GL_FRONT, GL_AMBIENT, materials.ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, materials.diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, materials.specular); glMaterialfv(GL_FRONT, GL_SHININESS, materials.shininess); } //initialization calls for opengl for static light //note that we still need to enable lighting in order for it to work //see keyboard 'l' event void init_lighting() { //turn on light0 glEnable(GL_LIGHT0); //set up the diffuse, ambient and specular components for the light glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diff); glLightfv(GL_LIGHT0, GL_AMBIENT, light_amb); glLightfv(GL_LIGHT0, GL_SPECULAR, light_spec); //specify our lighting model as 1 normal per face glShadeModel(GL_FLAT); } void pos_light() { //set the light's position glMatrixMode(GL_MODELVIEW); glLightfv(GL_LIGHT0, GL_POSITION, light_pos); } //dorky way to draw a cube one face at a time void drawcube() { //color of the cube for when lighting is disabled glColor3f(1.0, 0.0, 0.0); //left face: for lighting you must specify a normal for each face! glNormal3f(-1.0, 0.0, 0.0); glBegin(GL_POLYGON); glVertex3f(-0.5, 0.5, 0.5); //v5 glVertex3f(-0.5, 0.5, -0.5); //v4 glVertex3f(-0.5, -0.5, -0.5); //v1 glVertex3f(-0.5, -0.5, 0.5); //v8 glEnd(); //right face: for lighting you must specify a normal for each face! glNormal3f(1.0, 0.0, 0.0); glBegin(GL_POLYGON); glVertex3f(0.5, -0.5, -0.5); //v2 glVertex3f(0.5, 0.5, -0.5); //v3 glVertex3f(0.5, 0.5, 0.5); //v6 glVertex3f(0.5, -0.5, 0.5); glEnd(); //bottom face: for lighting you must specify a normal for each face! glNormal3f(0, -1.0, 0.0); glBegin(GL_POLYGON); glVertex3f(-0.5, -0.5, 0.5); //v8 glVertex3f(0.5, -0.5, 0.5); //v7 glVertex3f(0.5, -0.5, -0.5); //v2 glVertex3f(-0.5, -0.5, -0.5); //v1 glEnd(); //top face: for lighting you must specify a normal for each face! glNormal3f(0, 1.0, 0.0); glBegin(GL_POLYGON); glVertex3f(0.5, 0.5, -0.5); //v3 glVertex3f(-0.5, 0.5, -0.5); //v4 glVertex3f(-0.5, 0.5, 0.5); //v5 glVertex3f(0.5, 0.5, 0.5); //v6 glEnd(); //front face: for lighting you must specify a normal for each face! glNormal3f(0, 0, 1.0); glBegin(GL_POLYGON); glVertex3f(-0.5, 0.5, 0.5); //v5 glVertex3f(0.5, 0.5, 0.5); //v6 glVertex3f(0.5, -0.5, 0.5); //v7 glVertex3f(-0.5, -0.5, 0.5); //v8 glEnd(); //back face: for lighting you must specify a normal for each face! glNormal3f(0, 0, -1.0); glBegin(GL_POLYGON); glVertex3f(-0.5, -0.5, -0.5); //v1 glVertex3f(0.5, -0.5, -0.5); //v2 glVertex3f(0.5, 0.5, -0.5); //v3 glVertex3f(-0.5, 0.5, -0.5); //v4 glEnd(); } void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); //save current matrix glPushMatrix(); //set up the camera gluLookAt(1.0, 1.0, 1.5, //eye position 0.0, 0.0, 0.0, //point we are looking at 0.0, 1.0, 0.0); //up vector //position the light in the scene pos_light(); //draw the cube drawcube(); glPopMatrix(); glutSwapBuffers(); } void reshape(int w, int h) { GW = w; GH = h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); //notice the change in the near and far planes - they are measure with respect to the //camera position glOrtho( -2*(float)w/h, (float)2*w/h, -2, 2, 1.0, 15.0); glMatrixMode(GL_MODELVIEW); glViewport(0, 0, w, h); } void keyboard(unsigned char key, int x, int y ) { switch( key ) { case 'l': light = !light; if (light) glEnable(GL_LIGHTING); else glDisable(GL_LIGHTING); break; //simple way to toggle the materials case 'm': mat++; if (mat%2 == 0) materials(RedFlat); else if (mat%2 == 1) materials(GreenShiny); break; case 'q': case 'Q' : exit( EXIT_SUCCESS ); break; } glutPostRedisplay(); } int main(int argc, char** argv) { //set up glut window glutInit(&argc, argv); glutInitWindowSize(400, 400); glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutCreateWindow("Example 3D cube with lighting"); glClearColor(0.0, 0.0, 0.0, 1.0); //set up glut callbacks glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); //initialize globals GW = 400; GH = 400; light = 0; //enable GL features we want glEnable(GL_DEPTH_TEST); //only do this once init_lighting(); glutMainLoop(); }