5

我目前正在编写一个极其复杂和狡猾的游戏,它会让你充满敬畏和胜利 - 哦,好吧,这是 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

2 回答 2

4

主要编辑

事实证明,在询问之前我应该​​花更多的时间看。从 SDL 常见问题...

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

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

但...

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

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

进一步调查 - 当您在 WinG 中对屏幕执行 blit 时,blit 将排队等待稍后并退出呼叫。blit 在下一次垂直回撤时执行,所以希望不会撕裂。如果您在回溯之前对屏幕进行进一步的 blits(脏矩形),它们会被合并。如果您在垂直回扫之前加载了全屏 blit,则您正在渲染从未显示的帧。

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

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

所以我仍然不确定,但可能是窗口模式 SDL 在那些允许它的平台上一样免疫撕裂。结果似乎没有我想象的那么糟糕,即使在我的旧笔记本电脑上也是如此。

但是 - 任何人都可以提供明确的答案吗?

于 2010-11-28T04:05:11.927 回答
0

您可以使用SDL_gfx的帧率控制。查看库的文档,您的应用程序流程将是这样的:

// initialization code
FPSManager *fpsManager;
SDL_initFramerate(fpsManager);
SDL_setFramerate(fpsManager, 60 /* desired FPS */);


// in the render loop
SDL_framerateDelay(fpsManager);

此外,您可以查看源代码来创建自己的帧率控件。

于 2013-01-27T01:50:18.727 回答