OpenGL#

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

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

初始化#

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

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

垃圾数据收集和线程#

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

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

因此,Arade的默认垃圾回收模式需要主动释放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() 被称为。

将原始字节写入GL缓冲区和纹理#

Arade的许多OpenGL类都支持从任何支持 buffer protocol 。对最终用户最有用的类有:

此功能可用于显示计算结果,例如:

  • 显示来自NumPy数组的数据的科学可视化

  • 简单的控制台模拟器绘制其内部屏幕缓冲区

在使用Python的内置缓冲区协议对象作为 write 方法实现了Arade的GL对象。我们将这些内置类型列在 arcade.arcade_types.BufferProtocol Union 打字。

对于来自第三方库的对象,类型检查器可能会警告您类型不匹配。这是因为在此之前,Python将不支持缓冲区协议对象的常规批注 version 3.12 at the earliest

同时,对于想要从第三方缓冲区协议对象写入Arade的GL对象的用户,也有解决办法:

  • 使用 typing.cast 方法来转换Linter的对象类型

  • 使用 # type: ignore 为了让警告安静下来