如何避免 Linux/X11 上的 pygame 撕裂
我一直在玩 pygame(在 Debian/Lenny 上)。 除了烦人的位图撕裂(全屏或窗口模式)之外,它似乎工作得很好。
我正在使用默认的 SDL X11 驱动程序。 谷歌搜索表明,X11 不提供垂直同步设施(即使使用使用 FULLSCREEN|DOUBLEBUF|HWSURFACE 标志创建的显示器)是 SDL 的一个已知问题,我应该改用“dga”驱动程序。
然而,运行
SDL_VIDEODRIVER=dga ./mygame.py
会引发 pygame 初始化
pygame.error: No available video device
(尽管 xdpyinfo 显示存在 XFree86-DGA 扩展)。
那么:获得无撕裂垂直同步翻转的技巧是什么? 要么让这个 dga 的东西发挥作用,要么通过其他机制?
I've been playing with pygame (on Debian/Lenny).
It seems to work nicely, except for annoying tearing of blits (fullscreen or windowed mode).
I'm using the default SDL X11 driver. Googling suggests that it's a known issue with SDL that X11 provides no vsync facility (even with a display created with FULLSCREEN|DOUBLEBUF|HWSURFACE
flags), and I should use the "dga" driver instead.
However, running
SDL_VIDEODRIVER=dga ./mygame.py
throws in pygame initialisation with
pygame.error: No available video device
(despite xdpyinfo
showing an XFree86-DGA extension present).
So: what's the trick to getting tear-free vsynced flips ? Either by getting this dga thing working or some other mechanism ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
将撕裂降至最低的最佳方法是使帧速率尽可能接近屏幕频率。 SDL 库没有垂直同步,除非您通过它运行 OpenGL,因此唯一的方法是自己估算帧速率。
SDL 硬件双缓冲区虽然工作时很好,但无法得到保证。 我很少看到它的实际应用。
根据我使用 SDL 的经验,您必须使用 OpenGL 才能完全消除撕裂。 虽然需要进行一些调整,但绘制简单的 2D 纹理并不那么复杂,而且您还可以获得其他一些可以实现的额外功能,例如旋转、缩放、混合等。
但是,如果您仍然想使用软件渲染,我建议使用脏矩形更新。 这也有点难以适应,但它节省了处理负载,这可能使更新更容易,并且避免整个屏幕被撕裂(除非您滚动整个游戏区域或其他东西)。 绘制到缓冲区所需的时间也最短,这可以避免屏幕更新时发生位块传送,这是造成撕裂的原因。
The best way to keep tearing to a minimum is to keep your frame rate as close to the screen's frequency as possible. The SDL library doesn't have a vsync unless you're running OpenGL through it, so the only way is to approximate the frame rate yourself.
The SDL hardware double buffer isn't guaranteed, although nice when it works. I've seldomly seen it in action.
In my experience with SDL you have to use OpenGL to completely eliminate tearing. It's a bit of an adjustment, but drawing simple 2D textures isn't all that complicated and you get a few other added bonuses that you're able to implement like rotation, scaling, blending and so on.
However, if you still want to use the software rendering, I'd recommend using dirty rectangle updating. It's also a bit difficult to get used to, but it saves loads of processing which may make it easier to keep the updates up to pace and it avoids the whole screen being teared (unless you're scrolling the whole play area or something). As well as the time it takes to draw to the buffer is at a minimum which may avoid the blitting taking place while the screen is updating, which is the cause of the tearing.
好吧,我最终的解决方案是切换到 Pyglet,它似乎比 Pygame 更好地支持 OpenGL,但并不'没有任何闪烁问题。
Well my eventual solution was to switch to Pyglet, which seems to support OpenGL much better than Pygame, and doesn't have any flicker problems.
调用
set_mode
并且您应该已全部设置完毕(至少在任何实际支持此功能的系统上;在某些情况下,SDL 仍然无法为您提供支持垂直同步的表面,但它们越来越少)。Use the
SCALED
flag andvsync=True
when callingset_mode
and you should be all set (at least on any systems which actually support this; in some scenarios SDL still can't give you a VSync-capable surface but they are increasingly rare).