Source code for picogl.renderer.object

"""Object renderer module."""

from pathlib import Path

from OpenGL.raw.GL.VERSION.GL_1_0 import GL_TRIANGLES

from picogl.backend.modern.core.vertex.array.object import VertexArrayObject
from picogl.logger import Logger as log
from picogl.renderer import GLContext, MeshData, RendererBase
from picogl.utils.loader.texture import TextureLoader
from picogl.utils.texture import bind_texture_array


[docs] class ObjectRenderer(RendererBase): """Unified renderer for textured and untextured objects."""
[docs] def __init__( self, context: GLContext, data: MeshData, base_dir: str | Path | None = None, glsl_dir: str | Path | None = None, use_texture: bool = False, texture_file: str | None = None, resource_subdir: str = "tu02", ): super().__init__()
[docs] self.base_dir = base_dir
[docs] self.resource_subdir = resource_subdir
[docs] self.texture_file = texture_file
[docs] self.context = context
[docs] self.data = data
self.data.vertex_count = len(self.data.vbo.flatten()) // 3
[docs] self.show_model = True
[docs] self.glsl_dir = glsl_dir
# Texture-related
[docs] self.use_texture = use_texture
log.parameter("Using texture", use_texture)
[docs] self.texture = None
if use_texture: base_path = Path(base_dir) if base_dir else Path(".") resource_path = base_path / "resources" / resource_subdir if texture_file: texture_path = resource_path / texture_file self.texture = TextureLoader(str(texture_path)) self.context.texture_id = self.texture.texture_glid
[docs] def initialize_shaders(self): """Load and compile shaders.""" log.message("Loading shaders...") if not self.context: self.context = GLContext() self.context.create_shader_program( vertex_source_file="vertex.glsl", fragment_source_file="fragment.glsl", glsl_dir=self.glsl_dir, )
[docs] def initialize(self): """Create VAO and VBOs once.""" if self.context.vaos is None: self.context.vaos = {} model_vao = VertexArrayObject() model_vao.add_vbo(index=0, data=self.data.vbo, size=3) if self.use_texture and self.data.uvs is not None: model_vao.add_vbo(index=1, data=self.data.uvs, size=2) self.context.vaos["model"] = model_vao else: # fall back to colors + normals if self.data.cbo is not None: model_vao.add_vbo(index=1, data=self.data.cbo, size=3) if self.data.nbo is not None: model_vao.add_vbo(index=2, data=self.data.nbo, size=3) self.context.vaos["model"] = model_vao
[docs] def render(self) -> None: """Dispatch render pass.""" if self.show_model: self._draw_model() self._finalize_render()
[docs] def _draw_model(self): """Draw the model""" model_vao = self.context.vaos["model"] shader = self.context.shader with shader, model_vao: shader.uniform("mvp_matrix", self.context.mvp_matrix) shader.uniform("model_matrix", self.context.model_matrix) shader.uniform("viewPos", self.context.eye_np) if self.use_texture and self.texture: bind_texture_array(self.context.texture_id) shader.uniform("texture0", 0) model_vao.draw(mode=GL_TRIANGLES, index_count=self.data.vertex_count)