/* cube.c - extends lighting.c */ /* Purpose: demonstrate normals in lighting */ #ifdef __APPLE__ #include #else #include #endif #include #define KEY_ESC 27 /* glut doesn't define this one */ /* Module variables and constants */ GLboolean mUsingFaceNormals = GL_TRUE; /* face normals or averaged normal */ static const GLfloat mCubeVertices[8][3] = { {-1.0, -1.0, -1.0}, /* left, bottom, back - 0 */ {-1.0, -1.0, 1.0}, /* left, bottom, front - 1 */ {1.0, -1.0, 1.0}, /* right, bottom, front - 2 */ {1.0, -1.0, -1.0}, /* right, bottom, back - 3 */ {-1.0, 1.0, -1.0}, /* left, top, back - 4 */ {-1.0, 1.0, 1.0}, /* left, top, front - 5 */ {1.0, 1.0, 1.0}, /* right, top, front - 6 */ {1.0, 1.0, -1.0}, /* right, top, back - 7 */ }; /* convert a face number into vertices e.g. faces[i][j] is the j'th vertex of face i */ static const int mFacesToVertices[6][4] = { {0, 1, 2, 3}, /* bottom face */ {4, 5, 6, 7}, /* top face */ {0, 1, 5, 4}, /* left face */ {2, 3, 7, 6}, /* right face */ {1, 2, 6, 5}, /* front face */ {3, 0, 4, 7}, /* back face */ }; static const GLfloat mFaceNormals[6][3] ={ { 0.0, -1.0, 0.0 }, /* bottom face */ { 0.0, 1.0, 0.0 }, /* top face */ { -1.0, 0.0, 0.0 }, /* left face */ { 1.0, 0.0, 0.0 }, /* right face */ { 0.0, 0.0, 1.0 }, /* front face */ { 0.0, 0.0, -1.0 }, /* back face */ }; /* Functions */ GLvoid drawCube() { int faceNum, vertexNum; glBegin( GL_QUADS ); { for( faceNum = 0; faceNum < 6; ++faceNum ) { for( vertexNum = 0; vertexNum < 4; ++ vertexNum ) { if( mUsingFaceNormals ) { glNormal3fv( mFaceNormals[ faceNum ] ); } else { /* By a clever set up, the face weighted normal vectors are the same values as the corners of the cube ! :) */ glNormal3fv( mCubeVertices[ mFacesToVertices[faceNum][vertexNum] ] ); } glColor3fv( mCubeVertices[ mFacesToVertices[faceNum][vertexNum] ] ); glVertex3fv( mCubeVertices[ mFacesToVertices[faceNum][vertexNum] ] ); } } } glEnd(); } GLvoid display( GLvoid ) { glClear( GL_COLOR_BUFFER_BIT ); glLoadIdentity(); glRotatef( 45, 1, 1, 1 ); drawCube(); glFlush(); } GLvoid keyboard( GLubyte key, GLint x, GLint y) { switch (key) { case KEY_ESC: /* exit when escape key is pressed */ exit(0); break; case 's': case 'S': mUsingFaceNormals = !mUsingFaceNormals; break; case 'l': case 'L': { static GLboolean lightOn = GL_FALSE; /* Toggle the light on/off */ lightOn = !lightOn; /* Turn on/off the OpenGL lighting calculations */ lightOn ? glEnable( GL_LIGHTING ) : glDisable( GL_LIGHTING ); } break; } glutPostRedisplay(); } void init( void ) { /* What colour is the ambient light */ GLfloat pAmbientLightModel[] = { 0.3, 0.3, 0.3, 1.0 }; /* Where is the infinite directional light */ GLfloat pLight0Pos[] = { 0.0, 0.0, 2.0 , 0.0 }; /* What are the ambient, diffuse, and specular material properties for our torus */ GLfloat pMatAmbDiff[] = { 0.0, 0.2, 0.8, 1.0 }; GLfloat pMatSpecular[] = { 0.1, 0.1, 0.1, 1.0 }; /* Get some ambient light */ glLightModelfv( GL_LIGHT_MODEL_AMBIENT, pAmbientLightModel ); /* Get an infinite, but directional light (like a sun) */ glEnable( GL_LIGHT0 ); glLightfv( GL_LIGHT0, GL_POSITION, pLight0Pos ); /* Set up a material for our torus */ glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, pMatAmbDiff ); glMaterialfv( GL_FRONT, GL_SPECULAR, pMatSpecular ); /* Set up a large enough viewing volume for our unit cube */ glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glOrtho( -2, 2, -2, 2, -2, 2 ); glMatrixMode( GL_MODELVIEW ); /* Cull backward facing polygons */ glEnable( GL_CULL_FACE ); } int main( int argc, char *argv[] ) { glutInit( &argc, argv ); glutCreateWindow( argv[0] ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); init(); glutMainLoop(); return 0; }