PyOpenGl还是pyglet?
我想用OpenGL和Python做一些小实验,但我找不到使用PyOpenGL和Pyglet之间的好理由。
你会推荐哪个,为什么呢?
9 个回答
可以试试 ModernGL。
pip install ModernGL
PyOpenGL 是原始 OpenGL API 的自动生成版本(用 SWIG 生成的)。原始的 OpenGL API 对 Python 不太友好,生成的 Python 绑定使用起来比较麻烦。
pyglet 主要用于创建窗口和处理事件,不过你也可以使用类似 PyOpenGL 的 API(比如
pyglet.gl.glClearColor
)。pygame 提供了一个窗口,你可以在里面使用 PyOpenGL 来进行渲染。
ModernGL 是 PyOpenGL 的一个很好的替代品,你可以用更少的代码来使用现代的 OpenGL API。ModernGL 不会自己创建窗口,但你可以把它和 pyglet、pygame、PyQt5 甚至 GLUT 结合使用。补充 现在你可以使用 moderngl-window 独立创建窗口。
pip install moderngl-window
在 ModernGL 中,你可以通过一次调用来创建一个简单的着色器程序:
prog = ctx.program(
vertex_shader='''
#version 330
in vec2 in_vert;
void main() {
gl_Position = vec4(in_vert, 0.0, 1.0);
}
''',
fragment_shader='''
#version 330
out vec4 f_color;
void main() {
f_color = vec4(0.3, 0.5, 1.0, 1.0);
}
''',
)
使用 ModernGL,你可以完全控制 OpenGL API。
首先,你可以从pyglet开始。它提供了一个非常友好的高级接口,里面有你开始编程所需的一切,比如打开窗口、绘制精灵和使用OpenGL的基本图形。它的Sprite和Batch类特别好用。
之后,你可能会想写一些更底层的代码,直接调用OpenGL的函数,比如glDrawArrays等等。你可以使用pyglet的OpenGL绑定,或者使用PyOpenGL。好消息是,不管你选择哪个,都可以直接把这些调用放到你现有的pyglet应用程序中,它们都会正常工作。把代码从Pyglet转到PyOpenGL也比较简单,所以你不用太担心这个选择。
这两者之间的区别是:PyOpenGL的绑定让OpenGL的接口更友好,更符合Python的风格。比如,你可以用很多不同的方式传递顶点数组,比如ctypes数组、numpy数组、普通列表等等,PyOpenGL会把它们转换成OpenGL能用的格式。这些特点让PyOpenGL非常方便。
而pyglet的OpenGL绑定是自动生成的,使用起来没有PyOpenGL那么友好。有时候你需要手动创建ctypes对象,以便把一些“C指针”类型的参数传给OpenGL,这可能会有点麻烦。不过,优点是pyglet的绑定通常会快很多。
这意味着有一个最佳的折中方案:用pyglet来处理窗口、鼠标事件、声音等。然后在你想直接调用OpenGL函数时,使用PyOpenGL的友好接口。最后,在优化时,只替换掉你渲染循环中那些性能关键的少量PyOpenGL调用,换成pyglet的对应调用。对我来说,这样可以让帧率提高2到4倍,同时在90%的代码中享受PyOpenGL的便利。
正如Tony所说,这主要取决于你的目标。如果你只是想“玩玩”,想了解OpenGL或者3D渲染的基本知识,那我建议你直接使用PyOpenGL。这是用Python进行“原始”3D编程最接近的选择。
另一方面,如果你是在“玩玩”一个游戏或多媒体应用的原型,或者想学习一些编程的基本实践,那么Pyglet会为你节省很多开发时间。它提供了输入事件、声音、文本显示等功能的接口。很多时候,这种前期的投入会让人们无法完成他们的项目,所以有这些现成的工具是非常重要的。(而且,避免重复造轮子也是很符合Python的编程风格。)
如果你想做一些比较复杂的工作(这通常不算是我所说的“玩玩”,但如果你是在研究3D引擎设计,那可能就不一样了),那么你可以看看Python-Ogre,它是一个封装了功能非常强大且全面的OGRE 3D图形引擎的库。