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

Posted

技术标签:

【中文标题】如何避免在 Linux/X11 上使用 pygame 撕裂【英文标题】:How to avoid tearing with pygame on Linux/X11 【发布时间】:2009-07-04 16:53:12 【问题描述】:

我一直在玩 pygame(在 Debian/Lenny 上)。 它似乎工作得很好,除了烦人的 blit 撕裂(全屏或窗口模式)。

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

但是,正在运行

SDL_VIDEODRIVER=dga ./mygame.py

使用

引发 pygame 初始化
pygame.error: No available video device

(尽管 xdpyinfo 显示存在 XFree86-DGA 扩展)。

那么:获得无撕裂垂直同步翻转的诀窍是什么?通过让这个 dga 工作或其他一些机制?

【问题讨论】:

你的显卡有合适的内核驱动吗?对于 X11,您需要一个内核驱动程序和一个 X11 库来访问它。如果缺少一个,另一个将工作,但将无法使用。 我对此感到有点惊讶,因为 packages.debian.org/lenny/libxxf86dga1 似乎在 X11 中提供了 DGA 的东西,没有提到任何关于内核模块的内容(它会在 lsmod 中显示什么?) .对于它的价值,我正在使用带有旧 5 系列 AGP NVidia 卡的 nv xorg 驱动程序。 【参考方案1】:

将撕裂降至最低的最佳方法是让帧速率尽可能接近屏幕频率。除非您通过它运行 OpenGL,否则 SDL 库没有 vsync,因此唯一的方法是自己估算帧速率。 SDL 硬件双缓冲区无法保证,尽管它在工作时很好。我很少在实际中看到它。

根据我使用 SDL 的经验,您必须使用 OpenGL 才能完全消除撕裂。这需要一些调整,但绘制简单的 2D 纹理并不是那么复杂,而且您还可以获得一些其他额外的好处,您可以实现旋转、缩放、混合等。

但是,如果您仍想使用软件渲染,我建议您使用脏矩形更新。它也有点难以习惯,但它节省了大量的处理,这可能使更新更容易保持同步,并且避免了整个屏幕被撕裂(除非你滚动整个游戏区域或其他东西)。以及绘制到缓冲区所需的时间最少,这可以避免在屏幕更新时发生 blitting,这是导致撕裂的原因。

【讨论】:

现在(大部分)不正确。 PyGame 仍然需要一个 GPU 表面来打开 vsync,但您现在可以通过 PyGame 2 中的 SCALED 标志轻松获得一个与其现有 API 一起工作且不需要 OpenGL 的表面。【参考方案2】:

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

【讨论】:

Pyglet 在 API 和实践方面也更接近于其他语言和现代技术的其他图形库。 Gloss 是另一种选择,如果您不想一路走下去。它将 OpenGL 封装在简单的类和方法中,并且在 Pygame 中运行良好。【参考方案3】:

在调用set_mode 时使用SCALED 标志和vsync=True,您应该已准备就绪(至少在任何实际支持此功能的系统上;在某些情况下,SDL 仍然无法为您提供支持 VSync 的界面但它们越来越少了)。

【讨论】:

以上是关于如何避免在 Linux/X11 上使用 pygame 撕裂的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PyGame 画布上从 PyRealSense2 绘制视频帧?

如何在 Pygame 中获取用户的文本输入? [复制]

Pygame和PyQt4如何集成?

如何在pygame中控制单个子弹

如何在pygame中更改一段文本的颜色

在 Linux/X11 上的 Qt 中,如何解决主窗口排序问题?