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

array-operations.mddocs/

Array Operations

Unified array handling system providing seamless integration between OpenGL and various Python array types including NumPy arrays, Python lists, ctypes arrays, and buffer objects. Includes high-performance Vertex Buffer Object (VBO) support for modern graphics programming.

Capabilities

Vertex Buffer Objects (VBO)

High-performance buffer objects for storing vertex data in GPU memory with automatic memory management and context-aware binding.

class VBO:
    """
    Vertex Buffer Object wrapper providing high-performance vertex data storage.
    
    Usage:
        vbo = VBO(data)
        with vbo:
            glVertexPointer(3, GL_FLOAT, 0, vbo)
            glDrawArrays(GL_TRIANGLES, 0, len(data))
    """
    
    def __init__(self, data, usage=GL_STATIC_DRAW, target=GL_ARRAY_BUFFER):
        """
        Create VBO from array data.
        
        Parameters:
        - data: Array-like data (NumPy array, list, etc.)
        - usage: Buffer usage hint (GL_STATIC_DRAW, GL_DYNAMIC_DRAW, GL_STREAM_DRAW)
        - target: Buffer target (GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER)
        """
    
    def bind(self):
        """Bind VBO to its target."""
    
    def unbind(self):
        """Unbind VBO from its target."""
    
    def delete(self):
        """Delete VBO and free GPU memory."""
    
    def copy(self, array):
        """
        Copy data to VBO.
        
        Parameters:
        - array: New data to copy to buffer
        """
    
    def __enter__(self):
        """Context manager entry - binds VBO."""
        
    def __exit__(self, exc_type, exc_val, exc_tb):
        """Context manager exit - unbinds VBO."""
    
    def __add__(self, offset: int):
        """
        Create VBO offset for sub-arrays.
        
        Parameters:
        - offset: Byte offset into buffer
        
        Returns:
        VBOOffset object
        """
    
    @property
    def data(self):
        """Get original array data."""
    
    @property
    def size(self) -> int:
        """Get buffer size in bytes."""
    
    @property
    def target(self) -> int:
        """Get buffer target."""
    
    @property
    def usage(self) -> int:
        """Get buffer usage hint."""

class VBOOffset:
    """
    Represents an offset into a VBO for rendering sub-arrays.
    
    Usage:
        vertices = VBO(vertex_data)
        normals = vertices + 12  # Offset 12 bytes into buffer
        with vertices:
            glVertexPointer(3, GL_FLOAT, 24, vertices)
            glNormalPointer(GL_FLOAT, 24, normals)
    """
    
    def __init__(self, vbo: VBO, offset: int):
        """
        Create VBO offset.
        
        Parameters:
        - vbo: Parent VBO object
        - offset: Byte offset into buffer
        """

Array Format Handling

Automatic detection and conversion between different array formats with plugin architecture for extensibility.

class ArrayDatatype:
    """
    Base class for array format handlers providing unified interface
    to different array types (NumPy, ctypes, Python lists, etc.).
    """
    
    @classmethod
    def from_param(cls, value):
        """
        Convert value to appropriate array representation.
        
        Parameters:
        - value: Input data in any supported format
        
        Returns:
        Converted array data
        """
    
    @classmethod
    def dataPointer(cls, value):
        """
        Get memory pointer to array data.
        
        Parameters:
        - value: Array data
        
        Returns:
        Memory pointer suitable for OpenGL functions
        """
    
    @classmethod
    def arraySize(cls, value) -> int:
        """
        Get array size in bytes.
        
        Parameters:
        - value: Array data
        
        Returns:
        Size in bytes
        """
    
    @classmethod
    def arrayByteCount(cls, value) -> int:
        """Get total byte count of array."""
    
    @classmethod
    def unitSize(cls, value) -> int:
        """Get size of single array element in bytes."""
    
    @classmethod
    def dimensions(cls, value) -> tuple:
        """
        Get array dimensions.
        
        Returns:
        Tuple of dimension sizes
        """

def asArray(value, typeCode=None):
    """
    Convert value to array format suitable for OpenGL.
    
    Parameters:
    - value: Input data in any supported format
    - typeCode: Optional type specification
    
    Returns:
    Array in appropriate format for OpenGL operations
    """

NumPy Integration

Seamless NumPy array support with automatic type mapping and memory layout handling.

# NumPy arrays are automatically supported
import numpy as np

# Create vertex data
vertices = np.array([
    [0.0, 1.0, 0.0],
    [-1.0, -1.0, 0.0], 
    [1.0, -1.0, 0.0]
], dtype=np.float32)

# Use directly with OpenGL functions
glVertexPointer(3, GL_FLOAT, 0, vertices)

# Or with VBO for better performance
vbo = VBO(vertices)
with vbo:
    glVertexPointer(3, GL_FLOAT, 0, vbo)
    glDrawArrays(GL_TRIANGLES, 0, len(vertices))

Python List Support

Native Python list and tuple support with automatic conversion to appropriate OpenGL formats.

# Python lists work automatically
vertices = [
    [0.0, 1.0, 0.0],
    [-1.0, -1.0, 0.0],
    [1.0, -1.0, 0.0]
]

colors = [
    [1.0, 0.0, 0.0],  # Red
    [0.0, 1.0, 0.0],  # Green  
    [0.0, 0.0, 1.0]   # Blue
]

# Use directly with OpenGL
glVertexPointer(3, GL_FLOAT, 0, vertices)
glColorPointer(3, GL_FLOAT, 0, colors)

ctypes Integration

Direct ctypes array support for low-level control and C library integration.

import ctypes

# ctypes arrays
FloatArray = ctypes.c_float * 9
vertex_array = FloatArray(
    0.0, 1.0, 0.0,    # Vertex 1
    -1.0, -1.0, 0.0,  # Vertex 2  
    1.0, -1.0, 0.0    # Vertex 3
)

# Use with OpenGL functions
glVertexPointer(3, GL_FLOAT, 0, vertex_array)

Buffer Protocol Support

Support for Python buffer protocol objects including bytes, bytearray, and memoryview.

# Buffer objects supported
data = bytearray(36)  # 9 floats * 4 bytes each
buffer_view = memoryview(data)

# Can be used with OpenGL functions
glBufferData(GL_ARRAY_BUFFER, len(data), data, GL_STATIC_DRAW)

Memory Management

Automatic memory management with optional pointer storage for safety and performance control.

# Configuration flags affecting array handling
import OpenGL

# Prevent data copying (raises CopyError if copy would occur)
OpenGL.ERROR_ON_COPY = True

# Store array pointers to prevent garbage collection issues
OpenGL.STORE_POINTERS = True  # Default: True

# Enable/disable size checking
OpenGL.ARRAY_SIZE_CHECKING = True  # Default: True

VBO Utilities

Helper functions for VBO management and memory mapping.

def mapVBO(vbo: VBO, access=GL_READ_WRITE):
    """
    Map VBO memory for direct CPU access.
    
    Parameters:
    - vbo: VBO object to map
    - access: Access mode (GL_READ_ONLY, GL_WRITE_ONLY, GL_READ_WRITE)
    
    Returns:
    Memory pointer for direct access
    
    Usage:
        with vbo:
            ptr = mapVBO(vbo, GL_WRITE_ONLY)
            # Modify data through ptr
            glUnmapBuffer(vbo.target)
    """

class VBOHandler:
    """Format handler for VBO objects in the array system."""

Format Handler System

Plugin architecture for supporting additional array formats.

class FormatHandler:
    """
    Base class for array format plugins.
    Allows registration of handlers for custom array types.
    """
    
    def __init__(self, name: str, module: str, types: list, 
                 isOutput: bool = False):
        """
        Register format handler.
        
        Parameters:
        - name: Handler name
        - module: Python module containing handler
        - types: List of type names this handler supports
        - isOutput: Whether handler can produce output arrays
        """

# Pre-registered handlers
handlers = {
    'numpy': 'numpy.ndarray, numpy.core.memmap.memmap, numpy scalar types',
    'lists': 'list, tuple',
    'ctypes': 'ctypes arrays, parameters, pointers',
    'strings': 'str, bytes, unicode (Python 2)',
    'numbers': 'int, float, long (Python 2)',
    'buffers': 'buffer protocol objects (bytearray, memoryview)',
    'vbo': 'VBO, VBOOffset objects'
}

Usage Examples

Basic VBO Usage

import numpy as np
from OpenGL.GL import *
from OpenGL.arrays import vbo

# Create vertex data
vertices = np.array([
    [-1.0, -1.0, 0.0],
    [ 1.0, -1.0, 0.0],
    [ 0.0,  1.0, 0.0]
], dtype=np.float32)

# Create VBO
vertex_buffer = vbo.VBO(vertices)

# Use in render loop
with vertex_buffer:
    glEnableClientState(GL_VERTEX_ARRAY)
    glVertexPointer(3, GL_FLOAT, 0, vertex_buffer)
    glDrawArrays(GL_TRIANGLES, 0, 3)
    glDisableClientState(GL_VERTEX_ARRAY)

Interleaved Vertex Data

# Interleaved vertex and color data
# Format: [x, y, z, r, g, b, x, y, z, r, g, b, ...]
interleaved_data = np.array([
    # Vertex 1: position + color
    -1.0, -1.0, 0.0, 1.0, 0.0, 0.0,
    # Vertex 2: position + color  
     1.0, -1.0, 0.0, 0.0, 1.0, 0.0,
    # Vertex 3: position + color
     0.0,  1.0, 0.0, 0.0, 0.0, 1.0
], dtype=np.float32)

stride = 6 * 4  # 6 floats * 4 bytes per float
vertex_buffer = vbo.VBO(interleaved_data)

with vertex_buffer:
    glEnableClientState(GL_VERTEX_ARRAY)
    glEnableClientState(GL_COLOR_ARRAY)
    
    # Vertices start at offset 0
    glVertexPointer(3, GL_FLOAT, stride, vertex_buffer)
    
    # Colors start at offset 12 bytes (3 floats * 4 bytes)
    color_offset = vertex_buffer + 12
    glColorPointer(3, GL_FLOAT, stride, color_offset)
    
    glDrawArrays(GL_TRIANGLES, 0, 3)
    
    glDisableClientState(GL_COLOR_ARRAY)
    glDisableClientState(GL_VERTEX_ARRAY)

Dynamic Buffer Updates

# Create dynamic VBO
dynamic_data = np.zeros((100, 3), dtype=np.float32)
vertex_buffer = vbo.VBO(dynamic_data, usage=GL_DYNAMIC_DRAW)

# Update data each frame
def update_vertices(time):
    # Modify vertex positions based on time
    for i in range(100):
        dynamic_data[i] = [
            np.sin(time + i * 0.1),
            np.cos(time + i * 0.1), 
            0.0
        ]
    
    # Copy updated data to VBO
    vertex_buffer.copy(dynamic_data)

# In render loop
update_vertices(current_time)
with vertex_buffer:
    glVertexPointer(3, GL_FLOAT, 0, vertex_buffer)
    glDrawArrays(GL_POINTS, 0, 100)

Constants

VBO Usage Hints

GL_STATIC_DRAW: int   # Data rarely changes
GL_DYNAMIC_DRAW: int  # Data changes frequently  
GL_STREAM_DRAW: int   # Data changes every frame

VBO Targets

GL_ARRAY_BUFFER: int         # Vertex attribute data
GL_ELEMENT_ARRAY_BUFFER: int # Index data

Memory Access Modes

GL_READ_ONLY: int
GL_WRITE_ONLY: int
GL_READ_WRITE: 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