Source code for moderngl_window.loaders.texture.cube

from collections import namedtuple
from typing import Any, Optional

import moderngl

from moderngl_window.exceptions import ImproperlyConfigured
from moderngl_window.loaders.texture.pillow import PillowLoader, image_data
from moderngl_window.meta.base import ResourceDescription
from moderngl_window.meta.texture import TextureDescription

FaceInfo = namedtuple("FaceInfo", ["width", "height", "data", "components"])


[docs] class Loader(PillowLoader): kind = "cube" meta: TextureDescription def __init__(self, meta: ResourceDescription): super().__init__(meta)
[docs] def load(self) -> moderngl.TextureCube: """Load a texture cube as described by the supplied ``TextureDescription``` Returns: moderngl.TextureCube: The TextureArray instance """ pos_x = self._load_face(self.meta.pos_x, face_name="pos_x") pos_y = self._load_face(self.meta.pos_y, face_name="pos_y") pos_z = self._load_face(self.meta.pos_z, face_name="pos_z") neg_x = self._load_face(self.meta.neg_x, face_name="neg_x") neg_y = self._load_face(self.meta.neg_y, face_name="neg_y") neg_z = self._load_face(self.meta.neg_z, face_name="neg_z") self._validate([pos_x, pos_y, pos_z, neg_x, neg_y, neg_z]) texture = self.ctx.texture_cube( (pos_x.width, pos_x.height), pos_x.components, pos_x.data + neg_x.data + pos_y.data + neg_y.data + pos_z.data + neg_z.data, ) texture.extra = {"meta": self.meta} if self.meta.mipmap_levels is not None: self.meta.mipmap = True if self.meta.mipmap: if isinstance(self.meta.mipmap_levels, tuple): texture.build_mipmaps(*self.meta.mipmap_levels) else: texture.build_mipmaps() if self.meta.anisotropy: texture.anisotropy = self.meta.anisotropy return texture
def _load_face(self, path: Optional[str], face_name: Optional[str] = None) -> FaceInfo: """Obtain raw byte data for a face Returns: tuple[int, bytes]: number of components, byte data """ if not path: raise ImproperlyConfigured(f"{face_name} texture face not supplied") image = self._load_texture(path) components, data = image_data(image) return FaceInfo(width=image.size[0], height=image.size[1], data=data, components=components) def _validate(self, faces: list[FaceInfo]) -> Any: """Validates each face ensuring components and size it the same""" components = faces[0].components data_size = len(faces[0].data) for face in faces: if face.components != components: raise ImproperlyConfigured( "Cubemap face textures have different number of components" ) if len(face.data) != data_size: raise ImproperlyConfigured("Cubemap face textures must all have the same size") return components