OpenGL接口
Piglet提供了到OpenGL的直接接口。该接口被所有的pyglet高级API使用,因此所有的渲染都是由显卡而不是CPU高效地完成的。您可以直接访问此界面;使用它与在C中使用OpenGL非常相似。
界面是一个“薄包装器” libGL.so
在Linux上, opengl32.dll
在Windows和 OpenGL.framework
在OS X上,pyglet维护人员根据最新规范重新生成界面,因此它始终是最新版本和几乎所有扩展的最新版本。
该接口由 pyglet.gl
包裹。要使用它,你需要对OpenGL、C和ctype有很好的了解。您可能更喜欢使用OpenGL而不使用ctype,在这种情况下,您应该调查 PyOpenGL 。 PyOpenGL 提供类似的功能,具有更具“Pythonic”风格的界面,并且无需任何修改即可与Piglet一起使用。
使用OpenGL
上提供了OpenGL的文档 OpenGL website 以及(更全面地)在 OpenGL Programming SDK 。
导入程序包可以访问OpenGL和所有已注册的OpenGL扩展。这对于除最高级的OpenGL用法之外的所有用法都足够了:
from pyglet.gl import *
所有函数名和常量都与C语言中的对应函数相同。例如,下面的代码设置GL Clear颜色并启用深度测试和面剔除:
from pyglet.gl import *
# Direct OpenGL commands to this window.
window = pyglet.window.Window()
glClearColor(1, 1, 1, 1)
glEnable(GL_DEPTH_TEST)
glEnable(GL_CULL_FACE)
某些OpenGL函数需要数据数组。这些数组必须构造为 ctypes
正确类型的数组。下面的示例说明如何使用OpenGL类型构造数组:
from pyglet.gl import *
# Create a new array type of length 32:
array32f = GLfloat * 32
# Create an instance of this array with initial data:
array_instance = array32f(*data)
# More commonly, combine these steps:
array_instance = (GLfloat * 32)(*data)
类似的数组结构可用于为其他OpenGL对象创建数据。
调整窗口大小
pyglet会在每个窗口上自动设置视区和平行投影。它在默认情况下执行此操作 on_resize()
处理程序定义于 Window
。pyglet窗口有一个 projection 可以使用4x4投影矩阵设置的属性。看见 矩阵与向量数学 有关创建矩阵的详细信息,请参阅。默认设置 on_resize 处理程序定义为::
@window.event
def on_resize(width, height):
glViewport(0, 0, *window.get_framebuffer_size())
window.projection = Mat4.orthogonal_projection(0, width, 0, height, -255, 255)
如果需要定义您自己的投影(例如,要使用三维透视投影),则应使用您自己的事件覆盖此事件;例如:
@window.event
def on_resize(width, height):
glViewport(0, 0, *window.get_framebuffer_size())
window.projection = Mat4.perspective_projection(window.aspect_ratio, z_near=0.1, z_far=255)
return pyglet.event.EVENT_HANDLED
请注意, on_resize()
无论是第一次显示窗口,还是以后调整窗口大小,都会为窗口调用处理程序。
错误检查
默认情况下,pyglet调用 glGetError
在每次GL函数调用之后(除非这样的检查无效)。如果报告了错误,则会引发 GLException
其结果是 gluErrorString
作为这条信息。
这在开发过程中非常方便,因为它可以在早期捕获常见的编码错误。但是,它对性能有很大影响,当使用 -O
选择。
您也可以通过设置以下选项来禁用此错误检查 before 正在导入 pyglet.gl
或 pyglet.window
**
# Disable error checking for increased performance
pyglet.options['debug_gl'] = False
from pyglet.gl import *
在导入后设置选项 pyglet.gl
都不会有任何效果。一旦禁用,在每次GL调用中都不会有错误检查开销。
使用扩展函数
在使用扩展函数之前,您应该检查该扩展是否由当前驱动程序实现。通常,这是通过使用 glGetString(GL_EXTENSIONS)
,但pyglet有一个方便的模块, pyglet.gl.gl_info 这将为您实现以下目标:
if pyglet.gl.gl_info.have_extension('GL_ARB_shadow'):
# ... do shadow-related code.
else:
# ... raise an exception, or use a fallback method
您还可以轻松查看OpenGL::的版本
if pyglet.gl.gl_info.have_version(4, 6):
# We can assume all OpenGL 4.6 functions are implemented.
请记住,只调用 gl_info
在创建窗口后运行。
使用多个窗口
Piglet允许您同时创建和显示任意数量的窗口。每个上下文都将使用其自己的OpenGL上下文创建,但默认情况下,所有上下文将共享相同的纹理对象、显示列表、着色器程序等 [1]. 每个上下文都有自己的状态和帧缓冲区。
始终存在活动的上下文(除非没有窗口)。使用时 pyglet.app.run()
对于应用程序事件循环,pyglet在调度 on_draw()
或 on_resize()
事件。
在其他情况下,您可以使用显式设置活动上下文 pyglet.window.Window.switch_to
。
AGL、GLX和WGL
OpenGL上下文本身由特定于操作系统的库管理:OS X上的AGL、X11下的GLX和Windows上的WGL。在创建窗口时,pyglet会处理这些细节,但您可能需要直接使用这些函数(例如,使用pBuffers)或扩展函数。
这些模块被命名为 pyglet.gl.agl
, pyglet.gl.glx
和 pyglet.gl.wgl
。您只需为正在运行的操作系统导入正确的模块:
if sys.platform.startswith('linux'):
from pyglet.gl.glx import *
glxCreatePbuffer(...)
elif sys.platform == 'darwin':
from pyglet.gl.agl import *
aglCreatePbuffer(...)
或者,您也可以使用 pyglet.compat_platform
以支持与Piglet未正式支持的平台兼容的平台。例如,FreeBSD系统将显示为 linux-compat
在……里面 pyglet.compat_platform
。
有方便的模块用于查询WGL和GLX的版本和扩展名 pyglet.gl.wgl_info
和 pyglet.gl.glx_info
,分别为。AGL没有这样的模块,只需查询OS X的版本即可。
如果使用GLX扩展模块,则可以导入 pyglet.gl.glxext_arb
对于已注册的分机或 pyglet.gl.glxext_nv
获取最新的NVIDIA扩展。
同样,如果使用WGL扩展模块,请导入 pyglet.gl.wglext_arb
或 pyglet.gl.wglext_nv
。