代码之家  ›  专栏  ›  技术社区  ›  Steve314

如何在加窗SDL应用程序中同步页面翻转和垂直回溯?

  •  5
  • Steve314  · 技术社区  · 13 年前

    我正在写一个非常复杂和狡猾的游戏,这将充满敬畏和胜利-哦,好吧,这是15个谜题,我只是熟悉SDL。

    我在窗口模式下运行,使用SDL_Flip作为一般情况下的页面更新,因为它会自动映射到窗口模式下整个窗口的SDL_更新。不是最佳的方法,但考虑到这只是15个谜题。。。

    不管怎样,瓷砖的移动速度太快了。瞧,窗口模式下的SDL_翻转不包括任何垂直回程的同步。我在Windows XP ATM中工作,但我认为这对于SDL来说是正确的行为,在其他平台上也会发生。

    切换到使用SDL_update直立显然不会改变任何事情。大概,我需要在自己的代码中实现延迟逻辑。但是,一个简单的基于时钟的计时器可能会导致在窗口被绘制一半时发生更新,从而导致可见的失真(我忘记了技术名称)。

    编辑 这个问题被称为“撕裂”。

    所以-在SDL的窗口模式游戏中,我如何同步页面翻转和垂直回溯?

    编辑 在寻找解决方案的过程中,我看到了一些说法,即在窗口应用程序中,不可能将页面翻转同步到垂直回溯。至少在Windows上,这是错误的——我已经编写了一些游戏(我指的是类似于15个拼图的东西)来实现这一点。我曾经浪费了一些时间玩暗黑基本和暗黑GDK-都是基于DirectX和同步页翻转到垂直回溯窗口模式。

    2 回复  |  直到 13 年前
        1
  •  4
  •   Steve314    13 年前

    主要编辑

    原来我应该在问之前花更多的时间看看。从SDL常见问题解答。。。

    http://sdl.beuc.net/sdl.wiki/FAQ_Double_Buffering_is_Tearing

    这似乎非常强烈地暗示了SDL窗口模式应用不支持与垂直回溯同步。

    但是。。。

    基本技术 在Windows上是可能的,从某种意义上说,我开始认为SDL做到了。只是还不太确定。

    在Windows上,我之前说过,在窗口模式下将页面翻转同步到垂直同步一直都是有可能的,直到16位使用WinG的日子。事实证明,这并不是完全错误,而是误导。我用WinG挖掘了一些旧的源代码,有一个计时器触发了页面闪烁。机翼将以可笑的速度运行,正如我对SDL所做的感到惊讶-blit-to-screen页面翻转操作没有 等待 垂直回溯。

    在进一步调查中,当你对机翼的屏幕做一个BLIT时,BLIT将被排队等待,并且呼叫退出。blit是在下一个垂直回程执行的,所以希望没有撕裂。如果在回溯之前对屏幕(脏矩形)执行进一步的blits操作,则它们将合并。如果在垂直回溯之前加载全屏光点,则渲染的是从未显示的帧。

    机翼上的这个blit-to-screen明显类似于SDL_更新。SDLúu UpdateRects只是一种手动组合一些脏矩形的优化方法(并且确保它们可能应用于同一帧)。所以可能(在垂直回溯的平台上)是在SDL中完成的,类似于机翼-没有等待,但也没有撕裂。

    嗯,我测试了使用定时器触发帧更新,结果(在Windows XP上)是不确定的。我的旧笔记本电脑可能会有轻微的偶尔的撕裂,但这可能不是SDL的错——可能是“光栅”超过了blit。这可能是我使用SDLúu Flip而不是用最小的脏矩形直接调用SDL戋u update直立的错误-尽管在这种情况下,我试图撕裂,看看是否可以。

    所以我仍然不确定,但可能是窗口模式SDL在那些允许它的平台上一样对撕裂免疫。结果并不像我想象的那么糟糕,即使是在我古老的笔记本电脑上。

    但是,有谁能给出一个明确的答案吗?

        2
  •  0
  •   Thiago Negri    11 年前

    您可以使用的帧速率控件 SDL_gfx . 看着 docs 对于库,应用程序的流程如下:

    // initialization code
    FPSManager *fpsManager;
    SDL_initFramerate(fpsManager);
    SDL_setFramerate(fpsManager, 60 /* desired FPS */);
    
    
    // in the render loop
    SDL_framerateDelay(fpsManager);
    

    另外,你可以看看 source code 创建自己的帧速率控件。

    推荐文章