Source code for moderngl_window.loaders.program.separate

import logging
from pathlib import Path
from typing import Optional, Union

import moderngl

from moderngl_window.exceptions import ImproperlyConfigured
from moderngl_window.loaders.base import BaseLoader
from moderngl_window.opengl import program

logger = logging.getLogger(__name__)


[docs] class Loader(BaseLoader): kind = "separate" meta: program.ProgramDescription
[docs] def load( self, ) -> Union[moderngl.Program, moderngl.ComputeShader, program.ReloadableProgram]: """Loads a shader program were each shader is a separate file. This detected and dictated by the ``kind`` in the ``ProgramDescription``. Returns: moderngl.Program: The Program instance """ prog: Union[moderngl.Program, moderngl.ComputeShader, program.ReloadableProgram] vs_source = self._load_shader("vertex", self.meta.vertex_shader) geo_source = self._load_shader("geometry", self.meta.geometry_shader) fs_source = self._load_shader("fragment", self.meta.fragment_shader) tc_source = self._load_shader("tess_control", self.meta.tess_control_shader) te_source = self._load_shader("tess_evaluation", self.meta.tess_evaluation_shader) cs_source = self._load_shader("compute", self.meta.compute_shader) if vs_source: shaders = program.ProgramShaders.from_separate( self.meta, vs_source, geometry_source=geo_source, fragment_source=fs_source, tess_control_source=tc_source, tess_evaluation_source=te_source, ) shaders.handle_includes(self._load_source) prog = shaders.create() # Wrap the program if reloadable is set if self.meta.reloadable: # Disable reload flag so reloads will return Program instances self.meta.reloadable = False # Wrap it .. prog = program.ReloadableProgram(self.meta, prog) elif cs_source: shaders = program.ProgramShaders.compute_shader(self.meta, cs_source) shaders.handle_includes(self._load_source) prog = shaders.create_compute_shader() else: raise ImproperlyConfigured("Cannot find a shader source to load") return prog
def _load_shader(self, shader_type: str, path: Optional[str]) -> Optional[str]: """Load a single shader source""" if path is not None: resolved_path = self.find_program(path) if not resolved_path: raise ImproperlyConfigured("Cannot find {} shader '{}'".format(shader_type, path)) logger.info("Loading: %s", resolved_path) with open(str(resolved_path), "r") as fd: return fd.read() return None def _load_source(self, path: Union[Path, str]) -> tuple[Path, str]: """Finds and loads a single source file. Args: path: Path to resource Returns: tuple[resolved_path, source]: The resolved path and the source """ resolved_path = self.find_program(path) if resolved_path is None: raise ImproperlyConfigured("Cannot find program '{}'".format(path)) logger.info("Loading: %s", path) with open(str(resolved_path), "r") as fd: return resolved_path, fd.read()