Originally posted by Eric:
[b] OK, I’ll try to explain this one…
Usually, how do we calculate our FPS ???
- We take current time t1.
- We render the scene.
- We call glFinish.
- We take current time t2.
- We call wglSwapBuffers.
- Go back to 1)
Then, one frame took t2-t1 to be drawn. So you can have 1/(t2-t1) frames per seconds (if t1 and t2 are in seconds of course ! Otherwise, simply convert them !).
[/b]
Very bad way of calculating FPS (and a very commonly made mistake, I must add), as you are going to get inaccurate readings. Whats wrong with this picture? Lets look at a theoretical example here (numbers pulled off the top of my head).
>1) We take current time t1.
Lets say this happens at time 0ms.
t1 = 0
>2) We render the scene.
>3) We call glFinish.
Lets say these 2 steps take 250ms.
>4) We take current time t2.
t2 = 250
>5) We call wglSwapBuffers.
Lets say we “just missed” our vsynch, so this takes 250ms (yes, we’re going to pretend our refresh rate is set to 4hz. It may make you blind, but it makes my calculations easy).
>6) Go back to 1)
t2-t1 = 250-0 = 250ms = 0.25 seconds
>1/(t2-t1) frames per seconds
1/0.25 = 4FPS.
So, we calculated that your app is running at 4 frames per second. But WAIT!!! Each rendering loop takes 250ms to render, plus 250ms to flip. Thats 500ms, or 1/2 second per frame. You are actually only getting 2FPS, but your faulty counter code just told you DOUBLE the actual value. See how much the way you time makes a difference? This is why TheGecko was completely off base when he said:
Now, whether my counter code is wrong or not,this still implies a big frame rate drop.
As soon as your counter code is the slightest bit wrong, your readings begin to mean NOTHING!!! Also note that in the above scenario, you arent taking into account anything other that graphics. If you have AI, physics, network code, etc… and you place them OUTSIDE of your counter loop (like you did with the swap) you are going to exagerate your FPS even more. Whats the moral of the story? The moral is that every single instruction the executes each frame neads to happen INSIDE of the counter loop. The only true way to do that is to make your counter code span from one frame to the next.
The correct way to time your app is:
lastFrameEnd =0
BEGIN RENDER LOOP
frameEnd = NOW
FPS = 1/(frameEnd-lastFrameEnd)
lastFrameEnd = frameEnd
RENDER SCENE (and draw your FPS counter)
SWAP BUFFERS
END RENDER LOOP
Now this will give you truely accurate results (except for your first frame obviously, but it’s meaningless in the first frame anyway).