How to Make a Basic FPS Counter?
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;
}
just call this in any loop to measure the number of calls a second.
#include <chrono>
void printFPS() {
static std::chrono::time_point<std::chrono::steady_clock> oldTime = std::chrono::high_resolution_clock::now();
static int fps; fps++;
if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::high_resolution_clock::now() - oldTime) >= std::chrono::seconds{ 1 }) {
oldTime = std::chrono::high_resolution_clock::now();
std::cout << "FPS: " << fps << std::endl;
fps = 0;
}
}
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)