1
\$\begingroup\$

I have following code:

void Game::execute()
{
    isExit = false;
    init();

    double dt = 1.0 / 60.0;
    boost::timer timer;
    double accumulator = 0.0;

    boost::timer fps_timer;
    int fps = 0;
    while (isExit != true)
    {
        handleEvent();
        accumulator += timer.elapsed(); timer.restart();
        while (accumulator > dt)
        {
            accumulator -= dt;
            handleEvent();
            update(); // updating physics
        }
        if (fps_timer.elapsed() > 1.0) //if 1 second is elapsed
        {
            fps_timer.restart();
            m_fps = fps;  //m_fps - is result, which is rendered
            fps = 0;
        }
        else fps++;
        render(); // main rendering command
    }
}

And usually m_fps is equal 300-400. But I expect to see 30-60. Where I did wrong?

\$\endgroup\$
1
\$\begingroup\$

you're incrementing fps as fast as possible, regardless if you called the following:

while (accumulator > dt)
{
    accumulator -= dt;
    handleEvent();
    update(); // updating physics
}

Try updating to the following:

while (isExit != true)
    {
        handleEvent();
        accumulator += timer.elapsed(); timer.restart();
        while (accumulator > dt)
        {
            accumulator -= dt;
            handleEvent();
            update(); // updating physics
            render();
            fps++;
        }
        if (fps_timer.elapsed() > 1.0) //if 1 second is elapsed
        {
            fps_timer.restart();
            m_fps = fps;  //m_fps - is result, which is rendered
            fps = 0;
        }
    }
\$\endgroup\$
4
  • \$\begingroup\$ Cool. It work! FPS is almost always equal 60, but when I dragged Window, FPS is equal 78... It's strangely.... \$\endgroup\$ – user106609 Mar 8 '14 at 19:43
  • \$\begingroup\$ Do you notice if there's a lower-fps period right before the higher-fps period? \$\endgroup\$ – user39686 Mar 8 '14 at 21:28
  • \$\begingroup\$ The initial code is perfectly fine. It just measures the number of rendered frames - not the number of logic updates. This change will limit both to the target framerate. Your FPS while dragging the Window will obviously increase, since the time passed will be longer than one second (the code won't continue running while you drag the window). To fix this, you'll have to divide the number of frames by the time elapsed for fps_timer. \$\endgroup\$ – Mario Mar 9 '14 at 10:36
  • \$\begingroup\$ To add one more thing: I'd consider it bad practice to have your render code linked 1:1 to your game logic updates simply due to the fact that once vertical synchronization is enabled (e.g. due to a driver override), your game updates might be capped at 60 fps even though the code should run at 100 fps. In a similar way, bad performance (like the game only being able to run at 20 fps) will significantly slow down your game as a whole (not just rendering). Even big AAA titles run into this problem from time to time, like last year's Need for Speed: Rivals. \$\endgroup\$ – Mario Mar 9 '14 at 10:42
1
\$\begingroup\$

Let's break down your code:

accumulator += timer.elapsed(); timer.restart();

On every tick, accumulator is incremented by the elapsed time of the previous tick.

while (accumulator > dt)
{
  accumulator -= dt;
  handleEvent();
  update(); // updating physics
}

Once accumulator is more than 1/60th of a second you tick your physics in "1/60th second" intervals until accumulator is under a 1/60th of a second. This is probably why you expect to have frame-limiting in your FPS computation. However:

if (fps_timer.elapsed() > 1.0) //if 1 second is elapsed
{
  fps_timer.restart();
  m_fps = fps;  //m_fps - is result, which is rendered
  fps = 0;
} else {
  fps++;
}

Your actual computation to increment the FPS counter happens outside that frame-limiting code, above. So you're computing the "unlocked" FPS rather than the locked one you are expected.

To fix this, you can move the fps increment inside the while(accumulator... loop.

\$\endgroup\$
0
\$\begingroup\$

Your fps is actually displaying correctly (as in, the number displayed is equal to the number of renders per second). Notice that you are calling render() and incrementing fps outside of the while(accumulator > dt) loop. This means that your fps variable is being incremented on every single cycle of the while(!isExit) loop. Another thing that I would like to point out, is that you are calling render() more than what you need to.

To solve both of these issues, You simply add another variable outside of your while(!isExit) loop. You can call it something like shouldRender. Then, inside of your while(accumulator > dt) loop, add the line shouldRender = true. Then, add the following block of code after your while(accumulator > dt) loop:

if(shouldRender)
{
    render();
    shouldRender = false;
    fps++;
}

Because you are now only rendering if an update has occurred during the current iteration of the while(!isExit) loop, the fps will now be capped to the number of updates per second.

One last thing. Instead of writing while(isExit != true), you can simply write while(!isExit). This doesn't really affect performance, but it makes the code a bit cleaner.

The resulting code should now look like this:

...
bool shouldRender = false;
while (!isExit)
{
    handleEvent();
    accumulator += timer.elapsed(); timer.restart();
    while (accumulator > dt)
    {
        accumulator -= dt;
        handleEvent();
        update(); // updating physics
        shouldRender = true;
    }
    if(shouldRender)
    {
        render();
        shouldRender = false;
        fps++;
    }
    if (fps_timer.elapsed() > 1.0) //if 1 second is elapsed
    {
        fps_timer.restart();
        m_fps = fps;  //m_fps - is result, which is rendered
        fps = 0;
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.