Rendering Engine 0.2.0
Modular Graphics Rendering Engine | v0.2.0
Loading...
Searching...
No Matches
model_cache.cpp
Go to the documentation of this file.
1#include "model_cache.hpp"
2#include "i_renderer.hpp"
3#include "boost/filesystem.hpp"
4#include "mesh_data_gpu.hpp"
5#include "utility.hpp"
6
7namespace rendering_engine
8{
9
11 :
12 mRenderer(renderer),
15{
16 mRenderer->RegisterObserver(this);
17}
18
20{
21 mRenderer->UnregisterObserver(this);
22}
23
24void ModelCache::LoadModelsFromFolder(std::string pathToFolder)
25{
26 // 1. Check if path is valid and exist
27 boost::filesystem::path pathToDirectory = boost::filesystem::path(pathToFolder);
28 const bool isValidFolderPath = boost::filesystem::exists(boost::filesystem::path(pathToFolder)) && boost::filesystem::is_directory(boost::filesystem::path(pathToFolder));
29 if (!isValidFolderPath)
30 {
31 return;
32 }
33 // 2. Iterate through files in the folder.
34 // if file is in the list of supported extensions
35 for (boost::filesystem::directory_entry& x : boost::filesystem::directory_iterator(pathToDirectory))
36 {
37 (void)UploadModelToRAM(x.path().string());
38 }
39}
40
42{
43 const auto& entries = Utility::GetPackEntries();
44
45 std::string folderEntry = { "Models/" };
46 for (auto& entry : entries)
47 {
48 const std::string& virtualPath = entry.first;
49 if (virtualPath.rfind(folderEntry, 0) == 0) // starts with Models/
50 {
51 std::string modelName = virtualPath.substr(folderEntry.size());
52
53 std::vector<uint8_t> binaryFileData = Utility::ReadPackedFile(virtualPath);
54 if (binaryFileData.empty())
55 {
56 std::cerr << "[TextureCache] Could not read packed texture: "
57 << virtualPath << std::endl;
58 continue;
59 }
60
61 // Upload to RAM with textureName + binaryFileData
62 (void)UploadModelToRAM(modelName, binaryFileData);
63 }
64 }
65}
66
68{
69 mModels["Quad2D"] = std::make_shared<MeshDataGpu>(mRenderer);
70 mModels["Quad2D"]->CreateQuad2D();
71
72 const size_t sizeVertices = mModels.at("Quad2D")->GetCpuVertexBufferSize();
73 mTotalSizeRAM += sizeVertices;
74 const size_t sizeIndices = mModels.at("Quad2D")->GetCpuIndexBufferSize();
75 mTotalSizeRAM += sizeIndices;
76}
77
78std::string ModelCache::UploadModelToRAM(std::string path)
79{
80 auto filePath = boost::filesystem::path(path);
81 if (!boost::filesystem::is_regular_file(filePath))
82 {
83 return std::string{};
84 }
85
86 const std::string ext = filePath.extension().string();
87 const bool isExtensionSupported = (ext == ".fbx");
88 if (!isExtensionSupported)
89 {
90 return std::string{};
91 }
92
93 std::string filename = filePath.stem().string();
94 // If model is already loaded into RAM yet, do not add again.
95 if (auto search = mModels.find(filename); search != mModels.end())
96 {
97 return std::string{};
98 }
99 mModels[filename] = std::make_shared<MeshDataGpu>(filePath.string(), mRenderer);
100
101 const size_t sizeVertices = mModels.at(filename)->GetCpuVertexBufferSize();
102 mTotalSizeRAM += sizeVertices;
103 const size_t sizeIndices = mModels.at(filename)->GetCpuIndexBufferSize();
104 mTotalSizeRAM += sizeIndices;
105
106 return filename;
107}
108
109std::string ModelCache::UploadModelToRAM(std::string fileName, std::vector<uint8_t> const& fileBytes)
110{
111 auto modelName = boost::filesystem::path(fileName).stem().string();
112
113 // If model is already loaded into RAM yet, do not add again.
114 if (auto search = mModels.find(modelName); search != mModels.end())
115 {
116 return std::string{};
117 }
118
119 mModels[modelName] = std::make_shared<MeshDataGpu>(fileBytes, mRenderer);
120
121 const size_t sizeVertices = mModels.at(modelName)->GetCpuVertexBufferSize();
122 mTotalSizeRAM += sizeVertices;
123 const size_t sizeIndices = mModels.at(modelName)->GetCpuIndexBufferSize();
124 mTotalSizeRAM += sizeIndices;
125
126 return modelName;
127}
128
129void ModelCache::UploadModelToGPU(std::string filename)
130{
131 // If texture is not loaded in RAM yet, skip loading to GPU.
132 if (auto search = mModels.find(filename); search == mModels.end())
133 {
134 return;
135 }
136 if (mModels[filename]->IsOnGPU())
137 {
138 return;
139 }
140
141 mModels[filename]->UploadToGPU();
142 size_t sizeVertices = mModels[filename]->GetGpuVertexBufferSize();
143 mTotalSizeGPU += sizeVertices;
144 size_t sizeIndices = mModels[filename]->GetGpuIndexBufferSize();
145 mTotalSizeGPU += sizeIndices;
146}
147
148void ModelCache::ReleaseModelFromGPU(std::string filename)
149{
150 if (auto search = mModels.find(filename); search == mModels.end())
151 {
152 return;
153 }
154
155 auto& model = mModels[filename];
156 size_t sizeVertices = model->GetGpuVertexBufferSize();
157 size_t sizeIndices = model->GetGpuIndexBufferSize();
158 model->ReleaseFromGPU();
159
160 mTotalSizeGPU -= sizeVertices;
161 mTotalSizeGPU -= sizeIndices;
162}
163
165{
166 for (auto& texture : mModels)
167 {
168 texture.second->ReleaseFromGPU();
169 }
170 mTotalSizeGPU = 0;
171}
172
174{
175 mModels.clear();
176 mTotalSizeRAM = 0;
177 mTotalSizeGPU = 0;
178}
179
180std::shared_ptr<MeshDataGpu> ModelCache::GetMeshResources(std::string filename)
181{
182 auto search = mModels.find(filename);
183 if (search == mModels.end())
184 {
185 return nullptr;
186 }
187 return search->second;
188}
189
191{
192 if (auto search = mModels.find(filename); search == mModels.end())
193 {
194 return nullptr;
195 }
196
197 return mModels.at(filename)->GetMeshRenderResources();
198}
199
201{
202 return mTotalSizeRAM;
203}
204
206{
207 return mTotalSizeGPU;
208}
209
214
216{
217 for (auto& model : mModels)
218 {
219 model.second->UploadToGPU();
220 size_t sizeVertices = model.second->GetGpuVertexBufferSize();
221 mTotalSizeGPU += sizeVertices;
222 size_t sizeIndices = model.second->GetGpuIndexBufferSize();
223 mTotalSizeGPU += sizeIndices;
224 }
225}
226
227} // namespace rendering_engine
Interface for GPU mesh resource management.
Defines an abstract interface for rendering backends.
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.
static const PackEntries & GetPackEntries()
Returns the manifest of packed files.
Definition utility.cpp:219
static std::vector< uint8_t > ReadPackedFile(const std::string &entryPath)
Reads raw bytes of a file stored inside Pack.bin.
Definition utility.cpp:260