如何在Linux/X11上使用pygame避免画面撕裂

8

我一直在Debian/Lenny上使用pygame进行游戏开发。

除了全屏或窗口模式下出现的令人烦恼的blits撕裂外,它似乎运行良好。

我正在使用默认的SDL X11驱动程序。搜索表明,这是SDL的已知问题,X11不提供垂直同步功能(即使使用FULLSCREEN|DOUBLEBUF|HWSURFACE标志创建显示),因此我应该改用“dga”驱动程序。

然而,运行

SDL_VIDEODRIVER=dga ./mygame.py

在Pygame初始化中出现异常

pygame.error: No available video device

尽管 xdpyinfo 显示存在 XFree86-DGA 扩展,但仍然存在撕裂现象。
那么,如何实现无撕裂的垂直同步翻转?是通过让 dga 正常工作还是其他机制?

1
你是否拥有适当的内核驱动程序来支持你的显卡。对于X11,你需要同时拥有内核驱动程序和X11库来访问它。如果其中一个缺失,另一个虽然可以工作,但是将无法使用。 - SingleNegationElimination
我对此有些惊讶,因为在 X11 中提供 DGA 内容的 http://packages.debian.org/lenny/libxxf86dga1 没有提及任何有关内核模块的信息(在 lsmod 中会显示什么?)。值得一提的是,我正在使用带有旧的 5 系列 AGP NVidia 卡的 nv xorg 驱动程序。 - timday
3个回答

5
将撕裂最小化的最佳方法是尽可能使帧率接近屏幕频率。SDL库没有垂直同步,除非您通过OpenGL运行它,因此唯一的方法是自己近似帧速率。
SDL硬件双缓冲不是保证可用的,虽然在工作时很好。我很少见到它在实际应用中的使用。
根据我的SDL经验,您必须使用OpenGL才能完全消除撕裂。这需要一些调整,但绘制简单的2D纹理并不是很复杂,并且您可以实现一些其他额外的优点,例如旋转、缩放、混合等。
然而,如果您仍想使用软件渲染,我建议使用脏矩形更新。这也有点难以适应,但可以节省大量处理时间,使得更新更容易跟上步伐,并避免整个屏幕被撕裂(除非您正在滚动整个播放区域或类似情况)。同时,绘制到缓冲区所需的时间最少,这可能避免了在屏幕更新时进行blitting,这是导致撕裂的原因。

1
现在这个说法(大部分)是不正确的。PyGame仍然需要GPU表面来打开垂直同步,但是您现在可以通过PyGame 2中的SCALED标志轻松获取一个可与其现有API一起使用且不需要OpenGL的表面。 - Glyph

4

我的最终解决方案是切换到Pyglet,它似乎比Pygame更好地支持OpenGL,并且没有任何闪烁问题。


1
Pyglet在API和实践方面也更接近于其他语言和现代技术的图形库。 - Jotham
如果您不想走得太远,Gloss是另一个选择。它将OpenGL封装在易于使用的类和方法中,并与Pygame协作良好。 - fbmd

0

在调用set_mode时,使用SCALED标志和vsync=True,这样你就可以完成设置了(至少在任何实际支持此功能的系统上;在某些情况下,SDL仍然无法提供VSync-capable表面,但这种情况越来越少)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接