CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pyopengl

Comprehensive ctypes-based OpenGL binding for Python providing access to OpenGL, GLU, and GLUT functionality

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

shaders.mddocs/

Shaders

Modern OpenGL shader support providing utilities for compiling, linking, and managing vertex and fragment shaders. Includes error handling, uniform management, and integration with PyOpenGL's array system for high-performance graphics programming.

Capabilities

Shader Compilation

High-level utilities for compiling GLSL shader source code with comprehensive error reporting.

def compileShader(source: str, shaderType) -> int:
    """
    Compile GLSL shader source code.
    
    Parameters:
    - source: GLSL shader source code string
    - shaderType: Shader type (GL_VERTEX_SHADER, GL_FRAGMENT_SHADER, etc.)
    
    Returns:
    Compiled shader object identifier
    
    Raises:
    ShaderCompilationError: If compilation fails with error details
    """

def compileProgram(*shaders) -> int:
    """
    Link compiled shaders into a shader program.
    
    Parameters:
    - shaders: Variable number of compiled shader objects
    
    Returns:
    Linked shader program identifier
    
    Raises:
    ShaderLinkError: If linking fails with error details
    """

class ShaderCompilationError(Exception):
    """
    Exception raised when shader compilation fails.
    Contains detailed error information from GLSL compiler.
    """
    
    def __init__(self, message: str, shader_type: int, source: str):
        """
        Parameters:
        - message: Compiler error message
        - shader_type: Type of shader that failed
        - source: Original shader source code
        """

class ShaderLinkError(Exception):
    """
    Exception raised when shader program linking fails.
    Contains detailed error information from GLSL linker.
    """

Shader Program Management

Functions for using and managing shader programs with uniform variable support.

def glUseProgram(program: int):
    """
    Install shader program as part of rendering state.
    
    Parameters:
    - program: Shader program identifier, or 0 to use fixed-function pipeline
    """

def glDeleteShader(shader: int):
    """
    Delete shader object.
    
    Parameters:
    - shader: Shader object identifier
    """

def glDeleteProgram(program: int):
    """
    Delete shader program.
    
    Parameters:
    - program: Shader program identifier
    """

def glGetProgramiv(program: int, pname: int) -> int:
    """
    Get shader program parameter.
    
    Parameters:
    - program: Shader program identifier
    - pname: Parameter name (GL_LINK_STATUS, GL_ACTIVE_UNIFORMS, etc.)
    
    Returns:
    Parameter value
    """

def glGetShaderiv(shader: int, pname: int) -> int:
    """
    Get shader object parameter.
    
    Parameters:
    - shader: Shader object identifier
    - pname: Parameter name (GL_COMPILE_STATUS, GL_SHADER_TYPE, etc.)
    
    Returns:
    Parameter value
    """

def glGetProgramInfoLog(program: int) -> str:
    """
    Get shader program information log.
    
    Parameters:
    - program: Shader program identifier
    
    Returns:
    Information log string (linking errors, warnings, etc.)
    """

def glGetShaderInfoLog(shader: int) -> str:
    """
    Get shader object information log.
    
    Parameters:
    - shader: Shader object identifier
    
    Returns:
    Information log string (compilation errors, warnings, etc.)
    """

Uniform Variables

Uniform variable location and value management for passing data to shaders.

def glGetUniformLocation(program: int, name: str) -> int:
    """
    Get uniform variable location.
    
    Parameters:
    - program: Shader program identifier
    - name: Uniform variable name in shader
    
    Returns:
    Uniform location identifier, or -1 if not found
    """

# Scalar uniform functions
def glUniform1f(location: int, v0: float):
    """Set single float uniform value."""

def glUniform2f(location: int, v0: float, v1: float):
    """Set 2-component float uniform value."""

def glUniform3f(location: int, v0: float, v1: float, v2: float):
    """Set 3-component float uniform value."""

def glUniform4f(location: int, v0: float, v1: float, v2: float, v3: float):
    """Set 4-component float uniform value."""

def glUniform1i(location: int, v0: int):
    """Set single integer uniform value."""

def glUniform2i(location: int, v0: int, v1: int):
    """Set 2-component integer uniform value."""

def glUniform3i(location: int, v0: int, v1: int, v2: int):
    """Set 3-component integer uniform value."""

def glUniform4i(location: int, v0: int, v1: int, v2: int, v3: int):
    """Set 4-component integer uniform value."""

# Array uniform functions
def glUniform1fv(location: int, count: int, value: list):
    """
    Set array of float uniform values.
    
    Parameters:
    - location: Uniform location
    - count: Number of elements to modify
    - value: Array of float values
    """

def glUniform2fv(location: int, count: int, value: list):
    """Set array of 2-component float uniform values."""

def glUniform3fv(location: int, count: int, value: list):
    """Set array of 3-component float uniform values."""

def glUniform4fv(location: int, count: int, value: list):
    """Set array of 4-component float uniform values."""

def glUniform1iv(location: int, count: int, value: list):
    """Set array of integer uniform values."""

def glUniform2iv(location: int, count: int, value: list):
    """Set array of 2-component integer uniform values."""

def glUniform3iv(location: int, count: int, value: list):
    """Set array of 3-component integer uniform values."""

def glUniform4iv(location: int, count: int, value: list):
    """Set array of 4-component integer uniform values."""

# Matrix uniform functions
def glUniformMatrix2fv(location: int, count: int, transpose: bool, value: list):
    """
    Set 2x2 matrix uniform values.
    
    Parameters:
    - location: Uniform location
    - count: Number of matrices to modify
    - transpose: Whether to transpose matrices
    - value: Matrix values in column-major order
    """

def glUniformMatrix3fv(location: int, count: int, transpose: bool, value: list):
    """Set 3x3 matrix uniform values."""

def glUniformMatrix4fv(location: int, count: int, transpose: bool, value: list):
    """Set 4x4 matrix uniform values."""

Vertex Attributes

Vertex attribute management for modern shader-based rendering.

def glGetAttribLocation(program: int, name: str) -> int:
    """
    Get vertex attribute location.
    
    Parameters:
    - program: Shader program identifier
    - name: Attribute variable name in shader
    
    Returns:
    Attribute location identifier, or -1 if not found
    """

def glVertexAttribPointer(index: int, size: int, type: int, normalized: bool,
                         stride: int, pointer):
    """
    Define vertex attribute array.
    
    Parameters:
    - index: Attribute location
    - size: Components per attribute (1, 2, 3, or 4)
    - type: Data type (GL_FLOAT, GL_INT, etc.)
    - normalized: Whether to normalize integer values
    - stride: Byte offset between attributes
    - pointer: Array data or buffer offset
    """

def glEnableVertexAttribArray(index: int):
    """
    Enable vertex attribute array.
    
    Parameters:
    - index: Attribute location to enable
    """

def glDisableVertexAttribArray(index: int):
    """
    Disable vertex attribute array.
    
    Parameters:
    - index: Attribute location to disable
    """

def glVertexAttrib1f(index: int, x: float):
    """Set single-component vertex attribute value."""

def glVertexAttrib2f(index: int, x: float, y: float):
    """Set 2-component vertex attribute value."""

def glVertexAttrib3f(index: int, x: float, y: float, z: float):
    """Set 3-component vertex attribute value."""

def glVertexAttrib4f(index: int, x: float, y: float, z: float, w: float):
    """Set 4-component vertex attribute value."""

Shader Information Query

Functions for querying shader and program properties.

def glGetActiveUniform(program: int, index: int) -> tuple:
    """
    Get information about active uniform variable.
    
    Parameters:
    - program: Shader program identifier
    - index: Uniform index (0 to GL_ACTIVE_UNIFORMS-1)
    
    Returns:
    Tuple of (size, type, name) where:
    - size: Array size (1 for non-arrays)
    - type: Variable type (GL_FLOAT, GL_FLOAT_VEC3, etc.)
    - name: Variable name string
    """

def glGetActiveAttrib(program: int, index: int) -> tuple:
    """
    Get information about active vertex attribute.
    
    Parameters:
    - program: Shader program identifier
    - index: Attribute index (0 to GL_ACTIVE_ATTRIBUTES-1)
    
    Returns:
    Tuple of (size, type, name)
    """

def glGetShaderSource(shader: int) -> str:
    """
    Get shader source code.
    
    Parameters:
    - shader: Shader object identifier
    
    Returns:
    Shader source code string
    """

Usage Examples

Basic Vertex and Fragment Shader

from OpenGL.GL import *
from OpenGL.GL import shaders
import numpy as np

# Vertex shader source
vertex_shader_source = """
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;

out vec3 vertexColor;
uniform mat4 transform;

void main() {
    gl_Position = transform * vec4(aPos, 1.0);
    vertexColor = aColor;
}
"""

# Fragment shader source
fragment_shader_source = """
#version 330 core
in vec3 vertexColor;
out vec4 FragColor;

uniform float alpha;

void main() {
    FragColor = vec4(vertexColor, alpha);
}
"""

try:
    # Compile shaders
    vertex_shader = shaders.compileShader(vertex_shader_source, GL_VERTEX_SHADER)
    fragment_shader = shaders.compileShader(fragment_shader_source, GL_FRAGMENT_SHADER)
    
    # Link program
    shader_program = shaders.compileProgram(vertex_shader, fragment_shader)
    
    # Clean up shader objects (no longer needed after linking)
    glDeleteShader(vertex_shader)
    glDeleteShader(fragment_shader)
    
except shaders.ShaderCompilationError as e:
    print(f"Shader compilation failed: {e}")
except shaders.ShaderLinkError as e:
    print(f"Shader linking failed: {e}")

# Get uniform locations
transform_loc = glGetUniformLocation(shader_program, "transform")
alpha_loc = glGetUniformLocation(shader_program, "alpha")

# Use shader program
glUseProgram(shader_program)

# Set uniform values
transform_matrix = np.eye(4, dtype=np.float32)
glUniformMatrix4fv(transform_loc, 1, GL_FALSE, transform_matrix)
glUniform1f(alpha_loc, 1.0)

Vertex Attribute Setup

# Vertex data with positions and colors
vertices = np.array([
    # Positions      # Colors
    -0.5, -0.5, 0.0,  1.0, 0.0, 0.0,  # Bottom left, red
     0.5, -0.5, 0.0,  0.0, 1.0, 0.0,  # Bottom right, green
     0.0,  0.5, 0.0,  0.0, 0.0, 1.0   # Top center, blue
], dtype=np.float32)

from OpenGL.arrays import vbo

# Create VBO
vertex_buffer = vbo.VBO(vertices)

# Setup vertex attributes
with vertex_buffer:
    # Position attribute (location 0)
    glEnableVertexAttribArray(0)
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * 4, vertex_buffer)
    
    # Color attribute (location 1)  
    glEnableVertexAttribArray(1)
    color_offset = vertex_buffer + 12  # Offset 3 floats * 4 bytes
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * 4, color_offset)
    
    # Draw triangle
    glDrawArrays(GL_TRIANGLES, 0, 3)
    
    # Cleanup
    glDisableVertexAttribArray(0)
    glDisableVertexAttribArray(1)

Animated Uniforms

import math
import time

# Animation loop
start_time = time.time()

def render_frame():
    current_time = time.time() - start_time
    
    # Animated rotation matrix
    angle = current_time * 2.0  # 2 radians per second
    cos_a = math.cos(angle)
    sin_a = math.sin(angle)
    
    rotation_matrix = np.array([
        [cos_a, -sin_a, 0.0, 0.0],
        [sin_a,  cos_a, 0.0, 0.0],
        [0.0,    0.0,   1.0, 0.0],
        [0.0,    0.0,   0.0, 1.0]
    ], dtype=np.float32)
    
    # Update uniform
    glUseProgram(shader_program)
    glUniformMatrix4fv(transform_loc, 1, GL_FALSE, rotation_matrix)
    
    # Animated alpha
    alpha = (math.sin(current_time * 3.0) + 1.0) * 0.5  # 0.0 to 1.0
    glUniform1f(alpha_loc, alpha)
    
    # Render geometry
    render_triangle()

Error Handling

def safe_compile_shader(source, shader_type):
    try:
        return shaders.compileShader(source, shader_type)
    except shaders.ShaderCompilationError as e:
        print(f"Compilation Error in {shader_type}:")
        print(f"Error: {e}")
        print("Source code:")
        for i, line in enumerate(source.split('\n'), 1):
            print(f"{i:3}: {line}")
        return None

def safe_link_program(*shader_objects):
    try:
        return shaders.compileProgram(*shader_objects)
    except shaders.ShaderLinkError as e:
        print(f"Linking Error: {e}")
        return None

Constants

Shader Types

GL_VERTEX_SHADER: int
GL_FRAGMENT_SHADER: int
GL_GEOMETRY_SHADER: int         # OpenGL 3.2+
GL_TESS_CONTROL_SHADER: int     # OpenGL 4.0+
GL_TESS_EVALUATION_SHADER: int  # OpenGL 4.0+
GL_COMPUTE_SHADER: int          # OpenGL 4.3+

Shader Parameters

GL_COMPILE_STATUS: int
GL_DELETE_STATUS: int
GL_INFO_LOG_LENGTH: int
GL_SHADER_SOURCE_LENGTH: int
GL_SHADER_TYPE: int

Program Parameters

GL_LINK_STATUS: int
GL_VALIDATE_STATUS: int
GL_ACTIVE_UNIFORMS: int
GL_ACTIVE_ATTRIBUTES: int
GL_ACTIVE_UNIFORM_MAX_LENGTH: int
GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: int

Uniform Types

GL_FLOAT: int
GL_FLOAT_VEC2: int
GL_FLOAT_VEC3: int
GL_FLOAT_VEC4: int
GL_INT: int
GL_INT_VEC2: int
GL_INT_VEC3: int
GL_INT_VEC4: int
GL_BOOL: int
GL_BOOL_VEC2: int
GL_BOOL_VEC3: int
GL_BOOL_VEC4: int
GL_FLOAT_MAT2: int
GL_FLOAT_MAT3: int
GL_FLOAT_MAT4: int
GL_SAMPLER_2D: int
GL_SAMPLER_CUBE: int

Install with Tessl CLI

npx tessl i tessl/pypi-pyopengl

docs

array-operations.md

core-opengl.md

error-handling.md

glu-utilities.md

glut-window.md

index.md

platform-support.md

shaders.md

tile.json