/* prac7c.c */ /* Purpose: Timings with and without culling */ #ifdef __APPLE__ #include #else #include #endif #include #include #define KEY_ESC 27 /* glut doesn't define this one */ #ifdef WIN32 #include #else #include /* for the POSIX clock_gettime */ #endif /* Global variables */ static GLfloat mNearClip = 10.0; /* near clipping plane */ static GLfloat mFarClip = 20.0; /* far clipping plane */ static GLboolean mCullOn = GL_FALSE; void printHelp( void ) { fprintf(stdout, "\nHidden Surface Culling\n\n" "Escape key - exit the program\n\n" "Space key - toggle back face culling\n\n"); } GLvoid keyboard( GLubyte key, GLint x, GLint y) { switch (key) { case KEY_ESC: /* exit when escape key is pressed */ exit(0); break; case ' ': mCullOn = !mCullOn; if (mCullOn) { glEnable(GL_CULL_FACE); printf("Culling On\n"); } else { glDisable(GL_CULL_FACE); printf("Culling Off\n"); } glutPostRedisplay(); } } GLvoid specialkeys( GLint key, GLint x, GLint y) { switch (key) { case GLUT_KEY_F1: /* print Help information */ printHelp ( ); break; } } 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(); } } /* Return the number of milliseconds from some arbitrary start point */ unsigned int getMilliSecs() { #ifdef WIN32 return GetTickCount(); #else /* Make a guess that we are on IRIX */ /* static timespec_t tp; clock_gettime(CLOCK_REALTIME, &tp); return tp.tv_sec*1000 + tp.tv_nsec/1000000; */ /* if we are on LINUX comment out the IRIX code and use the following */ return clock()/CLOCKS_PER_SEC; #endif } void reshape(GLint width, GLint height) { GLdouble aspect; aspect = (GLdouble)width / (GLdouble)height; /* We still want the output to cover the whole window */ glViewport(0, 0, width, height); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective(80, aspect, mNearClip, mFarClip); glMatrixMode( GL_MODELVIEW ); } GLvoid init( GLvoid ) { glClearColor( 1.0, 1.0, 1.0, 1.0); glColor3f(1.0,0.0,0.0); glLineWidth(3.0); glCullFace(GL_BACK); mCullOn ? glEnable(GL_CULL_FACE) : glDisable(GL_CULL_FACE); } GLvoid display( GLvoid ) { unsigned int starttime; unsigned int endtime; int i; /* Do all your OpenGL rendering here */ glClear( GL_COLOR_BUFFER_BIT ); glLoadIdentity(); /* Reset the ModelView transformation every time we draw */ /* put our model in the middle of the near and far clipping plans */ glTranslatef(0, 0, -(mNearClip + mFarClip)/2); starttime = getMilliSecs(); glTranslatef(-10, -10, 0); for (i=0; i < 400000; i++) { glTranslatef( (GLfloat)i/5000000000, 0, 0); /* Draw front facing polygon */ glBegin(GL_TRIANGLES); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(1.0f, 0.0f, 0.0f); glVertex3f(1.0f, 1.0f, 0.0f); glEnd(); } glTranslatef( -8, 3, 0); for (i=0; i < 400000; i++) { glTranslatef( (GLfloat)i/5000000000, 0, 0); /* Draw back facing polygon - should be culled if culling is enabled and CCW vertex ordering is used. */ glBegin(GL_TRIANGLES); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(1.0f, 1.0f, 0.0f); glVertex3f(1.0f, 0.0f, 0.0f); glEnd(); } /* The glFlush function forces execution of OpenGL functions in finite time. However it is asynchronous and returns before all OpenGL execution is complete. glFlush(); */ /* The glFinish function blocks until all OpenGL execution is complete. */ glFinish(); endtime = getMilliSecs(); printf("Time for display: %u\n\n", endtime - starttime); /* Don't check errors every frame - expensive. Only do it while debugging. */ checkError( "display" ); } int main( int argc, char *argv[] ) { glutInit( &argc, argv ); glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB ); glutCreateWindow( argv[0] ); init(); glutKeyboardFunc( keyboard ); glutSpecialFunc( specialkeys ); glutDisplayFunc( display ); glutReshapeFunc( reshape ); printHelp(); glutMainLoop(); return 0; }