How to Make a Basic FPS Counter?

和自甴很熟 提交于 2020-01-31 03:46:04

问题


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.


回答1:


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)




回答2:


Simply save the time "ticks" before and after you render your scene, then do a simple calculation.

Here's an example that uses <ctime>'s clock() function. (note that clock() works differently on different platform)

clock_t current_ticks, delta_ticks;
clock_t fps = 0;
while(true)// your main loop. could also be the idle() function in glut or whatever
{
    current_ticks = clock();

    render();

    delta_ticks = clock() - current_ticks; //the time, in ms, that took to render the scene
    if(delta_ticks > 0)
        fps = CLOCKS_PER_SEC / delta_ticks;
    cout << fps << endl;
}


来源:https://stackoverflow.com/questions/28530798/how-to-make-a-basic-fps-counter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!