Vulkan Schnee 0.0.1
High-performance rendering engine
Loading...
Searching...
No Matches
AssetManager.h
Go to the documentation of this file.
1#pragma once
14#include "MeshAsset.h"
15#include "MeshAssetRef.h"
16
19#include <filesystem>
20#include <future>
21#include <memory>
22#include <optional>
23#include <string>
24#include <type_traits>
25#include <unordered_map>
26
27namespace Engine::Entities
28{
29 class GltfSpawner;
30} // namespace Engine::Entities
31
32namespace Engine::Rendering
33{
34 class Renderer;
35} // namespace Engine::Rendering
36
37namespace Engine::Assets
38{
39 class Material;
40 class Mesh;
41 class ModelAssetManager;
42 class MeshAssetManager;
43 class RuntimeTexture;
44 class Texture;
45} // namespace Engine::Assets
46
47namespace Engine::Core
48{
50 class RenderingDataManager;
51
53 {
54 std::size_t operator()( const std::filesystem::path & p ) const noexcept
55 {
56 return std::hash<std::string>{}( p.string() ); // Hash the string representation
57 }
58 };
59
61 {
62 glm::vec3 position; // 12 bytes (Keep full precision)
63 uint32_t packedNormal; // 4 bytes (A2B10G10R10_SNORM)
64 uint32_t packedColor; // 4 bytes (R8G8B8A8_UNORM)
65 uint32_t packedTexCoord; // 4 bytes (R16G16_SFLOAT)
66 // Total: 24 bytes
67 };
68
69 // Pack vec3 normal [-1, 1] into A2B10G10R10_SNORM uint32_t
70 inline uint32_t packNormalA2B10G10R10_SNORM( const glm::vec3 & n )
71 {
72 // Clamp input just in case
73 float x = std::max( -1.0f, std::min( 1.0f, n.x ) );
74 float y = std::max( -1.0f, std::min( 1.0f, n.y ) );
75 float z = std::max( -1.0f, std::min( 1.0f, n.z ) );
76
77 // Scale to signed 10-bit range [-511, 511]
78 int32_t ix = static_cast<int32_t>( std::round( x * 511.0f ) );
79 int32_t iy = static_cast<int32_t>( std::round( y * 511.0f ) );
80 int32_t iz = static_cast<int32_t>( std::round( z * 511.0f ) );
81
82 // Pack into uint32_t (masking handles two's complement correctly)
83 // Layout: | 2 unused | 10 bits B | 10 bits G | 10 bits R |
84 return ( static_cast<uint32_t>( iz & 0x3FF ) << 20 ) | ( static_cast<uint32_t>( iy & 0x3FF ) << 10 ) |
85 ( static_cast<uint32_t>( ix & 0x3FF ) );
86 // Alpha bits (highest 2) remain 0
87 }
88
89 // Pack vec3 color [0, 1] into R8G8B8A8_UNORM uint32_t (Alpha = 1.0)
90 inline uint32_t packColorR8G8B8A8_UNORM( const glm::vec3 & c )
91 {
92 // Clamp input
93 float r = std::max( 0.0f, std::min( 1.0f, c.x ) );
94 float g = std::max( 0.0f, std::min( 1.0f, c.y ) );
95 float b = std::max( 0.0f, std::min( 1.0f, c.z ) );
96
97 // Scale to [0, 255]
98 uint32_t ur = static_cast<uint32_t>( std::round( r * 255.0f ) );
99 uint32_t ug = static_cast<uint32_t>( std::round( g * 255.0f ) );
100 uint32_t ub = static_cast<uint32_t>( std::round( b * 255.0f ) );
101 uint32_t ua = 255; // Fully opaque alpha
102
103 // Pack (assuming typical RGBA little-endian layout)
104 return ( ua << 24 ) | ( ub << 16 ) | ( ug << 8 ) | ur;
105 }
106
107 // Pack vec2 texCoord into R16G16_SFLOAT uint32_t
108 inline uint32_t packTexCoordR16G16_SFLOAT( const glm::vec2 & tc )
109 {
110 // Use glm's packing function (requires <glm/gtc/packing.hpp>)
111 // It converts two floats to two 16-bit half-floats and packs them.
112 return glm::packHalf2x16( tc );
113 }
114
116 {
117 uint32_t index = 0u;
118 std::shared_ptr<Assets::Texture> texture = nullptr;
119
120 template <typename T>
121 bool operator>( const T & other )
122 {
123 return index > other.index;
124 }
125
126 template <typename T>
127 bool operator<( const T & other )
128 {
129 return index < other.index;
130 }
131 };
132
134 {
138
139 public:
144
145 template <typename AssetClass, typename Key>
146 [[nodiscard]] auto getAsset( const Key & asset )
147 {
148 if constexpr ( std::is_same_v<AssetClass, Assets::Mesh> )
149 {
150 static_assert(
151 std::is_same_v<std::decay_t<Key>, Asset::Path>,
152 "Mesh assets are keyed by Asset::Path"
153 );
154
155 MeshAssetRef ref = meshAssetManager->getOrCreateRef( asset );
156 (void)getMeshAsset( asset );
157 return ref;
158 }
159 else if constexpr ( std::is_same_v<AssetClass, Assets::Audio> )
160 {
161 static_assert(
162 std::is_same_v<std::decay_t<Key>, std::filesystem::path>,
163 "Audio assets are keyed by std::filesystem::path"
164 );
165
166 return loadAudioAsset( asset );
167 }
168 else if constexpr ( std::is_same_v<AssetClass, Assets::Material> )
169 {
170 static_assert(
171 std::is_same_v<std::decay_t<Key>, Asset::Path>,
172 "Material assets are keyed by Asset::Path"
173 );
174
175 return materialAssetManager->getOrCreateRef( asset );
176 }
177 else if constexpr ( std::is_same_v<AssetClass, Assets::Texture> )
178 {
179 static_assert(
180 std::is_same_v<std::decay_t<Key>, std::filesystem::path>,
181 "Texture assets are keyed by std::filesystem::path"
182 );
183
184 TextureAssetRef ref = textureAssetManager->getOrCreateRef( asset );
185 const Asset::LoadState state = textureAssetManager->getAssetLoadingState( asset );
186 if (state != Asset::LOADED && state != Asset::REQUESTED_LOAD && state != Asset::LOADING)
187 {
188 loadEcsTexture( asset );
189 }
190 return ref;
191 }
192 else
193 {
194 static_assert(
195 std::is_same_v<AssetClass, void>,
196 "Unsupported asset type for AssetManager::getAsset<T>()"
197 );
198 }
199 }
200
204
210
215 void setRenderingDataManager( RenderingDataManager * renderingDataManager );
216
217 private:
222 void loadEcsModel( const std::filesystem::path & path );
223
229 void loadEcsTexture( const std::filesystem::path & path );
230
231
232 public:
233 // TODO: loadEcsCubemap should be private and only load things via a getter so that all resources use the Ref resource handle.
237 Assets::CubemapTexture * loadEcsCubemap( const std::filesystem::path & path );
238
239
246 [[nodiscard]] uint32_t getTextureDescriptorIndex( const std::filesystem::path & path );
247
248 uint32_t getImageCount() const;
249
250 void cleanup();
251
252
253
254 std::vector<VkDescriptorImageInfo> getTextureDescriptorInfos() const;
255
260
265
270 AudioAssetRef loadAudioAsset(const std::filesystem::path& path);
271
277 [[nodiscard]] Assets::Audio * getAudioAsset(const std::filesystem::path& path);
278
284
285 private:
291 [[nodiscard]] Assets::Mesh * getMeshAsset( const Asset::Path & asset );
292
293 public:
294
300 {
302 }
303
308 [[nodiscard]] Assets::ModelAssetManager * getModelAssetManager() const
309 {
310 return modelAssetManager;
311 }
312
318 {
319 return meshAssetManager;
320 }
321
330
331 private:
332 NamedThreadPool * threadPool_ = new NamedThreadPool( 2, "Asset Loader" );
333 NamedThreadPool * threadedCalculation_ = new NamedThreadPool( 2, "Bounding Sphere" );
334
339 Assets::ModelAssetManager * modelAssetManager;
340
341 // IMPORTANT: textureHandleRegistry_ must be declared BEFORE modelAssetPipeline
342 // because modelAssetPipeline's constructor receives 'this' and may access the registry.
343 // C++ initializes members in declaration order, not initializer list order.
345
347
350
351 public:
353 {
355 }
356
358 {
359 return threadPool_;
360 }
361
362 private:
364
367
368 std::unordered_map<std::filesystem::path, Assets::RuntimeTexture *, PathHasher> textures = {};
369 std::unordered_map<std::filesystem::path, std::unique_ptr<Assets::CubemapTexture>, PathHasher> cubemapTextures = {};
371
372 std::array<std::optional<Assets::RuntimeTexture>, MAX_TEXTURE_COUNT> textureData;
374
382 bool doesTextureAlreadyExist( const std::filesystem::path & path );
383
393 Assets::RuntimeTexture * registerTexture( const std::filesystem::path & path, Assets::RuntimeTexture texture );
394
404 Assets::RuntimeTexture * registerTextureFromPrepared( const std::filesystem::path & path, Assets::RuntimeTexture texture );
405
409 Assets::RuntimeTexture * replaceTextureFromPrepared( const std::filesystem::path & path, Assets::RuntimeTexture texture );
410
413
414 TRACY_LOCKABLE( std::mutex, textureMutex, "Texture mutex" );
415
416 std::vector<TextureStorage> texturesToUpload{};
417 std::vector<Assets::RuntimeTexture *> texturesToCopyImageData;
418 };
419}
constexpr uint32_t MAX_TEXTURE_COUNT
Definition Settings.h:35
#define TRACY_LOCKABLE(type, varname, desc)
Manages audio assets by filesystem path, providing dedup and lookup.
Definition AudioAsset.h:70
Holds decoded PCM audio data as an engine asset.
Definition AudioAsset.h:13
the material asset is another wrapper for asset data which is stored in entt. It has the EngineCore::...
Stores mesh data with their primitives.
Definition MeshAsset.h:47
The mesh asset stores geometry data and.
Definition MeshAsset.h:20
Wrapper for texture data.
Central registry for texture handles, providing O(1) descriptor index lookup.
The application context is the core class which stores the basic openxr and vulkan objects.
bool doesTextureAlreadyExist(const std::filesystem::path &path)
Checks if a texture has already been loaded.
Assets::ModelAssetManager * modelAssetManager
DescriptorIndexAllocator textureAllocator
void discardSceneLoadingData()
Drops any queued or in-flight scene asset loading work.
Assets::TextureAssetRef TextureAssetRef
Assets::MaterialAssetManager * materialAssetManager
Assets::Textures::TextureHandleRegistry * getTextureHandleRegistry()
Gets the texture handle registry for O(1) descriptor index lookups.
Rendering::Renderer * renderer
std::unordered_map< std::filesystem::path, std::unique_ptr< Assets::CubemapTexture >, PathHasher > cubemapTextures
Assets::MaterialAssetManager * getMaterialAssetManager() const
Gets the material asset manager for material lookups.
uint32_t getImageCount() const
auto getAsset(const Key &asset)
std::vector< TextureStorage > texturesToUpload
Assets::RuntimeTexture * replaceTextureFromPrepared(const std::filesystem::path &path, Assets::RuntimeTexture texture)
Replace an already registered texture while preserving its descriptor index.
Assets::AudioAssetRef AudioAssetRef
Assets::MeshAssetRef MeshAssetRef
void setRenderingDataManager(RenderingDataManager *renderingDataManager)
Sets the RenderingDataManager on asset pipelines for hook notifications.
Assets::Textures::TextureHandleRegistry textureHandleRegistry_
Registry for type-safe texture handles.
AudioAssetRef loadAudioAsset(const std::filesystem::path &path)
Submit an audio file for async loading through the pipeline.
Ecs::AudioAssetPipeline & getAudioAssetPipeline()
void loadEcsTexture(const std::filesystem::path &path)
Loads a texture (.png / .jpg / .exr)
Assets::Loaders::GltfLoader gltfLoader
Assets::Mesh * getMeshAsset(const Asset::Path &asset)
Get a mesh asset by path. If not loaded, requests its model and returns nullptr.
Assets::MeshAssetManager * meshAssetManager
std::vector< VkDescriptorImageInfo > getTextureDescriptorInfos() const
NamedThreadPool * threadPool_
Assets::AudioAssetManager * getAudioAssetManager() const
Gets the audio asset manager for direct access.
Assets::AudioAssetManager * audioAssetManager_
AssetManager(ApplicationContext *context)
Ecs::TextureAssetPipeline texturePipeline
Assets::MaterialAssetRef MaterialAssetRef
void unregisterTexture(Assets::RuntimeTexture *texture)
Assets::RuntimeTexture * registerTexture(const std::filesystem::path &path, Assets::RuntimeTexture texture)
Registers a texture with the texture manager which prevents the same texture from being loaded twice.
Assets::ModelAssetManager * getModelAssetManager() const
Gets the model asset manager for model/GLTF file loading state lookups.
Assets::RuntimeTexture * registerTextureFromPrepared(const std::filesystem::path &path, Assets::RuntimeTexture texture)
Register a texture whose Vulkan resources are already created. Skips createResources() — only allocat...
void loadEcsModel(const std::filesystem::path &path)
Submits a gltf model for loading. You provide the path of the model to load. This can include 3D data...
Assets::TextureAssetManager * textureAssetManager
Ecs::AudioAssetPipeline audioAssetPipeline_
std::vector< Assets::RuntimeTexture * > texturesToCopyImageData
Ecs::TextureAssetPipeline & getTextureAssetPipeline()
NamedThreadPool * getAssetLoaderPool() const
NamedThreadPool * getCalculationPool() const
NamedThreadPool * threadedCalculation_
void attachToRenderer(Rendering::Renderer *renderer)
Sets what renderer the render process belongs to.
Ecs::ModelAssetPipeline modelAssetPipeline
BidirectionalMap< uint32_t, Assets::RuntimeTexture * > textureIndexMap
Assets::CubemapTexture * loadEcsCubemap(const std::filesystem::path &path)
Loads a six-face cubemap asset from a directory.
uint32_t getTextureDescriptorIndex(const std::filesystem::path &path)
Gets the descriptor index of a loaded texture by path.
std::unordered_map< std::filesystem::path, Assets::RuntimeTexture *, PathHasher > textures
Assets::MeshAssetManager * getMeshAssetManager() const
Gets the mesh asset manager for mesh asset lookups.
ApplicationContext * context
Assets::Audio * getAudioAsset(const std::filesystem::path &path)
Get a loaded audio asset by path.
std::array< std::optional< Assets::RuntimeTexture >, MAX_TEXTURE_COUNT > textureData
Ecs::ModelAssetPipeline & getMeshAssetPipeline()
Use this class to manage a finite amount of memory. The idea is to have an array which stores objects...
Async pipeline for loading audio assets (WAV, FLAC, MP3)
The model asset pipeline loads a gltf scene and loads and loads the mesh and material data....
Infrastructure to load images into the ecs.
Utility class for spawning GLTF meshes into a scene.
Definition GltfSpawner.h:15
The renderer is the main class for rendering. It owns all data which is used any time in any frame....
Definition Renderer.h:71
Tracy-named thread pool using BS_tracy::tracy_thread_pool.
@ LOADED
All components of the asset have been loaded, and it is ready to be used.
Definition Asset.h:40
@ REQUESTED_LOAD
An asset has been requested to load and is waiting for an asset pipeline to start working on it.
Definition Asset.h:32
@ LOADING
While the asset is currently being processed in the asset pipeline.
Definition Asset.h:36
CpuLoadingState LoadState
Definition Asset.h:47
Asset::Ref< Asset::Path, Mesh > MeshAssetRef
Asset::Ref< std::filesystem::path, Texture > TextureAssetRef
Asset::Ref< Asset::Path, Material > MaterialAssetRef
Asset::Ref< std::filesystem::path, Audio > AudioAssetRef
Core audio subsystem owning the miniaudio engine and managing playback.
Definition AudioConfig.h:9
uint32_t packTexCoordR16G16_SFLOAT(const glm::vec2 &tc)
uint32_t packColorR8G8B8A8_UNORM(const glm::vec3 &c)
uint32_t packNormalA2B10G10R10_SNORM(const glm::vec3 &n)
std::size_t operator()(const std::filesystem::path &p) const noexcept
std::shared_ptr< Assets::Texture > texture
bool operator<(const T &other)
bool operator>(const T &other)