OpenGL Mathematics (GLM) library for Python providing comprehensive vector and matrix manipulation capabilities for graphics programming.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
High-level transformation matrix creation functions essential for 3D graphics programming. These functions create the standard projection, view, and model transformation matrices used in OpenGL, DirectX, and other graphics APIs.
Functions for creating projection matrices that transform 3D coordinates to screen coordinates.
def perspective(fovy, aspect, near, far):
"""
Create a perspective projection matrix.
Args:
fovy: Field of view angle in radians (vertical)
aspect: Aspect ratio (width/height)
near: Near clipping plane distance (must be positive)
far: Far clipping plane distance (must be positive)
Returns:
4×4 perspective projection matrix
Example:
proj = glm.perspective(glm.radians(45.0), 16.0/9.0, 0.1, 100.0)
"""
def perspectiveFov(fov, width, height, near, far):
"""
Create a perspective projection matrix using field of view.
Args:
fov: Field of view angle in radians
width: Viewport width
height: Viewport height
near: Near clipping plane distance
far: Far clipping plane distance
Returns:
4×4 perspective projection matrix
"""
def ortho(left, right, bottom, top, near, far):
"""
Create an orthographic projection matrix.
Args:
left: Left clipping plane
right: Right clipping plane
bottom: Bottom clipping plane
top: Top clipping plane
near: Near clipping plane
far: Far clipping plane
Returns:
4×4 orthographic projection matrix
Example:
ortho_proj = glm.ortho(-10.0, 10.0, -10.0, 10.0, -1.0, 1.0)
"""
def frustum(left, right, bottom, top, near, far):
"""
Create a frustum projection matrix.
Args:
left: Left clipping plane at near
right: Right clipping plane at near
bottom: Bottom clipping plane at near
top: Top clipping plane at near
near: Near clipping plane distance
far: Far clipping plane distance
Returns:
4×4 frustum projection matrix
"""
def infinitePerspective(fovy, aspect, near):
"""
Create an infinite perspective projection matrix.
Args:
fovy: Field of view angle in radians
aspect: Aspect ratio (width/height)
near: Near clipping plane distance
Returns:
4×4 infinite perspective projection matrix (no far plane)
"""Functions for creating view matrices that position and orient the camera in 3D space.
def lookAt(eye, center, up):
"""
Create a view matrix for a camera looking at a target.
Args:
eye: Camera position (vec3)
center: Target position to look at (vec3)
up: Up direction vector (vec3, typically (0,1,0))
Returns:
4×4 view matrix that transforms world coordinates to camera space
Example:
view = glm.lookAt(glm.vec3(0,0,3), glm.vec3(0,0,0), glm.vec3(0,1,0))
"""
def lookAtRH(eye, center, up):
"""
Create a right-handed view matrix.
Args:
eye: Camera position (vec3)
center: Target position to look at (vec3)
up: Up direction vector (vec3)
Returns:
4×4 right-handed view matrix
"""
def lookAtLH(eye, center, up):
"""
Create a left-handed view matrix.
Args:
eye: Camera position (vec3)
center: Target position to look at (vec3)
up: Up direction vector (vec3)
Returns:
4×4 left-handed view matrix
"""Functions for creating model transformation matrices that position, rotate, and scale objects in 3D space.
def translate(m, v):
"""
Create or apply a translation transformation.
Args:
m: Input matrix (typically mat4)
v: Translation vector (vec3)
Returns:
Matrix with translation applied
Example:
# Translate by (1, 2, 3)
translated = glm.translate(glm.mat4(), glm.vec3(1, 2, 3))
"""
def rotate(m, angle, axis):
"""
Create or apply a rotation transformation.
Args:
m: Input matrix (typically mat4)
angle: Rotation angle in radians
axis: Rotation axis vector (vec3, should be normalized)
Returns:
Matrix with rotation applied
Example:
# Rotate 45 degrees around Z axis
rotated = glm.rotate(glm.mat4(), glm.radians(45), glm.vec3(0,0,1))
"""
def rotateX(m, angle):
"""
Create or apply a rotation around the X-axis.
Args:
m: Input matrix (typically mat4)
angle: Rotation angle in radians
Returns:
Matrix with X-axis rotation applied
Example:
rotated = glm.rotateX(glm.mat4(), glm.radians(90))
"""
def rotateY(m, angle):
"""
Create or apply a rotation around the Y-axis.
Args:
m: Input matrix (typically mat4)
angle: Rotation angle in radians
Returns:
Matrix with Y-axis rotation applied
Example:
rotated = glm.rotateY(glm.mat4(), glm.radians(45))
"""
def rotateZ(m, angle):
"""
Create or apply a rotation around the Z-axis.
Args:
m: Input matrix (typically mat4)
angle: Rotation angle in radians
Returns:
Matrix with Z-axis rotation applied
Example:
rotated = glm.rotateZ(glm.mat4(), glm.radians(180))
"""
def scale(m, v):
"""
Create or apply a scaling transformation.
Args:
m: Input matrix (typically mat4)
v: Scaling factors (vec3)
Returns:
Matrix with scaling applied
Example:
# Scale by 2x in all directions
scaled = glm.scale(glm.mat4(), glm.vec3(2, 2, 2))
"""Additional transformation functions for specific graphics applications.
def shearX(m, y, z):
"""
Apply shear transformation along X axis.
Args:
m: Input matrix
y: Shear factor for Y component
z: Shear factor for Z component
Returns:
Matrix with X-axis shear applied
"""
def shearY(m, x, z):
"""
Apply shear transformation along Y axis.
Args:
m: Input matrix
x: Shear factor for X component
z: Shear factor for Z component
Returns:
Matrix with Y-axis shear applied
"""
def shearZ(m, x, y):
"""
Apply shear transformation along Z axis.
Args:
m: Input matrix
x: Shear factor for X component
y: Shear factor for Y component
Returns:
Matrix with Z-axis shear applied
"""PyGLM provides variants for different coordinate systems and clipping conventions.
# Left-handed vs Right-handed coordinate systems
def perspectiveLH(fovy, aspect, near, far): ... # Left-handed perspective
def perspectiveRH(fovy, aspect, near, far): ... # Right-handed perspective
def orthoLH(left, right, bottom, top, near, far): ... # Left-handed orthographic
def orthoRH(left, right, bottom, top, near, far): ... # Right-handed orthographic
# Zero-to-one vs Negative-one-to-one depth range
def perspectiveZO(fovy, aspect, near, far): ... # Zero to one depth
def perspectiveNO(fovy, aspect, near, far): ... # Negative one to one depth
def orthoZO(left, right, bottom, top, near, far): ... # Zero to one depth
def orthoNO(left, right, bottom, top, near, far): ... # Negative one to one depth
# Combined variants (e.g., left-handed with zero-to-one depth)
def perspectiveLH_ZO(fovy, aspect, near, far): ...
def perspectiveLH_NO(fovy, aspect, near, far): ...
def perspectiveRH_ZO(fovy, aspect, near, far): ...
def perspectiveRH_NO(fovy, aspect, near, far): ...from pyglm import glm
import math
# === Projection Matrix Examples ===
# Perspective projection for 3D scene
fov = glm.radians(45.0) # 45 degree field of view
aspect_ratio = 1920.0 / 1080.0 # 16:9 aspect ratio
near_plane = 0.1
far_plane = 100.0
perspective_matrix = glm.perspective(fov, aspect_ratio, near_plane, far_plane)
# Orthographic projection for 2D UI or technical drawings
ortho_matrix = glm.ortho(-10.0, 10.0, -10.0, 10.0, -1.0, 1.0)
# === View Matrix Examples ===
# First-person camera
camera_pos = glm.vec3(0.0, 2.0, 5.0)
target_pos = glm.vec3(0.0, 0.0, 0.0)
up_vector = glm.vec3(0.0, 1.0, 0.0)
view_matrix = glm.lookAt(camera_pos, target_pos, up_vector)
# Orbiting camera (rotating around target)
angle = math.radians(45) # Python's math.radians
radius = 10.0
orbit_x = radius * math.cos(angle)
orbit_z = radius * math.sin(angle)
orbit_pos = glm.vec3(orbit_x, 5.0, orbit_z)
orbit_view = glm.lookAt(orbit_pos, glm.vec3(0, 0, 0), glm.vec3(0, 1, 0))
# === Model Transformation Examples ===
# Simple object transformation
model_matrix = glm.mat4() # Start with identity
# Apply transformations in order: Scale -> Rotate -> Translate
model_matrix = glm.scale(model_matrix, glm.vec3(2.0, 2.0, 2.0)) # Scale 2x
model_matrix = glm.rotate(model_matrix, glm.radians(45), glm.vec3(0, 1, 0)) # Rotate around Y
model_matrix = glm.translate(model_matrix, glm.vec3(5, 0, 0)) # Move right
# Complex transformation chain
transform = glm.mat4()
transform = glm.translate(transform, glm.vec3(1, 2, 3)) # Position
transform = glm.rotate(transform, glm.radians(30), glm.vec3(1, 0, 0)) # Pitch
transform = glm.rotate(transform, glm.radians(45), glm.vec3(0, 1, 0)) # Yaw
transform = glm.rotate(transform, glm.radians(60), glm.vec3(0, 0, 1)) # Roll
transform = glm.scale(transform, glm.vec3(0.5, 2.0, 1.0)) # Non-uniform scale
# === Complete Graphics Pipeline ===
# Model-View-Projection matrix for rendering
model = glm.mat4()
model = glm.translate(model, glm.vec3(0, 0, -5))
model = glm.rotate(model, glm.radians(45), glm.vec3(1, 1, 0))
view = glm.lookAt(
glm.vec3(0, 0, 3), # Camera position
glm.vec3(0, 0, 0), # Look at origin
glm.vec3(0, 1, 0) # Up vector
)
projection = glm.perspective(
glm.radians(45.0), # FOV
16.0/9.0, # Aspect ratio
0.1, # Near plane
100.0 # Far plane
)
# Combined transformation (applied right to left: Model -> View -> Projection)
mvp_matrix = projection * view * model
# Transform vertex positions
vertex_position = glm.vec4(1.0, 1.0, 1.0, 1.0) # Homogeneous coordinates
transformed_vertex = mvp_matrix * vertex_position
# === Coordinate System Specific Examples ===
# OpenGL (right-handed, -1 to 1 depth)
opengl_proj = glm.perspectiveRH_NO(glm.radians(45), 16.0/9.0, 0.1, 100.0)
# DirectX (left-handed, 0 to 1 depth)
directx_proj = glm.perspectiveLH_ZO(glm.radians(45), 16.0/9.0, 0.1, 100.0)
# Vulkan (right-handed, 0 to 1 depth)
vulkan_proj = glm.perspectiveRH_ZO(glm.radians(45), 16.0/9.0, 0.1, 100.0)Important: Matrix transformations are applied in reverse order of multiplication:
# This code:
result = glm.translate(glm.mat4(), glm.vec3(5, 0, 0))
result = glm.rotate(result, glm.radians(45), glm.vec3(0, 1, 0))
result = glm.scale(result, glm.vec3(2, 2, 2))
# Applies transformations in the order: Scale -> Rotate -> Translate
# (The last transformation applied is the first to affect the vertex)For predictable results, build transformation matrices step by step and be mindful of the order of operations based on your intended transformation sequence.
Install with Tessl CLI
npx tessl i tessl/pypi-pyglm