C++ - SDL: 限制帧率问题

3
虽然以下代码可以节省一些能量,但FPS没有被正确地限制。当它应该将帧率锁定在60 FPS时,我得到了82。同样的情况也发生在30 FPS上,我只得到了49 FPS。
计算FPS:
previousTime = currentTime;
currentTime = SDL_GetTicks();
fps_++;

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

限制帧率:

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

我哪里出了错?

maxFPS 的类型是什么?int(意味着整数除法和舍入误差)还是float? 顺便说一句,更好的fps计算不应该依赖于两个输出之间经过了一秒钟的事实,而应该使用currentTime和lastOutput之间的差异来提高准确性。 - Zeograd
浮点数。我没有完全听懂你关于FPS计算的说法。 - Aaron
你应该尝试每次以1毫秒为步长进行调整,这将给你更好的精度。请注意,由于这种方式的计时不准确,你永远无法获得完全的60fps。 - geometrian
3个回答

2

当您创建如下的渲染器:

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

SDL_RENDERER_PRESENTVSYNC 标志将匹配呈现函数与您的显示器刷新率。

我希望这可以帮助您!这曾经让我很头痛!!

这里有一个参考链接: https://wiki.libsdl.org/SDL_CreateRenderer


1

我绝对不是专家,但你可以试试这个!

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

使用新计算的当前时间可能会有所帮助。


0

这可能是由于SDL_Delay让操作系统切换了你正在运行的进程所致。根据你使用的操作系统,这可能会导致某种意义上不同的行为。SDL_Delay通常并不能保证执行一定会在指定的毫秒数后继续。有人说它保证至少等待那么长时间才会切换回进程,但我没有找到证据支持这一点。我认为这更像是对操作系统的建议,但最终操作系统会自行决定(取决于操作系统)。

对于Windows,上下文切换的粒度可以进行修改,从而让你更好地控制这个问题: timeBeginPeriod函数

也许你已经不再关心这个问题了,但也许这个答案可以帮助其他人。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接