#include "ResourceManager.h" #include #include #include #include #include #include "texture.h" #include "font.h" #include "MeshData.h" ResourceManager::~ResourceManager() { for (auto& [path, texture] : textures) { if (!texture) continue; texture->Delete(); delete texture; } for (Texture* texture : createdTextures) { texture->Delete(); delete texture; } for (auto& [path, font] : fonts) delete font; for (auto& [path, mesh] : meshes) delete mesh; } const MeshData* ResourceManager::GetMeshData(const std::string& path) { auto existing = meshes.find(path); if (existing != meshes.end()) return existing->second; // Pre-transforming bakes each node's placement in, so the merged meshes keep their layout Assimp::Importer importer; const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_JoinIdenticalVertices | aiProcess_PreTransformVertices); MeshData* data = nullptr; if (!scene || (scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE) || scene->mNumMeshes == 0) { std::cout << "RESOURCE MANAGER: couldn't load mesh " << path << ": " << importer.GetErrorString() << "\n"; } else { data = new MeshData(); for (unsigned int m = 0; m < scene->mNumMeshes; m++) { const aiMesh* mesh = scene->mMeshes[m]; const GLuint firstVertex = (GLuint)data->vertices.size(); for (unsigned int i = 0; i < mesh->mNumVertices; i++) { Vertex vertex; vertex.Position = glm::vec3(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z); vertex.Normal = mesh->HasNormals() ? glm::vec3(mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z) : glm::vec3(0.0f, 1.0f, 0.0f); vertex.TexCoords = mesh->mTextureCoords[0] ? glm::vec2(mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y) : glm::vec2(0.0f); data->vertices.push_back(vertex); } for (unsigned int f = 0; f < mesh->mNumFaces; f++) { for (unsigned int j = 0; j < mesh->mFaces[f].mNumIndices; j++) data->indices.push_back(firstVertex + mesh->mFaces[f].mIndices[j]); } } } meshes[path] = data; return data; } Texture* ResourceManager::CreateTexture(int width, int height) { createdTextures.push_back(new Texture(width, height)); return createdTextures.back(); } Texture* ResourceManager::CopyTexture(const Texture& source) { createdTextures.push_back(new Texture(source)); return createdTextures.back(); } // Failed loads are cached as nullptr too, so a missing file only gets reported once Texture* ResourceManager::GetTexture(const std::string& path) { auto existing = textures.find(path); if (existing != textures.end()) return existing->second; Texture* texture = nullptr; try { texture = new Texture(path.c_str()); } catch (const std::exception& error) { std::cout << "RESOURCE MANAGER: " << error.what() << "\n"; } textures[path] = texture; return texture; } Font* ResourceManager::GetFont(const std::string& path) { auto existing = fonts.find(path); if (existing != fonts.end()) return existing->second; Font* font = nullptr; try { font = new Font(path.c_str()); } catch (const std::exception& error) { std::cout << "RESOURCE MANAGER: " << error.what() << ": " << path << "\n"; } fonts[path] = font; return font; }