Large Json loading refactoring
This commit is contained in:
@@ -64,6 +64,34 @@
|
||||
"shaderProgram": "lightProgram"
|
||||
}
|
||||
],
|
||||
"directionalLight": {
|
||||
"intensity": 0.25,
|
||||
"direction": [
|
||||
-0.2,
|
||||
-1.0,
|
||||
-0.3
|
||||
],
|
||||
"color": [
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"pointLights": [
|
||||
{
|
||||
"intensity": 7.5,
|
||||
"position": [
|
||||
0.0,
|
||||
1.0,
|
||||
0.0
|
||||
],
|
||||
"color": [
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
]
|
||||
}
|
||||
],
|
||||
"textures": [
|
||||
{
|
||||
"unique_name": "fallback_normal",
|
||||
|
||||
@@ -37,7 +37,11 @@ Controller::Controller() : m_gameWindow(std::unique_ptr<Window>(new Window))
|
||||
m_camera = new Camera(90.0f, m_gameWindow->getWindowAspectRatio());
|
||||
|
||||
JsonParser shaderParser("data/shaderPrograms.json");
|
||||
m_shaderPrograms = shaderParser.getShaderPrograms();
|
||||
auto shaderProgramPrototypes = shaderParser.getShaderProgramPrototypes();
|
||||
|
||||
for (auto &prototype : shaderProgramPrototypes) {
|
||||
m_shaderPrograms.push_back(new ShaderProgram(prototype));
|
||||
}
|
||||
|
||||
m_postProcessFrameBuffer = new FrameBuffer(m_gameWindow->getWindowWidth(), m_gameWindow->getWindowHeight(),
|
||||
getShaderProgramByName("postProcessingProgram"));
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
uint32_t Entity::s_idCounter = 0;
|
||||
|
||||
Entity::Entity(Prototype prototype, Model *model, ShaderProgram *shaderProgram)
|
||||
: m_uniqueName(prototype.name), m_model(model), m_shaderProgram(shaderProgram), m_id(s_idCounter++)
|
||||
: m_id(s_idCounter++), m_uniqueName(prototype.name), m_model(model), m_shaderProgram(shaderProgram)
|
||||
{
|
||||
setPosition(prototype.position);
|
||||
setRotation(prototype.rotation);
|
||||
@@ -146,11 +146,19 @@ bool Entity::getIsLightSource()
|
||||
return m_isLightSource;
|
||||
}
|
||||
|
||||
Skybox::Skybox(Model *cubeModel, ShaderProgram *shaderProgram, const char *texturePseudoPath)
|
||||
: m_cubeModel(cubeModel), m_shaderProgram(shaderProgram), m_cubeMap(texturePseudoPath),
|
||||
Skybox::Skybox(Prototype prototype, Model *cubeModel, ShaderProgram *shaderProgram)
|
||||
: m_cubeModel(cubeModel), m_shaderProgram(shaderProgram), m_cubeMap(new CubeMap(prototype.texturePath.c_str())),
|
||||
m_vertexArray(cubeModel->getMesh(0)->getVertexArray())
|
||||
{}
|
||||
|
||||
Skybox::~Skybox()
|
||||
{
|
||||
// Empty
|
||||
delete m_cubeMap;
|
||||
}
|
||||
|
||||
void Skybox::initializeOnGPU()
|
||||
{
|
||||
m_cubeMap->initializeOnGPU();
|
||||
}
|
||||
|
||||
void Skybox::draw(glm::mat4 viewMatrix, glm::mat4 projectionMatrix)
|
||||
@@ -168,9 +176,9 @@ void Skybox::draw(glm::mat4 viewMatrix, glm::mat4 projectionMatrix)
|
||||
|
||||
m_shaderProgram->setUniform("u_viewProjectionMatrix", viewProjectionMatrix);
|
||||
|
||||
m_cubeMap.bind(m_shaderProgram);
|
||||
m_cubeMap->bind(m_shaderProgram);
|
||||
m_cubeModel->getMesh(0)->drawWithoutTextures();
|
||||
m_cubeMap.unbind();
|
||||
m_cubeMap->unbind();
|
||||
|
||||
m_shaderProgram->unbind();
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
15
src/Entity.h
15
src/Entity.h
@@ -68,16 +68,25 @@ private:
|
||||
class Skybox
|
||||
{
|
||||
public:
|
||||
Skybox(Model *cubeModel, ShaderProgram *shaderProgram, const char *texturePseudoPath);
|
||||
~Skybox() = default;
|
||||
struct Prototype
|
||||
{
|
||||
std::string texturePath;
|
||||
};
|
||||
|
||||
Skybox(Prototype prototype, Model *cubeModel, ShaderProgram *shaderProgram);
|
||||
~Skybox();
|
||||
|
||||
void initializeOnGPU();
|
||||
|
||||
void draw(glm::mat4 viewMatrix, glm::mat4 projectionMatrix);
|
||||
|
||||
private:
|
||||
bool m_isInitialized = false;
|
||||
|
||||
Model *m_cubeModel;
|
||||
ShaderProgram *m_shaderProgram;
|
||||
|
||||
CubeMap m_cubeMap;
|
||||
CubeMap *m_cubeMap;
|
||||
|
||||
VertexArray *m_vertexArray;
|
||||
};
|
||||
|
||||
@@ -10,12 +10,12 @@
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
JsonParser::JsonParser(const std::string &path)
|
||||
JsonParser::JsonParser(const std::string &jsonFilepath)
|
||||
{
|
||||
std::ifstream file(path.c_str(), std::ifstream::binary);
|
||||
std::ifstream file(jsonFilepath.c_str(), std::ifstream::binary);
|
||||
|
||||
if (!file) {
|
||||
std::cout << "Error reading file \"" << path << "\"." << std::endl;
|
||||
std::cout << "Error reading file \"" << jsonFilepath << "\"." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -87,9 +87,9 @@ std::vector<Entity::Prototype> JsonParser::getEntityPrototypes() const
|
||||
return entityPrototypes;
|
||||
}
|
||||
|
||||
std::vector<ShaderProgram *> JsonParser::getShaderPrograms()
|
||||
std::vector<ShaderProgram::Prototype> JsonParser::getShaderProgramPrototypes()
|
||||
{
|
||||
std::vector<ShaderProgram *> temp_shaderPrograms;
|
||||
std::vector<ShaderProgram::Prototype> prototypes;
|
||||
|
||||
const Json::Value shaderProgramsJson = m_root["shaderPrograms"];
|
||||
|
||||
@@ -99,28 +99,23 @@ std::vector<ShaderProgram *> JsonParser::getShaderPrograms()
|
||||
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;
|
||||
ShaderProgram::Prototype prototype{shaderProgram_name, shaderProgram_vertexPath, shaderProgram_fragmentPath,
|
||||
shaderProgram_geometryPath};
|
||||
|
||||
prototypes.push_back(prototype);
|
||||
// std::cout << "Loaded ShaderProgram \"" << shaderProgram_name << "\"" << std::endl;
|
||||
}
|
||||
|
||||
return temp_shaderPrograms;
|
||||
return prototypes;
|
||||
}
|
||||
|
||||
std::vector<Light *> JsonParser::getLights(ShaderProgram *shaderProgram)
|
||||
std::vector<std::unique_ptr<Light::Prototype>> JsonParser::getLightPrototypes() const
|
||||
{
|
||||
std::vector<Light *> temp_lights;
|
||||
glm::vec3 light_direction = {1.0f, 0.0f, 0.0f};
|
||||
glm::vec3 light_position = {};
|
||||
glm::vec3 light_color = {1.0f, 1.0f, 1.0f};
|
||||
float light_intensity = 10.0f;
|
||||
std::vector<std::unique_ptr<Light::Prototype>> prototypes;
|
||||
glm::vec3 direction = {1.0f, 0.0f, 0.0f};
|
||||
glm::vec3 position = {};
|
||||
glm::vec3 color = {1.0f, 1.0f, 1.0f};
|
||||
float intensity = 10.0f;
|
||||
|
||||
const Json::Value directionalLightsJson = m_root["directionalLight"];
|
||||
|
||||
@@ -129,52 +124,55 @@ std::vector<Light *> JsonParser::getLights(ShaderProgram *shaderProgram)
|
||||
Json::Value intensityJson = directionalLightsJson["intensity"];
|
||||
|
||||
if (!intensityJson.empty()) {
|
||||
light_intensity = intensityJson.asFloat();
|
||||
intensity = intensityJson.asFloat();
|
||||
}
|
||||
if (!directionJson.empty()) {
|
||||
light_direction.x = directionJson[0].asFloat();
|
||||
light_direction.y = directionJson[1].asFloat();
|
||||
light_direction.z = directionJson[2].asFloat();
|
||||
direction.x = directionJson[0].asFloat();
|
||||
direction.y = directionJson[1].asFloat();
|
||||
direction.z = directionJson[2].asFloat();
|
||||
}
|
||||
if (!colorJson.empty()) {
|
||||
light_color.x = colorJson[0].asFloat();
|
||||
light_color.y = colorJson[1].asFloat();
|
||||
light_color.z = colorJson[2].asFloat();
|
||||
color.x = colorJson[0].asFloat();
|
||||
color.y = colorJson[1].asFloat();
|
||||
color.z = colorJson[2].asFloat();
|
||||
}
|
||||
|
||||
DirectionalLight *current_directionalLight =
|
||||
new DirectionalLight(light_direction, light_color, light_intensity, shaderProgram);
|
||||
current_directionalLight->setActive(true);
|
||||
temp_lights.push_back(current_directionalLight);
|
||||
auto prototype = std::unique_ptr<Light::Prototype>(new DirectionalLight::Prototype{direction, color, intensity});
|
||||
|
||||
// DirectionalLight *current_directionalLight = new DirectionalLight(*prototype, shaderProgram);
|
||||
// current_directionalLight->setActive(true);
|
||||
|
||||
prototypes.push_back(std::move(prototype));
|
||||
|
||||
// Pointlights
|
||||
const Json::Value pointLightsJson = m_root["pointLights"];
|
||||
|
||||
int index = 0;
|
||||
for (; index < (int)pointLightsJson.size(); index++) {
|
||||
PointLight *current_pointLight;
|
||||
|
||||
const Json::Value positionJson = pointLightsJson[index]["position"];
|
||||
colorJson = pointLightsJson[index]["color"];
|
||||
intensityJson = pointLightsJson[index]["intensity"];
|
||||
|
||||
if (!intensityJson.empty()) {
|
||||
light_intensity = intensityJson.asFloat();
|
||||
intensity = intensityJson.asFloat();
|
||||
}
|
||||
if (!positionJson.empty()) {
|
||||
light_position.x = positionJson[0].asFloat();
|
||||
light_position.y = positionJson[1].asFloat();
|
||||
light_position.z = positionJson[2].asFloat();
|
||||
position.x = positionJson[0].asFloat();
|
||||
position.y = positionJson[1].asFloat();
|
||||
position.z = positionJson[2].asFloat();
|
||||
}
|
||||
if (!colorJson.empty()) {
|
||||
light_color.x = colorJson[0].asFloat();
|
||||
light_color.y = colorJson[1].asFloat();
|
||||
light_color.z = colorJson[2].asFloat();
|
||||
color.x = colorJson[0].asFloat();
|
||||
color.y = colorJson[1].asFloat();
|
||||
color.z = colorJson[2].asFloat();
|
||||
}
|
||||
|
||||
current_pointLight = new PointLight(light_position, light_color, light_intensity, shaderProgram);
|
||||
current_pointLight->setActive(true);
|
||||
temp_lights.push_back(current_pointLight);
|
||||
auto prototype = std::unique_ptr<Light::Prototype>(new PointLight::Prototype{position, color, intensity});
|
||||
|
||||
// current_pointLight = new PointLight(*prototype, shaderProgram);
|
||||
// current_pointLight->setActive(true);
|
||||
|
||||
prototypes.push_back(std::move(prototype));
|
||||
}
|
||||
|
||||
// In case there aren't enough PointLights defined in the Json file
|
||||
@@ -182,13 +180,16 @@ std::vector<Light *> JsonParser::getLights(ShaderProgram *shaderProgram)
|
||||
const glm::vec3 default_position(0.0f);
|
||||
const glm::vec3 default_color(1.0f);
|
||||
const float default_intensity = 10.0f;
|
||||
PointLight *current_pointLight =
|
||||
new PointLight(default_position, default_color, default_intensity, shaderProgram);
|
||||
current_pointLight->setActive(false);
|
||||
temp_lights.push_back(current_pointLight);
|
||||
auto prototype = std::unique_ptr<PointLight::Prototype>(
|
||||
new PointLight::Prototype{default_position, default_color, default_intensity});
|
||||
|
||||
// PointLight *current_pointLight = new PointLight(*prototype, shaderProgram);
|
||||
// current_pointLight->setActive(false);
|
||||
|
||||
prototypes.push_back(std::move(prototype));
|
||||
}
|
||||
|
||||
return temp_lights;
|
||||
return prototypes;
|
||||
}
|
||||
|
||||
std::vector<Screen::Prototype> JsonParser::getScreenPrototypes() const
|
||||
@@ -234,15 +235,12 @@ std::vector<Widget::Prototype> JsonParser::getWidgetPrototypesFromScreen(const J
|
||||
return widgetPrototypes;
|
||||
}
|
||||
|
||||
Skybox *JsonParser::getSkybox(Model *cubeModel, ShaderProgram *skyboxProgram)
|
||||
Skybox::Prototype JsonParser::getSkyboxPrototype() const
|
||||
{
|
||||
Skybox *temp_skybox;
|
||||
|
||||
const Json::Value shaderProgramsJson = m_root["skybox"];
|
||||
|
||||
std::string skybox_texturePath = shaderProgramsJson["texturePath"].asString();
|
||||
temp_skybox = new Skybox(cubeModel, skyboxProgram, skybox_texturePath.c_str());
|
||||
std::cout << "Loaded Skybox \"" << skybox_texturePath << "\"" << std::endl;
|
||||
std::string texturePath = shaderProgramsJson["texturePath"].asString();
|
||||
Skybox::Prototype prototype{texturePath};
|
||||
|
||||
return temp_skybox;
|
||||
return prototype;
|
||||
}
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <jsoncpp/json/json.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Entity.h"
|
||||
#include "Light.h"
|
||||
#include "Model.h"
|
||||
#include "Screen.h"
|
||||
#include "ShaderProgram.h"
|
||||
#include "Widget.h"
|
||||
|
||||
class Light;
|
||||
class Screen;
|
||||
class Skybox;
|
||||
class ShaderProgram;
|
||||
class FrameBuffer;
|
||||
class Widget;
|
||||
|
||||
class JsonParser
|
||||
{
|
||||
public:
|
||||
JsonParser(const std::string &path);
|
||||
JsonParser(const std::string &jsonFilepath);
|
||||
~JsonParser();
|
||||
|
||||
std::vector<Model::Prototype> getModelPrototypes() const;
|
||||
std::vector<Entity::Prototype> getEntityPrototypes() const;
|
||||
std::vector<Light *> getLights(ShaderProgram *shaderProgram); // should be under entities too
|
||||
std::vector<std::unique_ptr<Light::Prototype>> getLightPrototypes() const;
|
||||
std::vector<Screen::Prototype> getScreenPrototypes() const;
|
||||
Skybox *getSkybox(Model *cubeModel, ShaderProgram *skyboxProgram);
|
||||
Skybox::Prototype getSkyboxPrototype() const;
|
||||
|
||||
std::vector<ShaderProgram *> getShaderPrograms();
|
||||
std::vector<ShaderProgram::Prototype> getShaderProgramPrototypes();
|
||||
|
||||
private:
|
||||
std::vector<Widget::Prototype> getWidgetPrototypesFromScreen(const Json::Value &screenJson) const;
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
uint32_t Light::s_idCounter = 0;
|
||||
|
||||
// Light
|
||||
|
||||
Light::Light(glm::vec3 color, float intensity, ShaderProgram *shaderProgram)
|
||||
: m_shaderProgram(shaderProgram), m_intensity(intensity)
|
||||
{
|
||||
@@ -14,6 +12,9 @@ Light::Light(glm::vec3 color, float intensity, ShaderProgram *shaderProgram)
|
||||
m_lightColor = color * intensity;
|
||||
}
|
||||
|
||||
Light::~Light()
|
||||
{}
|
||||
|
||||
glm::vec3 Light::getColor()
|
||||
{
|
||||
return m_lightColor;
|
||||
@@ -42,13 +43,9 @@ void Light::setActive(bool active)
|
||||
update();
|
||||
}
|
||||
|
||||
// PointLight
|
||||
|
||||
PointLight::PointLight(glm::vec3 position, glm::vec3 color, float intensity, ShaderProgram *shaderProgram)
|
||||
: Light(color, intensity, shaderProgram), m_position(position)
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
PointLight::PointLight(Prototype prototype, ShaderProgram *shaderProgram)
|
||||
: Light(prototype.color, prototype.intensity, shaderProgram), m_position(prototype.position)
|
||||
{}
|
||||
|
||||
void PointLight::update()
|
||||
{
|
||||
@@ -79,13 +76,9 @@ void PointLight::setPosition(glm::vec3 position)
|
||||
update();
|
||||
}
|
||||
|
||||
// DirectionalLight
|
||||
|
||||
DirectionalLight::DirectionalLight(glm::vec3 direction, glm::vec3 color, float intensity, ShaderProgram *shaderProgram)
|
||||
: Light(color, intensity, shaderProgram), m_direction(direction)
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
DirectionalLight::DirectionalLight(Prototype prototype, ShaderProgram *shaderProgram)
|
||||
: Light(prototype.color, prototype.intensity, shaderProgram), m_direction(prototype.direction)
|
||||
{}
|
||||
|
||||
void DirectionalLight::update()
|
||||
{
|
||||
|
||||
36
src/Light.h
36
src/Light.h
@@ -10,8 +10,13 @@ class ShaderProgram;
|
||||
class Light
|
||||
{
|
||||
public:
|
||||
virtual ~Light()
|
||||
{}
|
||||
struct Prototype
|
||||
{
|
||||
virtual ~Prototype() = default;
|
||||
};
|
||||
|
||||
Light(glm::vec3 color, float intensity, ShaderProgram *shaderProgram);
|
||||
virtual ~Light() = 0;
|
||||
|
||||
virtual void update() = 0;
|
||||
|
||||
@@ -23,8 +28,6 @@ public:
|
||||
glm::vec3 getColor();
|
||||
|
||||
protected:
|
||||
Light(glm::vec3 color, float intensity, ShaderProgram *shaderProgram);
|
||||
|
||||
ShaderProgram *m_shaderProgram;
|
||||
|
||||
uint32_t m_id;
|
||||
@@ -42,7 +45,17 @@ protected:
|
||||
class PointLight : public Light
|
||||
{
|
||||
public:
|
||||
PointLight(glm::vec3 position, glm::vec3 color, float intensity, ShaderProgram *shaderProgram);
|
||||
struct Prototype : public Light::Prototype
|
||||
{
|
||||
Prototype(glm::vec3 position, glm::vec3 color, float intensity)
|
||||
: position(position), color(color), intensity(intensity)
|
||||
{}
|
||||
glm::vec3 position;
|
||||
glm::vec3 color;
|
||||
float intensity;
|
||||
};
|
||||
|
||||
PointLight(Prototype prototype, ShaderProgram *shaderProgram);
|
||||
~PointLight() override = default;
|
||||
|
||||
void setPosition(glm::vec3 position);
|
||||
@@ -59,7 +72,18 @@ private:
|
||||
class DirectionalLight : public Light
|
||||
{
|
||||
public:
|
||||
DirectionalLight(glm::vec3 direction, glm::vec3 color, float intensity, ShaderProgram *shaderProgram);
|
||||
struct Prototype : public Light::Prototype
|
||||
{
|
||||
Prototype(glm::vec3 direction, glm::vec3 color, float intensity)
|
||||
: direction(direction), color(color), intensity(intensity)
|
||||
{}
|
||||
glm::vec3 direction;
|
||||
glm::vec3 color;
|
||||
float intensity;
|
||||
};
|
||||
|
||||
DirectionalLight(Prototype prototype, ShaderProgram *shaderProgram);
|
||||
~DirectionalLight() override = default;
|
||||
|
||||
void setDirection(glm::vec3 direction);
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "VertexArray.h"
|
||||
|
||||
Mesh::Mesh(std::vector<Vertex> vertices, std::vector<uint32_t> indices, std::vector<Texture *> textures)
|
||||
: m_numElements(indices.size()), m_textures(textures), m_preInitializationVertexData{vertices, indices}
|
||||
: m_preInitializationVertexData{vertices, indices}, m_numElements(indices.size()), m_textures(textures)
|
||||
{}
|
||||
|
||||
void Mesh::initializeOnGPU()
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
uint32_t Model::s_idCounter = 0;
|
||||
|
||||
Model::Model(const Prototype &prototype) : m_uniqueName(prototype.modelName), m_id(s_idCounter++)
|
||||
Model::Model(const Prototype &prototype) : m_id(s_idCounter++), m_uniqueName(prototype.modelName)
|
||||
{
|
||||
m_workingPath = prototype.modelPath.substr(0, prototype.modelPath.find_last_of('/'));
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
uint32_t Screen::s_idCounter = 0;
|
||||
|
||||
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++), m_uniqueName(prototype.name), m_frameBuffer(framebuffer), m_shaderProgram(shaderProgram)
|
||||
{
|
||||
for (auto &prototype : prototype.widgetPrototypes) {
|
||||
Texture *currentTexture = new Texture(prototype.texturePrototype);
|
||||
|
||||
@@ -6,26 +6,32 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
ShaderProgram::ShaderProgram(const std::string &name, const std::string &vertexShaderPath,
|
||||
const std::string &fragmentShaderPath)
|
||||
: m_uniqueName(name)
|
||||
ShaderProgram::ShaderProgram(Prototype prototype) : m_uniqueName(prototype.name)
|
||||
{
|
||||
std::string vertexShaderSource = parse(vertexShaderPath.c_str());
|
||||
std::string fragmentShaderSource = parse(fragmentShaderPath.c_str());
|
||||
std::string vertexShaderSource = parse(prototype.vertexPath.c_str());
|
||||
std::string fragmentShaderSource = parse(prototype.fragmentPath.c_str());
|
||||
|
||||
m_shaderProgramId = glCreateProgram();
|
||||
GLuint vs = compile(vertexShaderSource, GL_VERTEX_SHADER);
|
||||
GLuint gs;
|
||||
GLuint fs = compile(fragmentShaderSource, GL_FRAGMENT_SHADER);
|
||||
|
||||
glAttachShader(m_shaderProgramId, vs);
|
||||
glAttachShader(m_shaderProgramId, fs);
|
||||
|
||||
if (!prototype.geometryPath.empty()) {
|
||||
std::string geometryShaderSource = parse(prototype.geometryPath.c_str());
|
||||
gs = compile(geometryShaderSource, GL_GEOMETRY_SHADER);
|
||||
glAttachShader(m_shaderProgramId, gs);
|
||||
}
|
||||
|
||||
glLinkProgram(m_shaderProgramId);
|
||||
|
||||
GLint isLinked = 0;
|
||||
glGetProgramiv(m_shaderProgramId, GL_LINK_STATUS, &isLinked);
|
||||
if (!isLinked) {
|
||||
std::cout << "Failed to link shaderProgram: " << vertexShaderPath << ", " << fragmentShaderPath << std::endl;
|
||||
std::cout << "Failed to link shaderProgram: " << prototype.vertexPath << ", " << prototype.geometryPath << ", "
|
||||
<< prototype.fragmentPath << std::endl;
|
||||
}
|
||||
|
||||
#ifdef _RELEASE
|
||||
@@ -34,43 +40,11 @@ ShaderProgram::ShaderProgram(const std::string &name, const std::string &vertexS
|
||||
|
||||
glDeleteShader(vs);
|
||||
glDeleteShader(fs);
|
||||
#endif
|
||||
}
|
||||
|
||||
ShaderProgram::ShaderProgram(const std::string &name, const std::string &vertexShaderPath,
|
||||
const std::string &geometryShaderPath, const std::string &fragmentShaderPath)
|
||||
: m_uniqueName(name)
|
||||
{
|
||||
std::string vertexShaderSource = parse(vertexShaderPath.c_str());
|
||||
std::string geometryShaderSource = parse(geometryShaderPath.c_str());
|
||||
std::string fragmentShaderSource = parse(fragmentShaderPath.c_str());
|
||||
|
||||
m_shaderProgramId = glCreateProgram();
|
||||
GLuint vs = compile(vertexShaderSource, GL_VERTEX_SHADER);
|
||||
GLuint gs = compile(geometryShaderSource, GL_GEOMETRY_SHADER);
|
||||
GLuint fs = compile(fragmentShaderSource, GL_FRAGMENT_SHADER);
|
||||
|
||||
glAttachShader(m_shaderProgramId, vs);
|
||||
glAttachShader(m_shaderProgramId, gs);
|
||||
glAttachShader(m_shaderProgramId, fs);
|
||||
|
||||
glLinkProgram(m_shaderProgramId);
|
||||
|
||||
GLint isLinked = 0;
|
||||
glGetProgramiv(m_shaderProgramId, GL_LINK_STATUS, &isLinked);
|
||||
if (!isLinked) {
|
||||
std::cout << "Failed to link shaderProgram: " << vertexShaderPath << ", " << geometryShaderPath << ", "
|
||||
<< fragmentShaderPath << std::endl;
|
||||
if (!prototype.geometryPath.empty()) {
|
||||
glDetachShader(program, gs);
|
||||
glDeleteShader(gs);
|
||||
}
|
||||
|
||||
#ifdef _RELEASE
|
||||
glDetachShader(program, vs);
|
||||
glDetachShader(program, gs);
|
||||
glDetachShader(program, fs);
|
||||
|
||||
glDeleteShader(vs);
|
||||
glDeleteShader(gs);
|
||||
glDeleteShader(fs);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -8,9 +8,16 @@
|
||||
class ShaderProgram
|
||||
{
|
||||
public:
|
||||
ShaderProgram(const std::string &name, const std::string &vertexShaderPath, const std::string &fragmentShaderPath);
|
||||
ShaderProgram(const std::string &name, const std::string &vertexShaderPath, const std::string &geometryShaderPath,
|
||||
const std::string &fragmentShaderPath);
|
||||
struct Prototype
|
||||
{
|
||||
std::string name;
|
||||
std::string vertexPath;
|
||||
std::string fragmentPath;
|
||||
std::string geometryPath;
|
||||
};
|
||||
|
||||
ShaderProgram(Prototype prototype);
|
||||
|
||||
~ShaderProgram();
|
||||
|
||||
void bind();
|
||||
|
||||
@@ -28,15 +28,20 @@ void Texture::initializeOnGPU()
|
||||
|
||||
GLenum internalFormat;
|
||||
GLenum dataFormat;
|
||||
if (m_numComponents == 1) {
|
||||
|
||||
switch (m_numComponents) {
|
||||
case 1:
|
||||
internalFormat = GL_RED;
|
||||
dataFormat = GL_RED;
|
||||
} else if (m_numComponents == 3) {
|
||||
break;
|
||||
case 3:
|
||||
internalFormat = (m_textureType == TextureType::Diffuse) ? GL_SRGB8 : GL_RGB8;
|
||||
dataFormat = GL_RGB;
|
||||
} else if (m_numComponents == 4) {
|
||||
break;
|
||||
case 4:
|
||||
internalFormat = (m_textureType == TextureType::Diffuse) ? GL_SRGB8_ALPHA8 : GL_RGBA8;
|
||||
dataFormat = GL_RGBA;
|
||||
break;
|
||||
}
|
||||
|
||||
// Push texture to grahics card
|
||||
@@ -80,6 +85,8 @@ void Texture::bind(uint8_t textureUnit, ShaderProgram *shaderProgram, uint8_t te
|
||||
case TextureType::Gloss:
|
||||
uniformName += "gloss" + std::to_string(textureTypeNum);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Add u_material as we store textures in a struct
|
||||
@@ -114,6 +121,9 @@ CubeMap::CubeMap(const char *texturePseudoPath)
|
||||
{
|
||||
// Reserve space in vector so that elements can be accessed explicitly.
|
||||
m_texturePaths.resize(CUBEMAP_FACES_NUM_ITEMS);
|
||||
m_textureBuffers.resize(CUBEMAP_FACES_NUM_ITEMS);
|
||||
m_numComponents.resize(CUBEMAP_FACES_NUM_ITEMS);
|
||||
|
||||
fillTexturePathVector(texturePseudoPath);
|
||||
|
||||
stbi_set_flip_vertically_on_load(0);
|
||||
@@ -127,34 +137,20 @@ CubeMap::CubeMap(const char *texturePseudoPath)
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
|
||||
for (unsigned int i = 0; i < CUBEMAP_FACES_NUM_ITEMS; i++) {
|
||||
int i = 0;
|
||||
for (auto &path : m_texturePaths) {
|
||||
|
||||
int32_t numComponents;
|
||||
auto *textureBuffer =
|
||||
stbi_load(m_texturePaths[i].c_str(), &m_textureWidth, &m_textureHeight, &numComponents, 0);
|
||||
|
||||
GLenum internalFormat;
|
||||
GLenum dataFormat;
|
||||
if (numComponents == 1) {
|
||||
internalFormat = GL_RED;
|
||||
dataFormat = GL_RED;
|
||||
} else if (numComponents == 3) {
|
||||
internalFormat = GL_SRGB8;
|
||||
dataFormat = GL_RGB;
|
||||
} else if (numComponents == 4) {
|
||||
internalFormat = GL_SRGB8_ALPHA8;
|
||||
dataFormat = GL_RGBA;
|
||||
}
|
||||
auto textureBuffer = stbi_load(path.c_str(), &m_textureWidth, &m_textureHeight, &numComponents, 0);
|
||||
|
||||
if (!textureBuffer) {
|
||||
std::cout << "[Warning] CubeMap Texture " << m_texturePaths[i].c_str() << " not found!" << std::endl;
|
||||
std::cout << "[Warning] CubeMap Texture " << path.c_str() << " not found!" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internalFormat, m_textureWidth, m_textureHeight, 0,
|
||||
dataFormat, GL_UNSIGNED_BYTE, textureBuffer);
|
||||
|
||||
stbi_image_free(textureBuffer);
|
||||
m_textureBuffers[i] = textureBuffer;
|
||||
m_numComponents[i] = numComponents;
|
||||
i++;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||
@@ -186,6 +182,52 @@ CubeMap::~CubeMap()
|
||||
// glDeleteTextures(1, &m_textureId);
|
||||
}
|
||||
|
||||
void CubeMap::initializeOnGPU()
|
||||
{
|
||||
if (m_isInitialized)
|
||||
return;
|
||||
|
||||
m_isInitialized = true;
|
||||
|
||||
glGenTextures(1, &m_textureId);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, m_textureId);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
|
||||
int i = 0;
|
||||
for (auto &textureBuffer : m_textureBuffers) {
|
||||
GLenum internalFormat;
|
||||
GLenum dataFormat;
|
||||
|
||||
switch (m_numComponents[i]) {
|
||||
case 1:
|
||||
internalFormat = GL_RED;
|
||||
dataFormat = GL_RED;
|
||||
break;
|
||||
case 3:
|
||||
internalFormat = GL_SRGB8;
|
||||
dataFormat = GL_RGB;
|
||||
break;
|
||||
case 4:
|
||||
internalFormat = GL_SRGB8_ALPHA8;
|
||||
dataFormat = GL_RGBA;
|
||||
break;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internalFormat, m_textureWidth, m_textureHeight, 0,
|
||||
dataFormat, GL_UNSIGNED_BYTE, textureBuffer);
|
||||
|
||||
stbi_image_free(textureBuffer);
|
||||
i++;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||
}
|
||||
|
||||
void CubeMap::bind(ShaderProgram *shaderProgram)
|
||||
{
|
||||
std::string uniformName = "u_skybox";
|
||||
|
||||
@@ -65,6 +65,8 @@ public:
|
||||
CubeMap(const char *texturePseudoPath);
|
||||
CubeMap(int RESOLUTION);
|
||||
|
||||
void initializeOnGPU();
|
||||
|
||||
~CubeMap();
|
||||
|
||||
void bind(ShaderProgram *shaderProgram);
|
||||
@@ -75,7 +77,11 @@ public:
|
||||
private:
|
||||
void fillTexturePathVector(const char *texturePseudoPath);
|
||||
|
||||
bool m_isInitialized = false;
|
||||
|
||||
std::vector<std::string> m_texturePaths;
|
||||
std::vector<stbi_uc *> m_textureBuffers;
|
||||
std::vector<int> m_numComponents;
|
||||
|
||||
GLuint m_textureId;
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
#include <thread>
|
||||
|
||||
World::World(std::vector<ShaderProgram *> shaderPrograms)
|
||||
: m_depthMapDirectionalFBO(DepthMapType::Normal, SHADOW_RES),
|
||||
m_shaderProgram(Controller::getShaderProgramByName("defaultProgram", shaderPrograms))
|
||||
: m_shaderProgram(Controller::getShaderProgramByName("defaultProgram", shaderPrograms)),
|
||||
m_depthMapDirectionalFBO(DepthMapType::Normal, SHADOW_RES)
|
||||
{
|
||||
// Create 4 depthMaps
|
||||
for (int i = 0; i < 4; i++) {
|
||||
@@ -28,6 +28,7 @@ World::World(std::vector<ShaderProgram *> shaderPrograms)
|
||||
m_shaderProgram->unbind();
|
||||
|
||||
JsonParser modelParser("data/models.json");
|
||||
|
||||
std::vector<Model::Prototype> modelPrototypes = modelParser.getModelPrototypes();
|
||||
|
||||
{
|
||||
@@ -53,6 +54,15 @@ World::World(std::vector<ShaderProgram *> shaderPrograms)
|
||||
for (auto &model : m_models)
|
||||
model->initializeOnGPU();
|
||||
|
||||
// TODO: use geometry shader instead of model and load skybox before models.
|
||||
Skybox::Prototype skyboxPrototype = modelParser.getSkyboxPrototype();
|
||||
std::thread skyboxThread([=]() {
|
||||
m_skybox = new Skybox(skyboxPrototype, getModelByName("cube"),
|
||||
Controller::getShaderProgramByName("skyboxProgram", shaderPrograms));
|
||||
|
||||
std::cout << "Loaded Skybox \"" << skyboxPrototype.texturePath << "\"" << std::endl;
|
||||
});
|
||||
|
||||
std::vector<Entity::Prototype> entityPrototypes = modelParser.getEntityPrototypes();
|
||||
|
||||
std::vector<Entity *> entities;
|
||||
@@ -84,13 +94,30 @@ World::World(std::vector<ShaderProgram *> shaderPrograms)
|
||||
entities.push_back(currentEntity);
|
||||
}
|
||||
}
|
||||
|
||||
m_entities = entities;
|
||||
m_skybox = modelParser.getSkybox(getModelByName("cube"),
|
||||
Controller::getShaderProgramByName("skyboxProgram", shaderPrograms));
|
||||
|
||||
JsonParser lightParser("data/lights.json");
|
||||
m_lights = lightParser.getLights(m_shaderProgram);
|
||||
auto lightPrototypes = lightParser.getLightPrototypes();
|
||||
|
||||
std::vector<Light *> lights;
|
||||
{
|
||||
for (auto &prototype : lightPrototypes) {
|
||||
Light *currentLight;
|
||||
auto directionalPrototype = dynamic_cast<DirectionalLight::Prototype *>(prototype.get());
|
||||
if (directionalPrototype) {
|
||||
currentLight = new DirectionalLight(*directionalPrototype, m_shaderProgram);
|
||||
}
|
||||
auto pointPrototype = dynamic_cast<PointLight::Prototype *>(prototype.get());
|
||||
if (pointPrototype) {
|
||||
currentLight = new PointLight(*pointPrototype, m_shaderProgram);
|
||||
}
|
||||
lights.push_back(currentLight);
|
||||
}
|
||||
}
|
||||
m_lights = lights;
|
||||
|
||||
skyboxThread.join();
|
||||
m_skybox->initializeOnGPU();
|
||||
}
|
||||
|
||||
World::~World()
|
||||
|
||||
@@ -14,6 +14,7 @@ Imgui::Handler::Handler(GLFWwindow *window) : m_GLFWwindow(window)
|
||||
ImGui::CreateContext();
|
||||
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
(void)io;
|
||||
// io.IniFilename = nullptr;
|
||||
|
||||
// Setup Platform/Renderer bindings
|
||||
|
||||
Reference in New Issue
Block a user