Mi2dRPGamEng/engine/render/texture.py

38 lines
1.2 KiB
Python

from __future__ import annotations
from pathlib import Path
import numpy as np
import wgpu
from PIL import Image
class TextureCache:
def __init__(self, device, textures_dir: Path):
self.device = device
self.textures_dir = textures_dir
self._views: dict[str, "wgpu.GPUTextureView"] = {}
def get_view(self, relative_path: str) -> "wgpu.GPUTextureView":
if relative_path not in self._views:
self._views[relative_path] = self._load(relative_path)
return self._views[relative_path]
def _load(self, relative_path: str) -> "wgpu.GPUTextureView":
image = Image.open(self.textures_dir / relative_path).convert("RGBA")
data = np.asarray(image, dtype=np.uint8)
width, height = image.width, image.height
texture = self.device.create_texture(
size=(width, height, 1),
format=wgpu.TextureFormat.rgba8unorm,
usage=wgpu.TextureUsage.TEXTURE_BINDING | wgpu.TextureUsage.COPY_DST,
)
self.device.queue.write_texture(
{"texture": texture},
data.tobytes(),
{"bytes_per_row": width * 4, "rows_per_image": height},
(width, height, 1),
)
return texture.create_view()