This commit is contained in:
2022-04-24 22:12:07 +02:00
parent 40a1723544
commit 3cfdd7a3f2
43 changed files with 777 additions and 457 deletions

View File

@@ -4,6 +4,7 @@ AccessModifierOffset: '-4'
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: 'false'
AlwaysBreakTemplateDeclarations: 'true'
BreakBeforeBraces: Mozilla
ColumnLimit: '120'
IndentWidth: '4'

View File

@@ -5,11 +5,8 @@ add_executable(Fall-Fever
EventHandler.cpp
ShaderProgram.cpp
VertexArray.cpp
Texture.cpp
TextureFactory.cpp
Camera.cpp
Mesh.cpp
Model.cpp
Entity.cpp
Light.cpp
Scene.cpp
@@ -24,6 +21,11 @@ add_executable(Fall-Fever
imgui/Handler.cpp
imgui/Window.cpp
util/Log.cpp
resources/Resource.cpp
resources/ResourceHandler.cpp
resources/Texture.cpp
resources/Model.cpp
resources/CubeMap.cpp
)
target_link_libraries(

View File

@@ -21,14 +21,15 @@
#include "JsonParser.h"
#include "Light.h"
#include "Menu.h"
#include "Model.h"
#include "Scene.h"
#include "Screen.h"
#include "ShaderProgram.h"
#include "Texture.h"
#include "VertexArray.h"
#include "Widget.h"
#include "Window.h"
#include "resources/Model.h"
#include "resources/ResourceHandler.h"
#include "resources/Texture.h"
#include "util/Log.h"
Controller::Controller() : m_gameWindow(std::unique_ptr<Window>(new Window))

View File

@@ -1,8 +1,10 @@
#include "Entity.h"
#include "Mesh.h"
#include "Model.h"
#include "ShaderProgram.h"
#include "VertexArray.h"
#include "resources/CubeMap.h"
#include "resources/Model.h"
#include "resources/ResourceHandler.h"
#include <glm/ext/matrix_transform.hpp>
#include <glm/gtc/matrix_transform.hpp>
@@ -125,7 +127,7 @@ glm::mat4 Entity::getModelMatrix() const
return m_modelMatrix;
}
ModelEntity::ModelEntity(Prototype prototype, Model *model, ShaderProgram *shaderProgram)
ModelEntity::ModelEntity(Prototype prototype, const Model *model, ShaderProgram *shaderProgram)
: Entity(prototype.name), m_model(model), m_shaderProgram(shaderProgram)
{
setPosition(prototype.position);
@@ -191,18 +193,20 @@ void ModelEntity::drawPointShadows(ShaderProgram *shaderProgram)
}
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())
{}
: m_cubeModel(cubeModel), m_shaderProgram(shaderProgram), m_vertexArray(cubeModel->getMesh(0)->getVertexArray())
{
m_cubeMap =
ResourceHandler::instance().registerResource<TextureCubeMap>(TextureCubeMapDescriptor{prototype.texturePath});
}
Skybox::~Skybox()
{
delete m_cubeMap;
// delete m_cubeMap;
}
void Skybox::initializeOnGPU()
{
m_cubeMap->initializeOnGPU();
// m_cubeMap->initializeOnGPU();
}
void Skybox::draw(glm::mat4 viewMatrix, glm::mat4 projectionMatrix)
@@ -220,9 +224,10 @@ void Skybox::draw(glm::mat4 viewMatrix, glm::mat4 projectionMatrix)
m_shaderProgram->setUniform("u_viewProjectionMatrix", viewProjectionMatrix);
m_cubeMap->bind(m_shaderProgram);
auto cubeMap = std::static_pointer_cast<TextureCubeMap>(ResourceHandler::instance().resource(m_cubeMap));
cubeMap->bind(m_shaderProgram);
m_cubeModel->getMesh(0)->drawWithoutTextures();
m_cubeMap->unbind();
cubeMap->unbind();
m_shaderProgram->unbind();
glDepthMask(GL_TRUE);

View File

@@ -1,14 +1,17 @@
#pragma once
#include "Texture.h"
#include "resources/Resource.h"
#include <glm/glm.hpp>
#include <glm/gtx/quaternion.hpp>
#include <memory>
#include <string>
#include <vector>
class VertexArray;
class ShaderProgram;
class Model;
class TextureCubeMap;
class Entity
{
@@ -87,7 +90,7 @@ public:
std::string shaderProgramName;
};
ModelEntity(Prototype prototype, Model *model, ShaderProgram *shaderProgram);
ModelEntity(Prototype prototype, const Model *model, ShaderProgram *shaderProgram);
~ModelEntity() = default;
void draw(glm::mat4 viewProjMatrix, glm::vec3 viewPosition);
@@ -95,7 +98,7 @@ public:
void drawPointShadows(ShaderProgram *p_shaderProgram);
private:
Model *m_model;
const Model *m_model;
ShaderProgram *m_shaderProgram;
};
@@ -120,7 +123,7 @@ private:
Model *m_cubeModel;
ShaderProgram *m_shaderProgram;
CubeMap *m_cubeMap;
ResourceId m_cubeMap;
VertexArray *m_vertexArray;
};

View File

@@ -1,6 +1,8 @@
#include "FrameBuffer.h"
#include "ShaderProgram.h"
#include "Texture.h"
#include "resources/CubeMap.h"
#include "resources/ResourceHandler.h"
#include "resources/Texture.h"
#include "util/Log.h"
#include <cstddef>
@@ -150,14 +152,15 @@ GLuint DepthMap::getDepthMap() const
return m_depthMap;
}
DepthMapCube::DepthMapCube(int RESOLUTION)
DepthMapCube::DepthMapCube(int resolution)
{
glGenFramebuffers(1, &m_FBO);
bind();
m_cubeMap = new CubeMap(RESOLUTION);
m_cubeMap = ResourceHandler::instance().registerResource<InternalCubeMap>(resolution);
GLuint glId = std::static_pointer_cast<InternalCubeMap>(ResourceHandler::instance().resource(m_cubeMap))->glId();
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_cubeMap->getTextureId(), 0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, glId, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
@@ -172,5 +175,5 @@ DepthMapCube::~DepthMapCube()
GLuint DepthMapCube::getCubeMapTextureId()
{
return m_cubeMap->getTextureId();
return std::static_pointer_cast<InternalCubeMap>(ResourceHandler::instance().resource(m_cubeMap))->glId();
}

View File

@@ -1,5 +1,6 @@
#pragma once
#include "resources/CubeMap.h"
#include <glad/glad.h>
class ShaderProgram;
@@ -51,7 +52,7 @@ public:
class DepthMap : public AbstractDepthMap
{
public:
DepthMap(int RESOLUTION);
DepthMap(int resolution);
~DepthMap();
GLuint getDepthMap() const;
@@ -63,11 +64,11 @@ private:
class DepthMapCube : public AbstractDepthMap
{
public:
DepthMapCube(int RESOLUTION);
DepthMapCube(int resolution);
~DepthMapCube();
GLuint getCubeMapTextureId();
private:
CubeMap *m_cubeMap;
ResourceId m_cubeMap;
};

View File

@@ -122,13 +122,13 @@ void Helper::gl_debug_callback(GLenum source, GLenum type, GLuint id, GLenum sev
}
if (severity == GL_DEBUG_SEVERITY_HIGH || severity == GL_DEBUG_SEVERITY_MEDIUM)
Log::logger().info("[OpenGL Debug Message]\n"
"Message: {}\n"
"Source: {}\n"
"Type: {}\n"
"ID: {}\n"
"Severity: {}\n",
_message, _source, _type, id, _severity);
Log::logger().debug("\n[OpenGL Debug Message]\n"
"Message: {}\n"
"Source: {}\n"
"Type: {}\n"
"ID: {}\n"
"Severity: {}\n",
_message, _source, _type, id, _severity);
}
Helper::Timer::Timer(const std::string &name) : m_name(name)

View File

@@ -25,20 +25,19 @@ JsonParser::JsonParser(const std::string &jsonFilepath)
JsonParser::~JsonParser()
{}
std::vector<Model::Prototype> JsonParser::getModelPrototypes() const
std::vector<ModelDescriptor> JsonParser::getModelDescriptors() const
{
const Json::Value modelsJson = m_root["models"];
std::vector<Model::Prototype> modelPrototypes;
std::vector<ModelDescriptor> modelDescriptors;
for (unsigned int index = 0; index < modelsJson.size(); index++) {
std::string modelName = modelsJson[index]["unique_name"].asString();
std::string modelPath = modelsJson[index]["path"].asString();
Model::Prototype prototype{modelName, modelPath};
modelPrototypes.push_back(prototype);
modelDescriptors.push_back({modelPath, modelName});
}
return modelPrototypes;
return modelDescriptors;
}
std::vector<ModelEntity::Prototype> JsonParser::getEntityPrototypes() const
@@ -229,9 +228,9 @@ std::vector<Widget::Prototype> JsonParser::getWidgetPrototypesFromScreen(const J
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};
TextureDescriptor textureDescriptor{currentWidgetTextureJson.asString(), TextureType::Diffuse};
Widget::Prototype widgetPrototype{name, position, dimensions, texturePrototype, callBackId};
Widget::Prototype widgetPrototype{name, position, dimensions, textureDescriptor, callBackId};
widgetPrototypes.push_back(widgetPrototype);
}

View File

@@ -7,10 +7,10 @@
#include "Entity.h"
#include "Light.h"
#include "Model.h"
#include "Screen.h"
#include "ShaderProgram.h"
#include "Widget.h"
#include "resources/Model.h"
class Screen;
class ShaderProgram;
@@ -22,7 +22,7 @@ public:
JsonParser(const std::string &jsonFilepath);
~JsonParser();
std::vector<Model::Prototype> getModelPrototypes() const;
std::vector<ModelDescriptor> getModelDescriptors() const;
std::vector<ModelEntity::Prototype> getEntityPrototypes() const;
std::vector<std::unique_ptr<Light::Prototype>> getLightPrototypes() const;
std::vector<Screen::Prototype> getScreenPrototypes() const;

View File

@@ -71,7 +71,6 @@ void Menu::handleMouseButtonActionMap(const MouseButtonActionMap &mouseButtonAct
auto widgets = m_activeScreen->getWidgets();
for (auto it = widgets.begin(); it != widgets.end(); it++) {
if ((*it)->isHovered(window)) {
// std::cout << (*it)->getUniqueName() << " clicked!" << std::endl;
if ((*it)->getCallbackId() == 1)
resetActiveScreen();
if ((*it)->getCallbackId() == 2)

View File

@@ -1,9 +1,10 @@
#include "Mesh.h"
#include "ShaderProgram.h"
#include "Texture.h"
#include "VertexArray.h"
#include "resources/ResourceHandler.h"
#include "resources/Texture.h"
Mesh::Mesh(std::vector<Vertex> vertices, std::vector<uint32_t> indices, std::vector<Texture *> textures)
Mesh::Mesh(std::vector<Vertex> vertices, std::vector<uint32_t> indices, std::vector<ResourceId> textures)
: m_preInitializationVertexData{vertices, indices}, m_numElements(indices.size()), m_textures(textures)
{}
@@ -27,9 +28,10 @@ void Mesh::draw(ShaderProgram *shaderProgram)
// Bind all textures in order to its texture unit
int i = 0;
for (auto it : m_textures) {
TextureType currentTextureType = it->getTextureType();
auto texture = std::static_pointer_cast<Texture>(ResourceHandler::instance().resource(it));
TextureType currentTextureType = texture->textureType();
it->bind(i, shaderProgram, typeNumberCount[static_cast<int>(currentTextureType)]);
texture->bind(i, shaderProgram, typeNumberCount[static_cast<int>(currentTextureType)]);
typeNumberCount[static_cast<int>(currentTextureType)] += 1;
@@ -42,8 +44,9 @@ void Mesh::draw(ShaderProgram *shaderProgram)
m_vertexArray->unbind();
// Unbind all textures
for (auto it = m_textures.begin(); it != m_textures.end(); it++) {
(*it)->unbind();
for (auto it : m_textures) {
auto texture = std::static_pointer_cast<Texture>(ResourceHandler::instance().resource(it));
texture->unbind();
}
}

View File

@@ -1,17 +1,17 @@
#pragma once
#include "VertexArray.h"
#include "definitions/models.h"
#include "resources/Texture.h"
#include <vector>
class ShaderProgram;
class Texture;
class VertexArray;
class Mesh
{
public:
Mesh(std::vector<Vertex> vertices, std::vector<unsigned int> indices, std::vector<Texture *> textures);
Mesh(std::vector<Vertex> vertices, std::vector<unsigned int> indices, std::vector<ResourceId> textures);
~Mesh();
void initializeOnGPU();
@@ -31,7 +31,7 @@ private:
bool m_isInitialized = false;
uint32_t m_numElements;
std::vector<Texture *> m_textures;
std::vector<ResourceId> m_textures;
VertexArray *m_vertexArray;
};

View File

@@ -1,45 +0,0 @@
#pragma once
#include "definitions/models.h"
#include <string>
#include <vector>
class ShaderProgram;
class Mesh;
class Texture;
class Model
{
public:
struct Prototype
{
std::string modelName;
std::string modelPath;
};
Model(const Prototype &prototype);
~Model();
void initializeOnGPU();
void draw(ShaderProgram *shaderProgram);
void drawWithoutTextures();
Mesh *getMesh(unsigned int index);
const std::string &getUniqueName();
private:
void loadModel(const std::string &pathToModel);
bool m_isInitialized = false;
std::vector<Mesh *> m_meshes;
std::vector<Texture *> m_textures;
std::string m_workingPath;
static uint32_t s_idCounter;
uint32_t m_id;
std::string m_uniqueName;
};

View File

@@ -5,9 +5,10 @@
#include "FrameBuffer.h"
#include "JsonParser.h"
#include "Light.h"
#include "Model.h"
#include "ShaderProgram.h"
#include "Texture.h"
#include "resources/Model.h"
#include "resources/ResourceHandler.h"
#include "resources/Texture.h"
#include "util/Log.h"
#include <future>
@@ -30,34 +31,32 @@ Scene::Scene(std::vector<ShaderProgram *> shaderPrograms)
JsonParser modelParser("data/scene.json");
std::vector<Model::Prototype> modelPrototypes = modelParser.getModelPrototypes();
std::vector<ModelDescriptor> modelDescriptors = modelParser.getModelDescriptors();
{
std::vector<std::future<void>> futures;
std::mutex mutex;
for (auto &prototype : modelPrototypes) {
for (const auto &descriptor : modelDescriptors) {
auto loadModel = [=, &mutex]() {
Model *currentModel = new Model(prototype);
ResourceId model = ResourceHandler::instance().registerResource<Model>(descriptor);
Log::logger().info("Loaded model \"{}\": {}", prototype.modelName, prototype.modelPath);
Log::logger().info("Loaded model \"{}\": {}", descriptor.name, descriptor.path);
std::lock_guard<std::mutex> lock(mutex);
m_models.push_back(currentModel);
m_models.push_back(model);
};
futures.push_back(std::async(std::launch::async, loadModel));
}
}
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"),
m_skybox = new Skybox(skyboxPrototype,
std::static_pointer_cast<Model>(ResourceHandler::instance().resource("cube")).get(),
Controller::getShaderProgramByName("skyboxProgram", shaderPrograms));
Log::logger().info("Loaded skybox: {}", skyboxPrototype.texturePath);
@@ -68,11 +67,13 @@ Scene::Scene(std::vector<ShaderProgram *> shaderPrograms)
{
for (auto &prototype : entityPrototypes) {
// Get model
Model *currentModel = getModelByName(prototype.modelName);
const Model *currentModel =
std::static_pointer_cast<Model>(ResourceHandler::instance().resource(prototype.modelName)).get();
if (!currentModel) {
// Apply fallback model (first model in vector)
currentModel = m_models[0];
currentModel = std::static_pointer_cast<Model>(ResourceHandler::instance().resource("fallback"))
.get(); // TODO rename fallbackModel
Log::logger().warn("Model could not be found by name \"{}\"", prototype.modelName);
}
@@ -138,9 +139,9 @@ Scene::~Scene()
delete (*it);
}
// Iterate over models and entities and delete all items
for (auto it = m_models.begin(); it != m_models.end(); it++) {
delete (*it);
}
// for (auto it = m_models.begin(); it != m_models.end(); it++) {
// delete (*it);
// }
for (auto it = m_entities.begin(); it != m_entities.end(); it++) {
delete (*it);
}
@@ -306,17 +307,6 @@ void Scene::calculateShadows(ShaderProgram *directionalShaderProgram, ShaderProg
glCullFace(GL_FRONT);
}
Model *Scene::getModelByName(const std::string &name)
{
for (auto it = m_models.begin(); it != m_models.end(); it++) {
if ((*it)->getUniqueName() == name) {
return *it;
}
}
Log::logger().warn("Model could not be found by unique name \"{}\"", name);
return nullptr;
}
ModelEntity *Scene::getEntityByName(const std::string &name)
{
for (auto it = m_entities.begin(); it != m_entities.end(); it++) {

View File

@@ -1,6 +1,7 @@
#pragma once
#include "FrameBuffer.h"
#include "resources/Resource.h"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
@@ -36,7 +37,6 @@ public:
Skybox *getSkybox();
ModelEntity *getEntityByName(const std::string &name);
ModelEntity *getEntityById(uint32_t id);
Model *getModelByName(const std::string &name);
void draw(glm::mat4 viewProjMatrix, glm::vec3 viewPosition);
void calculateShadows(ShaderProgram *directionalShaderProgram, ShaderProgram *pointShaderProgram);
@@ -44,7 +44,7 @@ public:
private:
ShaderProgram *m_shaderProgram;
std::vector<Model *> m_models;
std::vector<ResourceId> m_models;
std::vector<ModelEntity *> m_entities;
Skybox *m_skybox;

View File

@@ -3,8 +3,9 @@
#include "Helper.h"
#include "Menu.h"
#include "ShaderProgram.h"
#include "Texture.h"
// #include "Texture.h"
#include "Widget.h"
#include "resources/ResourceHandler.h"
uint32_t Screen::s_idCounter = 0;
@@ -13,10 +14,9 @@ Screen::Screen(Prototype prototype, FrameBuffer *framebuffer, ShaderProgram *sha
{
for (auto &prototype : prototype.widgetPrototypes) {
auto texturePrototype = prototype.texturePrototype;
Texture *currentTexture = new Texture({texturePrototype.texturePath, texturePrototype.textureType});
currentTexture->initializeOnGPU();
ResourceId textureId = ResourceHandler::instance().registerResource<Texture>(texturePrototype);
Widget *currentWidget = new Widget(prototype, currentTexture);
Widget *currentWidget = new Widget(prototype, textureId);
m_widgets.push_back(currentWidget);
}
}
@@ -27,9 +27,6 @@ Screen::~Screen()
for (auto it = m_widgets.begin(); it != m_widgets.end(); it++) {
delete *it;
}
for (auto it = m_textures.begin(); it != m_textures.end(); it++) {
delete *it;
}
}
const std::string &Screen::getUniqueName() const

View File

@@ -1,15 +1,15 @@
#pragma once
#include "Widget.h"
#include "resources/Texture.h"
#include <string>
#include <unordered_map>
#include <vector>
#include "Widget.h"
class Menu;
class FrameBuffer;
class ShaderProgram;
class Texture;
class Screen
{
@@ -38,7 +38,7 @@ private:
FrameBuffer *m_frameBuffer;
ShaderProgram *m_shaderProgram;
std::vector<Texture *> m_textures;
std::vector<ResourceId> m_textures;
std::vector<Widget *> m_widgets;
mutable std::unordered_map<std::string, Widget *> m_widgetNameCache;

View File

@@ -1,94 +0,0 @@
#pragma once
#include "definitions/models.h"
#include <cstdint>
#include <glad/glad.h>
#include <stb/stb_image.h>
#include <string>
#include <vector>
class ShaderProgram;
// Order is important!
enum class cubeMapFaces
{
cm_right,
cm_left,
cm_top,
cm_bottom,
cm_back,
cm_front,
CUBEMAP_FACES_NUM_ITEMS
};
class Texture
{
public:
struct Prototype
{
std::string texturePath;
TextureType textureType;
};
void bind(uint8_t textureUnit, ShaderProgram *shaderProgram, uint8_t textureTypeNum);
void unbind();
TextureType getTextureType();
std::string getPath();
GLuint textureId();
Texture(const Prototype &texturePrototype); // TODO make private
void initializeOnGPU(); // TODO make private
~Texture(); // TODO make private
private:
Texture(const Texture &other) = delete;
Texture(Texture &&other) = delete;
Texture &operator=(const Texture &other) = delete;
Texture &operator=(Texture &&other) = delete;
std::string m_texturePath;
stbi_uc *m_textureBuffer;
int32_t m_textureWidth;
int32_t m_textureHeight;
int32_t m_numComponents;
GLuint m_textureId; // TODO inherit from abstract class resource
TextureType m_textureType;
friend class TextureFactory;
};
class CubeMap
{
public:
CubeMap(const std::string &texturePseudoPath);
CubeMap(int RESOLUTION);
void initializeOnGPU();
~CubeMap();
void bind(ShaderProgram *shaderProgram);
void unbind();
GLuint getTextureId() const;
private:
void fillTexturePathVector(const std::string &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;
int32_t m_textureWidth;
int32_t m_textureHeight;
};

View File

@@ -1,20 +0,0 @@
#include "TextureFactory.h"
TextureFactory &TextureFactory::instance()
{
static TextureFactory instance;
return instance;
}
void TextureFactory::registerTexture(const Texture::Prototype &prototype)
{
auto texture = std::make_unique<Texture>(prototype);
m_textureMap.insert({texture->textureId(), std::move(texture)});
}
std::unique_ptr<Texture> TextureFactory::texture(uint64_t resourceId)
{
auto texture = std::move(m_textureMap.at(resourceId));
texture->initializeOnGPU();
return texture;
}

View File

@@ -1,18 +0,0 @@
#pragma once
#include "Texture.h"
#include <map>
#include <memory>
class TextureFactory // TODO not yet used
{
public:
static TextureFactory &instance();
void registerTexture(const Texture::Prototype &prototype);
std::unique_ptr<Texture> texture(uint64_t resourceId);
private:
std::map<uint64_t, std::unique_ptr<Texture>> m_textureMap;
};

View File

@@ -1,115 +1,7 @@
#include "Texture.h"
#include "ShaderProgram.h"
#include "Texture.h"
#include "util/Log.h"
Texture::Texture(const Prototype &texturePrototype)
: m_texturePath(texturePrototype.texturePath), m_textureType(texturePrototype.textureType)
{
stbi_set_flip_vertically_on_load(1);
m_textureBuffer = stbi_load(m_texturePath.c_str(), &m_textureWidth, &m_textureHeight, &m_numComponents, 0);
if (!m_textureBuffer)
Log::logger().warn("Texture {} could not be loaded", m_texturePath);
}
Texture::~Texture()
{
glDeleteTextures(1, &m_textureId);
}
void Texture::initializeOnGPU()
{
GLenum internalFormat;
GLenum dataFormat;
switch (m_numComponents) {
case 1:
internalFormat = GL_RED;
dataFormat = GL_RED;
break;
case 3:
internalFormat = (m_textureType == TextureType::Diffuse) ? GL_SRGB8 : GL_RGB8;
dataFormat = GL_RGB;
break;
case 4:
internalFormat = (m_textureType == TextureType::Diffuse) ? GL_SRGB8_ALPHA8 : GL_RGBA8;
dataFormat = GL_RGBA;
break;
}
// Push texture to grahics card
glGenTextures(1, &m_textureId);
glBindTexture(GL_TEXTURE_2D, m_textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -2.0f);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, m_textureWidth, m_textureHeight, 0, dataFormat, GL_UNSIGNED_BYTE,
m_textureBuffer);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
stbi_image_free(m_textureBuffer);
}
void Texture::bind(uint8_t textureUnit, ShaderProgram *shaderProgram, uint8_t textureTypeNum)
{
std::string uniformName = "texture_";
switch (m_textureType) {
case TextureType::Diffuse:
uniformName += "diffuse" + std::to_string(textureTypeNum);
break;
case TextureType::Specular:
uniformName += "specular" + std::to_string(textureTypeNum);
break;
case TextureType::Normal:
uniformName += "normal" + std::to_string(textureTypeNum);
break;
case TextureType::Height:
uniformName += "height" + std::to_string(textureTypeNum);
break;
case TextureType::Gloss:
uniformName += "gloss" + std::to_string(textureTypeNum);
break;
default:
break;
}
// Add u_material as we store textures in a struct
uniformName = "u_material." + uniformName;
shaderProgram->setUniform(uniformName.c_str(), textureUnit);
glActiveTexture(GL_TEXTURE0 + textureUnit);
glBindTexture(GL_TEXTURE_2D, m_textureId);
}
void Texture::unbind()
{
glBindTexture(GL_TEXTURE_2D, 0);
}
TextureType Texture::getTextureType()
{
return m_textureType;
}
std::string Texture::getPath()
{
return m_texturePath;
}
GLuint Texture::textureId()
{
return m_textureId;
}
CubeMap::CubeMap(const std::string &texturePseudoPath)
{
// Reserve space in vector so that elements can be accessed explicitly.

54
src/Texture_old.h Normal file
View File

@@ -0,0 +1,54 @@
#pragma once
#include "definitions/models.h"
#include "resources/Texture.h"
#include <cstdint>
#include <glad/glad.h>
#include <stb/stb_image.h>
#include <string>
#include <vector>
class ShaderProgram;
// Order is important!
enum class cubeMapFaces
{
cm_right,
cm_left,
cm_top,
cm_bottom,
cm_back,
cm_front,
CUBEMAP_FACES_NUM_ITEMS
};
class CubeMap
{
public:
CubeMap(const std::string &texturePseudoPath);
CubeMap(int RESOLUTION);
void initializeOnGPU();
~CubeMap();
void bind(ShaderProgram *shaderProgram);
void unbind();
GLuint getTextureId() const;
private:
void fillTexturePathVector(const std::string &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;
int32_t m_textureWidth;
int32_t m_textureHeight;
};

View File

@@ -4,22 +4,17 @@
#include "ShaderProgram.h"
#include "VertexArray.h"
#include "Window.h"
#include "resources/ResourceHandler.h"
#include <GLFW/glfw3.h>
Widget::Widget(Prototype prototype, Texture *texture)
Widget::Widget(Prototype prototype, ResourceId texture)
: m_position(prototype.position), m_dimensions(prototype.dimensions), m_uniqueName(prototype.name),
m_callbackId(prototype.callBackId)
{
m_widgetTextures.push_back(texture);
}
Widget::~Widget()
{
for (auto &texture : m_widgetTextures)
delete texture;
}
std::string Widget::getUniqueName()
{
return m_uniqueName;
@@ -41,7 +36,8 @@ void Widget::draw(ShaderProgram *shaderProgram)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_widgetTextures[0]->textureId());
auto texture = std::static_pointer_cast<Texture>(ResourceHandler::instance().resource(m_widgetTextures[0]));
glBindTexture(GL_TEXTURE_2D, texture->glId());
GLint location = glGetUniformLocation(shaderProgram->getShaderProgramId(), "u_texture");
glUniform1i(location, 0);

View File

@@ -1,7 +1,7 @@
#pragma once
#include "Texture.h"
#include "definitions/models.h"
#include "resources/Texture.h"
#include <glm/glm.hpp>
#include <string>
@@ -9,7 +9,6 @@
class Menu;
class ShaderProgram;
class Texture;
class Window;
class Mesh;
@@ -21,12 +20,11 @@ public:
std::string name;
glm::vec2 position;
glm::vec2 dimensions;
Texture::Prototype texturePrototype;
TextureDescriptor texturePrototype;
uint16_t callBackId; // TODO: will be removed...
};
Widget(Prototype prototype, Texture *texture);
~Widget();
Widget(Prototype prototype, ResourceId texture);
void draw(ShaderProgram *shaderProgram);
@@ -43,5 +41,5 @@ private:
uint16_t m_callbackId;
std::vector<Texture *> m_widgetTextures;
std::vector<ResourceId> m_widgetTextures;
};

View File

@@ -2,16 +2,6 @@
#include <glm/glm.hpp>
enum class TextureType
{
Diffuse,
Specular,
Normal,
Height,
Gloss,
TEXTURE_TYPE_NUM_ITEMS
};
struct Vertex
{
// Postition

View File

@@ -0,0 +1,15 @@
#pragma once
#include "Resource.h"
class AbstractTexture : public Resource, public GlResource
{
public:
AbstractTexture(const std::string &path) : Resource(path)
{}
protected:
int32_t m_textureWidth;
int32_t m_textureHeight;
int32_t m_numComponents;
};

119
src/resources/CubeMap.cpp Normal file
View File

@@ -0,0 +1,119 @@
#include "CubeMap.h"
#include "../ShaderProgram.h"
#include "../util/Log.h"
#include <glad/glad.h>
TextureCubeMap::TextureCubeMap(const TextureCubeMapDescriptor &descriptor) : AbstractCubeMap(descriptor.path)
{
// Reserve space in vector so that elements can be accessed explicitly.
m_textureBuffers.resize(static_cast<int>(CubeMapFace::CUBEMAP_FACES_NUM_ITEMS));
stbi_set_flip_vertically_on_load(0);
glGenTextures(1, &m_glId);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_glId);
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 (const auto &faceName : FACE_NAMES) {
std::string texturePath = descriptor.path + faceName;
auto textureBuffer = stbi_load(texturePath.c_str(), &m_textureWidth, &m_textureHeight, &m_numComponents, 0);
if (!textureBuffer) {
Log::logger().warn("CubeMap texture {} could not be loaded", texturePath);
return;
}
m_textureBuffers[i] = textureBuffer;
i++;
}
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
}
void TextureCubeMap::initialize()
{
m_initialized = true;
glGenTextures(1, &m_glId);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_glId);
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) {
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 AbstractCubeMap::bind(ShaderProgram *shaderProgram) const
{
std::string uniformName = "u_skybox";
shaderProgram->setUniform(uniformName, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_glId);
}
void AbstractCubeMap::unbind() const
{
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
}
InternalCubeMap::InternalCubeMap(unsigned int resolution) : AbstractCubeMap("internal")
{
m_textureWidth = resolution;
m_textureHeight = resolution;
m_initialized = true;
glGenTextures(1, &m_glId);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_glId);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
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);
for (unsigned int i = 0; i < static_cast<int>(CubeMapFace::CUBEMAP_FACES_NUM_ITEMS); i++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT24, resolution, resolution, 0,
GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
}
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
}

60
src/resources/CubeMap.h Normal file
View File

@@ -0,0 +1,60 @@
#pragma once
#include "AbstractTexture.h"
#include <array>
#include <stb/stb_image.h>
#include <vector>
// Order is important!
enum class CubeMapFace
{
Right,
Left,
Top,
Bottom,
Back,
Front,
CUBEMAP_FACES_NUM_ITEMS
};
const std::array<std::string, 6> FACE_NAMES{"right.png", "left.png", "top.png", "bottom.png", "back.png", "front.png"};
class ShaderProgram;
struct TextureCubeMapDescriptor
{
std::string path;
};
class AbstractCubeMap : public AbstractTexture
{
public:
AbstractCubeMap(const std::string path) : AbstractTexture(path)
{}
void bind(ShaderProgram *shaderProgram) const;
void unbind() const override;
};
class TextureCubeMap : public AbstractCubeMap
{
public:
TextureCubeMap(const TextureCubeMapDescriptor &descriptor);
protected:
void initialize() override;
private:
std::vector<stbi_uc *> m_textureBuffers;
};
class InternalCubeMap : public AbstractCubeMap
{
public:
InternalCubeMap(unsigned int resolution);
protected:
void initialize() override
{}
};

View File

@@ -1,59 +1,46 @@
#include "Model.h"
#include "Mesh.h"
#include "ShaderProgram.h"
#include "Texture.h"
#include "util/Log.h"
#include "../util/Log.h"
#include "ResourceHandler.h"
#include <fstream>
#include <future>
uint32_t Model::s_idCounter = 0;
Model::Model(const Prototype &prototype) : m_id(s_idCounter++), m_uniqueName(prototype.modelName)
Model::Model(const ModelDescriptor &descriptor) : Resource(descriptor.path), NamedResource(descriptor.name)
{
m_workingPath = prototype.modelPath.substr(0, prototype.modelPath.find_last_of('/'));
m_workingPath = descriptor.path.substr(0, descriptor.path.find_last_of('/'));
loadModel(prototype.modelPath);
loadModel(descriptor.path);
}
void Model::initializeOnGPU()
void Model::initialize()
{
if (m_isInitialized)
return;
m_isInitialized = true;
for (auto texture : m_textures)
texture->initializeOnGPU();
m_initialized = true;
for (auto mesh : m_meshes)
mesh->initializeOnGPU();
}
Model::~Model()
{
// Go through all loaded textures and delete them
for (auto it = m_textures.begin(); it != m_textures.end(); it++) {
delete (*it);
}
}
void Model::draw(ShaderProgram *shaderProgram)
void Model::draw(ShaderProgram *shaderProgram) const
{
// Iterate through every mesh and call the draw function
for (auto mesh : m_meshes) {
for (const auto &mesh : m_meshes) {
mesh->draw(shaderProgram);
}
}
void Model::drawWithoutTextures()
void Model::drawWithoutTextures() const
{
// Iterate through every mesh and call the draw function
for (auto mesh : m_meshes) {
for (const auto &mesh : m_meshes) {
mesh->drawWithoutTextures();
}
}
Mesh *Model::getMesh(unsigned int index) const
{
return m_meshes[index];
}
void Model::loadModel(const std::string &pathToModel)
{
std::ifstream input(pathToModel, std::ios::in | std::ios::binary);
@@ -96,10 +83,11 @@ void Model::loadModel(const std::string &pathToModel)
std::string texturePath = m_workingPath + '/' + textureSources[i].c_str();
auto loadModel = [=, &mutex]() {
Texture *currentTex = new Texture({texturePath, textureTypes[i]});
ResourceId texture = ResourceHandler::instance().registerResource<Texture>(
TextureDescriptor{texturePath, textureTypes[i]});
std::lock_guard<std::mutex> lock(mutex);
m_textures.push_back(currentTex);
m_textures.push_back(texture);
};
futures.push_back(std::async(std::launch::async, loadModel));
@@ -114,9 +102,10 @@ void Model::loadModel(const std::string &pathToModel)
}
if (!hasNormalMap) {
Texture *currentTex = new Texture({"data/res/models/tex/fallback_normal.png", TextureType::Normal});
ResourceId texture = ResourceHandler::instance().registerResource<Texture>(
TextureDescriptor{"data/res/models/tex/fallback_normal.png", TextureType::Normal});
m_textures.push_back(currentTex);
m_textures.push_back(texture);
}
// Here starts the first mesh
@@ -144,7 +133,7 @@ void Model::loadModel(const std::string &pathToModel)
input.read((char *)meshIndices.data(), indexBlockSize);
std::vector<uint32_t> meshTextureIds;
std::vector<Texture *> meshTextures;
std::vector<ResourceId> meshTextures;
for (unsigned int i = 0; i < numMeshTextureIds; i++) {
uint32_t currentTextureId;
@@ -166,13 +155,3 @@ void Model::loadModel(const std::string &pathToModel)
input.close();
}
Mesh *Model::getMesh(unsigned int index)
{
return m_meshes[index];
}
const std::string &Model::getUniqueName()
{
return m_uniqueName;
}

35
src/resources/Model.h Normal file
View File

@@ -0,0 +1,35 @@
#pragma once
#include "../Mesh.h"
#include "Resource.h"
#include <string>
#include <vector>
struct ModelDescriptor
{
std::string path;
std::string name;
};
class Model : public Resource, public NamedResource
{
public:
Model(const ModelDescriptor &descriptor);
void draw(ShaderProgram *shaderProgram) const;
void drawWithoutTextures() const;
Mesh *getMesh(unsigned int index) const; // TODO...
protected:
void initialize() override;
private:
void loadModel(const std::string &pathToModel);
std::vector<Mesh *> m_meshes;
std::vector<ResourceId> m_textures;
std::string m_workingPath;
};

View File

@@ -0,0 +1,40 @@
#include "Resource.h"
#include "../util/Log.h"
ResourceId Resource::s_idCounter = 0;
Resource::Resource(const std::string &path) : m_id(s_idCounter++), m_path(path)
{
Log::logger().info("Resource \"{}\" with id {} created", m_path, m_id);
}
ResourceId Resource::id() const
{
return m_id;
}
bool Resource::isInitialized() const
{
return m_initialized;
}
const std::string &Resource::resourcePath() const
{
return m_path;
}
GLuint GlResource::glId() const
{
return m_glId;
}
NamedResource::NamedResource(const std::string &name) : m_name(name)
{}
const std::string &NamedResource::name() const
{
return m_name;
}
NamedResource::~NamedResource()
{}

58
src/resources/Resource.h Normal file
View File

@@ -0,0 +1,58 @@
#pragma once
#include <cstdint>
#include <glad/glad.h>
#include <string>
using ResourceId = uint64_t;
class Resource
{
public:
Resource(const std::string &path);
Resource(const Resource &other) = delete;
Resource(Resource &&other) = delete;
Resource &operator=(const Resource &other) = delete;
Resource &operator=(Resource &&other) = delete;
ResourceId id() const;
const std::string &resourcePath() const;
protected:
bool isInitialized() const;
virtual void initialize() = 0;
bool m_initialized = false;
private:
ResourceId m_id;
static ResourceId s_idCounter;
std::string m_path;
friend class ResourceHandler;
};
class GlResource
{
public:
// virtual ~GlResource() = 0; TODO!!
virtual void unbind() const = 0;
GLuint glId() const;
protected:
GLuint m_glId;
};
class NamedResource
{
public:
NamedResource(const std::string &name);
virtual ~NamedResource() = 0;
const std::string &name() const;
protected:
std::string m_name;
};

View File

@@ -0,0 +1,67 @@
#include "ResourceHandler.h"
#include "../util/Log.h"
#include "CubeMap.h"
#include "Model.h"
#include "Texture.h"
#include <algorithm>
ResourceHandler ResourceHandler::s_instance;
ResourceHandler &ResourceHandler::instance()
{
return s_instance;
}
template <typename T, typename... Param>
ResourceId ResourceHandler::registerResource(Param const &...param)
{
auto resource = std::make_shared<T>(param...);
m_resources.emplace(resource->id(), resource);
return resource->id();
}
template ResourceId ResourceHandler::registerResource<Texture>(TextureDescriptor const &);
template ResourceId ResourceHandler::registerResource<TextureCubeMap>(TextureCubeMapDescriptor const &);
template ResourceId ResourceHandler::registerResource<InternalCubeMap>(int const &);
template ResourceId ResourceHandler::registerResource<Model>(ModelDescriptor const &);
const std::shared_ptr<Resource> ResourceHandler::resource(const ResourceId id) const
{
auto it = m_resources.find(id);
if (it != m_resources.end()) {
auto resource = it->second;
if (!resource->isInitialized())
resource->initialize();
return resource;
}
Log::logger().warn("Could not find resource with id {}", id);
return std::shared_ptr<Resource>();
}
const std::shared_ptr<Resource> ResourceHandler::resource(const std::string &name) const
{
auto it = std::find_if(m_resources.begin(), m_resources.end(), [&name](const auto &resource) {
if (auto namedResource = std::dynamic_pointer_cast<NamedResource>(resource.second)) {
return namedResource->name() == name;
}
return false;
});
if (it != m_resources.end()) {
auto resource = it->second;
if (!resource->isInitialized())
resource->initialize();
return resource;
}
Log::logger().warn("Could not find resource with unique name \"{}\"", name);
return std::shared_ptr<Resource>();
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include "Resource.h"
#include <map>
#include <memory>
class ResourceHandler
{
public:
static ResourceHandler &instance();
template <typename T, typename... Param>
ResourceId registerResource(Param const &...param);
const std::shared_ptr<Resource> resource(ResourceId id) const;
const std::shared_ptr<Resource> resource(const std::string &name) const;
private:
ResourceHandler() = default;
static ResourceHandler s_instance;
std::map<ResourceId, std::shared_ptr<Resource>> m_resources;
};

View File

@@ -0,0 +1,12 @@
#pragma once
#include "Resource.h"
class ShaderProgram : public GlResource, public NamedResource
{
public:
ShaderProgram();
void bind() const;
void unbind() const override;
}

98
src/resources/Texture.cpp Normal file
View File

@@ -0,0 +1,98 @@
#include "Texture.h"
#include "../ShaderProgram.h"
#include "../util/Log.h"
Texture::Texture(const TextureDescriptor &descriptor)
: AbstractTexture(descriptor.path), m_textureType(descriptor.textureType)
{
stbi_set_flip_vertically_on_load(1);
m_textureBuffer = stbi_load(resourcePath().c_str(), &m_textureWidth, &m_textureHeight, &m_numComponents, 0);
if (!m_textureBuffer)
Log::logger().warn("Texture {} could not be loaded", resourcePath());
}
void Texture::initialize()
{
m_initialized = true;
GLenum internalFormat;
GLenum dataFormat;
switch (m_numComponents) {
case 1:
internalFormat = GL_RED;
dataFormat = GL_RED;
break;
case 3:
internalFormat = (m_textureType == TextureType::Diffuse) ? GL_SRGB8 : GL_RGB8;
dataFormat = GL_RGB;
break;
case 4:
internalFormat = (m_textureType == TextureType::Diffuse) ? GL_SRGB8_ALPHA8 : GL_RGBA8;
dataFormat = GL_RGBA;
break;
}
// Push texture to grahics card
glGenTextures(1, &m_glId);
glBindTexture(GL_TEXTURE_2D, m_glId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -2.0f);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, m_textureWidth, m_textureHeight, 0, dataFormat, GL_UNSIGNED_BYTE,
m_textureBuffer);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
stbi_image_free(m_textureBuffer);
}
TextureType Texture::textureType() const
{
return m_textureType;
}
void Texture::bind(uint8_t textureUnit, ShaderProgram *shaderProgram, uint8_t textureTypeNum) const
{
std::string uniformName = "texture_";
switch (m_textureType) {
case TextureType::Diffuse:
uniformName += "diffuse" + std::to_string(textureTypeNum);
break;
case TextureType::Specular:
uniformName += "specular" + std::to_string(textureTypeNum);
break;
case TextureType::Normal:
uniformName += "normal" + std::to_string(textureTypeNum);
break;
case TextureType::Height:
uniformName += "height" + std::to_string(textureTypeNum);
break;
case TextureType::Gloss:
uniformName += "gloss" + std::to_string(textureTypeNum);
break;
default:
break;
}
// Add u_material as we store textures in a struct
uniformName = "u_material." + uniformName;
shaderProgram->setUniform(uniformName.c_str(), textureUnit);
glActiveTexture(GL_TEXTURE0 + textureUnit);
glBindTexture(GL_TEXTURE_2D, m_glId);
}
void Texture::unbind() const
{
glBindTexture(GL_TEXTURE_2D, 0);
}

35
src/resources/Texture.h Normal file
View File

@@ -0,0 +1,35 @@
#pragma once
#include "AbstractTexture.h"
#include "Resource.h"
#include "TextureTypes.h"
#include <stb/stb_image.h>
#include <string>
class ShaderProgram;
struct TextureDescriptor
{
std::string path;
TextureType textureType;
};
class Texture : public AbstractTexture
{
public:
Texture(const TextureDescriptor &descriptor);
TextureType textureType() const;
void bind(uint8_t textureUnit, ShaderProgram *shaderProgram, uint8_t textureTypeNum) const;
void unbind() const override;
protected:
void initialize() override;
private:
stbi_uc *m_textureBuffer;
TextureType m_textureType;
};

View File

@@ -0,0 +1,11 @@
#pragma once
enum class TextureType
{
Diffuse,
Specular,
Normal,
Height,
Gloss,
TEXTURE_TYPE_NUM_ITEMS
};

View File

@@ -0,0 +1 @@
#pragma once

View File

@@ -7,8 +7,13 @@ Log Log::s_instance;
Log::Log()
{
m_logger = spdlog::stdout_color_mt("Core");
m_logger->set_level(spdlog::level::debug);
// m_logger->set_pattern("");
#ifdef _DEBUG
m_logger->set_level(spdlog::level::debug);
#else
m_logger->set_level(spdlog::level::warn);
#endif
}
spdlog::logger &Log::logger()

View File

@@ -18,11 +18,13 @@
#include <fstream>
#include "../src/definitions/models.h"
#include "../src/resources/TextureTypes.h"
#include "primitiveModel.h"
void processNode(aiNode *node, const aiScene *scene, Model *model);
Mesh processMesh(aiMesh *mesh, const aiScene *scene, Model *model);
std::vector<Texture> loadMaterialTextures(aiMaterial *mat, aiTextureType type, uint8_t textureType, Mesh *mesh, Model *model);
std::vector<Texture> loadMaterialTextures(aiMaterial *mat, aiTextureType type, uint8_t textureType, Mesh *mesh,
Model *model);
int main(int argc, char** argv) {
@@ -221,7 +223,9 @@ Mesh processMesh(aiMesh *mesh, const aiScene *scene, Model *model) {
return currentMesh;
}
std::vector<Texture> loadMaterialTextures(aiMaterial *mat, aiTextureType type, uint8_t textureType, Mesh *mesh, Model *model) {
std::vector<Texture> loadMaterialTextures(aiMaterial *mat, aiTextureType type, uint8_t textureType, Mesh *mesh,
Model *model)
{
std::vector<Texture> textures;
for(uint32_t i = 0; i < mat->GetTextureCount(type); i++) {

View File

@@ -3,23 +3,22 @@
#include <vector>
#include <string>
struct Texture {
struct Texture
{
std::string pathToTexture;
uint32_t textureType;
uint32_t m_textureId;
};
struct Mesh {
struct Mesh
{
std::vector<Vertex> vertices;
std::vector<uint32_t> indices;
std::vector<uint32_t> textureIds;
};
struct Model {
struct Model
{
std::vector<Texture> textures;
std::vector<Mesh> m_meshes;
std::string m_workingPath;