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

Ste*_*314 5 sdl vertical-sync

我现在正在写一个非常复杂和狡猾的游戏,这会让你充满敬畏和喜悦 - 哦,好吧,这是15个谜题,我只是熟悉SDL.

我正在窗口模式下运行,并使用SDL_Flip作为一般情况页面更新,因为它在窗口模式下自动映射到完整窗口的SDL_UpdateRect.不是最佳方法,但鉴于这只是15个难题......

无论如何,瓷砖移动的速度很快.IOW,窗口模式下的SDL_Flip不包括与垂直回扫的任何同步.我在Windows XP ATM中工作,但我认为这是SDL的正确行为,也会在其他平台上发生.

切换到使用SDL_UpdateRect显然不会改变任何东西.据推测,我需要在自己的代码中实现延迟逻辑.但是一个简单的基于时钟的计时器可能会导致窗口被半绘时发生更新,导致可见的扭曲(我忘记了技术名称).

编辑 这个问题被称为"撕裂".

那么 - 在SDL的窗口模式游戏中,如何将页面翻转与垂直回扫同步?

编辑 我在搜索解决方案时看到了几个声明,在窗口化的应用程序中无法将页面翻转同步到垂直回扫.在Windows上,至少,这简直是假的 - 我写过游戏(我的意思是与15拼图类似的东西).我曾经浪费过一段时间玩Dark Ba​​sic和Dark GDK--基于DirectX和同步翻页都是在窗口模式下垂直回扫.

小智 4

主要编辑

事实证明我应该在询问之前花更多的时间看看。来自 SDL 常见问题解答...

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

这似乎强烈暗示 SDL 窗口模式应用程序不支持与垂直回扫同步。

但...

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

在 Windows 上,我之前说过,在窗口模式下将页面翻转同步到垂直同步一直可以追溯到使用 WinG 的 16 位时代。事实证明,这并不完全错误,而是具有误导性。我使用 WinG 挖出了一些旧的源代码,并且有一个计时器触发页面位块传输。WinG 将以惊人的速度运行,正如我对 SDL 的做法感到惊讶一样 - 位图传输到屏幕的翻页操作不会等待垂直回溯。

进一步调查 - 当您在 WinG 中对屏幕执行 blit 时,blit 将排队等待稍后,并且调用退出。blit 在下一个垂直回扫时执行,因此希望不会出现撕裂。如果您在回扫之前对屏幕(脏矩形)进行进一步的位图传送,它们将被合并。如果您在垂直回扫之前执行大量全屏位图传输,则您将渲染从未显示的帧。

WinG 中的 blit-to-screen 显然与 SDL_UpdateRect 类似。SDL_UpdateRects 只是手动组合一些脏矩形的优化方法(并且确保它们可能应用于同一帧)。因此,也许(在可以进行垂直回溯的平台上)它是在 SDL 中完成的,类似于在 WinG 中 - 无需等待,但也无需撕裂。

好吧,我测试了使用计时器来触发帧更新,结果(在 Windows XP 上)不确定。我的老式笔记本电脑可能会出现非常轻微且偶尔的撕裂,但这可能不是 SDL 的错 - 可能是“光栅”超出了位块传输。这可能是我使用 SDL_Flip 而不是直接调用带有最小脏矩形的 SDL_UpdateRect 的错误 - 尽管我试图在这种情况下撕裂,看看我是否可以。

所以我仍然不确定,但窗口模式 SDL 可能与那些允许撕裂的平台一样不受撕裂影响。即使在我古老的笔记本电脑上,结果似乎也没有我想象的那么糟糕。

但是 - 谁能提供明确的答案?