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

C++ 为什么SDL_Flip不限制FPS以匹配屏幕频率?,c++,visual-c++,sdl,game-loop,sdl-1.2,C++,Visual C++,Sdl,Game Loop,Sdl 1.2,我将SDL1.2和VS2008用于一个较小的类似游戏的应用程序。我最近(从其他帖子中获得了一些想法,但我现在找不到,如果你觉得我应该链接你的问题以供参考,那么很抱歉)重新编写了我的游戏循环,不使用睡眠或SDL_延迟来计时。相反,我用已知的频率调用我的游戏逻辑,并根据实际的时间步长计算距离和位置 当我这样做时,我希望FPS会受到SDL_翻转到屏幕帧速率(vsynch?)的限制,但我的机器运行Windows7,最终大约有300 FPS。这可能是什么原因?你能在监视器vsynchs之间多次运行整个游戏

我将SDL1.2和VS2008用于一个较小的类似游戏的应用程序。我最近(从其他帖子中获得了一些想法,但我现在找不到,如果你觉得我应该链接你的问题以供参考,那么很抱歉)重新编写了我的游戏循环,不使用睡眠或SDL_延迟来计时。相反,我用已知的频率调用我的游戏逻辑,并根据实际的时间步长计算距离和位置

当我这样做时,我希望FPS会受到SDL_翻转到屏幕帧速率(vsynch?)的限制,但我的机器运行Windows7,最终大约有300 FPS。这可能是什么原因?你能在监视器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;

这提供了一种比使用SDL_延迟或睡眠更稳定的结果,至少在我的机器上,对于SDL_延迟或睡眠,您可以获得某种程度上可变的FPS。当然,这两种方法都会中断示例中processEvents()的计时

为了完整性,还添加了SDL_延迟变量:

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

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


我认为,管理fps SDL_延迟(简称睡眠)是您最好的选择。

SDL_延迟使Windows关闭您的进程,并且无法保证何时将其切换回,这使得控制fps的效果不太好。我多次执行SDL_翻转的意思是,游戏循环将在监视器vsynch之间运行多次。我将在问题中澄清。是的,这就是现代多任务操作系统的生活。猜猜看——如果你不退回你的时间片,在某个时候操作系统仍然会进入并从你的进程中夺取控制权,而不保证它何时会返回。因为这就是现代抢占式多任务操作系统中的生活,而这正是当今的大多数操作系统。你应该使用这个功能,这样睡眠时间是准确的(尽可能多)。在stackoverflow中查找计时问题,有很多很好的答案;)(顺便说一句,如果你看不到任何闪烁,那么在我看来这很好。有些游戏有vsync作为选项,因此你可以打开/关闭它。所以这应该不是一个问题。你可能只是想放慢它的速度,这样你就不会使用太多的cpu,并且可以控制不依赖deltaTime的基本物理量)jofra,你怎么可能提出这样的要求呢
SDL\u Flip()
应该等待VSYNC,等待应该会影响fps。wiki中的“SDL\u Flip()交换屏幕缓冲区”。它只是交换缓冲区,我敢肯定它与vsync无关。
        Sint32 timeToSleep = (Uint32)(1000/getDesiredFPS()) - m_ActualFrameTime;
        if(timeToSleep > 0)
        {
            SDL_Delay((Uint32)timeToSleep);
        }