我目前正在编写一款极其复杂和狡猾的游戏,这会让你感到敬畏和啰嗦哦,好吧,这就是15难题,我只是熟悉SDL。
我正在窗口模式下运行,并使用SDL_Flip作为常规页面更新,因为它在窗口模式下自动映射到完整窗口的SDL_UpdateRect。不是最佳方法,但鉴于这只是15个难题......
无论如何,瓷砖移动的速度很快。 IOW,窗口模式下的SDL_Flip不包括与垂直回扫的任何同步。我在Windows XP ATM中工作,但我认为这是SDL的正确行为,也会在其他平台上发生。
切换到使用SDL_UpdateRect显然不会改变任何东西。据推测,我需要在自己的代码中实现延迟逻辑。但是,一个简单的基于时钟的计时器可能会导致窗口被半绘时发生更新,从而导致可见的扭曲(我忘记了技术名称)。
编辑此问题称为“撕裂”。
所以 - 在SDL的窗口模式游戏中,如何将页面翻转与垂直回扫同步?
编辑在搜索解决方案时,我看到了几个声明,在窗口化的应用程序中无法将页面翻转同步到垂直回扫。在Windows上,至少,这简直是假的 - 我写过游戏(我的意思是与15拼图类似的东西)。我曾经浪费过一段时间玩Dark Basic和Dark GDK - 基于DirectX和同步翻页都以窗口模式翻转到垂直回扫。
答案 0 :(得分:4)
主要编辑
事实证明我应该花更多的时间在询问之前。来自SDL FAQ ......
http://sdl.beuc.net/sdl.wiki/FAQ_Double_Buffering_is_Tearing
这似乎意味着SDL窗口模式应用程序不支持与垂直回扫同步。
但是...
在Windows上可以使用基本技术 ,从某种意义上说,我开始认为SDL可以做到这一点。还不太确定。
在Windows上,我之前说过,在窗口模式下将页面翻转同步到垂直同步已经可以使用WinG一直回到16位日。事实证明,这不是完全错误,而是误导。我使用WinG挖出了一些旧的源代码,并且有一个计时器触发了页面blits。 WinG将以极快的速度运行,正如我对SDL所做的那样感到惊讶 - blit-to-screen页面翻转操作不会等待进行垂直回扫。
进一步调查 - 当您在WinG中对屏幕进行blit时,blit排队等待以后呼叫退出。 blit在下一次垂直回扫时执行,所以希望没有撕裂。如果在回扫之前对屏幕进行进一步的blits(脏矩形),它们会合并。如果在垂直回扫之前执行大量全屏blits,则会渲染从不显示的帧。
WinG中的这种blit-to-screen显然与SDL_UpdateRect类似。 SDL_UpdateRects只是一种手动组合一些脏矩形的优化方法(并且可以肯定,它们应用于同一帧)。所以也许(在可以进行垂直回扫的平台上)它在SDL中完成,类似于WinG - 没有等待,但也没有撕裂。
好吧,我测试了使用计时器来触发帧更新,结果(在Windows XP上)是不确定的。我可以在我的古老笔记本电脑上轻微地偶尔撕裂,但这可能不是SDL的错 - 它可能是“光栅”超越了这一点。这可能是我使用SDL_Flip而不是直接调用带有最小脏矩形的SDL_UpdateRect的错 - 尽管我试图在这种情况下撕裂,看看我是否可以。
所以我仍然不确定,但可能是窗口模式SDL不像在那些允许它的平台上那样撕裂。即使在我的古老笔记本电脑上,结果也不像我想象的那么糟糕。
但是 - 有人能提供明确的答案吗?
答案 1 :(得分:0)
您可以使用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以创建自己的帧速率控件。