From 1caf93ca6ecb1fc2f0112ed30bf5bdf044c227a8 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Mon, 29 Mar 2021 14:16:59 +0200 Subject: [PATCH 1/3] progess... --- data/lights.json | 2 +- data/res | 2 +- src/CMakeLists.txt | 1 + src/JsonParser.cpp | 32 +++++++++++++++++++++++++++----- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/data/lights.json b/data/lights.json index 846b679..a280e51 100644 --- a/data/lights.json +++ b/data/lights.json @@ -6,7 +6,7 @@ }, "pointLights": [ { - "intensity": 10.0, + "intensity": 4.0, "position": [0.0, 1.0, 0.0], "color": [1.0, 1.0, 1.0] } diff --git a/data/res b/data/res index 598d92b..1cf275e 160000 --- a/data/res +++ b/data/res @@ -1 +1 @@ -Subproject commit 598d92bdd62413d4110687d448bb49f38d83245e +Subproject commit 1cf275e513e9c4e5982d1458c534f651583fd0eb diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7150d19..26350aa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -29,6 +29,7 @@ target_link_libraries( ${OPENGL_LIBRARIES} ${FREETYPE_LIBRARIES} imgui + pthread ) target_compile_options(Fall-Fever PRIVATE -Wall -Wextra -pedantic) diff --git a/src/JsonParser.cpp b/src/JsonParser.cpp index 8e42fe8..702fdb1 100644 --- a/src/JsonParser.cpp +++ b/src/JsonParser.cpp @@ -2,6 +2,7 @@ #include #include +#include JsonParser::JsonParser(std::string path) { @@ -33,14 +34,35 @@ std::vector JsonParser::getModels() const Json::Value modelsJson = root["models"]; + struct ModelSkeleton { + std::string model_name; + std::string model_path; + }; + + std::vector model_skeletons; + for (unsigned int index = 0; index < modelsJson.size(); index++) { std::string model_name = modelsJson[index]["unique_name"].asString(); std::string model_path = modelsJson[index]["path"].asString(); - Model *current_model = new Model(model_name, model_path); - if(current_model) { - temp_models.push_back(current_model); - std::cout << "Loaded Model \"" << model_name << "\" from \"" << model_path << "\"" << std::endl; - } + ModelSkeleton model_skeleton = {model_name, model_path}; + model_skeletons.push_back(model_skeleton); + } + + std::vector> futures; + + std::mutex s_ModelsMutex; + auto* temp_models_ptr = &temp_models; + for (auto model_skeleton : model_skeletons) { + auto loadModel = [&]() { + Model *current_model = new Model(model_skeleton.model_name, model_skeleton.model_path); + if(current_model) { + std::lock_guard lock(s_ModelsMutex); + temp_models_ptr->push_back(current_model); + std::cout << "Loaded Model \"" << model_skeleton.model_name << "\" from \"" << model_skeleton.model_path << "\"" << std::endl; + } + }; + + futures.push_back(std::async(std::launch::async, loadModel)); } return temp_models; From 741f44e7d8cdf211d825a5922496eebd97525a3d Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Mon, 12 Apr 2021 20:37:05 +0200 Subject: [PATCH 2/3] Something with mesh loading does not work --- src/JsonParser.cpp | 30 ++++++++++++++++++++---------- src/Model.cpp | 4 ++-- src/Model.h | 4 ++-- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/JsonParser.cpp b/src/JsonParser.cpp index 702fdb1..eca4ca7 100644 --- a/src/JsonParser.cpp +++ b/src/JsonParser.cpp @@ -28,6 +28,17 @@ JsonParser::~JsonParser() } +static std::mutex s_ModelsMutex; + +static void loadModel(const std::string modelName, const std::string modelPath, std::vector* model_vec) { + Model *current_model = new Model(modelName, modelPath); + if(current_model) { + std::lock_guard lock(s_ModelsMutex); + model_vec->push_back(current_model); + std::cout << "Loaded Model \"" << modelName << "\" from \"" << modelPath << "\"" << std::endl; + } +} + std::vector JsonParser::getModels() { std::vector temp_models; @@ -50,20 +61,19 @@ std::vector JsonParser::getModels() std::vector> futures; - std::mutex s_ModelsMutex; auto* temp_models_ptr = &temp_models; - for (auto model_skeleton : model_skeletons) { - auto loadModel = [&]() { - Model *current_model = new Model(model_skeleton.model_name, model_skeleton.model_path); + for (const auto& model_skeleton : model_skeletons) { + /*auto loadModel = [](const std::string& modelName, const std::string& modelPath, std::mutex& mutex, std::vector* model_vec) { + Model *current_model = new Model(modelName, modelPath); if(current_model) { - std::lock_guard lock(s_ModelsMutex); - temp_models_ptr->push_back(current_model); - std::cout << "Loaded Model \"" << model_skeleton.model_name << "\" from \"" << model_skeleton.model_path << "\"" << std::endl; + std::lock_guard lock(mutex); + model_vec->push_back(current_model); + std::cout << "Loaded Model \"" << modelName << "\" from \"" << modelPath << "\"" << std::endl; } - }; + };*/ - futures.push_back(std::async(std::launch::async, loadModel)); - } + futures.push_back(std::async(std::launch::async, loadModel, model_skeleton.model_name, model_skeleton.model_path, temp_models_ptr)); + } return temp_models; } diff --git a/src/Model.cpp b/src/Model.cpp index 49ea3cb..21265d3 100644 --- a/src/Model.cpp +++ b/src/Model.cpp @@ -5,7 +5,7 @@ uint32_t Model::id_counter = 0; -Model::Model(std::string &modelName, std::string &modelPath) : +Model::Model(const std::string &modelName, const std::string &modelPath) : unique_name(modelName) { directory = modelPath.substr(0, modelPath.find_last_of('/')); @@ -38,7 +38,7 @@ void Model::drawWithoutTextures() } } -void Model::loadModel(std::string &pathToModel) +void Model::loadModel(const std::string &pathToModel) { std::ifstream input(pathToModel, std::ios::in | std::ios::binary); diff --git a/src/Model.h b/src/Model.h index 03e35f4..4df2697 100644 --- a/src/Model.h +++ b/src/Model.h @@ -8,7 +8,7 @@ class Model { public: - Model(std::string &modelName, std::string &pathToModel); + Model(const std::string& modelName, const std::string& pathToModel); ~Model(); void draw(ShaderProgram *shaderProgram); @@ -18,7 +18,7 @@ public: std::string getUniqueName(); private: - void loadModel(std::string &pathToModel); + void loadModel(const std::string &pathToModel); private: std::vector meshes; From d3c755713d293863b58a57c1e4e78a6ea6d3fea0 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Tue, 13 Apr 2021 20:29:29 +0200 Subject: [PATCH 3/3] Working Multithreading --- src/JsonParser.cpp | 26 +++++++--------------- src/JsonParser.h | 2 +- src/Model.cpp | 54 ++++++++++++++++++++++++++++++++++++++++------ src/Model.h | 18 ++++++++++++++++ src/Texture.cpp | 8 +++---- src/Texture.h | 2 +- src/World.cpp | 5 +++++ 7 files changed, 83 insertions(+), 32 deletions(-) diff --git a/src/JsonParser.cpp b/src/JsonParser.cpp index eca4ca7..6036d0a 100644 --- a/src/JsonParser.cpp +++ b/src/JsonParser.cpp @@ -4,7 +4,7 @@ #include #include -JsonParser::JsonParser(std::string path) +JsonParser::JsonParser(const std::string& path) { std::ifstream file(path.c_str(), std::ifstream::binary); @@ -28,17 +28,6 @@ JsonParser::~JsonParser() } -static std::mutex s_ModelsMutex; - -static void loadModel(const std::string modelName, const std::string modelPath, std::vector* model_vec) { - Model *current_model = new Model(modelName, modelPath); - if(current_model) { - std::lock_guard lock(s_ModelsMutex); - model_vec->push_back(current_model); - std::cout << "Loaded Model \"" << modelName << "\" from \"" << modelPath << "\"" << std::endl; - } -} - std::vector JsonParser::getModels() { std::vector temp_models; @@ -60,19 +49,20 @@ std::vector JsonParser::getModels() } std::vector> futures; + std::mutex mutex; auto* temp_models_ptr = &temp_models; for (const auto& model_skeleton : model_skeletons) { - /*auto loadModel = [](const std::string& modelName, const std::string& modelPath, std::mutex& mutex, std::vector* model_vec) { - Model *current_model = new Model(modelName, modelPath); + auto loadModel = [&]() { + Model *current_model = new Model(model_skeleton.model_name, model_skeleton.model_path); if(current_model) { std::lock_guard lock(mutex); - model_vec->push_back(current_model); - std::cout << "Loaded Model \"" << modelName << "\" from \"" << modelPath << "\"" << std::endl; + temp_models_ptr->push_back(current_model); + std::cout << "Loaded Model \"" << model_skeleton.model_name << "\" from \"" << model_skeleton.model_path << "\"" << std::endl; } - };*/ + }; - futures.push_back(std::async(std::launch::async, loadModel, model_skeleton.model_name, model_skeleton.model_path, temp_models_ptr)); + futures.push_back(std::async(std::launch::async, loadModel)); } return temp_models; diff --git a/src/JsonParser.h b/src/JsonParser.h index db15ed6..f0a3959 100644 --- a/src/JsonParser.h +++ b/src/JsonParser.h @@ -13,7 +13,7 @@ class JsonParser { public: - JsonParser(std::string path); + JsonParser(const std::string& path); ~JsonParser(); std::vector getModels(); diff --git a/src/Model.cpp b/src/Model.cpp index 21265d3..2c73d97 100644 --- a/src/Model.cpp +++ b/src/Model.cpp @@ -24,6 +24,11 @@ Model::~Model() void Model::draw(ShaderProgram *shaderProgram) { + if (!model_prepared) { + std::cout << "WARNING: Model not prepared! Unable to draw!" << std::endl; + return; + } + // Iterate through every mesh and call the draw function for (auto it = meshes.begin(); it != meshes.end(); it++) { (*it)->draw(shaderProgram); @@ -32,6 +37,11 @@ void Model::draw(ShaderProgram *shaderProgram) void Model::drawWithoutTextures() { + if (!model_prepared) { + std::cout << "WARNING: Model not prepared! Unable to draw!" << std::endl; + return; + } + // Iterate through every mesh and call the draw function for (auto it = meshes.begin(); it != meshes.end(); it++) { (*it)->drawWithoutTextures(); @@ -71,10 +81,15 @@ void Model::loadModel(const std::string &pathToModel) textureSources.push_back(currentTextureSource); } + for (unsigned int i = 0; i < numTextures; i++) { - std::string textureSource = directory + '/' + textureSources[i].c_str(); - Texture *newTex = new Texture(textureSource.c_str(), textureTypes[i]); - loadedTextures.push_back(newTex); + TexturePrototype texture_prototype; + std::string texturePath = directory + '/' + textureSources[i].c_str(); + + texture_prototype.texturePath = std::move(texturePath); + texture_prototype.textureType = textureTypes[i]; + + modelTexturePrototypes.push_back(texture_prototype); } // Here starts the first mesh @@ -83,6 +98,8 @@ void Model::loadModel(const std::string &pathToModel) for (unsigned int j = 0; j < numMeshes; j++) { + MeshPrototype mesh_prototype; + uint32_t numMeshVertices, numMeshIndices, numMeshTextureIds; input.read((char *) &numMeshVertices, sizeof(uint32_t)); @@ -97,25 +114,48 @@ void Model::loadModel(const std::string &pathToModel) std::vector meshVertices; meshVertices.resize(numMeshVertices); input.read((char *) meshVertices.data(), vertexBlockSize); + mesh_prototype.meshVertices = std::move(meshVertices); std::vector meshIndices; meshIndices.resize(numMeshIndices); input.read((char *) meshIndices.data(), indexBlockSize); + mesh_prototype.meshIndices = std::move(meshIndices); - std::vector meshTextures; for (unsigned int i = 0; i < numMeshTextureIds; i++) { uint32_t currentTextureId; input.read((char *) ¤tTextureId, sizeof(uint32_t)); - meshTextures.push_back(loadedTextures[currentTextureId]); + mesh_prototype.textureIds.push_back(currentTextureId); } - Mesh *currentMesh = new Mesh(meshVertices, meshIndices, meshTextures); - meshes.push_back(currentMesh); + modelMeshPrototypes.push_back(std::move(mesh_prototype)); } input.close(); } +void Model::prepareModel() +{ + model_prepared = true; + + // Create textures on GPU + for (auto& it : modelTexturePrototypes) { + Texture *newTex = new Texture(it.texturePath.c_str(), it.textureType); + loadedTextures.push_back(newTex); + } + + // Create meshes on GPU + for (const auto& it : modelMeshPrototypes) { + std::vector meshTextures; + for (const auto it2 : it.textureIds) { + meshTextures.push_back(loadedTextures[it2]); + } + + Mesh *currentMesh = new Mesh(std::move(it.meshVertices), std::move(it.meshIndices), meshTextures); + meshes.push_back(currentMesh); + } +} + + Mesh* Model::getMesh(unsigned int index) { return meshes[index]; diff --git a/src/Model.h b/src/Model.h index 4df2697..b94ffc9 100644 --- a/src/Model.h +++ b/src/Model.h @@ -5,12 +5,25 @@ #include "Mesh.h" +struct TexturePrototype { + uint32_t textureType; + std::string texturePath; +}; + +struct MeshPrototype { + std::vector textureIds; + std::vector meshVertices; + std::vector meshIndices; +}; + class Model { public: Model(const std::string& modelName, const std::string& pathToModel); ~Model(); + void prepareModel(); + void draw(ShaderProgram *shaderProgram); void drawWithoutTextures(); @@ -24,8 +37,13 @@ private: std::vector meshes; std::vector loadedTextures; + std::vector modelTexturePrototypes; + std::vector modelMeshPrototypes; + std::string directory; + bool model_prepared = false; + static uint32_t id_counter; uint32_t id; std::string unique_name; diff --git a/src/Texture.cpp b/src/Texture.cpp index 87fd51a..cbe5a0f 100644 --- a/src/Texture.cpp +++ b/src/Texture.cpp @@ -3,13 +3,11 @@ #include #include -Texture::Texture(const char *texturePath, uint8_t textureType) +Texture::Texture(const std::string& texturePath, uint8_t textureType) : + texturePath(texturePath), textureType(textureType) { - this->texturePath = texturePath; - this->textureType = textureType; - stbi_set_flip_vertically_on_load(1); - auto *textureBuffer = stbi_load(texturePath, &textureWidth, &textureHeight, &numComponents, 0); + auto *textureBuffer = stbi_load(texturePath.c_str(), &textureWidth, &textureHeight, &numComponents, 0); GLenum internalFormat; GLenum dataFormat; diff --git a/src/Texture.h b/src/Texture.h index d15b23c..871fbcb 100644 --- a/src/Texture.h +++ b/src/Texture.h @@ -15,7 +15,7 @@ enum cubeMapFaces {cm_right, cm_left, cm_top, cm_bottom, cm_back, cm_front, CUBE class Texture { public: - Texture(const char *texturePath, uint8_t textureType); + Texture(const std::string& texturePath, uint8_t textureType); ~Texture(); void bind(uint8_t textureUnit, ShaderProgram *shaderProgram, uint8_t textureTypeNum); diff --git a/src/World.cpp b/src/World.cpp index 157b1f5..f2fc013 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -21,6 +21,11 @@ World::World(std::vector shaderPrograms) : JsonParser modelParser("data/models.json"); models = modelParser.getModels(); + + for (const auto& it : models) { + it->prepareModel(); + } + entities = modelParser.getEntities(models, shaderPrograms); skybox = modelParser.getSkybox(getModelByName("cube"), Controller::getShaderProgramByName(shaderPrograms, "skyboxProgram"));