Calculating the frames per second in our Graphics application makes sense when we are displaying animation, which is simply a collection of images displayed rapidly and in sequence.When we watch a video\movie, the usual number of frames displayed in a second is 24. Our eyes can’t see all the 24 frames one by one in a single second, and that’s why we get the illusion of something moving, rotating, or growing in size.
In this post, we are going to create an OpenGL app that animates an object and calculates the frames per second for that animation.
To make this calculation, we need to find a way to keep track of the number of frames and time elapsed. The key here is to do the calculation in the GLUT idle function (callback function passed to glutIdleFunc), which is called only when our application is not busy doing something else (such as drawing the current frame). So every time the idle function is called, we increment the frame count, check the time elapsed, and if the time is greater than or equal to 1 second, we calculate the FPS.
//------------------------------------------------------------------------- // This function is called when OpenGL\GLUT is not working on // something else... It is mainly used for animation... // // It's like the timers but time intervals are dependent on how busy // the app is, instead of having a constant value set by the user. //------------------------------------------------------------------------- void idle (void) { // Animate the object animateObject(); // Calculate FPS calculateFPS(); // Call display function (draw the current frame) glutPostRedisplay (); }
As you can see in the code above, the idle function is animating the object, calculating the FPS, then triggering the display function (callback function passed to glutDisplayFunc) by calling glutPostRedisplay().
The display function would basically display the object and text showing the FPS value.
//------------------------------------------------------------------------- // This function is passed to glutDisplayFunc in order to display // OpenGL contents on the window. //------------------------------------------------------------------------- void display (void) { glClear (GL_COLOR_BUFFER_BIT); drawObject(); drawFPS(); glutSwapBuffers (); }
To get the time elapsed, we use the glutGet(GLUT_ELAPSED_TIME) function which will get the time passed in milliseconds since the program started or since it was last called. The implementation of calculateFPS would look like this:
//------------------------------------------------------------------------- // Calculates the frames per second //------------------------------------------------------------------------- void calculateFPS() { // Increase frame count frameCount++; // Get the number of milliseconds since glutInit called // (or first call to glutGet(GLUT ELAPSED TIME)). currentTime = glutGet(GLUT_ELAPSED_TIME); // Calculate time passed int timeInterval = currentTime - previousTime; if(timeInterval > 1000) { // calculate the number of frames per second fps = frameCount / (timeInterval / 1000.0f); // Set time previousTime = currentTime; // Reset frame count frameCount = 0; } }
Download full source code here. If you have any issues compiling or running the app, check out this section for details about compiling and running an OpenGL app that uses the GLUT library. Toby Howard has a different implementation that is not dependent on GLUT. You can find it here.
Filed under: C, OpenGL
