Monday, June 18, 2012

Game Loop and Frame Capping

This is probably something I should have known to do - but for all my C++ code I've never capped the frame rate of my gameloop. Oh I've thrown the odd Sleep(0) or Sleep(1) in there but it's never really done anything.

My applications use 100% of the CPU and eat up as many of the cycles as they can. Windows shows 25% CPU use for my programs - due to it be a quad core underneath. Also it invariably causes the fan to spin up - either on my CPU or the graphics card and I hate that! Really hate it. I'd take silence over power everytime I think.

In SDL it's easy enough to cap the game loop to a certain no of frames per second and not overheat  the GPU / CPU.

As it turns out the SDL_Delay on Win32 is just a call to Sleep which is included with windows.h

void SDL_Delay(Uint32 ms)
{
    Sleep(ms)
}

In the game loop I use it like this.

unsigned int fpsTicks = 0;

while(mRunning)
{
    fpsTicks = SDL_GetTicks();
    UpdateInput();
    Update();
    Render();

    fpsTicks = SDL_GetTicks() - fpsTicks;

    if (fpsTicks < 1000 / frames_per_second)
    {
        SDL_Delay((1000 / frames_per_second) - fpsTicks);
    }

    SDL_GL_SwapBuffers();
}

On most Windows systems SDL_GetTicks() is defined:

Uint32 SDL_GetTicks(void)
{
    LARGE_INTEGER hires_now;

    QueryPerformanceCounter(&hires_now);

    hires_now.QuadPart -= hires_start_ticks.QuadPart;
    hires_now.QuadPart *= 1000;
    hires_now.QuadPart /= hires_ticks_per_second.QuadPart;

    return (DWORD)hires_now.QuadPart;
}

Both LARGE_INTEGER and QueryPerformanceCounter come from windows.h
They're in SDL_systimer.c if you fancy a look.

No comments: