Matrix and Vector Math
Modern OpenGL depends on matrixes for projection, translation, and other things. To provide out-of-the-box functionality, pyglet’s math module includes the necessary Matrix and Vector types to cover most use cases:
pyglet.math.Vec2
pyglet.math.Vec3
pyglet.math.Vec4
pyglet.math.Mat3
pyglet.math.Mat4
These types support most common Matrix and Vector operations, including
rotating, scaling, and transforming. See the math
module
for full API documentation.
Note
For performance, Matrix types are subclasses of the tuple type. They are therefore immutable - all operations return a new object; they are not updated in-place.
Creating a Matrix
A Matrix can be created with no arguments, or by passing a tuple or list of float:
my_matrix = Mat4()
# or
my_matrix = Mat4([1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0])
If no arguments are given, an “identity” matrix will be created by default. (1.0 on the main diagonal).
Matrix Multiplication
Matrix classes in pyglet use the modern Python matmul (@) operator for matrix multiplication. The star operator (*) is not allowed. For example:
new_matrix = rotation_matrix @ translation_matrix
Helper Methods
A common operation in OpenGL is creating a 2D or 3D projection matrix. The Mat4 module includes a helper method for this task. The arguments should be similar to what you will find in popular OpenGL math libraries:
# Orthographic (2D) projection matrix:
projection = Mat4.orthogonal_projection(0, width, 0, height, z_near=-255, z_far=255)
# Perspective (3D) projection matrix:
projection = Mat4.perspective_projection(aspect_ratio, z_near=0.1, z_far=255)
For setting a 3D projection on the current OpenGL context, pyglet Windows have a projection property. For example:
my_matrix = Mat4.perspective_projection(aspect_ratio, z_near=0.1, z_far=255)
window.projection = my_matrix
By default, pyglet automatically sets a 2D projection whenever a Window is resized. If you plan to set your own 3D or 2D projection matrix, a useful pattern is to override the default on_resize event handler:
@window.event
def on_resize(width, height):
# window.viewport = (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 # Don't call the default handler