3#include "boost/filesystem.hpp"
31 LOG_INFO(
"Loading models from folder: " + pathToFolder);
32 auto start = std::chrono::steady_clock::now();
34 boost::filesystem::path pathToDirectory = boost::filesystem::path(pathToFolder);
35 const bool isValidFolderPath = boost::filesystem::exists(boost::filesystem::path(pathToFolder)) && boost::filesystem::is_directory(boost::filesystem::path(pathToFolder));
36 if (!isValidFolderPath)
42 for (boost::filesystem::directory_entry& x : boost::filesystem::directory_iterator(pathToDirectory))
47 auto end = std::chrono::steady_clock::now();
48 float ms = std::chrono::duration<float, std::milli>(end - start).count();
51 " models from folder in " +
52 std::to_string(ms) +
" ms. RAM usage: " +
58 LOG_INFO(
"Loading models from package.");
59 auto start = std::chrono::steady_clock::now();
62 std::string folderEntry = {
"Models/" };
63 for (
auto& entry : entries)
65 const std::string& virtualPath = entry.first;
66 if (virtualPath.rfind(folderEntry, 0) == 0)
68 std::string modelName = virtualPath.substr(folderEntry.size());
71 if (binaryFileData.empty())
73 LOG_ERROR(
"Failed to read packed model: " + virtualPath);
81 auto end = std::chrono::steady_clock::now();
82 float ms = std::chrono::duration<float, std::milli>(end - start).count();
85 " models from package in " +
86 std::to_string(ms) +
" ms. RAM usage: " +
93 mModels[
"Quad2D"]->CreateQuad2D();
95 const size_t sizeVertices =
mModels.at(
"Quad2D")->GetCpuVertexBufferSize();
97 const size_t sizeIndices =
mModels.at(
"Quad2D")->GetCpuIndexBufferSize();
101void ModelCache::LoadCustomMesh(std::string meshName, std::vector<glm::vec2> positions2D, std::vector<glm::vec2> texCoords, std::vector<glm::vec4> colors, std::vector<std::uint32_t> indices)
103 LOG_DEBUG(
"Loading custom mesh: " + meshName);
104 auto start = std::chrono::steady_clock::now();
105 auto search =
mModels.find(meshName);
114 mModels[meshName]->LoadCustomMesh(positions2D, texCoords, colors, indices);
116 const size_t sizeVertices =
mModels.at(meshName)->GetCpuVertexBufferSize();
118 const size_t sizeIndices =
mModels.at(meshName)->GetCpuIndexBufferSize();
121 auto end = std::chrono::steady_clock::now();
122 float ms = std::chrono::duration<float, std::milli>(end - start).count();
124 LOG_DEBUG(
"Custom mesh loaded: " + meshName +
126 std::to_string(sizeVertices + sizeIndices) +
127 " bytes, " + std::to_string(ms) +
" ms)");
132 auto filePath = boost::filesystem::path(path);
133 if (!boost::filesystem::is_regular_file(filePath))
135 return std::string{};
138 const std::string ext = filePath.extension().string();
139 const bool isExtensionSupported = (ext ==
".fbx");
140 if (!isExtensionSupported)
142 return std::string{};
145 std::string filename = filePath.stem().string();
147 if (
auto search =
mModels.find(filename); search !=
mModels.end())
149 return std::string{};
151 LOG_DEBUG(
"Uploading model to RAM: " + filename);
152 auto start = std::chrono::steady_clock::now();
153 mModels[filename] = std::make_shared<MeshDataGpu>(filePath.string(),
mRenderer);
155 const size_t sizeVertices =
mModels.at(filename)->GetCpuVertexBufferSize();
157 const size_t sizeIndices =
mModels.at(filename)->GetCpuIndexBufferSize();
159 auto end = std::chrono::steady_clock::now();
160 float ms = std::chrono::duration<float, std::milli>(end - start).count();
162 LOG_DEBUG(
"Model loaded to RAM: " + filename +
163 " (Vertices+Indices: " +
164 std::to_string(sizeVertices + sizeIndices) +
165 " bytes, " + std::to_string(ms) +
" ms)");
171 auto modelName = boost::filesystem::path(fileName).stem().string();
174 if (
auto search =
mModels.find(modelName); search !=
mModels.end())
176 return std::string{};
178 LOG_DEBUG(
"Uploading model to RAM: " + fileName);
179 auto start = std::chrono::steady_clock::now();
182 const size_t sizeVertices =
mModels.at(modelName)->GetCpuVertexBufferSize();
184 const size_t sizeIndices =
mModels.at(modelName)->GetCpuIndexBufferSize();
186 auto end = std::chrono::steady_clock::now();
187 float ms = std::chrono::duration<float, std::milli>(end - start).count();
189 LOG_INFO(
"Model loaded to RAM: " + fileName +
190 " (Vertices+Indices: " +
191 std::to_string(sizeVertices + sizeIndices) +
192 " bytes, " + std::to_string(ms) +
" ms)");
199 if (
auto search =
mModels.find(filename); search ==
mModels.end())
203 if (
mModels[filename]->IsOnGPU())
207 LOG_DEBUG(
"Uploading model to GPU: " + filename);
208 auto start = std::chrono::steady_clock::now();
209 mModels[filename]->UploadToGPU();
210 size_t sizeVertices =
mModels[filename]->GetGpuVertexBufferSize();
212 size_t sizeIndices =
mModels[filename]->GetGpuIndexBufferSize();
214 auto end = std::chrono::steady_clock::now();
215 float ms = std::chrono::duration<float, std::milli>(end - start).count();
217 LOG_DEBUG(
"Model uploaded to GPU: " + filename +
219 std::to_string(sizeVertices + sizeIndices) +
220 " bytes, " + std::to_string(ms) +
" ms)");
225 if (
auto search =
mModels.find(filename); search ==
mModels.end())
229 LOG_DEBUG(
"Releasing model from GPU: " + filename);
230 auto& model =
mModels[filename];
231 size_t sizeVertices = model->GetGpuVertexBufferSize();
232 size_t sizeIndices = model->GetGpuIndexBufferSize();
233 model->ReleaseFromGPU();
243 texture.second->ReleaseFromGPU();
250 LOG_INFO(
"Releasing all models. RAM usage: " +
261 auto search =
mModels.find(filename);
266 return search->second;
271 if (
auto search =
mModels.find(filename); search ==
mModels.end())
276 return mModels.at(filename)->GetMeshRenderResources();
298 model.second->UploadToGPU();
299 size_t sizeVertices = model.second->GetGpuVertexBufferSize();
301 size_t sizeIndices = model.second->GetGpuIndexBufferSize();
Interface for GPU mesh resource management.
Defines an abstract interface for rendering backends.
virtual void RegisterObserver(IRendererObserver *notifier)=0
Registers an observer for rendering events.
virtual void UnregisterObserver(IRendererObserver *notifier)=0
Unregisters a previously registered observer.
void CreateQuad2D()
Creates a built-in 2D quad mesh.
void ReleaseAll()
Remove all models from both GPU and RAM, clearing the cache.
void UploadModelToGPU(std::string filename)
Upload a cached model's mesh data to the GPU.
std::shared_ptr< MeshDataGpu > GetMeshResources(std::string filename)
Get a shared pointer to the MeshDataGpu for a model.
IMeshRenderResources * GetMeshRenderResources(std::string filename)
Get the IMeshRenderResources interface for a model's GPU resources.
std::unordered_map< std::string, std::shared_ptr< MeshDataGpu > > mModels
~ModelCache()
Destructor. Releases all resources and unregisters observer.
size_t GetSizeInRAM() const
Get the total size (in bytes) of all models loaded in RAM.
void LoadModelsFromFolder(std::string pathToFolder)
Load all models found in the specified folder into RAM.
size_t GetSizeInGPU() const
Get the total size (in bytes) of all models currently resident on GPU.
void OnRenderResourcesRebuild() override
Renderer callback: re-upload or recreate all GPU resources (used after device reset/rebuild).
std::string UploadModelToRAM(std::string path)
Load a single model from file into RAM.
void OnRenderResourcesRelease() override
Renderer callback: release all GPU resources (used during device loss/reset).
void LoadModelsFromPackage()
Load all models from the packed asset container.
void ReleaseAllFromGPU()
Release all model mesh data from GPU memory.
ModelCache(IRenderer *renderer)
Construct a ModelCache and register it with the given renderer.
void ReleaseModelFromGPU(std::string filename)
Release a model's mesh data from GPU memory.
void LoadCustomMesh(std::string meshName, std::vector< glm::vec2 > positions2D, std::vector< glm::vec2 > texCoords, std::vector< glm::vec4 > colors, std::vector< std::uint32_t > indices)
static const PackEntries & GetPackEntries()
Returns the manifest of packed files.
static std::vector< uint8_t > ReadPackedFile(const std::string &entryPath)
Reads raw bytes of a file stored inside Pack.bin.
Engine-wide logging system for runtime diagnostics and performance tracking.