/* prac5a.c */ /* Purpose: This program constructs a house, and uses function keys to control the projection transfomations. */ #ifdef __APPLE__ #include #else #include #endif #include #include #define KEY_ESC 27 /* glut doesn't define this one */ /* Global Definitions */ static const float mV0[3] = {0.0,0.0,0.0}; static const float mV1[3] = {1.0,0.0,0.0}; static const float mV2[3] = {1.0,1.0,0.0}; static const float mV3[3] = {0.0,1.0,0.0}; static const float mV4[3] = {0.0,0.0,1.0}; static const float mV5[3] = {1.0,0.0,1.0}; static const float mV6[3] = {1.0,1.0,1.0}; static const float mV7[3] = {0.0,1.0,1.0}; static const float mV8[3] = {0.5,1.25,0.0}; static const float mV9[3] = {0.5,1.25,1.0}; void printHelp( void ) { fprintf(stdout, "\nHouse\n\n" "Escape key - exit the program\n\n" "F2 - 2D orthographic projection\n" "F3 - 3D orthographic projection\n" "F4 - 3D perspective projection\n" "F5 - rotate model\n"); } GLvoid keyboard( GLubyte key, GLint x, GLint y) { switch (key) { case KEY_ESC: /* exit when escape key is pressed */ exit(0); } } GLvoid specialkeys( GLint key, GLint x, GLint y) { switch (key) { case GLUT_KEY_F1: /* print Help information */ printHelp ( ); break; case GLUT_KEY_F2: /* 2D orthographic projection */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-2.0, 2.0, -2.0, 2.0); /* Note that this is equivalent to glOrtho(-2,2,-2,2,-1,1); */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); break; case GLUT_KEY_F3: /* 3D orthographic projection*/ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-2.0, 2.0, -2.0, 2.0, -2.0, 2.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); break; case GLUT_KEY_F4: /* Perspective projection*/ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(50, 1.0, 1.0, 8.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -4.0); break; case GLUT_KEY_F5: /* Rotate*/ glRotatef(30.0, 0, 1, 0); break; } glutPostRedisplay(); } GLvoid checkError( const char* const label ) { GLenum error; error = glGetError(); while ( GL_NO_ERROR != error ) { fprintf( stderr,"%s: %s\n", label, gluErrorString(error) ); error = glGetError(); } } GLvoid drawHouse( GLvoid ) { /* draw rear of house */ glBegin(GL_LINE_LOOP); glVertex3fv(mV0); glVertex3fv(mV1); glVertex3fv(mV2); glVertex3fv(mV3); glEnd(); /* draw front of house */ glBegin(GL_LINE_LOOP); glVertex3fv(mV4); glVertex3fv(mV5); glVertex3fv(mV6); glVertex3fv(mV7); glEnd(); /* draw roof gable at rear and front of house, and connect the two pieces */ glBegin(GL_LINES); glVertex3fv(mV2); glVertex3fv(mV8); glVertex3fv(mV8); glVertex3fv(mV3); glVertex3fv(mV6); glVertex3fv(mV9); glVertex3fv(mV9); glVertex3fv(mV7); glVertex3fv(mV8); glVertex3fv(mV9); /* join front frame to back frame (the sides of the house) */ glVertex3fv(mV0); glVertex3fv(mV4); glVertex3fv(mV1); glVertex3fv(mV5); glVertex3fv(mV3); glVertex3fv(mV7); glVertex3fv(mV2); glVertex3fv(mV6); glEnd(); } GLvoid init( GLvoid ) { glClearColor( 1.0, 1.0, 1.0, 1.0); glColor3f(1.0,0.0,0.0); glLineWidth(1.0); /* Initially do a 2D orthographic projection */ glMatrixMode(GL_PROJECTION); gluOrtho2D(-2.0, 2.0, -2.0, 2.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } GLvoid display( GLvoid ) { glClear( GL_COLOR_BUFFER_BIT ); /* Do all your OpenGL rendering here */ /* Note that we have deliberately NOT set the modelview matrix to the identity. This allows rotations by pressing F5 to build up. In general, this is _bad_ programming practice. */ drawHouse(); checkError( "display" ); glFlush(); } int main( int argc, char *argv[] ) { glutInit( &argc, argv ); glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB ); glutCreateWindow( argv[0] ); init(); glutKeyboardFunc( keyboard ); glutSpecialFunc( specialkeys ); glutDisplayFunc( display ); printHelp( ); glutMainLoop(); return 0; }