Source code for picogl.backend.gl.backend

"""
This module provides an OpenGL backend implementation for rendering, state
management, texture handling, and other graphics-related operations. It wraps
OpenGL functionality with a higher-level interface for easier usage in 3D
graphics applications.

Classes:Ï
    - GLBackend: Encapsulates functions for managing OpenGL state and
      performing rendering operations.
"""

import platform
import warnings

from picogl.backend.gl.driver.blend import GLBlendDriver
from picogl.backend.gl.driver.capability import GLCapabilityDriver
from picogl.backend.gl.driver.depth import GLDepthDriver
from picogl.backend.gl.driver.frame import GLFrameDriver
from picogl.backend.gl.driver.geometry import GLGeometryDriver
from picogl.backend.gl.driver.raster import GLRasterDriver
from picogl.backend.gl.driver.texture import GLTextureSystem
from picogl.backend.gl.enums import GLBitMask
from picogl.backend.gl.enums.point_size import GLPointCapability
from picogl.backend.legacy.core.attribute_binder import LegacyAttributeBinder
from picogl.backend.legacy.core.pipeline import GLLegacyPipeline, LegacyPipeline
from picogl.backend.modern.core.pipeline import ShaderPipeline
from picogl.backend.opengl import GLBindingStrategy
from picogl.backend.state import (
    DrawCommand,
    GLClipPlaneState,
    GLStateManager,
    RenderState,
    RenderStateApplier,
)
from picogl.gpu.buffers.glframe import GLFramebuffer
from picogl.renderer.readback import GLReadback


[docs] class GLBackend: """gl Backend""" def __init__(self, binding: GLBindingStrategy):
[docs] self.binding = binding
[docs] self.framebuffer = GLFramebuffer()
[docs] self.read = GLReadback()
[docs] self.clip = GLClipPlaneState(enabled0=False, enabled1=False)
[docs] self.capabilities = GLCapabilityDriver()
[docs] self.frame = GLFrameDriver()
[docs] self.depth = GLDepthDriver(self.capabilities)
[docs] self.blend = GLBlendDriver(self.capabilities)
[docs] self.raster = GLRasterDriver()
[docs] self.legacy: LegacyPipeline = GLLegacyPipeline()
[docs] self.shader = ShaderPipeline()
[docs] self.geometry = GLGeometryDriver(binding)
[docs] self.textures = GLTextureSystem()
[docs] self.attributes = LegacyAttributeBinder()
[docs] self.state_manager = GLStateManager(self.capabilities)
[docs] self.state_applier = RenderStateApplier(self)
@property
[docs] def pipeline(self) -> LegacyPipeline: """Deprecated alias for :attr:`legacy`.""" warnings.warn( "GLBackend.pipeline is deprecated; use GLBackend.legacy", DeprecationWarning, stacklevel=2, ) return self.legacy
@pipeline.setter def pipeline(self, value: LegacyPipeline) -> None: warnings.warn( "GLBackend.pipeline is deprecated; use GLBackend.legacy", DeprecationWarning, stacklevel=2, ) self.legacy = value
[docs] def draw_command(self, command: DrawCommand): """Apply command state/resources and draw through this backend.""" command.execute(self)
[docs] def apply_state(self, state: RenderState) -> None: """Apply a render-state descriptor through cached subsystem drivers.""" self.state_applier.apply(state)
[docs] def apply_clip_state(self, clip: GLClipPlaneState | None = None) -> None: """Apply clip-plane capability state.""" if clip is not None: self.clip = clip self.clip.apply(self.state_manager)
[docs] def create_shader_pipeline(self, program) -> ShaderPipeline: """Return a shader pipeline bound to *program*.""" pipeline = ShaderPipeline(program) self.shader = pipeline return pipeline
[docs] def prepare_viewport(self, width: int, height: int) -> None: """ prepare :param width: int :param height: int :return: None Prepares an OpenGL Frame Viewport """ if platform.system() == "Darwin": dpr = 2 # macOS Retina displays else: dpr = 1 self.frame.viewport(0, 0, width * dpr, height * dpr) self.depth.set_depth_test(True) self.frame.set_clear_color((0.1, 0.1, 0.1, 1.0)) self.capabilities.enable(GLPointCapability.PROGRAM_POINT_SIZE) self.frame.clear(GLBitMask.COLOR_BUFFER | GLBitMask.DEPTH_BUFFER)