Refactor Widget loading.

This commit is contained in:
2021-07-08 21:34:18 +02:00
parent be4e63046a
commit 5385b7ede7
15 changed files with 176 additions and 131 deletions

View File

@@ -61,8 +61,8 @@ Controller::Controller() : m_gameWindow(std::unique_ptr<Window>(new Window))
Controller::~Controller()
{
for (auto it = m_shaderPrograms.begin(); it != m_shaderPrograms.end(); it++) {
delete *it;
for (auto program : m_shaderPrograms) {
delete program;
}
delete m_world;
@@ -72,6 +72,12 @@ Controller::~Controller()
delete m_gameEventHandler;
}
Controller &Controller::instance()
{
static Controller s_instance;
return s_instance;
}
void Controller::run()
{
updateExposure(getShaderProgramByName("postProcessingProgram"));
@@ -212,22 +218,17 @@ void Controller::updateExposure(ShaderProgram *shaderProgram)
ShaderProgram *Controller::getShaderProgramByName(const std::string &name)
{
for (auto it = m_shaderPrograms.begin(); it != m_shaderPrograms.end(); it++) {
if ((*it)->getUniqueName() == name) {
return *it;
}
}
std::cout << "[Warning] ShaderProgram could not be found by name \"" << name << "\"" << std::endl;
return nullptr;
return getShaderProgramByName(name, m_shaderPrograms);
}
ShaderProgram *Controller::getShaderProgramByName(std::vector<ShaderProgram *> shaderPrograms, const std::string &name)
ShaderProgram *Controller::getShaderProgramByName(const std::string &name, std::vector<ShaderProgram *> shaderPrograms)
{
for (auto it = shaderPrograms.begin(); it != shaderPrograms.end(); it++) {
if ((*it)->getUniqueName() == name) {
return *it;
for (auto program : shaderPrograms) {
if (program->getUniqueName() == name) {
return program;
}
}
std::cout << "[Warning] ShaderProgram could not be found by name \"" << name << "\"" << std::endl;
return nullptr;
}

View File

@@ -19,24 +19,26 @@ class Handler;
class Controller
{
public:
Controller();
~Controller();
static Controller &instance();
void run();
void setMaxFps(uint16_t fps);
static ShaderProgram *getShaderProgramByName(std::vector<ShaderProgram *> shaderPrograms, const std::string &name);
ShaderProgram *getShaderProgramByName(const std::string &name);
static ShaderProgram *getShaderProgramByName(const std::string &name, std::vector<ShaderProgram *> shaderPrograms);
void updateExposure(ShaderProgram *shaderProgram);
private:
Controller();
void limit_framerate();
void updateWindowDimensions();
ShaderProgram *getShaderProgramByName(const std::string &name);
void renderImGui(World *world, glm::vec3 *lightColor, bool *rotateEntity, bool *rotateLightSource,
ShaderProgram *postProcessingProgram, float *intensity, bool *drawShadows);

View File

@@ -9,9 +9,13 @@
uint32_t Entity::s_idCounter = 0;
Entity::Entity(const std::string &name, Model *model, ShaderProgram *shaderProgram)
: m_uniqueName(name), m_model(model), m_shaderProgram(shaderProgram), m_id(s_idCounter++)
{}
Entity::Entity(Prototype prototype, Model *model, ShaderProgram *shaderProgram)
: m_uniqueName(prototype.name), m_model(model), m_shaderProgram(shaderProgram), m_id(s_idCounter++)
{
setPosition(prototype.position);
setRotation(prototype.rotation);
setScale(prototype.scale);
}
void Entity::draw(glm::mat4 viewProjMatrix, glm::vec3 viewPosition)
{

View File

@@ -12,7 +12,17 @@ class Model;
class Entity
{
public:
Entity(const std::string &name, Model *model, ShaderProgram *shaderProgram);
struct Prototype
{
std::string name;
std::string modelName;
std::string shaderProgramName;
glm::vec3 position;
glm::vec3 rotation;
float scale;
};
Entity(Prototype prototype, Model *model, ShaderProgram *shaderProgram);
~Entity() = default;
void draw(glm::mat4 viewProjMatrix, glm::vec3 viewPosition);

View File

@@ -1,7 +1,5 @@
#include "GLBucket.h"
#include <iostream>
std::unique_ptr<GLBucket> GLBucket::s_instance = std::unique_ptr<GLBucket>(new GLBucket);
GLBucket &GLBucket::instance()

View File

@@ -48,67 +48,43 @@ std::vector<Model::Prototype> JsonParser::getModelPrototypes() const
return modelPrototypes;
}
std::vector<Entity *> JsonParser::getEntities(std::vector<Model *> &models, std::vector<ShaderProgram *> shaderPrograms)
std::vector<Entity::Prototype> JsonParser::getEntityPrototypes() const
{
std::vector<Entity *> temp_entities;
std::vector<Entity::Prototype> entityPrototypes;
const Json::Value entitiesJson = m_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();
glm::vec3 entitiy_position = {}, entity_rotation = {};
float entity_scale = 1.0f;
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) {
// Apply fallback model (first model in vector)
current_model = models[0];
std::cout << "[Warning] Model could not be found by unique name \"" << entity_model << "\"" << std::endl;
}
std::string entityName = entitiesJson[index]["unique_name"].asString();
std::string entityModel = entitiesJson[index]["model"].asString();
std::string entityShaderProgram = entitiesJson[index]["shaderProgram"].asString();
glm::vec3 entitiyPosition = {}, entityRotation = {};
float entityScale = 1.0f;
const Json::Value positionJson = entitiesJson[index]["position"];
const Json::Value rotationJson = entitiesJson[index]["rotation"];
const Json::Value scaleJson = entitiesJson[index]["scale"];
if (!positionJson.empty()) {
entitiy_position.x = positionJson[0].asFloat();
entitiy_position.y = positionJson[1].asFloat();
entitiy_position.z = positionJson[2].asFloat();
entitiyPosition.x = positionJson[0].asFloat();
entitiyPosition.y = positionJson[1].asFloat();
entitiyPosition.z = positionJson[2].asFloat();
}
if (!rotationJson.empty()) {
entity_rotation.s = rotationJson[0].asFloat();
entity_rotation.t = rotationJson[1].asFloat();
entity_rotation.p = rotationJson[2].asFloat();
entityRotation.s = rotationJson[0].asFloat();
entityRotation.t = rotationJson[1].asFloat();
entityRotation.p = rotationJson[2].asFloat();
}
if (!scaleJson.empty()) {
entity_scale = scaleJson.asFloat();
entityScale = scaleJson.asFloat();
}
Entity *current_entity = new Entity(entity_name, current_model, shaderProgram);
current_entity->setPosition(entitiy_position);
current_entity->setRotation(entity_rotation);
current_entity->setScale(entity_scale);
temp_entities.push_back(current_entity);
std::cout << "Loaded Entity \"" << entity_name << "\" with model \"" << entity_model << "\"" << std::endl;
Entity::Prototype prototype{entityName, entityModel, entityShaderProgram,
entitiyPosition, entityRotation, entityScale};
entityPrototypes.push_back(prototype);
}
return temp_entities;
return entityPrototypes;
}
std::vector<ShaderProgram *> JsonParser::getShaderPrograms()
@@ -215,49 +191,47 @@ std::vector<Light *> JsonParser::getLights(ShaderProgram *shaderProgram)
return temp_lights;
}
std::vector<Screen *> JsonParser::getScreens(ShaderProgram *menuProgram, FrameBuffer *framebuffer)
std::vector<Screen::Prototype> JsonParser::getScreenPrototypes() const
{
std::vector<Screen *> temp_screens;
std::vector<Screen::Prototype> screenPrototypes;
const Json::Value loadingScreenJson = m_root["loadingScreen"];
const Json::Value mainMenuScreenJson = m_root["mainMenuScreen"];
std::string name;
Screen *screen;
name = "loadingScreen";
screen = new Screen(name, getWidgetsFromScreen(loadingScreenJson), framebuffer, menuProgram);
temp_screens.push_back(screen);
Screen::Prototype loadingScreen = Screen::Prototype{name, getWidgetPrototypesFromScreen(loadingScreenJson)};
screenPrototypes.push_back(loadingScreen);
name = "mainMenuScreen";
screen = new Screen(name, getWidgetsFromScreen(mainMenuScreenJson), framebuffer, menuProgram);
temp_screens.push_back(screen);
Screen::Prototype mainMenuScreen = Screen::Prototype{name, getWidgetPrototypesFromScreen(mainMenuScreenJson)};
screenPrototypes.push_back(mainMenuScreen);
return temp_screens;
return screenPrototypes;
}
std::vector<Widget *> JsonParser::getWidgetsFromScreen(const Json::Value &screenJson)
std::vector<Widget::Prototype> JsonParser::getWidgetPrototypesFromScreen(const Json::Value &screenJson) const
{
std::vector<Widget *> temp_widgets;
std::vector<Widget::Prototype> widgetPrototypes;
// Iterate over widgets
unsigned int index = 0;
for (; index < screenJson.size(); index++) {
for (unsigned int index = 0; index < screenJson.size(); index++) {
const Json::Value currentWidgetJson = screenJson[index];
const Json::Value currentWidgetTextureJson = currentWidgetJson["texture"];
const Json::Value currentWidgetPosition = currentWidgetJson["position"];
const Json::Value currentWidgetDimensions = currentWidgetJson["dimensions"];
std::string name = currentWidgetJson["unique_name"].asString();
glm::vec2 position(currentWidgetPosition[0].asFloat(), currentWidgetPosition[1].asFloat());
glm::vec2 dimensions(currentWidgetDimensions[0].asFloat(), currentWidgetDimensions[1].asFloat());
uint16_t callBackId = currentWidgetJson["callbackId"].asUInt();
Texture::Prototype texturePrototype{currentWidgetTextureJson.asString(), TextureType::Diffuse};
Texture *currentWidgetTexture = new Texture(texturePrototype);
currentWidgetTexture->initializeOnGPU();
Widget *currentWidget =
new Widget(name, currentWidgetTexture, currentWidgetPosition[0].asFloat(),
currentWidgetPosition[1].asFloat(), currentWidgetDimensions[0].asFloat(),
currentWidgetDimensions[1].asFloat(), currentWidgetJson["callbackId"].asUInt());
temp_widgets.push_back(currentWidget);
Widget::Prototype widgetPrototype{name, position, dimensions, texturePrototype, callBackId};
widgetPrototypes.push_back(widgetPrototype);
}
return temp_widgets;
return widgetPrototypes;
}
Skybox *JsonParser::getSkybox(Model *cubeModel, ShaderProgram *skyboxProgram)

View File

@@ -1,12 +1,14 @@
#pragma once
#include "Model.h"
#include <jsoncpp/json/json.h>
#include <string>
#include <vector>
class Entity;
#include "Entity.h"
#include "Model.h"
#include "Screen.h"
#include "Widget.h"
class Light;
class Screen;
class Skybox;
@@ -21,15 +23,15 @@ public:
~JsonParser();
std::vector<Model::Prototype> getModelPrototypes() const;
std::vector<Entity *> getEntities(std::vector<Model *> &models, std::vector<ShaderProgram *> shaderPrograms);
std::vector<Light *> getLights(ShaderProgram *shaderProgram);
std::vector<Screen *> getScreens(ShaderProgram *menuProgram, FrameBuffer *framebuffer);
std::vector<Entity::Prototype> getEntityPrototypes() const;
std::vector<Light *> getLights(ShaderProgram *shaderProgram); // should be under entities too
std::vector<Screen::Prototype> getScreenPrototypes() const;
Skybox *getSkybox(Model *cubeModel, ShaderProgram *skyboxProgram);
std::vector<ShaderProgram *> getShaderPrograms();
private:
std::vector<Widget *> getWidgetsFromScreen(const Json::Value &screenJson);
std::vector<Widget::Prototype> getWidgetPrototypesFromScreen(const Json::Value &screenJson) const;
Json::Value m_root;
Json::CharReaderBuilder m_rbuilder;

View File

@@ -14,7 +14,12 @@ Menu::Menu(FrameBuffer *p_framebuffer, ShaderProgram *p_shaderProgram)
: m_frameBuffer(p_framebuffer), m_shaderProgram(p_shaderProgram)
{
JsonParser screenParser("data/screens.json");
m_screens = screenParser.getScreens(m_shaderProgram, m_frameBuffer);
std::vector<Screen::Prototype> screenPrototypes = screenParser.getScreenPrototypes();
for (auto &prototype : screenPrototypes) {
auto currentScreen = new Screen(prototype, p_framebuffer, p_shaderProgram);
m_screens.push_back(currentScreen);
}
}
Menu::~Menu()

View File

@@ -9,13 +9,6 @@ class ShaderProgram;
class Mesh;
class Texture;
struct MeshPrototype
{
std::vector<uint32_t> textureIds;
std::vector<Vertex> meshVertices;
std::vector<uint32_t> meshIndices;
};
class Model
{
public:

View File

@@ -8,11 +8,16 @@
uint32_t Screen::s_idCounter = 0;
Screen::Screen(const std::string &name, std::vector<Widget *> widgets, FrameBuffer *framebuffer,
ShaderProgram *shaderProgram)
: m_uniqueName(name), m_frameBuffer(framebuffer), m_shaderProgram(shaderProgram), m_widgets(widgets)
Screen::Screen(Prototype prototype, FrameBuffer *framebuffer, ShaderProgram *shaderProgram)
: m_uniqueName(prototype.name), m_frameBuffer(framebuffer), m_shaderProgram(shaderProgram), m_id(s_idCounter++)
{
m_id = s_idCounter++;
for (auto &prototype : prototype.widgetPrototypes) {
Texture *currentTexture = new Texture(prototype.texturePrototype);
currentTexture->initializeOnGPU();
Widget *currentWidget = new Widget(prototype, currentTexture);
m_widgets.push_back(currentWidget);
}
}
Screen::~Screen()

View File

@@ -4,8 +4,9 @@
#include <unordered_map>
#include <vector>
#include "Widget.h"
class Menu;
class Widget;
class FrameBuffer;
class ShaderProgram;
class Texture;
@@ -13,8 +14,13 @@ class Texture;
class Screen
{
public:
Screen(const std::string &name, std::vector<Widget *> widgets, FrameBuffer *framebuffer,
ShaderProgram *shaderProgram);
struct Prototype
{
std::string name;
std::vector<Widget::Prototype> widgetPrototypes;
};
Screen(Prototype prototype, FrameBuffer *framebuffer, ShaderProgram *shaderProgram);
~Screen();
void addWidget(Widget *widget);

View File

@@ -7,23 +7,24 @@
#include <GLFW/glfw3.h>
Widget::Widget(std::string &name, Texture *texture, float p_x, float p_y, float p_w, float p_h, uint16_t callbackId)
: m_posX(p_x), m_posY(p_y), m_width(p_w), m_height(p_h), m_uniqueName(name), m_callbackId(callbackId)
Widget::Widget(Prototype prototype, Texture *texture)
: m_position(prototype.position), m_dimensions(prototype.dimensions), m_uniqueName(prototype.name),
m_callbackId(prototype.callBackId)
{
m_widgetTextures.push_back(texture);
double widgetVerticesData[12] = {
2 * (m_posX + m_width) - 1.0f,
2 * (m_posY)-1.0f,
2 * (m_position.x + m_dimensions.x) - 1.0f,
2 * (m_position.y) - 1.0f,
0.0f, // Bottom right
2 * (m_posX)-1.0f,
2 * (m_posY + m_height) - 1.0f,
2 * (m_position.x) - 1.0f,
2 * (m_position.y + m_dimensions.y) - 1.0f,
0.0f, // Top left
2 * (m_posX)-1.0f,
2 * (m_posY)-1.0f,
2 * (m_position.x) - 1.0f,
2 * (m_position.y) - 1.0f,
0.0f, // Bottom left
2 * (m_posX + m_width) - 1.0f,
2 * (m_posY + m_height) - 1.0f,
2 * (m_position.x + m_dimensions.x) - 1.0f,
2 * (m_position.y + m_dimensions.y) - 1.0f,
0.0f // Top right
};
@@ -70,7 +71,8 @@ bool Widget::isHovered(Window *window)
double yrel = -ypos / height + 1;
bool isHovered = false;
if (xrel >= m_posX && xrel <= m_posX + m_width && yrel >= m_posY && yrel <= m_posY + m_height)
if (xrel >= m_position.x && xrel <= m_position.x + m_dimensions.x && yrel >= m_position.y &&
yrel <= m_position.y + m_dimensions.x)
isHovered = true;
return isHovered;

View File

@@ -1,7 +1,9 @@
#pragma once
#include "Texture.h"
#include "definitions/models.h"
#include <glm/glm.hpp>
#include <string>
#include <vector>
@@ -14,7 +16,16 @@ class Mesh;
class Widget
{
public:
Widget(std::string &name, Texture *texture, float x, float y, float w, float h, uint16_t callbackId);
struct Prototype
{
std::string name;
glm::vec2 position;
glm::vec2 dimensions;
Texture::Prototype texturePrototype;
uint16_t callBackId; // TODO: will be removed...
};
Widget(Prototype prototype, Texture *texture);
~Widget();
void draw(ShaderProgram *shaderProgram);
@@ -25,7 +36,8 @@ public:
bool isHovered(Window *window);
private:
double m_posX, m_posY, m_width, m_height;
glm::vec2 m_position;
glm::vec2 m_dimensions;
std::string m_uniqueName;

View File

@@ -13,8 +13,8 @@
#include <thread>
World::World(std::vector<ShaderProgram *> shaderPrograms)
: m_shaderProgram(Controller::getShaderProgramByName(shaderPrograms, "defaultProgram")),
m_depthMapDirectionalFBO(DepthMapType::Normal, SHADOW_RES)
: m_depthMapDirectionalFBO(DepthMapType::Normal, SHADOW_RES),
m_shaderProgram(Controller::getShaderProgramByName("defaultProgram", shaderPrograms))
{
// Create 4 depthMaps
for (int i = 0; i < 4; i++) {
@@ -37,13 +37,13 @@ World::World(std::vector<ShaderProgram *> shaderPrograms)
for (auto &prototype : modelPrototypes) {
auto loadModel = [=, &mutex]() {
Model *current_model = new Model(prototype);
Model *currentModel = new Model(prototype);
std::cout << "Loaded Model \"" << prototype.modelName << "\" from \"" << prototype.modelPath << "\""
<< std::endl;
std::lock_guard<std::mutex> lock(mutex);
m_models.push_back(current_model);
m_models.push_back(currentModel);
};
futures.push_back(std::async(std::launch::async, loadModel));
@@ -53,9 +53,41 @@ World::World(std::vector<ShaderProgram *> shaderPrograms)
for (auto &model : m_models)
model->initializeOnGPU();
m_entities = modelParser.getEntities(m_models, shaderPrograms);
std::vector<Entity::Prototype> entityPrototypes = modelParser.getEntityPrototypes();
std::vector<Entity *> entities;
{
for (auto &prototype : entityPrototypes) {
// Get model
Model *currentModel = getModelByName(prototype.modelName);
if (!currentModel) {
// Apply fallback model (first model in vector)
currentModel = m_models[0];
std::cout << "[Warning] Model could not be found by name \"" << prototype.modelName << "\""
<< std::endl;
}
// Get shaderprogram
ShaderProgram *currentProgram =
Controller::getShaderProgramByName(prototype.shaderProgramName, shaderPrograms);
if (!currentProgram) {
currentProgram = Controller::getShaderProgramByName("basic", shaderPrograms);
}
Entity *currentEntity = new Entity(prototype, currentModel, currentProgram);
std::cout << "Loaded Entity \"" << prototype.name << "\" with model \"" << prototype.modelName << "\""
<< std::endl;
entities.push_back(currentEntity);
}
}
m_entities = entities;
m_skybox = modelParser.getSkybox(getModelByName("cube"),
Controller::getShaderProgramByName(shaderPrograms, "skyboxProgram"));
Controller::getShaderProgramByName("skyboxProgram", shaderPrograms));
JsonParser lightParser("data/lights.json");
m_lights = lightParser.getLights(m_shaderProgram);

View File

@@ -13,17 +13,16 @@ int main(int argc, char **argv)
#endif
// Create controller
Controller *mainController = new Controller();
Controller &controller = Controller::instance();
const char *fps_env = std::getenv("MAXFPS");
if (fps_env) {
uint16_t maxfps = std::stoul(fps_env);
mainController->setMaxFps(maxfps);
controller.setMaxFps(maxfps);
std::cout << "[Warning] Default max FPS overridden with " << maxfps << " by environment." << std::endl;
}
mainController->run();
controller.run();
delete mainController;
return 0;
}