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 。对最终用户最有用的类有:
arcade.gl.Texture
此功能可用于显示计算结果,例如:
显示来自NumPy数组的数据的科学可视化
简单的控制台模拟器绘制其内部屏幕缓冲区
在使用Python的内置缓冲区协议对象作为 write
方法实现了Arade的GL对象。我们将这些内置类型列在 arcade.arcade_types.BufferProtocol
Union 打字。
对于来自第三方库的对象,类型检查器可能会警告您类型不匹配。这是因为在此之前,Python将不支持缓冲区协议对象的常规批注 version 3.12 at the earliest 。
同时,对于想要从第三方缓冲区协议对象写入Arade的GL对象的用户,也有解决办法:
使用 typing.cast 方法来转换Linter的对象类型
使用
# type: ignore
为了让警告安静下来