OpenGL备注#

Arcade正在使用OpenGL进行底层渲染。当窗口被装箱时,通过Piglet提供OpenGL功能来使用。它的底层表示是一个OpenGL上下文。Arcade对此上下文的表示是 arcade.Window.ctx 。这是一个 ArcadeContext

使用OpenGL增加了一些我们需要意识到的挑战。

初始化#

在创建窗口之前,无法执行某些操作。在Arcade中,我们在许多类型中执行延迟初始化,以使用户尽可能轻松地执行此操作。 SpriteList 例如,可以在创建窗口之前构建,并将在第一次绘制调用中在内部进行初始化。

TextureAtlas 另一方面,不能在创建窗口之前装入箱子,但是 Texture 可以在任何时候自由加载,因为这些只用枕头管理像素数据和在CPU上计算命中率数据。

垃圾数据收集和线程#

OpenGL不是线程安全的,这意味着除了主线程之外,不可能从任何地方执行操作。您仍然可以在Arcade中使用线程,但它们不能与任何影响OpenGL对象的对象交互。这将立即抛出一个错误。

当在项目或底层库中使用线程时,始终存在在主线程之外运行Python的垃圾回收器的风险。这就是Python的垃圾收集器的工作方式。

因此,Arcade的默认垃圾回收模式需要主动释放OpenGL对象。我们正在为您做这件事 arcade.Window.flip() 方法,该方法会在每一帧中自动调用。

这种垃圾收集模式称为 context_gc 因为死的OpenGL对象是在上下文中收集的,并且仅在 ctx.gc() 被称为。

垃圾收集模式可以在创建窗口期间配置,也可以在上下文中更改运行时配置。

# auto mode works like python's garbage collection (but more risky)
window = Window(gc_mode="auto")

# This context mode is implied by default
window = Window(gc_mode="context_gc")
# From now on you need to manually call window.ctx.gc()
# for OpenGL resources to be deleted. This can be
# done very frame if needed or in shorter intervals
num_released = window.ctx.gc()
print("Resources released:", num_released)

# Change gc mode runtime
window.gc_mode = "auto"
window.gc_mode = "context_gc"

如果出于某种原因,您需要在每个帧上多次运行垃圾收集,则可以安全地从主线程调用它。

在绝大多数情况下,这不是你需要担心的。当前的默认设置是为了让您的生活尽可能轻松。

线程和虚拟同步#

请注意,如果启用了vsync,则所有线程将在所有渲染完成后停止,并且OpenGL正在等待下一个垂直空白。解决此问题的唯一方法是禁用vsync或使用子进程。

SpriteList和线程#

如果SpriteList是用 lazy=True 参数。这可确保直到第一个 draw() 呼叫或 initialize() 被称为。