opengl.py

lunaengine/backend/opengl.py

OpenGL-based hardware-accelerated renderer for LunaEngine
- GPU-accelerated particles via instancing (CPU physics)
- Full filter system (post-processing)
- 2D drawing primitives (lines, circles, polygons, etc.)
- Rounded rectangles with per-corner radii
- Texture and surface rendering

This version uses the reliable CPU particle system and only uses OpenGL
for rendering - no compute shaders, no GPU physics.

Shader files are now loaded from lunaengine/assets/shaders/ by default.
Users can add custom shader search paths via set_shader_folder().

class FilterType

Description

No documentation

Attributes
NONE: Any = 'none'
VIGNETTE: Any = 'vignette'
BLUR: Any = 'blur'
SEPIA: Any = 'sepia'
GRAYSCALE: Any = 'grayscale'
INVERT: Any = 'invert'
TEMPERATURE_WARM: Any = 'temperature_warm'
TEMPERATURE_COLD: Any = 'temperature_cold'
NIGHT_VISION: Any = 'night_vision'
CRT: Any = 'crt'
PIXELATE: Any = 'pixelate'
BLOOM: Any = 'bloom'
EDGE_DETECT: Any = 'edge_detect'
EMBOSS: Any = 'emboss'
SHARPEN: Any = 'sharpen'
POSTERIZE: Any = 'posterize'
NEON: Any = 'neon'
RADIAL_BLUR: Any = 'radial_blur'
FISHEYE: Any = 'fisheye'
TWIRL: Any = 'twirl'
Methods

No methods defined.

class FilterRegionType

Description

No documentation

Attributes
FULLSCREEN: Any = 'fullscreen'
RECTANGLE: Any = 'rectangle'
CIRCLE: Any = 'circle'
Methods

No methods defined.

class Filter

Description

No documentation

Methods
def __init__(self: Any, filter_type: FilterType = FilterType.NONE, intensity: float = 1.0, region_type: FilterRegionType = FilterRegionType.FULLSCREEN, region_pos: Tuple[float, float] = (0, 0), region_size: Tuple[float, float] = (100, 100), radius: float = 50.0, feather: float = 10.0, blend_mode: str = 'normal') -> Any
No documentation
def update(self: Any, dt: float) -> None
No documentation
def copy(self: Any) -> Filter
No documentation

class ShaderProgram

Description

No documentation

Methods
def __init__(self: Any, shader_name: str, has_geometry: bool = False) -> Any
No documentation
def _load_source(self: Any, stage: str) -> Optional[str]
No documentation
def _get_uniform_location(self: Any, name: str) -> int
No documentation
def _create_program(self: Any, vertex_source: str, fragment_source: str, geometry_source: Optional[str] = None) -> None
No documentation
def use(self: Any) -> None
No documentation
def unuse(self: Any) -> None
No documentation
def _setup_geometry(self: Any) -> None
No documentation

class ParticleShader

Description

No documentation

Methods
def __init__(self: Any) -> Any
No documentation
def _setup_geometry(self: Any) -> None
No documentation

class SimpleShader

Description

No documentation

Methods
def __init__(self: Any) -> Any
No documentation
def _setup_geometry(self: Any) -> None
No documentation

class TextureShader

Description

No documentation

Methods
def __init__(self: Any) -> Any
No documentation
def _setup_geometry(self: Any) -> None
No documentation

class RoundedRectShader

Description

No documentation

Methods
def __init__(self: Any) -> Any
No documentation
def _setup_geometry(self: Any) -> None
No documentation

class FilterShader

Description

No documentation

Methods
def __init__(self: Any) -> Any
No documentation
def _setup_geometry(self: Any) -> None
No documentation

class MaskShader

Description

No documentation

Methods
def __init__(self: Any) -> Any
No documentation
def _setup_geometry(self: Any) -> None
No documentation

class DepthShader

Description

No documentation

Methods
def __init__(self: Any) -> Any
No documentation
def _setup_geometry(self: Any) -> None
No documentation

class OpenGLRenderer

Description

No documentation

Attributes
camera_position: Any = pygame.math.Vector2(0, 0)
Methods
def __init__(self: Any, width: int, height: int) -> Any
No documentation
def get_opengl_version(self: Any) -> str
No documentation
def set_text_cache_timeout(self: Any, seconds: float) -> None
No documentation
def get_cache_usage(self: Any, target: str = 'all', humanize: bool = False) -> Any
No documentation
def max_particles(self: Any) -> int
No documentation
def max_particles(self: Any, value: int) -> None
No documentation
def initialize(self: Any) -> bool
No documentation
def _initialize_filter_framebuffer(self: Any) -> bool
No documentation
def add_filter(self: Any, filter_obj: Filter) -> None
No documentation
def remove_filter(self: Any, filter_obj: Filter) -> None
No documentation
def clear_filters(self: Any) -> None
No documentation
def create_quick_filter(self: Any, filter_type: FilterType, intensity: float = 1.0, x: float = 0, y: float = 0, width: float = None, height: float = None, radius: float = 50.0, feather: float = 10.0) -> Filter
No documentation
def apply_vignette(self: Any, intensity: float = 0.7, feather: float = 100.0) -> Filter
No documentation
def apply_blur(self: Any, intensity: float = 0.5, x: float = 0, y: float = 0, width: float = None, height: float = None) -> Filter
No documentation
def apply_sepia(self: Any, intensity: float = 1.0) -> Filter
No documentation
def apply_grayscale(self: Any, intensity: float = 1.0) -> Filter
No documentation
def apply_invert(self: Any, intensity: float = 1.0) -> Filter
No documentation
def apply_warm_temperature(self: Any, intensity: float = 0.5) -> Filter
No documentation
def apply_cold_temperature(self: Any, intensity: float = 0.5) -> Filter
No documentation
def apply_night_vision(self: Any, intensity: float = 0.9) -> Filter
No documentation
def apply_crt_effect(self: Any, intensity: float = 0.8) -> Filter
No documentation
def apply_pixelate(self: Any, intensity: float = 0.7) -> Filter
No documentation
def apply_bloom(self: Any, intensity: float = 0.5) -> Filter
No documentation
def apply_edge_detect(self: Any, intensity: float = 0.8) -> Filter
No documentation
def apply_emboss(self: Any, intensity: float = 0.7) -> Filter
No documentation
def apply_sharpen(self: Any, intensity: float = 0.5) -> Filter
No documentation
def apply_posterize(self: Any, intensity: float = 0.6) -> Filter
No documentation
def apply_neon(self: Any, intensity: float = 0.7) -> Filter
No documentation
def apply_radial_blur(self: Any, intensity: float = 0.5) -> Filter
No documentation
def apply_fisheye(self: Any, intensity: float = 0.4) -> Filter
No documentation
def apply_twirl(self: Any, intensity: float = 0.3) -> Filter
No documentation
def apply_circular_grayscale(self: Any, center_x: float, center_y: float, radius: float = 100.0, intensity: float = 1.0) -> Filter
No documentation
def apply_rectangular_blur(self: Any, x: float, y: float, width: float, height: float, intensity: float = 0.5) -> Filter
No documentation
def begin_frame(self: Any) -> None
No documentation
def end_frame(self: Any) -> None
No documentation
def apply_filter_to_texture(self: Any, tex_id: int, width: int, height: int, filter_type: FilterType, intensity: float = 1.0) -> int
Render the texture through the filter shader and produce a new filtered texture.

Args:
   tex_id: OpenGL texture ID of the source image.
   width, height: Dimensions of the texture (must match the texture).
   filter_type: The filter to apply (e.g., FilterType.BLUR).
   intensity: Filter intensity (0.0–1.0).

Returns:
   int: New texture ID with the filter applied. Caller must delete it when done.
def _apply_filters(self: Any) -> None
No documentation
def get_surface(self: Any) -> pygame.Surface
No documentation
def set_surface(self: Any, surface: Optional[pygame.Surface]) -> None
No documentation
def capture_to_surface(self: Any, draw_callback: Callable[[], None]) -> pygame.Surface
Render once into an off-screen framebuffer and return a pygame surface.

OpenGL rendering cannot populate a ``pygame.Surface`` directly. The old
transition prototype attached a texture to an FBO but then read the
untouched pygame surface, which produced blank captures. This helper
owns the FBO, reads its pixels back, and restores the caller's target.
def _surface_to_texture(self: Any, surface: pygame.Surface) -> int
No documentation
def _surface_to_texture_cached(self: Any, surface: pygame.Surface, rect: Optional[pygame.Rect] = None, dest: Optional[pygame.Rect] = None, flags: int = 0) -> int
No documentation
def _convert_color(self: Any, color: Any) -> Any
No documentation
def _read_texture_pixel(self: Any, tex_id: int, x: int = 0, y: int = 0) -> Tuple[int, int, int, int]
No documentation
def enable_scissor(self: Any, x: Any, y: Any, width: Any, height: Any) -> Any
No documentation
def disable_scissor(self: Any) -> Any
No documentation
def draw_rect(self: Any, x: Union[int, float], y: Union[int, float], width: Union[int, float], height: Union[int, float], color: Any = None, fill: Any = True, pivot: Any = (0.0, 0.0), border_width: Union[int, float] = 1, surface: Any = None, corner_radius: Union[int, float, Tuple[int | float, int | float, int | float, int | float]] = 0, border_color: Any = None, style: Optional[Dict[str, Any]] = None) -> Any
No documentation
def _draw_rect_fast(self: Any, x: Any, y: Any, width: Any, height: Any, color: Any, fill: Any = True, border_width: Any = 1, corner_radius: Any = 0, border_color: Any = None) -> Any
No documentation
def _draw_outline_rect(self: Any, x: Any, y: Any, width: Any, height: Any, color: Any, border_width: Any, radii: Any) -> Any
No documentation
def _draw_sharp_rect(self: Any, x: Any, y: Any, width: Any, height: Any, color: Any, fill: Any = True, border_width: Any = 1) -> Any
No documentation
def _draw_rounded_rect(self: Any, x: Any, y: Any, w: Any, h: Any, color: Any, fill: Any = True, border_width: Any = 1, radii: Any = (0, 0, 0, 0)) -> Any
No documentation
def draw_isosceles_triangle(self: Any, x: Union[int, float], y: Union[int, float], width: Union[int, float], height: Union[int, float], color: Any = None, fill: Any = True, border_width: Any = 1, border_color: Any = None, surface: Any = None, pivot: Any = (0.0, 0.0), style: Any = None) -> Any
No documentation
def draw_equilateral_triangle(self: Any, x: Union[int, float], y: Union[int, float], side_length: Union[int, float], color: Any = None, fill: Any = True, border_width: Any = 1, border_color: Any = None, surface: Any = None, pivot: Any = (0.0, 0.0), style: Any = None) -> Any
No documentation
def draw_line(self: Any, start_x: Any, start_y: Any, end_x: Any, end_y: Any, color: Any, width: Any = 2, surface: Any = None) -> Any
No documentation
def _draw_thick_line(self: Any, x1: Any, y1: Any, x2: Any, y2: Any, color: Any, width: Any) -> Any
No documentation
def draw_lines(self: Any, points: Any, color: Any, width: Any = 2, surface: Any = None) -> Any
No documentation
def draw_circle(self: Any, center_x: Any, center_y: Any, radius: Any, color: Any = None, fill: Any = True, border_width: Any = 1, surface: Any = None, pivot: Any = (0.5, 0.5), style: Optional[Dict[str, Any]] = None) -> Any
No documentation
def _draw_circle_fast(self: Any, center_x: Any, center_y: Any, radius: Any, color: Any, fill: Any = True, border_width: Any = 1, pivot: Any = (0.5, 0.5)) -> Any
No documentation
def _generate_filled_circle_geometry(self: Any, segments: Any) -> Any
No documentation
def _generate_hollow_circle_geometry(self: Any, segments: Any, border_width: Any, radius: Any) -> Any
No documentation
def _upload_geometry(self: Any, vertices: Any, indices: Any) -> Any
No documentation
def draw_polygon(self: Any, points: Iterable[Union[Tuple[Union[int, float], Union[int, float]], List[Union[int, float]], pygame.Vector2, Any]], color: Any = None, fill: Any = True, border_width: Union[int, float] = 1, border_color: Any = None, surface: Any = None, pivot: Tuple[Union[int, float], Union[int, float]] = (0.0, 0.0), style: Optional[Dict[str, Any]] = None) -> None
No documentation
def _draw_polygon_outline(self: Any, points: Any, color: Any, border_width: Any, pivot: Any = (0.0, 0.0)) -> Any
Draw a clean polygon outline using GL_LINE_LOOP.
This avoids shrinking geometry issues.
def _generate_filled_polygon_geometry(self: Any, points: Any) -> Any
No documentation
def _draw_polygon_fast(self: Any, points: Any, color: Any, fill: Any = True, border_width: Any = 1, pivot: Any = (0.0, 0.0)) -> Any
Draw a filled polygon using the simple shader.
def _generate_gradient_texture(self: Any, color_keys: Union[ColorKeys, List[Tuple[int, int, int, float]], List[Color]], width: Union[int, float], height: Union[int, float], gradient_type: Literal['linear', 'radial', 'conic'] = 'linear', angle: Union[int, float] = 0.0, scale_x: Union[int, float] = 1.0, scale_y: Union[int, float] = 1.0, offset_x: Union[int, float] = 0.0, offset_y: Union[int, float] = 0.0) -> int
No documentation
def _ensure_temp_fbo(self: Any, width: int, height: int) -> None
No documentation
def draw_text(self: Any, text: str, x: int | float, y: int | float, color: Any, font: pygame.font.Font, surface: Optional[pygame.Surface] = None, pivot: Tuple[int | float, int | float] = (0.0, 0.0), flip: Tuple[bool, bool] = (False, False), rotate: int | float = 0.0, style: Optional[Dict] = None, *args: tuple, **kwargs: dict) -> None
No documentation
def draw_rich_text(self: Any, text: Any, x: Any, y: Any, default_color: Any, font: Any, surface: Any = None, pivot: Any = (0.0, 0.0), **kwargs: dict) -> Any
No documentation
def draw_rich_text_line(self: Any, line: Any, x: Any, y: Any, default_color: Any, font: Any, surface: Any = None) -> Any
No documentation
def _cleanup_text_cache(self: Any, now: float) -> Any
No documentation
def _cleanup_texture_cache(self: Any, time_dur: Any = 5.0, force_cleanup: Any = False) -> Any
No documentation
def draw_surface(self: Any, surface: Any, x: Any, y: Any, pivot: Any = (0.0, 0.0), use_cache: Any = True) -> Any
No documentation
def blit(self: Any, source: Any, dest: Any, area: Any = None, special_flags: Any = 0, pivot: Any = (0.0, 0.0), use_cache: Any = True) -> Any
No documentation
def fill_screen(self: Any, color: Any) -> Any
No documentation
def clear(self: Any) -> Any
No documentation
def render_particles(self: Any, particle_data: Any, camera: Any) -> Any
No documentation
def _ensure_particle_capacity(self: Any, required: Any) -> Any
No documentation
def cleanup(self: Any) -> Any
No documentation
def set_blend_mode(self: Any, mode: str) -> Any
No documentation

Global Functions

def set_shader_folder(folder: str) -> None

No documentation

def get_shader_folder() -> str

No documentation

Back to Backend Module