创建OpenGL上下文
本节介绍如何配置OpenGL上下文。对于大多数应用程序来说,这里描述的信息级别太低,不会引起任何关注,但是更高级的应用程序可以利用小程序提供的完整控制。
显示、屏幕、配置和环境

从抽象画布到新创建的窗口及其上下文的构造流。
环境和配置
在pyglet中的窗口上绘制时,您是在OpenGL上下文中绘制。每个窗口都有自己的上下文,上下文是在创建窗口时创建的。您可以通过窗口的 context
属性。
上下文是从OpenGL配置(或“配置”)创建的,它描述了上下文的各种属性,例如使用什么颜色格式、可用的缓冲区数量等。可以通过上下文的访问用于创建上下文的配置 config
属性。
例如,在这里,我们使用默认配置创建一个窗口,并检查其一些属性:
>>> import pyglet
>>> window = pyglet.window.Window()
>>> context = window.context
>>> config = context.config
>>> config.double_buffer
c_int(1)
>>> config.stereo
c_int(0)
>>> config.sample_buffers
c_int(0)
请注意,配置属性的值都是ctype实例。这是因为配置不是由pyglet指定的。相反,它是由pyglet从系统支持的配置列表中选择的。您不能保证给定的配置在系统上有效,除非它是由系统提供给您的。
通过允许您创建只指定您感兴趣的值的“模板”配置,pyglet简化了选择系统配置之一的过程。看见 简单的情景配置 了解更多细节。
显示
系统实际上可能支持几组不同的配置,具体取决于所使用的显示设备。例如,具有两个视频卡的计算机可能不支持每个显卡上的相同配置。另一个例子是远程使用X11:显示设备将支持与本地驱动程序不同的配置。即使本地计算机上的单个视频卡也可能支持插入两台显示器的不同配置。
在pyglet中,一个 Display
是连接到单个显示设备的“屏幕”的集合。在Linux上,显示设备对应于正在使用的X11显示器。在Windows和Mac OS X上,只有一个显示器(因为这些操作系统将多个视频卡作为一个虚拟设备呈现)。
这个 pyglet.canvas
模块提供对显示器的访问(S)。使用 get_display()
函数以获取默认显示::
>>> display = pyglet.canvas.get_display()
屏风
一旦您获得了显示,您就可以列举所连接的屏幕。屏幕是连接到显示设备的物理显示介质;例如,计算机显示器、电视或投影仪。大多数计算机将只有一个屏幕,但连接到投影仪的双头工作站和笔记本电脑是常见的情况,其中将出现多个屏幕。
在下面的示例中,列出了双头工作站的屏幕:
>>> for screen in display.get_screens():
... print(screen)
...
XlibScreen(screen=0, x=1280, y=0, width=1280, height=1024, xinerama=1)
XlibScreen(screen=0, x=0, y=0, width=1280, height=1024, xinerama=1)
由于该工作站运行的是Linux,因此返回的屏幕为 XlibScreen
,是的子类 Screen
。这个 screen
和 xinerama
属性特定于Linux,但 x
, y
, width
和 height
属性出现在所有屏幕上,并描述屏幕的几何形状,如下所示。

屏幕的排列及其报告的几何图形的示例。请注意,根据该特定用户的喜好,主显示器(标记为“1”)位于右侧。
总是有一个“默认”屏幕,这是由返回的第一个屏幕 get_screens()
。根据操作系统的不同,默认屏幕通常是包含任务栏(Windows)或菜单栏(OS X)的屏幕。您可以使用以下命令直接访问此屏幕 get_default_screen()
。
OpenGL配置选项
在配置或选择 Config
,则根据该配置的属性执行此操作。Piglet支持由AGL、GLX、WGL及其扩展提供的选项的固定子集。特别是,这些约束被放置在所有OpenGL配置上:
缓冲区始终是组件(RGB或RGBA)颜色,而不是调色板索引。
缓冲区的“级别”始终为0(该参数基本上不受现代OpenGL驱动程序的支持)。
无法设置缓冲区的透明颜色(同样,此特定于GLX的选项不受很好的支持)。
不支持pBuffers(使用帧缓冲区对象可以更简单、更高效地实现同等功能)。
缓冲区的可见部分(有时称为颜色缓冲区)配置有以下属性:
buffer_size
每个样本的位数。公用值为24和32,每种颜色分量专用8位。缓冲器大小16也是可能的,其通常分别对应于红色、绿色和蓝色的5、6和5比特。
通常不需要设置此属性,因为默认情况下,设备驱动程序将选择与当前显示模式兼容的缓冲区大小。
red_size
,blue_size
,green_size
,alpha_size
它们每个都给出了专用于其各自颜色分量的位数。应避免设置任何红色、绿色或蓝色大小,因为这些大小由驱动程序根据
buffer_size
财产。如果颜色缓冲区中需要Alpha通道(例如,如果要在多个过程中合成),则应指定
alpha_size=8
以确保创建此频道。sample_buffers
andsamples
配置多重采样缓冲区(MSAA),其中使用多个颜色样本来确定每个像素的颜色,从而产生更高质量的抗锯齿图像。
通过设置启用多重采样(MSAA)
sample_buffers=1
,然后给出每像素要使用的样本数。samples
。例如,samples=2
是速度最快、质量最低的多样本配置。samples=4
仍然受到广泛支持,即使在英特尔高清和AMD Vega上也表现相当出色。大多数现代GPU支持2×、4×、8×和16×MSAA样本,具有相当高的性能。stereo
创建单独的左侧和右侧缓冲区,用于立体声硬件。只有立体眼镜等专用视频硬件才会支持这一选项。使用时,您需要手动渲染到每个缓冲区,例如使用 glDrawBuffers 。
double_buffer
创建单独的前台缓冲区和后台缓冲区。在没有双缓冲的情况下,绘图命令在屏幕上立即可见,当图像在他们面前重新绘制时,用户将注意到可见的闪烁。
建议您设置
double_buffer=True
,它创建一个单独的隐藏缓冲区,在该缓冲区中执行绘制。当 Window.flip 调用时,将交换缓冲区,使新图形几乎瞬间可见。
除颜色缓冲区外,还可以根据这些属性的值有选择地创建其他几个缓冲区:
depth_size
3D渲染通常需要深度缓冲区。典型的深度大小为24位。指定
0
如果不需要深度缓冲区。stencil_size
模板缓冲区是屏蔽其他缓冲区和实现某些体积阴影算法所必需的。典型的模板大小为8位;或指定
0
如果你不需要的话。accum_red_size
,accum_blue_size
,accum_green_size
,accum_alpha_size
累积缓冲区可用于简单的抗锯齿、景深、运动模糊和其他合成操作。它现在的使用正在被浮点纹理的使用所取代,但对于在较旧的硬件上实现这些效果来说,它仍然是一个实用的解决方案。
如果需要累积缓冲区,请指定
8
这些属性中的每一个(当然,Alpha组件是可选的)。aux_buffers
每个辅助缓冲器被配置为与颜色缓冲器相同。通常最多可以创建四个辅助缓冲区。指定
0
如果您不需要任何辅助缓冲区。像累积缓冲区一样,辅助缓冲区现在不常使用,因为可以使用更有效的技术,如渲染到纹理。然而,它们几乎在较旧的硬件上普遍可用,而较新的技术不可能实现。
如果您希望直接使用OpenGL,您可以请求更高级别的上下文。如果您希望使用现代的OpenGL可编程管道,这是必需的。然而,请注意,Piglet目前在其许多内部模块(如文本、图形和精灵模块)中使用遗留的OpenGL功能。请求更高版本的上下文当前将阻止使用这些模块。
major_version
对于OpenGL 3.x或4.x环境,此值为3或4。
minor_version
请求的上下文的次要版本。在某些情况下,OpenGL驱动程序可能返回比请求的版本更高的版本。
forward_compatible
将其设置为 True 将要求驱动程序从上下文中排除旧的OpenGL功能。Khronos不建议使用此选项。
备注
要在Mac OSX上请求更高版本的OpenGL上下文,必须禁用pyglet阴影上下文。要执行此操作,请设置pyglet选项 pyglet.options['shadow_window']
至 False
before 创建窗口或导入 pyglet.window
。
默认配置
如果您创建一个 Window
在不指定上下文或配置的情况下,pyglet将使用具有以下属性的模板配置:
属性
价值
double_buffer
千真万确
depth_size
24
简单的情景配置
只能从系统提供的配置创建上下文。枚举和比较所有可能配置的属性是一个复杂的过程,因此Piglet提供了一个基于“模板”配置的更简单的接口。
要获得具有所需属性的配置,请构造一个 Config
并且只设置您感兴趣的属性。然后,您可以将此配置提供给 Window
构造函数来创建上下文。
例如,要创建具有Alpha通道的窗口:
config = pyglet.gl.Config(alpha_size=8)
window = pyglet.window.Window(config=config)
有时有必要自己创建上下文,而不是让 Window
构造函数为您完成此操作。在本例中,使用 get_best_config()
要获取“完整”配置,然后可以使用该配置来创建上下文:
display = pyglet.canvas.get_display()
screen = display.get_default_screen()
template = pyglet.gl.Config(alpha_size=8)
config = screen.get_best_config(template)
context = config.create_context(None)
window = pyglet.window.Window(context=context)
请注意,您不能直接从模板(任何模板)创建上下文 Config
你构建了你自己)。这个 Window
如果给定了模板配置,则构造函数执行与上面类似的过程来创建上下文。
并非所有配置都可以在所有计算机上使用。呼唤 get_best_config()
将筹集 NoSuchConfigException
如果硬件不支持请求的属性。它永远不会返回不符合或超过您在模板中指定的属性的配置。
您可以使用它来支持可用的较新硬件功能,但也可以在必要时接受较低的配置。例如,如果可能,下面的代码将创建一个具有多采样的窗口,否则将禁用多采样:
template = pyglet.gl.Config(sample_buffers=1, samples=4)
try:
config = screen.get_best_config(template)
except pyglet.window.NoSuchConfigException:
template = gl.Config()
config = screen.get_best_config(template)
window = pyglet.window.Window(config=config)
选择最佳配置
允许Piglet基于模板选择最佳配置对于大多数应用程序来说已经足够了,然而,一些复杂的程序可能希望指定自己的算法来选择一组OpenGL属性。
方法枚举屏幕的配置。 get_matching_configs()
方法。您必须提供模板作为最低规格,但您可以提供“空”模板(未设置属性)以获取屏幕支持的所有配置的列表。
在以下示例中,打印具有辅助缓冲区或累积缓冲区的所有配置:
display = pyglet.canvas.get_display()
screen = display.get_default_screen()
for config in screen.get_matching_configs(gl.Config()):
if config.aux_buffers or config.accum_red_size:
print(config)
除了支持更复杂的配置选择算法外,枚举还允许您高效地找到属性的最大值(例如,每像素的最大样本数),或向用户显示可能的配置列表。