Search code examples
c++openglframe-rate

How to Make a Basic FPS Counter?


I'm trying to display my frames-per-second in my cube-rendering program. I would like to see its performance. So, how can I do it? I have done research on this already, but the examples I've seen use either multiple classes and still don't work, or they use libraries that I don't have. Is there a way to get the FPS by using pre-installed libs like ctime? I am using OpenGL with C++.

Here is my (empty) function:

void GetFPS()
{

}

and then I display my FPS in my render function with:

std::cout << xRot << " " << yRot << " " << zRot << " " << FPS << "\n"; //xRot, yRot, and zRot are my cube's rotation.

My program is set to 60FPS, but I would like to see the actual FPS, not what it's set to.


Solution

  • You have to sample 2 different time intervals using clock() however notes that there are several problems:

    • resolution of clock is several milliseconds (you may workaround using std::chrono etc, however even chrono may have not so high resolution depending on implementation. On my PC with GCC 4.9.1 I never get better resolution than 16 milliseconds even with std::chrono.
    • tipically using clock() you will get 0 many times and at some time you will measure a real time (in my case it just make a jump of 15/16 milliseconds)
    • unless you are using vertical syncronization (vsync), you will not measure real frametime but just the CPU time spent in your render loop (to activate vsync you have to SetSwapInterval(1) wich your OS function or for example using a library like SDL that provide portable cross platform implementaiton)
    • To measure real rendering time you may use a GL'S time query (you may have only 1 timer bound at any time so if you are measuring framerate you cann't measure how long takes render something specific).
    • Do not measure FPS (well unless you want just to show it to users), instead measure frame time in milliseconds, that gives much more intuitive approximation of performance. (you know going from 100 to 80 FPS is 2,5 ms difference, going from 40 to 20 FPS is 25 ms difference!)

    Do that:

    double clockToMilliseconds(clock_t ticks){
        // units/(units/time) => time (seconds) * 1000 = milliseconds
        return (ticks/(double)CLOCKS_PER_SEC)*1000.0;
    }
    //...
    
    clock_t deltaTime = 0;
    unsigned int frames = 0;
    double  frameRate = 30;
    double  averageFrameTimeMilliseconds = 33.333;
    
    while(rendering){
    
        clock_t beginFrame = clock();
        render();
        clock_t endFrame = clock();
    
        deltaTime += endFrame - beginFrame;
        frames ++;
    
        //if you really want FPS
        if( clockToMilliseconds(deltaTime)>1000.0){ //every second
            frameRate = (double)frames*0.5 +  frameRate*0.5; //more stable
            frames = 0;
            deltaTime -= CLOCKS_PER_SEC;
            averageFrameTimeMilliseconds  = 1000.0/(frameRate==0?0.001:frameRate);
    
            if(vsync)
                std::cout<<"FrameTime was:"<<averageFrameTimeMilliseconds<<std::endl;
            else
               std::cout<<"CPU time was:"<<averageFrameTimeMilliseconds<<std::endl;
        }
    }
    

    The above code works also when you do something that takes several seconds. I do a computation that is updated every second, you could as well update it more often. (note I use exactly that code in most of my projects that need FPS)