Large Json loading refactoring

This commit is contained in:
2021-07-10 11:28:02 +02:00
parent 5385b7ede7
commit 2305180272
17 changed files with 294 additions and 173 deletions

View File

@@ -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",

View File

@@ -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"));

View File

@@ -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);

View File

@@ -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;
};

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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()
{

View File

@@ -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);

View File

@@ -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()

View File

@@ -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('/'));

View File

@@ -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);

View File

@@ -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
}

View File

@@ -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();

View File

@@ -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";

View File

@@ -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;

View File

@@ -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()

View File

@@ -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