From ad7ec85dced7245b2952b7eabdc02914c55bfe71 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Sun, 10 Jan 2021 22:08:57 +0100 Subject: [PATCH] Load resources from Json file --- res/models.json | 36 ++++++++++++++ res/shaderPrograms.json | 40 +++++++++++++++ src/Controller.cpp | 107 ++++++++++++++++++++------------------- src/Controller.h | 18 +++---- src/Entity.cpp | 10 ++-- src/Entity.h | 9 +++- src/JsonParser.cpp | 108 ++++++++++++++++++++++++++++++++++++++++ src/JsonParser.h | 25 ++++++++++ src/Light.h | 2 + src/Menu.h | 1 + src/Model.cpp | 15 +++--- src/Model.h | 14 +++++- src/ShaderProgram.cpp | 16 +++--- src/ShaderProgram.h | 10 +++- src/World.cpp | 82 +++++++++++++++++++++++++----- src/World.h | 20 +++++--- 16 files changed, 409 insertions(+), 104 deletions(-) create mode 100644 res/models.json create mode 100644 res/shaderPrograms.json create mode 100644 src/JsonParser.cpp create mode 100644 src/JsonParser.h diff --git a/res/models.json b/res/models.json new file mode 100644 index 0000000..ac280c2 --- /dev/null +++ b/res/models.json @@ -0,0 +1,36 @@ +{ + "models": [ + { + "unique_name": "backpack", + "path": "res/models/backpack.ffo" + }, + { + "unique_name": "ground", + "path": "res/models/wood_floor.ffo" + }, + { + "unique_name": "cube", + "path": "res/models/cube.ffo" + } + ], + "entities": [ + { + "unique_name": "backpack", + "model": "backpack", + "shaderProgram": "defaultProgram" + }, + { + "unique_name": "ground", + "model": "ground", + "shaderProgram": "defaultProgram" + }, + { + "unique_name": "light", + "model": "cube", + "shaderProgram": "lightProgram" + } + ], + "skybox": { + "texturePath": "res/textures/skybox/" + } +} diff --git a/res/shaderPrograms.json b/res/shaderPrograms.json new file mode 100644 index 0000000..85af681 --- /dev/null +++ b/res/shaderPrograms.json @@ -0,0 +1,40 @@ +{ + "shaderPrograms": [ + { + "unique_name": "defaultProgram", + "vertexPath": "res/shaders/basic.vert", + "fragmentPath": "res/shaders/basic.frag" + }, + { + "unique_name": "lightProgram", + "vertexPath": "res/shaders/light.vert", + "fragmentPath": "res/shaders/light.frag" + }, + { + "unique_name": "skyboxProgram", + "vertexPath": "res/shaders/skybox.vert", + "fragmentPath": "res/shaders/skybox.frag" + }, + { + "unique_name": "postProcessingProgram", + "vertexPath": "res/shaders/postprocessing.vert", + "fragmentPath": "res/shaders/postprocessing.frag" + }, + { + "unique_name": "menuProgram", + "vertexPath": "res/shaders/menu.vert", + "fragmentPath": "res/shaders/menu.frag" + }, + { + "unique_name": "directionalShadowDepthProgram", + "vertexPath": "res/shaders/directionalShadowDepth.vert", + "fragmentPath": "res/shaders/directionalShadowDepth.frag" + }, + { + "unique_name": "pointShadowDepthProgram", + "vertexPath": "res/shaders/pointShadowDepth.vert", + "fragmentPath": "res/shaders/pointShadowDepth.frag", + "geometryPath": "res/shaders/pointShadowDepth.geom" + } + ] +} diff --git a/src/Controller.cpp b/src/Controller.cpp index cbfc07d..8ee6339 100644 --- a/src/Controller.cpp +++ b/src/Controller.cpp @@ -27,6 +27,7 @@ #include "World.h" #include "Widget.h" #include "Screen.h" +#include "JsonParser.h" Controller::Controller() { @@ -47,16 +48,11 @@ Controller::Controller() camera = new Camera(90.0f, gameWindow->getWindowAspectRatio()); - shaderProgram = new ShaderProgram("res/shaders/basic.vert", "res/shaders/basic.frag"); - lightProgram = new ShaderProgram("res/shaders/light.vert", "res/shaders/light.frag"); - skyboxProgram = new ShaderProgram("res/shaders/skybox.vert", "res/shaders/skybox.frag"); - postProcessingProgram = new ShaderProgram("res/shaders/postprocessing.vert", "res/shaders/postprocessing.frag"); - menuProgram = new ShaderProgram("res/shaders/menu.vert", "res/shaders/menu.frag"); - directionalShadowDepthProgram = new ShaderProgram("res/shaders/directionalShadowDepth.vert", "res/shaders/directionalShadowDepth.frag"); - pointShadowDepthProgram = new ShaderProgram("res/shaders/pointShadowDepth.vert", "res/shaders/pointShadowDepth.geom", "res/shaders/pointShadowDepth.frag"); + JsonParser shaderParser("res/shaderPrograms.json"); + shaderPrograms = shaderParser.getShaderPrograms(); - pp_framebuffer = new Framebuffer(INIT_WINDOW_WIDTH, INIT_WINDOW_HEIGHT, postProcessingProgram); - menu = new Menu(pp_framebuffer, menuProgram); + pp_framebuffer = new Framebuffer(INIT_WINDOW_WIDTH, INIT_WINDOW_HEIGHT, getShaderProgramByName("postProcessingProgram")); + menu = new Menu(pp_framebuffer, getShaderProgramByName("menuProgram")); #ifdef _DEBUG glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); @@ -87,13 +83,9 @@ Controller::~Controller() delete gameEventHandler; delete camera; - delete shaderProgram; - delete lightProgram; - delete skyboxProgram; - delete postProcessingProgram; - delete menuProgram; - delete directionalShadowDepthProgram; - delete pointShadowDepthProgram; + for (auto it = shaderPrograms.begin(); it != shaderPrograms.end(); it++) { + delete *it; + } delete pp_framebuffer; delete menu; @@ -104,33 +96,23 @@ void Controller::run() { glClearColor(0.0015f, 0.0015f, 0.0015f, 1.0f); - updateExposure(postProcessingProgram); + updateExposure(getShaderProgramByName("postProcessingProgram")); // Show loading screen... glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); menu->showLoadingScreen(); glfwSwapBuffers(gameWindow->getGLFWwindow()); - Model model_backpack("res/models/backpack.ffo"); - Model model_cube("res/models/cube.ffo"); - //Model model_dragon("res/models/dragon.ffo"); - Model model_ground("res/models/wood_floor.ffo"); + World world(shaderPrograms); - Entity backpack(&model_backpack, shaderProgram); - Entity ground(&model_ground, shaderProgram); - Entity lightSource(&model_cube, lightProgram); + Model *skyboxModel = world.getModelByName("cube"); + Skybox skybox(skyboxModel, getShaderProgramByName("skyboxProgram"), "res/textures/skybox/"); - lightSource.setScale(0.1f); - lightSource.setRotation(glm::vec3(0.f)); - lightSource.setPosition(glm::vec3(-2.f, 1.5f, 2.f)); - lightSource.setIsLightSource(true); - - Skybox skybox(&model_cube, skyboxProgram, "res/textures/skybox/"); - - World world(shaderProgram); - world.addEntity(backpack); - world.addEntity(lightSource); - world.addEntity(ground); + Entity *lightSource = world.getEntityByName("light"); + lightSource->setScale(0.1f); + lightSource->setRotation(glm::vec3(0.f)); + lightSource->setPosition(glm::vec3(-2.f, 1.5f, 2.f)); + lightSource->setIsLightSource(true); camera->translate(glm::vec3(0.0f, 1.5f, 5.0f)); @@ -145,30 +127,30 @@ void Controller::run() if (rotateLightSource) { float radius = 4.0; glm::vec3 newPos = glm::vec3(-cos(glfwGetTime() * 0.5), 0.5f, sin(glfwGetTime() * 0.5)) * radius; - world.getEntities()->operator[](1).setPosition(newPos); + world.getEntityByName("light")->setPosition(newPos); } if (rotateEntity) { - world.getEntities()->operator[](0).rotate(glm::vec3(0.0f, 1.0f, 0.0f), 0.2f * deltaTime); + world.getEntityById(0)->rotate(glm::vec3(0.0f, 1.0f, 0.0f), -0.2f * deltaTime); } static glm::vec3 lightColor = glm::vec3(1.f); static float intensity = 20.f; - world.updatePointLight(0, true, world.getEntities()->operator[](1).getPosition(), lightColor * intensity); + world.updatePointLight(0, true, world.getEntityByName("light")->getPosition(), lightColor * intensity); world.updateDirectionalLight(true, glm::vec3(-0.2f, -1.0f, -0.3f), lightColor * 0.25f); - lightProgram->bind(); - lightProgram->setUniform("v_lightColor", lightColor * 100.0f); - lightProgram->unbind(); + getShaderProgramByName("lightProgram")->bind(); + getShaderProgramByName("lightProgram")->setUniform("v_lightColor", lightColor * 100.0f); + getShaderProgramByName("lightProgram")->unbind(); // --- Render and buffer swap --- // Calc shadows static bool drawShadows = false; static bool firstRun = true; - shaderProgram->bind(); - shaderProgram->setUniform("b_drawShadows", (int)drawShadows); - shaderProgram->unbind(); + getShaderProgramByName("defaultProgram")->bind(); + getShaderProgramByName("defaultProgram")->setUniform("b_drawShadows", (int)drawShadows); + getShaderProgramByName("defaultProgram")->unbind(); if (drawShadows || firstRun) { firstRun = false; - world.calculateShadows(directionalShadowDepthProgram, pointShadowDepthProgram); + world.calculateShadows(getShaderProgramByName("directionalShadowDepthProgram"), getShaderProgramByName("pointShadowDepthProgram")); } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -188,14 +170,14 @@ void Controller::run() pp_framebuffer->render(); #ifdef _DEBUG - renderImGui(world.getEntities(), &world.getPointLights()[0], &lightColor, &rotateEntity, &rotateLightSource, postProcessingProgram, &intensity, &drawShadows); + renderImGui(world, &world.getPointLights()[0], &lightColor, &rotateEntity, &rotateLightSource, getShaderProgramByName("postProcessingProgram"), &intensity, &drawShadows); #endif glfwSwapBuffers(gameWindow->getGLFWwindow()); // Update window size if (gameWindow->checkWindowWasResized()) { - updateWindowSize(postProcessingProgram); + updateWindowSize(getShaderProgramByName("postProcessingProgram")); } // --- Check events, handle input --- @@ -255,8 +237,30 @@ void Controller::updateExposure(ShaderProgram *shaderProgram) shaderProgram->unbind(); } +ShaderProgram* Controller::getShaderProgramByName(const char *name) +{ + for (auto it = shaderPrograms.begin(); it != shaderPrograms.end(); it++) { + if((*it)->getUniqueName() == name) { + return *it; + } + } + std::cout << "[Warning] ShaderProgram could not be found by name \"" << name << "\"" << std::endl; + return nullptr; +} + +ShaderProgram* Controller::getShaderProgramByName(std::vector shaderPrograms, const char *name) +{ + for (auto it = shaderPrograms.begin(); it != shaderPrograms.end(); it++) { + if((*it)->getUniqueName() == name) { + return *it; + } + } + std::cout << "[Warning] ShaderProgram could not be found by name \"" << name << "\"" << std::endl; + return nullptr; +} + #ifdef _DEBUG -void Controller::renderImGui(std::vector *entites, PointLight *pointLight, glm::vec3 *lightColor, bool *rotateEntity, bool *rotateLightSource, ShaderProgram *postProcessingProgram, float *intensity, bool *drawShadows) +void Controller::renderImGui(World &world, PointLight *pointLight, glm::vec3 *lightColor, bool *rotateEntity, bool *rotateLightSource, ShaderProgram *postProcessingProgram, float *intensity, bool *drawShadows) { ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); @@ -274,11 +278,12 @@ void Controller::renderImGui(std::vector *entites, PointLight *pointLigh ImGui::SliderFloat("Scale", &scale, 0.02, 2.0); ImGui::Checkbox("Rotate Object", rotateEntity); - entites->operator[](0).setPosition(glm::vec3(translation[0], translation[1], translation[2])); + Entity *mainObject = world.getEntityById(0); + mainObject->setPosition(glm::vec3(translation[0], translation[1], translation[2])); if (!*rotateEntity) { - entites->operator[](0).setRotation(glm::vec3(0.f, 1.0f, 0.f), rotation); + mainObject->setRotation(glm::vec3(0.f, 1.0f, 0.f), rotation); } - entites->operator[](0).setScale(scale); + mainObject->setScale(scale); // color picker ImGui::Text("\nLight Source"); diff --git a/src/Controller.h b/src/Controller.h index bf48b74..ed2e311 100644 --- a/src/Controller.h +++ b/src/Controller.h @@ -11,6 +11,7 @@ #include "Light.h" #include "Framebuffer.h" #include "Menu.h" +#include "World.h" class Controller @@ -21,6 +22,7 @@ public: void run(); + static ShaderProgram* getShaderProgramByName(std::vector shaderPrograms, const char *name); static void error_callback(int error, const char *description); private: @@ -29,23 +31,15 @@ private: void updateWindowSize(ShaderProgram *pp_program); void updateExposure(ShaderProgram *shaderProgram); - void renderImGui(std::vector *entites, PointLight *pointLight, glm::vec3 *lightColor, bool *rotateEntity, bool *rotateLightSource, ShaderProgram *postProcessingProgram, float *intensity, bool *drawShadows); + ShaderProgram* getShaderProgramByName(const char *name); + + void renderImGui(World &world, PointLight *pointLight, glm::vec3 *lightColor, bool *rotateEntity, bool *rotateLightSource, ShaderProgram *postProcessingProgram, float *intensity, bool *drawShadows); Window *gameWindow; EventHandler *gameEventHandler; Camera *camera; - /*struct shaderProgram { - - }*/ - - ShaderProgram *shaderProgram; - ShaderProgram *lightProgram; - ShaderProgram *skyboxProgram; - ShaderProgram *postProcessingProgram; - ShaderProgram *menuProgram; - ShaderProgram *directionalShadowDepthProgram; - ShaderProgram *pointShadowDepthProgram; + std::vector shaderPrograms; Framebuffer *pp_framebuffer; diff --git a/src/Entity.cpp b/src/Entity.cpp index 5b9bfcd..875bc82 100644 --- a/src/Entity.cpp +++ b/src/Entity.cpp @@ -3,14 +3,14 @@ #include #include +uint32_t Entity::id_counter = 0; -Entity::Entity(Model *model, ShaderProgram *shaderProgram) : +Entity::Entity(std::string name, Model *model, ShaderProgram *shaderProgram) : + unique_name(name), model(model), shaderProgram(shaderProgram) { - - // Empty... - + id = id_counter++; } void Entity::draw(glm::mat4 viewProjMatrix, glm::vec3 viewPosition) @@ -38,7 +38,7 @@ void Entity::drawDirectionalShadows(glm::mat4 viewProjMatrix, ShaderProgram *p_s p_shaderProgram->bind(); glm::mat4 modelViewProj = viewProjMatrix * modelMatrix; - shaderProgram->setUniform("u_modelViewProjMatrix", modelViewProj); + shaderProgram->setUniform("u_modelViewProjMatrix", modelViewProj); // wtf is this // Draw the model model->drawWithoutTextures(); diff --git a/src/Entity.h b/src/Entity.h index 96d7f3c..87c9175 100644 --- a/src/Entity.h +++ b/src/Entity.h @@ -10,7 +10,7 @@ class Entity { public: - Entity(Model *model, ShaderProgram *shaderProgram); + Entity(std::string name, Model *model, ShaderProgram *shaderProgram); ~Entity() = default; void draw(glm::mat4 viewProjMatrix, glm::vec3 viewPosition); @@ -38,6 +38,10 @@ public: { return id; } + std::string getUniqueName() + { + return unique_name; + } glm::vec3 getPosition() { @@ -55,7 +59,10 @@ public: private: void updateModelMatrix(); + static uint32_t id_counter; uint32_t id; + std::string unique_name; + bool isLightSource = false; glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f); diff --git a/src/JsonParser.cpp b/src/JsonParser.cpp new file mode 100644 index 0000000..88b6d25 --- /dev/null +++ b/src/JsonParser.cpp @@ -0,0 +1,108 @@ +#include "JsonParser.h" + +#include +#include + +JsonParser::JsonParser(std::string path) +{ + std::ifstream file(path.c_str(), std::ifstream::binary); + + if (!file) { + std::cout << "Error reading file \"" << path << "\"." << std::endl; + return; + } + + std::string errs; + rbuilder["collectComments"] = false; + bool parsingSuccessful = Json::parseFromStream(rbuilder, file, &root, &errs); + file.close(); + if (!parsingSuccessful) { + std::cout << "Failed to parse file\n" << errs << std::endl; + return; + } +} + +JsonParser::~JsonParser() +{ + +} + +std::vector JsonParser::getModels() +{ + std::vector temp_models; + + const Json::Value modelsJson = root["models"]; + + 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); + temp_models.push_back(current_model); + std::cout << "Loaded Model \"" << model_name << "\" from \"" << model_path << "\"" << std::endl; + } + + return temp_models; +} + +std::vector JsonParser::getEntities(std::vector &models, std::vector shaderPrograms) +{ + std::vector temp_entities; + + const Json::Value entitiesJson = root["entities"]; + + for (unsigned int index = 0; index < entitiesJson.size(); index++) { + std::string entity_name = entitiesJson[index]["unique_name"].asString(); + std::string entity_model = entitiesJson[index]["model"].asString(); + std::string entity_shaderProgram = entitiesJson[index]["shaderProgram"].asString(); + + ShaderProgram *shaderProgram = nullptr; + for (auto it = shaderPrograms.begin(); it != shaderPrograms.end(); it++) { + if((*it)->getUniqueName() == entity_shaderProgram) { + shaderProgram = *it; + } + } + if(!shaderProgram) + std::cout << "[Warning] ShaderProgram could not be found by name \"" << entity_shaderProgram << "\"" << std::endl; + + Model *current_model = nullptr; + for (auto it = models.begin(); it != models.end(); it++) { + if((*it)->getUniqueName() == entity_model) { + current_model = *it; + } + } + if(!current_model) + std::cout << "[Warning] Model could not be found by unique name \"" << entity_model << "\"" << std::endl; + + Entity *current_entity = new Entity(entity_name, current_model, shaderProgram); + temp_entities.push_back(current_entity); + std::cout << "Loaded Entity \"" << entity_name << "\" with model \"" << entity_model << "\"" << std::endl; + } + + return temp_entities; +} + +std::vector JsonParser::getShaderPrograms() +{ + std::vector temp_shaderPrograms; + + const Json::Value shaderProgramsJson = root["shaderPrograms"]; + + for (unsigned int index = 0; index < shaderProgramsJson.size(); index++) { + std::string shaderProgram_name = shaderProgramsJson[index]["unique_name"].asString(); + std::string shaderProgram_vertexPath = shaderProgramsJson[index]["vertexPath"].asString(); + std::string shaderProgram_fragmentPath = shaderProgramsJson[index]["fragmentPath"].asString(); + std::string shaderProgram_geometryPath = shaderProgramsJson[index]["geometryPath"].asString(); + + ShaderProgram *current_shaderProgram; + if(shaderProgram_geometryPath.empty()) { + current_shaderProgram = new ShaderProgram(shaderProgram_name, shaderProgram_vertexPath, shaderProgram_fragmentPath); + } else { + current_shaderProgram = new ShaderProgram(shaderProgram_name, shaderProgram_vertexPath, shaderProgram_geometryPath, shaderProgram_fragmentPath); + } + temp_shaderPrograms.push_back(current_shaderProgram); + std::cout << "Loaded ShaderProgram \"" << shaderProgram_name << "\"" << std::endl; + } + + return temp_shaderPrograms; +} + diff --git a/src/JsonParser.h b/src/JsonParser.h new file mode 100644 index 0000000..9c9f5c6 --- /dev/null +++ b/src/JsonParser.h @@ -0,0 +1,25 @@ +#pragma once + +#include "Model.h" +#include "Entity.h" +#include "ShaderProgram.h" + +#include +#include +#include + +class JsonParser +{ +public: + JsonParser(std::string path); + ~JsonParser(); + + std::vector getModels(); + std::vector getEntities(std::vector &models, std::vector shaderPrograms); + + std::vector getShaderPrograms(); + +private: + Json::Value root; + Json::CharReaderBuilder rbuilder; +}; diff --git a/src/Light.h b/src/Light.h index e273d4c..c07bb91 100644 --- a/src/Light.h +++ b/src/Light.h @@ -38,6 +38,7 @@ public: protected: Light(ShaderProgram *shaderProgram) : shaderProgram(shaderProgram) {} + ~Light() {} ShaderProgram *shaderProgram; @@ -55,6 +56,7 @@ class PointLight : public Light { public: PointLight(ShaderProgram *shaderProgram); + ~PointLight() = default; void setPosition(glm::vec3 position) { diff --git a/src/Menu.h b/src/Menu.h index 75ca947..446b592 100644 --- a/src/Menu.h +++ b/src/Menu.h @@ -2,6 +2,7 @@ #include "Screen.h" #include "Framebuffer.h" +#include "JsonParser.h" class Menu { diff --git a/src/Model.cpp b/src/Model.cpp index 71234a3..634ff4b 100644 --- a/src/Model.cpp +++ b/src/Model.cpp @@ -3,12 +3,15 @@ #include #include -Model::Model(const char *pathToModel) -{ - std::string modelSource = pathToModel; - directory = modelSource.substr(0, modelSource.find_last_of('/')); +uint32_t Model::id_counter = 0; - loadModel(pathToModel); +Model::Model(std::string &modelName, std::string &modelPath) : + unique_name(modelName) +{ + directory = modelPath.substr(0, modelPath.find_last_of('/')); + + loadModel(modelPath); + id = id_counter++; } Model::~Model() @@ -35,7 +38,7 @@ void Model::drawWithoutTextures() } } -void Model::loadModel(std::string pathToModel) +void Model::loadModel(std::string &pathToModel) { std::ifstream input(pathToModel, std::ios::in | std::ios::binary); diff --git a/src/Model.h b/src/Model.h index abfccff..03b4086 100644 --- a/src/Model.h +++ b/src/Model.h @@ -8,7 +8,7 @@ class Model { public: - Model(const char *pathToModel); + Model(std::string &modelName, std::string &pathToModel); ~Model(); void draw(ShaderProgram *shaderProgram); @@ -19,12 +19,22 @@ public: return meshes[index]; } + std::string getUniqueName() + { + return unique_name; + } + private: - void loadModel(std::string pathToModel); + void loadModel(std::string &pathToModel); std::vector meshes; std::vector loadedTextures; std::string directory; + + static uint32_t id_counter; + uint32_t id; + std::string unique_name; + }; diff --git a/src/ShaderProgram.cpp b/src/ShaderProgram.cpp index 6fef87f..436e48b 100644 --- a/src/ShaderProgram.cpp +++ b/src/ShaderProgram.cpp @@ -5,10 +5,11 @@ #include "ShaderProgram.h" -ShaderProgram::ShaderProgram(const char *vertexShaderPath, const char *fragmentShaderPath) +ShaderProgram::ShaderProgram(std::string &name, std::string &vertexShaderPath, std::string &fragmentShaderPath) : + unique_name(name) { - std::string vertexShaderSource = parse(vertexShaderPath); - std::string fragmentShaderSource = parse(fragmentShaderPath); + std::string vertexShaderSource = parse(vertexShaderPath.c_str()); + std::string fragmentShaderSource = parse(fragmentShaderPath.c_str()); shaderProgramId = glCreateProgram(); GLuint vs = compile(vertexShaderSource, GL_VERTEX_SHADER); @@ -34,11 +35,12 @@ ShaderProgram::ShaderProgram(const char *vertexShaderPath, const char *fragmentS #endif } -ShaderProgram::ShaderProgram(const char *vertexShaderPath, const char *geometryShaderPath, const char *fragmentShaderPath) +ShaderProgram::ShaderProgram(std::string &name, std::string &vertexShaderPath, std::string &geometryShaderPath, std::string &fragmentShaderPath) : + unique_name(name) { - std::string vertexShaderSource = parse(vertexShaderPath); - std::string geometryShaderSource = parse(geometryShaderPath); - std::string fragmentShaderSource = parse(fragmentShaderPath); + std::string vertexShaderSource = parse(vertexShaderPath.c_str()); + std::string geometryShaderSource = parse(geometryShaderPath.c_str()); + std::string fragmentShaderSource = parse(fragmentShaderPath.c_str()); shaderProgramId = glCreateProgram(); GLuint vs = compile(vertexShaderSource, GL_VERTEX_SHADER); diff --git a/src/ShaderProgram.h b/src/ShaderProgram.h index 16eeaaa..8069e2d 100644 --- a/src/ShaderProgram.h +++ b/src/ShaderProgram.h @@ -7,8 +7,8 @@ class ShaderProgram { public: - ShaderProgram(const char *vertexShaderPath, const char *fragmentShaderPath); - ShaderProgram(const char *vertexShaderPath, const char *geometryShaderPath, const char *fragmentShaderPath); + ShaderProgram(std::string &name, std::string &vertexShaderPath, std::string &fragmentShaderPath); + ShaderProgram(std::string &name, std::string &vertexShaderPath, std::string &geometryShaderPath, std::string &fragmentShaderPath); ~ShaderProgram(); void bind(); @@ -27,9 +27,15 @@ public: return shaderProgramId; } + std::string getUniqueName() + { + return unique_name; + } + private: std::string parse(const char *filename); GLuint compile(std::string shaderSource, GLenum type); GLuint shaderProgramId; + std::string unique_name; }; diff --git a/src/World.cpp b/src/World.cpp index 2268ab6..5d49ddd 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1,10 +1,12 @@ #include "World.h" +#include "JsonParser.h" +#include "Controller.h" #include -World::World(ShaderProgram *shaderProgram) : - shaderProgram(shaderProgram), - directionalLight(shaderProgram), +World::World(std::vector shaderPrograms) : + shaderProgram(Controller::getShaderProgramByName(shaderPrograms, "defaultProgram")), + directionalLight(shaderProgram), // wtf is this depthMapDirectionalFBO(DEPTHMAP_NORMAL, SHADOW_RES) { // PointLights @@ -24,6 +26,10 @@ World::World(ShaderProgram *shaderProgram) : shaderProgram->bind(); shaderProgram->setUniform("u_material.shininess", 100.0f); shaderProgram->unbind(); + + JsonParser worldParser("res/models.json"); + models = worldParser.getModels(); + entities = worldParser.getEntities(models, shaderPrograms); } World::~World() @@ -32,26 +38,45 @@ World::~World() for (auto it = depthMapPointFBO.begin(); it != depthMapPointFBO.end(); it++) { delete (*it); } + // Iterate over models and entities and delete all items + for (auto it = models.begin(); it != models.end(); it++) { + delete (*it); + } + for (auto it = entities.begin(); it != entities.end(); it++) { + delete (*it); + } } -void World::addEntity(Entity entity) +void World::addEntity(Entity *entity) { - uint32_t new_id = entities.size(); - entity.setId(new_id); entities.push_back(entity); } -void World::removeEntity(uint32_t id) +void World::removeEntityByName(std::string name) { for (auto it = entities.begin(); it != entities.end(); it++) { - if (it->getId() == id) { + if ((*it)->getUniqueName() == name) { entities.erase(it); + return; } } - std::cout << "[Warning] Entity with ID " << id << " could not be removed." << std::endl; + std::cout << "[Warning] Entity with name " << name << " could not be removed." << std::endl; } +void World::clearEntities() +{ + for (auto it = entities.begin(); it != entities.end(); it++) { + entities.erase(it); + } +} + +void World::loadWorld ( unsigned int id ) +{ + // Load World from File... +} + + void World::updatePointLight(unsigned int lightId, bool active, glm::vec3 position, glm::vec3 color) { pointLights[lightId].setActive(active); @@ -71,7 +96,7 @@ void World::draw(glm::mat4 viewProjMatrix, glm::vec3 viewPosition) { // Draw all entities for (auto it = entities.begin(); it != entities.end(); it++) { - it->draw(viewProjMatrix, viewPosition); + (*it)->draw(viewProjMatrix, viewPosition); } // Calculate shadows (unclear if it should belong here or somewhere else) @@ -99,7 +124,7 @@ void World::calculateShadows(ShaderProgram *directionalShaderProgram, ShaderProg // Draw scene from light perspective // Draw all entities for (auto it = entities.begin(); it != entities.end(); it++) { - it->drawDirectionalShadows(directionalLightViewProjectionMatrix, directionalShaderProgram); + (*it)->drawDirectionalShadows(directionalLightViewProjectionMatrix, directionalShaderProgram); } depthMapDirectionalFBO.unbind(); @@ -147,7 +172,7 @@ void World::calculateShadows(ShaderProgram *directionalShaderProgram, ShaderProg // Draw scene from light perspective // Draw all entities for (auto it = entities.begin(); it != entities.end(); it++) { - it->drawPointShadows(pointShaderProgram); + (*it)->drawPointShadows(pointShaderProgram); } depthMapPointFBO[i]->unbind(); @@ -168,3 +193,36 @@ void World::calculateShadows(ShaderProgram *directionalShaderProgram, ShaderProg glViewport(VIEWPORT[0], VIEWPORT[1], VIEWPORT[2], VIEWPORT[3]); glCullFace(GL_FRONT); } + +Model* World::getModelByName(std::string name) +{ + for (auto it = models.begin(); it != models.end(); it++) { + if((*it)->getUniqueName() == name) { + return *it; + } + } + std::cout << "[Warning] Model could not be found by unique name \"" << name << "\"" << std::endl; + return nullptr; +} + +Entity* World::getEntityByName(std::string name) +{ + for (auto it = entities.begin(); it != entities.end(); it++) { + if((*it)->getUniqueName() == name) { + return *it; + } + } + std::cout << "[Warning] Entity could not be found by unique name \"" << name << "\"" << std::endl; + return nullptr; +} + +Entity* World::getEntityById(uint32_t id) +{ + for (auto it = entities.begin(); it != entities.end(); it++) { + if((*it)->getId() == id) { + return *it; + } + } + std::cout << "[Warning] Entity could not be found by ID \"" << id << "\"" << std::endl; + return nullptr; +} diff --git a/src/World.h b/src/World.h index 35f081c..8d345d4 100644 --- a/src/World.h +++ b/src/World.h @@ -11,18 +11,21 @@ class World { public: - World(ShaderProgram *shaderProgram); + World(std::vector shaderPrograms); ~World(); - void addEntity(Entity entity); - void removeEntity(uint32_t id); + void addEntity(Entity *entity); + void removeEntityByName(std::string name); + void clearEntities(); + + void loadWorld(unsigned int id); void updatePointLight(unsigned int lightId, bool active, glm::vec3 position, glm::vec3 color); void updateDirectionalLight(bool active, glm::vec3 direction, glm::vec3 color); - std::vector *getEntities() + std::vector getEntities() { - return &entities; + return entities; } PointLight *getPointLights() @@ -30,13 +33,18 @@ public: return pointLights.data(); } + Entity* getEntityByName(std::string name); + Entity* getEntityById(uint32_t id); + Model* getModelByName(std::string name); + void draw(glm::mat4 viewProjMatrix, glm::vec3 viewPosition); void calculateShadows(ShaderProgram *directionalShaderProgram, ShaderProgram *pointShaderProgram); private: ShaderProgram *shaderProgram; - std::vector entities; + std::vector models; + std::vector entities; // Lights DirectionalLight directionalLight;