/* I've been compiling this with: gcc -Wall -Werror -g -Os performance.c -lX11 -lGL -lGLU -lXcomposite -lglut -lGLEW -o performance */ #include #include #include #include #include #include /* Remove the #undef if you wish to use VBOs - these don't work for indirect rendering, as the xserver only exposes OpenGL 1.4, not 1.5 */ #define USE_VBO 1 #undef USE_VBO static const GLfloat m_vertexes[] = { 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f }; static const GLfloat m_texcoords[] = { 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f }; #ifdef USE_VBO static const size_t vertex = 0; static const size_t texcoord = 1; static GLuint m_buffers[2]; #endif static GLuint m_textures[2]; static double start_time; static unsigned frames = 0; #ifdef USE_VBO static void setupBuffers( void ) { glGenBuffers( 2, m_buffers ); glBindBuffer( GL_ARRAY_BUFFER, m_buffers[vertex] ); glBufferData( GL_ARRAY_BUFFER, sizeof( GLfloat ) * 8, m_vertexes, GL_STATIC_DRAW ); glVertexPointer( 2, GL_FLOAT, sizeof(GLfloat) * 2, 0 ); glBindBuffer( GL_ARRAY_BUFFER, m_buffers[texcoord] ); glBufferData( GL_ARRAY_BUFFER, sizeof( GLfloat ) * 8, m_texcoords, GL_STATIC_DRAW ); glTexCoordPointer( 2, GL_FLOAT, sizeof(GLfloat) * 2, 0 ); } #endif static void setupTextures( void ) { glGenTextures( 2, m_textures ); int texno; for( texno = 0; texno < 2; ++texno ) { GLubyte data[ 256 * 256 * 4]; size_t i; for( i = 0; i < 256 * 256 * 4; ++i ) { if( i % 4 == texno ) { data[i] = 0; } else { data[i] = -1; } } glBindTexture( GL_TEXTURE_2D, m_textures[texno] ); glPixelTransferf( GL_ALPHA_BIAS, 1.0 ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, data); glPixelTransferf( GL_ALPHA_BIAS, 0.0 ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); } } static double timeOfDay() { struct timeval t; gettimeofday( &t, NULL ); return ((double)(t.tv_sec) + (double)( t.tv_usec )/1000000.0); } static void renderScene( void ) { static int texno = 0; static double last_frame_time = 0; double current_frame_time; double frame_time; glColor4f( 1.0, 1.0, 1.0, 1.0 ); glBindTexture( GL_TEXTURE_2D, m_textures[texno] ); #ifdef USE_VBO glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 ); #else glVertexPointer( 2, GL_FLOAT, sizeof(GLfloat) * 2, m_vertexes ); glTexCoordPointer( 2, GL_FLOAT, sizeof(GLfloat) * 2, m_texcoords ); glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 ); #endif glutSwapBuffers(); current_frame_time = timeOfDay(); texno = (texno + 1) % 2; ++frames; if( (frames % 60) == 0 ) { double now = timeOfDay(); printf( "Last 60 frames rate %f fps\n", 60 / (now - start_time) ); start_time = now; } frame_time = current_frame_time - last_frame_time; if( frame_time * 60.0 < 0.9 ) { printf( "Frames too fast at frame %d\n", frames ); printf( "%lf frames per second\n" , 1.0 / frame_time ); } if( frame_time * 60.0 > 1.1 ) { printf( "Frames too slow at frame %d\n", frames ); printf( "%lf frames per second\n" , 1.0 / frame_time ); } last_frame_time = current_frame_time; } int main( int argc, char *argv[] ) { glutInit( &argc, argv ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA ); glutInitWindowPosition( 0, 0 ); glutInitWindowSize( 1024, 768 ); glutCreateWindow( "3D performance test" ); glutFullScreen(); glewExperimental = GL_TRUE; GLenum err = glewInit(); if( err != GLEW_OK ) { fprintf( stderr, "GLEW init: %s\n", glewGetErrorString( err ) ); exit(1); } glMatrixMode( GL_PROJECTION ); glLoadIdentity(); /* left, right, bottom, top - gets 0,0 at top, left */ gluOrtho2D( 0, 1, 1, 0 ); glutDisplayFunc( renderScene ); glutIdleFunc( renderScene ); glEnable( GL_TEXTURE_2D ); glEnable( GL_BLEND ); glEnableClientState( GL_VERTEX_ARRAY ); glEnableClientState( GL_TEXTURE_COORD_ARRAY ); setupTextures(); #ifdef USE_VBO setupBuffers(); #endif if( glXSwapIntervalSGI( 1 ) != 0 ) { fprintf( stderr, "Could not set swap interval\n" ); } start_time = timeOfDay(); glutMainLoop(); return 0; }