Source code for picogl.renderer.glresourceregistry

"""
gl Context Class
"""

import threading
from dataclasses import field
from typing import Callable, Optional, TypeVar
from weakref import WeakKeyDictionary

import numpy as np
from decologr import Decologr as log
from PySide6.QtGui import QOpenGLContext

from picogl.backend.modern.core.vertex.array.object import VertexArrayObject
from picogl.shaders import ShaderType

[docs] T = TypeVar("T")
[docs] class GLResourceRegistry: """gl Resource Registry""" def __init__(self):
[docs] self._creation_context = QOpenGLContext.currentContext()
log.message( f"gl context :{id(self._creation_context)}", scope="GLResourceRegistry" )
[docs] self._contexts = WeakKeyDictionary()
[docs] self._cache: dict[object, object] = {}
[docs] self.vaos: dict[str, VertexArrayObject] = field(default_factory=dict)
[docs] self.current_vao: Optional[VertexArrayObject] = None
[docs] self._creation_thread_id = threading.get_ident()
[docs] self.shader_type: ShaderType = ShaderType.DEFAULT
[docs] self.textures: dict[str, int] = field(default_factory=dict)
[docs] self.active_texture: Optional[str] = None
[docs] self.model_matrix: np.ndarray = field( default_factory=lambda: np.identity(4, dtype=np.float32) )
[docs] self.view_matrix: np.ndarray = field( default_factory=lambda: np.identity(4, dtype=np.float32) )
[docs] self.projection_matrix: np.ndarray = field( default_factory=lambda: np.identity(4, dtype=np.float32) )
[docs] self.eye_position: np.ndarray = field( default_factory=lambda: np.zeros(3, dtype=np.float32) )
@property
[docs] def context(self): return self._creation_context
[docs] def _get_bucket(self, ctx): if ctx not in self._contexts: self._contexts[ctx] = { "vao": set(), "vbo": set(), "shader": set(), "ebo": set(), } return self._contexts[ctx]
[docs] def register(self, ctx, resource_type: str, resource): bucket = self._get_bucket(ctx) bucket[resource_type].add(resource)
[docs] def unregister(self, ctx, resource_type: str, resource): bucket = self._get_bucket(ctx) bucket[resource_type].discard(resource)
[docs] def get_context_resources(self, ctx): return self._contexts.get(ctx, None)
[docs] def validate_context(self): ctx = QOpenGLContext.currentContext() if ctx is None: raise RuntimeError("No current OpenGL context") if self._creation_context is None: raise RuntimeError("Resource has no creation context") if ctx != self._creation_context: raise RuntimeError("VAO used in a different OpenGL context")
[docs] def get_context_key(self, ctx): if ctx is None: return None return ctx # simple version
[docs] def get_or_create(self, key: object, factory: Callable[[], T]) -> T: """Return a cached gl resource, creating it with *factory* if needed.""" if key not in self._cache: self._cache[key] = factory() return self._cache[key]