Synthetic Synthetic - 2 months ago 46
C++ Question

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 the performance of it, so how could 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 library's that I do not 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 than 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.

Answer

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)