0
\$\begingroup\$

My game loop currently looks something like this:

while (!quit) {
    takeInput(); // Input is sampled however fast loop can run

    time_now = get_time()
    time_passed += (time_now - time_prev);
    time_prev = time_now;

    while (time_passed > SOME_TIME) {
        update(); // Update is done over fixed time-step for determinism
        time_passed -= SOME_TIME_STEP; // This time step is less than or equal to SOME_TIME
    }
    render(time_passed); // Render using interpolation from previously updated position and velocity
}

Basically, I take input as fast as I can, run the movement and physics only in discreet chunks of time after certain period and interpolate the difference in the renderer. The renderer is set to draw at Vsync (using SDL_GL_SetSwapInterval(-1)) and currently, the value of SOME_TIME is set so that update() runs at half of display's refresh frequency (but with a minimum bound of SOME_TIME_STEP which is set to 5 millisecond).

The problem is that I am running the renderer as fast as I can which is submitting frames continuously. Because I am currently loading a test level, the game loop is basically finishing up in a few microseconds (unless there is something wrong with how I am calculating time too). As far as I understand, my program will submit frames to the driver way faster than it is going to draw (because of Vsync) and this should lead to some type of periodic locking up/lagging.

So my question is, how to I prevent this? Should I put the render call in a time bound loop too just like update()? Should I call sleep() manually instead of relying on graphics driver for Vsync?

\$\endgroup\$
  • \$\begingroup\$ sleep guarantees that the thread will sleep at least the amount of time you ask for, not exactly the amount of time you ask for. The delay is generally longer than what you ask for, so it should not be used. Perhaps limiting the amount of render call to one very 1/60 th of a second would be enough? \$\endgroup\$ – Alexandre Vaillancourt Oct 8 '16 at 5:17
  • \$\begingroup\$ You can use a sync object in opengl to find out when the gpu has finished processing. You can find more information about it here: > khronos.org/opengl/wiki/Sync_Object Also see this similar question: > stackoverflow.com/questions/21557279/… \$\endgroup\$ – Kyy13 Feb 22 '18 at 15:46
0
\$\begingroup\$

In SDL2 is standard practice as far as I know to use an SDL_Delay to delay the game loop after you've completed all rendering of textures and game logic.

Here is code that will delay you to a 60 FPS game, you can adjust the number accordingly:

#define FRAMES_PER_SECOND 60

uint32_t timer = 0;

while(1)
{
    /* Game logic... rendering... */

    if(SDL_TICKS_PASSED(timer, SDL_GetTicks()))
    {
        SDL_Delay(timer - SDL_GetTicks());
    }

    /* Global Timer */
    timer = SDL_GetTicks() + (1000 / framesPerSecond);
}

Because SDL_GetTicks() can overflow, you must use SDL_TICKS_PASSED which is a builtin SDL2 macro based that allows integer overflow into the equation.

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

As far as I understand, my program will submit frames to the driver way faster than it is going to draw (because of Vsync) and this should lead to some type of periodic locking up/lagging.

Not it wont. The video driver doesn't buffer frames indefinitely.

The video driver buffers at most 1 frame (double buffering) or 2 frames (triple buffering).

If your render loop attempts to draw faster than the display the video driver can display it will sleep/hold your thread until the vblank happens and a render back buffer becomes available.

Which is at most 1 frame time (eg: 16ms at 60Hz).

You don't need to put your thread to sleep, the video driver takes care of that.

If you put your thread to sleep manually the video driver can't force the OS to wake up your thread when the vertical blank signal happens because it doesn't know that's what you're waiting for. That could cause your app to sleep for easily 10ms longer than it should.

\$\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.