simvx.graphics.materials.texture

Texture loading and bindless descriptor array management.

One canonical TextureManager serves both the Vulkan and web backends — the only thing that differs between them is the _TextureRegistrar that turns RGBA pixels into a backend-specific texture id. On the web path the manager also retains pixel data so prepare_2d_overlays can re-ship it over the drain channel; on the desktop path that’s skipped (retain_pixels=False) to avoid doubling VRAM.

Module Contents

Classes

TextureManager

Loads textures via a backend registrar and caches by source identity.

Data

API

simvx.graphics.materials.texture.__all__

[‘TextureManager’]

simvx.graphics.materials.texture.log

‘getLogger(…)’

simvx.graphics.materials.texture.TextureSource

None

class simvx.graphics.materials.texture.TextureManager(registrar: simvx.graphics.materials.texture._TextureRegistrar, *, retain_pixels: bool = False)[source]

Loads textures via a backend registrar and caches by source identity.

Desktop Vulkan: TextureManager(engine) — pixels uploaded and forgotten. Web: TextureManager(renderer, retain_pixels=True) — pixels retained so prepare_2d_overlays can re-ship them over the drain channel on demand.

Initialization

resolve(source: simvx.graphics.materials.texture.TextureSource | None) int[source]

Resolve any supported texture source to a backend texture index.

Returns -1 for None, empty strings, or sources that cannot be resolved (e.g. a path that does not exist). All callers that accept a user-provided texture property should go through this method.

Supported sources: * str / pathlib.Path — file on disk (PNG / JPG / …) * bytes — raw encoded image data (PNG / JPG) * numpy.ndarray — RGBA uint8 pixels, shape (H, W, 4)

load(path: str | pathlib.Path) int[source]

Load a texture from disk. Cached by resolved path.

load_from_bytes(data: bytes) int[source]

Load a texture from in-memory image bytes. Cached by content hash.

load_from_array(pixels: numpy.ndarray) int[source]

Upload an RGBA uint8 ndarray of shape (H, W, 4).

Cached by the array’s object identity plus shape/dtype — passing the same ndarray instance returns the same index.

load_if_exists(path: str | pathlib.Path) int[source]

Load a texture if the file exists. Returns -1 if not found.

get_texture_size(tex_idx: int) tuple[int, int][source]

Return (width, height) for a loaded texture index. (0, 0) if unknown.

get_pixels(tex_id: int) numpy.ndarray | None[source]

Return retained RGBA pixels for tex_id, or None.

Only populated when the manager was constructed with retain_pixels=True. Used by the web runtime to re-ship 2D overlay pixels over the drain channel without the browser having to fetch them back out.

property count: int[source]

Number of unique textures loaded.

destroy() None[source]

Clear all caches (GPU resources are owned by the backend).

release(idx: int, cache_key: str | None = None, source_id: int | None = None) None[source]

Reclaim a texture slot + drop cache bookkeeping.

Called by the weakref.finalize attached in load_from_array when the source ndarray is GC’d. Backend unregister is delegated to the registrar when it exposes unregister_texture (desktop Engine); web registrars may opt out.