Vulkan Schnee 0.0.1 (22840dc8)
High-performance rendering engine
Loading...
Searching...
No Matches
Asset Loading System

The asset loading system owns asset records, submits asynchronous loading work, and hands renderer-ready data to RenderingDataManager.

Use AssetRegistry handles for stable authored references. Use Asset::Ref when code needs the loaded payload.

Storage And Identity Flow

Asset files exist on disk before the engine creates any asset object. Runtime code addresses the copied files under assets/ with relative paths such as assets/AirHockey/Data/geometry/House/export/House.gltf.

Source asset file
-> copied runtime file under assets/
-> Asset::Path or Asset::MeshPath
-> AssetRegistry metadata store
-> typed AssetHandle { index, generation }
-> AssetManager record and Asset::Ref
-> CPU payload
-> renderer-owned GPU resource, when applicable

The asset registry does not own file bytes, decoded mesh vertices, decoded audio samples, or Vulkan resources. It owns deduplicated authored identities and lightweight metadata. The central AssetManager owns payload records and asynchronous loading state. The renderer owns GPU texture and mesh resources.

Layer Identity Stored Data Lifetime Owner
File storage Runtime-relative path Source bytes such as glTF, PNG, KTX2, or WAV Runtime assets/ directory
Authored key Asset::Path or Asset::MeshPath File path, plus a named glTF sub-asset for MeshPath Calling code or registry record
Scene identity AssetHandle<Tag> Store slot index and generation AssetRegistry
Payload identity Asset::Ref Weak reference to a load record Specialized manager in AssetManager
Texture render identity TextureHandle Path/type registry ID and descriptor slot TextureHandleRegistry and renderer

Asset::MeshPath distinguishes named objects within one glTF. For example, ("assets/.../House.gltf", "Door") and ("assets/.../House.gltf", "Window") identify different mesh payloads from the same source file.

Key Types

Type Meaning Used For
Asset::Path Wrapper around std::filesystem::path Single-file assets: audio clips and direct texture requests
Asset::MeshPath Source file path plus named object glTF sub-assets: meshes, materials, skins, animations
Engine::Assets::AssetHandle<Tag> Index plus generation handle AssetRegistry stores for scene and component references
Engine::Assets::TextureHandle Texture registry id plus semantic type Descriptor lookup for material textures

Use Asset::MeshPath when the asset is a named object inside a container file.

constexpr auto modelPath = CREATE_ASSET_PATH(
Engine::Core::Path::engineGeometry() / "Defaults/cube_no_texture/cube_no_texture.gltf"
);
Asset::MeshPath cubeMesh(modelPath.fsPath(), "Cube");
static constexpr auto engineGeometry()
Path to engine geometry assets.
Definition Path.h:191
Identifies a named mesh-like asset inside an asset file.
Definition AssetPath.h:89

Use Asset::Path when the asset is the file itself.

static constexpr auto engineSounds()
Path to engine audio files.
Definition Path.h:252
Identifies a single asset file on disk.
Definition AssetPath.h:13

Asset Types

Type Payload Access Stable Handle Owner Primary Storage
glTF file Engine::Assets::Model by std::filesystem::path GltfHandle ModelAssetManager, GltfStore Tracks sub-assets created from one source file
glTF renderable GltfRenderableRecord GltfRenderableHandle GltfStore Node index, mesh index, transform, geometry handle, material handles
Mesh MeshAssetRef by Asset::MeshPath GeometryMeshHandle MeshAssetManager, GeometryMeshStore Hidden ECS entity with MeshPrimitiveData
Material MaterialAssetRef by Asset::MeshPath MaterialHandle MaterialAssetManager, MaterialStore Hidden ECS entity with MaterialData and typed texture handles
Texture TextureAssetRef by Asset::Path Texture2DHandle, TextureHandle TextureAssetManager, Texture2DStore, TextureHandleRegistry Hidden ECS entity with ImageData, then renderer-owned RuntimeTexture
Audio AudioAssetRef by Asset::Path AudioClipHandle AudioAssetManager, AudioClipStore Decoded PCM fields on Engine::Assets::Audio
Skin SkinAssetRef by Asset::MeshPath SkinHandle via SkinStore SkinAssetManager, SkinStore Joint hierarchy on Engine::Assets::Skin
Animation AnimationAssetRef by Asset::MeshPath AnimationClipHandle via AnimationClipStore AnimationAssetManager, AnimationClipStore Animation channels on Engine::Assets::Animation

Asset::Ref::isLoaded() returns true when the current record generation has a loaded payload. AssetHandle<Tag> values are stable references into registry stores, not loaded payload pointers.

Handle Validity And Residency

A non-null AssetHandle<Tag> has a non-zero generation. Call store.isValid(handle) before resolving a handle read from serialized or long-lived data because that verifies the index and store generation.

Handle validity and payload availability are independent:

GeometryMeshHandle is store-valid
!= MeshAssetRef has a loaded Mesh payload
Texture2DHandle is store-valid
!= TextureHandleRegistry has a resident RuntimeTexture

Unloading payload managers removes CPU and GPU data without changing a valid registry handle into a null handle. Resolve the handle back to its authored path, then request or await its payload again.

Asset Registry

Engine::Core::AssetRegistry stores stable handles for scene and component data. The engine creates it with the central AssetManager, and each Scene exposes it through Scene::getAssetRegistry().

Engine::Core::AssetRegistry* registry = scene->getAssetRegistry();
Engine::Assets::GltfHandle gltf = registry->gltfs().load(modelPath.fsPath());
registry->gltfs().renderable(gltf, "Cube");
registry->gltfs().geometryMesh(renderable);
Groups typed asset registry stores and resolves authored asset references.
GltfStore & gltfs()
Returns the mutable glTF store.
Assets::GeometryMeshHandle geometryMesh(Assets::GltfRenderableHandle renderable) const
Returns the geometry mesh handle used by a glTF renderable.
Assets::GltfRenderableHandle renderable(Assets::GltfHandle gltf, std::string_view nodeName)
Looks up a renderable node handle inside a loaded glTF file.
Assets::GltfHandle load(const std::filesystem::path &source)
Gets or creates a stable handle for a glTF source file and imports its renderable metadata.
AssetHandle< GltfRenderableHandleTag > GltfRenderableHandle
Handle to one mesh-bearing node inside a glTF file.
AssetHandle< GltfHandleTag > GltfHandle
Handle to a glTF container file.
AssetHandle< GeometryMeshHandleTag > GeometryMeshHandle
Handle to non-skinned mesh geometry.

GltfStore::load() reads glTF metadata and creates renderable, geometry mesh, and material handles. Geometry handle creation requests the backing mesh through AssetManager::getAsset<Engine::Assets::Mesh>().

Registry stores reject absolute paths for geometry meshes, materials, glTF files, textures, and audio clips. Use engine-relative authored paths for those handles.

Payload Access

Use Engine::Core::AssetManager::getAsset<T>() when code needs the loaded asset payload.

assetManager->getAsset<Engine::Assets::Mesh>(cubeMesh);
if (!meshRef.isLoaded()) {
return;
}
Engine::Assets::Mesh* mesh = meshRef.get();
bool isLoaded() const
Checks whether the referenced asset has a loaded payload.
Definition Asset.h:204
AssetClass * get() const
Gets the loaded payload.
Definition Asset.h:213
The mesh asset stores geometry data and.
Definition MeshAsset.h:20
Asset::Ref< Asset::MeshPath, Mesh > MeshAssetRef
Asset reference to mesh geometry loaded from a mesh asset path.

getAsset<Engine::Assets::Mesh>() returns a ref immediately and requests the backing glTF model when the mesh payload is absent.

getAsset<Engine::Assets::Skin>() and getAsset<Engine::Assets::Animation>() request the backing glTF model when the target record is UNLOADED.

getAsset<Engine::Assets::Material>() creates or returns the material ref. Material payloads are resolved when the model pipeline processes the source glTF.

getAsset<Engine::Assets::Texture>() and getAsset<Engine::Assets::Audio>() accept Asset::Path or std::filesystem::path. The facade converts the key to Asset::Path.

Frame Processing

EngineKern::processResourceLoadingPipelines() advances asset work once per frame.

assetManager->getTextureAssetPipeline().tick(true);
assetManager->getMeshAssetPipeline().tick(true);
assetManager->getAudioAssetPipeline().tick(true);
renderer->getRenderingDataManager()->processCompletedTextures();

Texture preparation finishes on worker threads. RenderingDataManager::processCompletedTextures() registers finished RuntimeTexture objects and updates TextureHandleRegistry.

Meshlet generation also finishes asynchronously. ModelAssetPipeline::takePendingMeshletCompletions() returns completed meshlet data at render-safe points.

Model Pipeline

ModelAssetPipeline loads glTF files and resolves sub-assets from them.

Stage Work
submitLoadModel() Submit tinygltf parse work to the asset loader pool
processModel() Parse scene extensions, pre-register texture handles, register textures, resolve skins and animations, create material records, and submit primitive loading
processSkinData() Reserved stage; skin loading currently runs inside processModel()
processMaterial() Write MaterialData to material asset entities and notify the renderer
processMeshData() Write mesh primitive metadata, optimize geometry, and schedule meshlet generation
processKtx2Textures() Poll KTX/KTX2 texture load futures and notify the renderer

Model keeps non-owning pointers to sub-assets created from one source file. The owning managers are MeshAssetManager, MaterialAssetManager, TextureAssetManager, SkinAssetManager, and AnimationAssetManager.

Lightmapped glTF nodes receive material keys named <material>__lightmap__<node>. The metadata import path and the runtime model pipeline use the same naming rule.

Texture Loading

Textures have a CPU asset record and a renderer-owned runtime texture.

Source Flow
glTF PNG/JPG tinygltf loads image bytes during model load; processTextures() creates GltfTextureAsset records
glTF KTX/KTX2 Ktx2Loader runs on the asset loader pool; RenderingDataManager::onKtx2TextureLoaded() prepares the runtime texture
EXR lightmaps TextureAssetPipeline loads headers, then image data, then calls RenderingDataManager::onTextureLoaded()
Direct KTX/KTX2 requests TextureAssetPipeline runs Ktx2Loader and reports to RenderingDataManager

RenderingDataManager::onTextureLoaded() moves Ecs::ImageData out of the asset entity and creates a RuntimeTexture on a worker thread. RenderingDataManager::processCompletedTextures() registers the texture in AssetManager and writes its descriptor index to TextureHandleRegistry.

Materials store typed texture handles for descriptor lookup.

uint32_t descriptorIndex = textureRegistry->resolveDescriptorIndex(
material->getBaseColorTextureHandle()
);

TextureHandleRegistry::resolveDescriptorIndex() returns 0xFFFFFFFF until a descriptor slot has been reserved. File-backed texture handles normally reserve a stable slot before the real image is resident; that slot samples the fallback texture until the runtime texture replaces it.

Mesh And Material Assets

Meshes and materials are glTF sub-assets keyed by Asset::MeshPath.

Asset::MeshPath materialPath(modelPath.fsPath(), "DefaultMaterial");
assetManager->getAsset<Engine::Assets::Material>(materialPath);
the material asset is another wrapper for asset data which is stored in entt. It has the EngineCore::...
Asset::Ref< Asset::MeshPath, Material > MaterialAssetRef
Asset reference to material data loaded from a mesh asset path.

A mesh is loaded when its hidden asset entity has Engine::Ecs::MeshPrimitiveData.

A material is loaded when its hidden asset entity has Engine::Core::MaterialData.

Skin And Animation Assets

Skins and animations are loaded from glTF by the model pipeline and owned by their managers. Gameplay code references them through stable handles resolved from the registry stores.

Engine::Assets::SkinHandle skin = scene->getAssetRegistry()->skins().load(skinPath);
Engine::Assets::AnimationClipHandle clip = scene->getAssetRegistry()->animations().load(animationPath);
AssetHandle< AnimationClipHandleTag > AnimationClipHandle
Handle to an animation clip.
AssetHandle< SkinHandleTag > SkinHandle
Handle to skin binding data.

Skeletal runtime data stores stable handles in the ECS components and resolves payloads through the stores behind the manager boundary.

ECS Component Handle
Engine::Ecs::SkeletalMeshData Engine::Assets::SkinHandle
Engine::Ecs::AnimationState Engine::Assets::AnimationClipHandle

Runtime-created animation clips can be registered through AnimationClipStore::registerRuntimeAnimation() to obtain a stable handle, mirroring registerRuntimeMaterial().

Audio Assets

Gameplay code stores an AudioClipHandle. AudioClipStore::load() gets or creates the stable handle and submits the backing payload for asynchronous decoding when it creates a new handle.

scene->getAssetRegistry()->audioClips().load(clipPath);
AssetHandle< AudioClipHandleTag > AudioClipHandle
Handle to audio clip asset data.

Calling load() repeatedly with the same path returns the same handle and does not synchronously decode or restart an active load. Use AudioClipStore::ref() only when code needs the legacy AudioAssetRef to inspect payload readiness.

AudioAssetPipeline decodes files on the asset loader pool and resolves Engine::Assets::Audio records. AudioEngine::onAudioLoaded() registers loaded clips, and AudioEngine::play(AudioClipHandle) resolves typed handles through the audio clip store. It returns INVALID_AUDIO_HANDLE when the handle is invalid or the payload is not loaded yet.

Loading State

Asset::Record owns the current payload, load state, generation, error string, and ready future. Asset::Ref is a non-owning handle to that record.

State Meaning
UNLOADED No payload is available
REQUESTED_LOAD A load was requested but no worker owns it yet
LOADING A pipeline is processing the asset
LOADED The payload is ready
FAILED Loading reached a terminal failure

Asset::Ref::readyFuture() resolves with Asset::LoadResult<Key, AssetClass> when the current generation succeeds or fails. A new generation starts when loading restarts, a payload is replaced, or a payload is unloaded.

Unloading And Cancellation

AssetManager::discardSceneLoadingData() clears queued and in-flight scene loading work from texture, model, and audio pipelines. It also asks RenderingDataManager to discard pending texture preparations.

AssetManager::unloadAllData() discards pending work, clears renderer scene resource caches, unloads runtime textures, clears texture handles, and clears all asset managers.

API Reference

API Purpose
Asset::Path, Asset::MeshPath Asset keys
Asset::Record, Asset::Ref, Asset::AssetManager, Asset::LoadResult Generic asset record and payload access API
Engine::Core::AssetManager Central asset manager facade
Engine::Core::AssetRegistry Stable handle stores and authored reference resolution
GltfStore, GeometryMeshStore, MaterialStore, Texture2DStore, AudioClipStore, AnimationClipStore, SkinStore Registry stores
Engine::Assets::AssetHandle Stable index/generation handle template
TextureAssetPipeline, ModelAssetPipeline, AudioAssetPipeline Async loading pipelines
Model, Mesh, Material, Texture, Audio, Skin, Animation Asset payload classes
TextureHandleRegistry, TextureHandle Runtime texture handle and descriptor lookup API
RenderingDataManager Runtime texture preparation, GPU upload, and renderer cache invalidation