PyOpenGL
PyOpenGL (version 3.1.10) provides standard OpenGL bindings for Python, allowing Python programs to interact directly with OpenGL graphics APIs. It offers access to both core OpenGL functionality and extensions, enabling development of 2D/3D graphics applications. The library is mature and stable, with a moderate release cadence driven by bug fixes and OpenGL specification updates.
Warnings
- gotcha Many simple PyOpenGL examples, including the quickstart, use the fixed-function pipeline (`glBegin`/`glEnd`), which is deprecated in modern OpenGL (3.1+ core profiles). This can lead to poor performance, driver issues, or not working at all on systems configured for core profiles.
- gotcha PyOpenGL is solely a binding library; it does not handle window creation or OpenGL context management itself. An external library like Pygame, Pyglet, GLFW (via `pyGLFW`), PyQt, or GLUT (as shown in quickstart) is required to set up the rendering environment.
- gotcha On Linux, installing PyOpenGL often requires system-level OpenGL development libraries (e.g., `mesa-common-dev` or `libgl1-mesa-dev` for Debian/Ubuntu, `freeglut-dev` for GLUT). Without these, `pip install` or runtime might fail.
- gotcha OpenGL errors are not automatically translated into Python exceptions by PyOpenGL. Developers must explicitly call `glGetError()` after OpenGL operations to check for errors and handle them, especially during development.
- gotcha While PyOpenGL automatically converts Python types (lists, tuples, numbers) to C types for OpenGL calls, for large data sets (e.g., vertex data), using `numpy` arrays is significantly more performant due to reduced Python overhead and direct memory access.
Install
-
pip install PyOpenGL PyOpenGL_accelerate
Imports
- GL
from OpenGL.GL import *
- GLUT
from OpenGL.GLUT import *
- GLU
from OpenGL.GLU import *
- shaders
from OpenGL.GL.shaders import compileShader, compileProgram
Quickstart
import sys
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
def draw_triangle():
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glTranslatef(0.0, 0.0, -5.0)
glBegin(GL_TRIANGLES)
glColor3f(1.0, 0.0, 0.0) # Red
glVertex3f(-1.0, -1.0, 0.0)
glColor3f(0.0, 1.0, 0.0) # Green
glVertex3f(1.0, -1.0, 0.0)
glColor3f(0.0, 0.0, 1.0) # Blue
glVertex3f(0.0, 1.0, 0.0)
glEnd()
glutSwapBuffers()
def reshape(width, height):
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45, (width / height), 0.1, 50.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
def keyboard(key, x, y):
if key == b'\x1b': # ESC key
sys.exit()
def main():
glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowSize(600, 600)
glutInitWindowPosition(100, 100)
glutCreateWindow(b"PyOpenGL Triangle (ESC to exit)")
glClearColor(0.2, 0.2, 0.2, 1.0) # Dark gray background
glEnable(GL_DEPTH_TEST)
glutDisplayFunc(draw_triangle)
glutIdleFunc(draw_triangle) # Redraw continuously
glutReshapeFunc(reshape)
glutKeyboardFunc(keyboard)
glutMainLoop()
if __name__ == '__main__':
main()