为什么SDL_Flip不限制FPS以匹配屏幕频率?

时间:2014-05-03 10:57:54

标签: c++ visual-c++ sdl game-loop sdl-1.2

我使用SDL 1.2和VS2008来制作类似游戏的小应用程序。我最近(从其他帖子中得到一些我现在找不到的帖子的想法,如果你认为我应该将你的问题链接起来以供参考),重新编写我的游戏循环以不使用Sleep或SDL_Delay进行计时。相反,我用已知频率调用我的游戏逻辑,并根据实际时间步长计算距离和位置。

当我这样做时,我期待FPS被SDL_Flip限制到屏幕的帧速率(vsynch?),但我最终在我的机器上运行大约300 FPS,运行Windows 7.这可能是导致这种情况的原因。 ?你可以在监视器vsynchs之间多次运行整个游戏循环(包括SDL_Flip)吗?在不同的机器上行为可能是不同的,或者SDL_Flip永远不应该同步到vsynch?我没有看到任何闪烁或其他不期待的屏幕更新效果。

这是我的游戏循环供参考:

void GraphicsFramework::run()
{
    Uint32 last_input_check = 0;
    Uint32 last_logics_check = 0;

    while(true)
    {
        Uint32 now = SDL_GetTicks();

        if(now - last_input_check > 10) // Every 10 millisecond
        {
            if(!processEvents())
            {
                return;
            }
            last_input_check = now;
        }

        if(now - last_logics_check > 20) // Every 20 milliseconds
        {
            handleGameLogics();
            last_logics_check = now;
        }

        draw();                          // No FPS limitation
        m_Window.flipSurface();          // Calls SDL_Flip(surface)
        m_ActualFrameTime = SDL_GetTicks() - now;
    }
}

修改 固定等待繁忙的FPS看起来像这样。取代

        m_ActualFrameTime = SDL_GetTicks() - now;

        do
        {
            m_ActualFrameTime = SDL_GetTicks() - now;
        } while ((Uint32)(1000/m_ActualFrameTime) > getDesiredFPS());

这比使用SDL_Delay或Sleep提供了更稳定的结果,至少在我的机器上,你可以得到一些可变的FPS。当然,两者都会破坏示例中processEvents()的时间。

还为完整性添加了SDL_Delay变体:

        Sint32 timeToSleep = (Uint32)(1000/getDesiredFPS()) - m_ActualFrameTime;
        if(timeToSleep > 0)
        {
            SDL_Delay((Uint32)timeToSleep);
        }

1 个答案:

答案 0 :(得分:1)

SDL_Flip只是将表面上的内容推送到屏幕上。它与fps无关。并且你不应该在同一个循环中多次使用SDL_Flip,你应该在更新曲面后准备好在屏幕上显示它。

管理fps SDL_Delay(简称为睡眠)是我认为最好的选择。