【问题标题】:Capping & Calculating FPS in SDL?在 SDL 中限制和计算 FPS?
【发布时间】:2024-01-04 11:48:01
【问题描述】:

我已经编写了这段代码来将 SDL 游戏的速度限制为 60 fps,这是实现 fps 计数的正确方法吗?

int fps=60;
int desiredDelta=1000/fps;  //desired time b/w frames


while (gameRunning)
{

    int starttick=SDL_GetTicks();

    // Get our controls and events
    while (SDL_PollEvent(&event))
    {
        if (event.type == SDL_QUIT)
            gameRunning = false;
    }
    window.Clear();

    for(Entity& e: entities)
    {
        window.Render(e);
    }

    window.Display();

    int delta=SDL_GetTicks()-starttick;     //actual time b/w frames

    int avgFPS=1000/(desiredDelta-delta);  //calculating FPS HERE

    if(delta<desiredDelta)
    {
        SDL_Delay(desiredDelta-delta);
    }
  
    std::cout<<avgFPS<<std::endl;


}

【问题讨论】:

  • 不是您的问题的答案,但是您是否会尝试将渲染限制为屏幕刷新率?因为如果这是您的实际意图,您可以启用 VSync 并完成它。
  • 是的,我添加了垂直同步标志,但我认为您仍然需要手动限制 fps 对吧?我正在看 codergopheers 教程,他添加了一个时间步长,我认为这就像一个帧速率上限
  • 如果您启用了 vsync,那么您的框架对结果的实际呈现应该会被适当地阻止(我对 SDL 的了解不够,无法将您指向正确的文档,唉)。您仍然需要跟踪时间,这样您就可以知道经过了多少时间并且可以适当地计算世界更新(因此您的游戏在 100Hz 显示器上的速度不会比在 60Hz 显示器上快 66%)。

标签: c++ sdl frame-rate game-development


【解决方案1】:

在游戏中,通常需要担心两个“帧率”:显示器的帧率和游戏物理的帧率。理想情况下,您绘制以显示器的本机帧速率。为此,请确保将 SDL_RENDERER_PRESENTVSYNC 标志传递给 SDL_CreateRenderer()

对于游戏的物理特性,您可以测量两个渲染帧之间的时间,并将其用作您的物理时间步长,这样您就可以基本匹配显示帧速率。优点是您的速率自然同步,但缺点是游戏的物理性能可能会受到准确性问题的影响,尤其是在渲染时间过长以致显示帧速率下降到低值的时候。

或者,您可以为物理使用固定的帧速率。但是,如果您执行后者,那么您必须考虑如何处理两个帧速率不同步的问题,但这并不能通过添加 SDL_Delay()s 来解决。通常的方法是让渲染线程根据需要根据物理插入动画。

您的代码中一个更实际的问题是SDL_GetTicks() 以毫秒为单位为您提供时间。那不是很准确;如果您的显示器以 60 fps 运行,则一帧需要 16.66666... 毫秒。你的计算会有高达 1 毫秒的误差,这是一帧长度的 6.25%。根据游戏的类型,这实际上可能很明显!

【讨论】: