"""
ShaderRegistry
==============
Example Usage:
==============
>>>shader_registry = ShaderRegistry()
...# Load src at app start
...for shader_type_value in ShaderType:
... shader_registry.load_and_add(shader_type_value)
...
...# Later...
...shader_manager.current_shader_program = shader_registry.get(ShaderType.ATOMS)
...if shader_manager.current_shader_program:
... shader_manager.current_shader_program.bind()
...
File naming convention:
=======================
Ensure GLSL files follow the naming pattern:
atoms_vert.glsl
atoms_frag.glsl
bonds_vert.glsl
bonds_frag.glsl
"""
from dataclasses import dataclass, field
from typing import Dict, Optional
from picogl.backend.modern.core.shader.load import load_shader
from picogl.backend.modern.core.shader.program import ShaderProgram
from picogl.logger import Logger as log
from picogl.shaders.compile import compile_shaders
from picogl.shaders.type import ShaderType
@dataclass
[docs]
class ShaderRegistry:
"""ShaderRegistry"""
[docs]
shaders: Dict[ShaderType, ShaderProgram] = field(default_factory=dict)
[docs]
def load_and_add(self, shader_type: ShaderType) -> Optional[ShaderProgram]:
"""
Load, compile, and register a shader_manager.current_shader_program for the given ShaderType.
"""
try:
vertex_src = load_shader(shader_type.vertex_path())
fragment_src = load_shader(shader_type.fragment_path())
program = compile_shaders(vertex_src, fragment_src, shader_name="default")
if program:
self.shaders[shader_type] = program
return program
except Exception as ex:
log.error(
f"❌ Failed to load shader_manager.current_shader_program {shader_type}: {ex}"
)
return None
[docs]
def get(self, shader_type: ShaderType) -> Optional[ShaderProgram]:
return self.shaders.get(shader_type)
[docs]
def has(self, shader_type: ShaderType) -> bool:
return shader_type in self.shaders
[docs]
def release_all(self):
for shader_type, shader in self.shaders.items():
if hasattr(shader, "release") and callable(shader.release):
try:
shader.release()
except Exception as e:
log.warning(
f"⚠️ Failed to release shader_manager.current_shader_program '{shader_type}': {e}"
)
self.shaders.clear()