Aaron
Aaron

Reputation: 65

C++ - SDL: Limiting framerate issue

Although the following code does some power saving, the FPS is not capped properly. When it is supposed to lock the framerate at 60 FPS, I get 82. Same for 30, I get 49 FPS.

Calculating FPS:

previousTime = currentTime;
currentTime = SDL_GetTicks();
fps_++;

if (currentTime - lastOutput >= 1000)
{
    lastOutput = currentTime;
    fps = fps_; // the variable 'fps' is displayed 
    fps_ = 0;
}

Limiting FPS:

if (currentTime - previousTime < 1000 / maxFPS)
{
    SDL_Delay(1000 / maxFPS - currentTime + previousTime);
}

What did I mess up?

Upvotes: 3

Views: 6251

Answers (3)

HgMerk
HgMerk

Reputation: 91

When you create a Renderer like this:

SDL_Renderer *renderPtr = SDL_CreateRenderer(windowPtr, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

The SDL_RENDERER_PRESENTVSYNC FLAG Will match the Present Function to your monitor Refresh rate.

I hope this can help!! Has caused me much headaches!!!

Here is a reference: https://wiki.libsdl.org/SDL_CreateRenderer

Upvotes: 2

Martin G
Martin G

Reputation: 18109

This is likely caused by the fact that SDL_Delay tells the operating system to switch out the process you are running. Depending on what OS you have this will likely lead to different behavior in some sense. SDL_Delay typically doesn't mean that execution is guranteed to continue exactly after the specified number of milliseconds. Some say it guarantees to wait at least that long to switch the process back but i have not been able to find proof of that. I think it's more like a recommendation to the OS, but in the end the OS will decide on its' own (depending on OS).

For Windows, the granularity of context switching can be modified though, giving you a better chance to control this: timeBeginPeriod function

You are probably not wondering about this anymore but perhaps the answer can help someone else..

Upvotes: 0

Jacob Jensen
Jacob Jensen

Reputation: 115

I'm defo not an expert, but you can try this!

SDL_Delay(1000 / maxFPS - SDL_GetTicks() + previousTime);

Using a newly calculated current time might help

Upvotes: 1

Related Questions