Initial support for gltf scenes
This commit is contained in:
@@ -111,7 +111,7 @@ void main() {
|
||||
//fragmentColor += spotLightContribution(u_spotLight, normal, v_fragmentPositionTangent, viewDir);
|
||||
|
||||
f_color = vec4(fragmentColor, 1.0f);
|
||||
|
||||
f_color = vec4(0.95f, 0.16f, 0.33f, 1.0f);
|
||||
}
|
||||
|
||||
vec3 directionalLightContribution(DirectionalLight light, vec3 normal, vec3 viewDir) {
|
||||
|
||||
1
lib/CMakeLists.txt
vendored
1
lib/CMakeLists.txt
vendored
@@ -2,6 +2,7 @@ option(SPDLOG_NO_EXCEPTIONS "" ON)
|
||||
|
||||
set(TINYGLTF_HEADER_ONLY OFF CACHE INTERNAL "" FORCE)
|
||||
set(TINYGLTF_INSTALL OFF CACHE INTERNAL "" FORCE)
|
||||
set(TINYGLTF_NOEXCEPTION OFF CACHE INTERNAL "" FORCE)
|
||||
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/glad)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/entt)
|
||||
|
||||
@@ -31,6 +31,7 @@ target_link_libraries(
|
||||
fmt
|
||||
pthread
|
||||
spdlog
|
||||
tinygltf
|
||||
)
|
||||
|
||||
add_executable(Fall-Fever
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#include "Controller.h"
|
||||
#include "Camera.h"
|
||||
#include "Entity.h"
|
||||
#include "FrameBuffer.h"
|
||||
#include "Helper.h"
|
||||
#include "Light.h"
|
||||
#include "Scene.h"
|
||||
#include "Mesh.h"
|
||||
#include "ShaderProgram.h"
|
||||
#include "Window.h"
|
||||
#include "definitions/attribute_locations.h"
|
||||
#include "resources/Model.h"
|
||||
#include "util/Log.h"
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
@@ -21,6 +21,73 @@ Controller::Controller()
|
||||
m_postProcessFrameBuffer(m_gameWindow->dimensions().first, m_gameWindow->dimensions().second,
|
||||
postProcessingProgram)
|
||||
{
|
||||
tinygltf::TinyGLTF loader;
|
||||
|
||||
std::string err;
|
||||
std::string warn;
|
||||
bool ret = loader.LoadASCIIFromFile(&m_model, &err, &warn, "glTF/ABeautifulGame.gltf");
|
||||
// bool ret = loader.LoadASCIIFromFile(&m_model, &err, &warn, "minimal.gltf");
|
||||
|
||||
if (!warn.empty()) {
|
||||
Log::logger().warn("{}", warn);
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
Log::logger().error("{}", err);
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
Log::logger().error("Failed to parse glTF");
|
||||
}
|
||||
|
||||
defaultProgram.bind();
|
||||
AttributeLocations locations{};
|
||||
|
||||
locations.position = glGetAttribLocation(defaultProgram.getShaderProgramId(), "a_position");
|
||||
locations.normal = glGetAttribLocation(defaultProgram.getShaderProgramId(), "a_normal");
|
||||
locations.uv = glGetAttribLocation(defaultProgram.getShaderProgramId(), "a_texCoord");
|
||||
|
||||
ShaderProgram::unbind();
|
||||
|
||||
std::vector<Model> models;
|
||||
for (auto const &mesh : m_model.meshes) {
|
||||
std::vector<Mesh> meshes;
|
||||
for (auto const &primitive : mesh.primitives) {
|
||||
meshes.emplace_back(Mesh({primitive, m_model, locations}, {}));
|
||||
}
|
||||
models.emplace_back(Model(mesh.name, std::move(meshes)));
|
||||
}
|
||||
m_models = std::move(models);
|
||||
|
||||
std::vector<ModelEntity> entities;
|
||||
for (auto const &node : m_model.nodes) {
|
||||
ModelEntity entity(Entity::Prototype(node.name, {}, {}, 1.0F), m_models[static_cast<unsigned>(node.mesh)],
|
||||
defaultProgram);
|
||||
|
||||
if (!node.translation.empty()) {
|
||||
entity.setPosition(glm::vec3(node.translation[0], node.translation[1], node.translation[2]));
|
||||
}
|
||||
|
||||
if (!node.rotation.empty()) {
|
||||
entity.setRotation(
|
||||
glm::eulerAngles(glm::quat(node.rotation[3], node.rotation[0], node.rotation[1], node.rotation[2])));
|
||||
}
|
||||
|
||||
if (!node.scale.empty()) {
|
||||
entity.setScale(node.scale[0]);
|
||||
}
|
||||
|
||||
entities.push_back(std::move(entity));
|
||||
|
||||
for (auto const &child : node.children) {
|
||||
if (!node.translation.empty()) {
|
||||
entities[child].translate(glm::vec3(node.translation[0], node.translation[1], node.translation[2]));
|
||||
}
|
||||
}
|
||||
|
||||
Log::logger().info("Load node {}.", node.name);
|
||||
}
|
||||
m_entities = std::move(entities);
|
||||
}
|
||||
|
||||
void Controller::run()
|
||||
@@ -29,7 +96,7 @@ void Controller::run()
|
||||
|
||||
m_camera->translate(glm::vec3(0., 1.5, 5.));
|
||||
|
||||
Log::logger().info("Startup complete.");
|
||||
Log::logger().info("Startup complete. Enter game loop.");
|
||||
|
||||
// This is the game loop
|
||||
while (glfwWindowShouldClose(&m_gameWindow->glfw_window()) == GLFW_FALSE) {
|
||||
@@ -40,7 +107,7 @@ void Controller::run()
|
||||
// --- Update game ---
|
||||
lightProgram.bind();
|
||||
lightProgram.setUniform("v_lightColor", glm::vec3{1., 1., 1.} * 100.0F);
|
||||
lightProgram.unbind();
|
||||
ShaderProgram::unbind();
|
||||
|
||||
// --- Render and buffer swap ---
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
@@ -51,6 +118,13 @@ void Controller::run()
|
||||
m_camera->lookForward();
|
||||
m_camera->updateVPM();
|
||||
|
||||
// Draw scene
|
||||
defaultProgram.bind();
|
||||
for (auto const &entity : m_entities) {
|
||||
entity.draw(m_camera->getViewProj(), m_camera->getPosition());
|
||||
}
|
||||
ShaderProgram::unbind();
|
||||
|
||||
m_postProcessFrameBuffer.unbind();
|
||||
m_postProcessFrameBuffer.drawOnEntireScreen();
|
||||
|
||||
@@ -68,7 +142,6 @@ void Controller::run()
|
||||
|
||||
auto const &key_input = m_gameWindow->key_input();
|
||||
auto const &mouse_cursor_input = m_gameWindow->mouse_cursor_input();
|
||||
// auto const &mouse_button_input = m_gameWindow->mouse_button_input();
|
||||
|
||||
m_camera->updatePositionFromKeyboardInput(key_input, (float)m_deltaTime);
|
||||
|
||||
|
||||
@@ -2,9 +2,13 @@
|
||||
|
||||
#include "FrameBuffer.h"
|
||||
#include "ShaderProgram.h"
|
||||
#include "VertexArray.h"
|
||||
#include "resources/Model.h"
|
||||
#include "Entity.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <memory>
|
||||
#include <tiny_gltf.h>
|
||||
#include <vector>
|
||||
|
||||
class Window;
|
||||
@@ -39,6 +43,11 @@ private:
|
||||
|
||||
static constexpr unsigned MAX_FPS = 60;
|
||||
|
||||
tinygltf::Model m_model;
|
||||
|
||||
std::vector<ModelEntity> m_entities;
|
||||
std::vector<Model> m_models;
|
||||
|
||||
double m_deltaTime{};
|
||||
float m_exposure = 1.0;
|
||||
};
|
||||
|
||||
@@ -12,10 +12,8 @@
|
||||
uint32_t Entity::s_idCounter = 0;
|
||||
|
||||
Entity::Entity(const std::string &name) : m_id(s_idCounter++), m_uniqueName(name)
|
||||
{}
|
||||
|
||||
Entity::~Entity()
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t Entity::getId() const
|
||||
{
|
||||
@@ -93,7 +91,7 @@ glm::mat4 Entity::getModelMatrix() const
|
||||
return m_modelMatrix;
|
||||
}
|
||||
|
||||
ModelEntity::ModelEntity(Prototype prototype, const Model *model, ShaderProgram *shaderProgram)
|
||||
ModelEntity::ModelEntity(Entity::Prototype prototype, Model const &model, ShaderProgram const &shaderProgram)
|
||||
: Entity(prototype.name), m_model(model), m_shaderProgram(shaderProgram)
|
||||
{
|
||||
setPosition(prototype.position);
|
||||
@@ -101,27 +99,27 @@ ModelEntity::ModelEntity(Prototype prototype, const Model *model, ShaderProgram
|
||||
setScale(prototype.scale);
|
||||
}
|
||||
|
||||
void ModelEntity::draw(glm::mat4 viewProjMatrix, glm::vec3 viewPosition)
|
||||
void ModelEntity::draw(glm::mat4 viewProjMatrix, glm::vec3 viewPosition) const
|
||||
{
|
||||
m_shaderProgram->bind();
|
||||
m_shaderProgram.bind();
|
||||
|
||||
glm::mat4 modelViewProj = viewProjMatrix * m_modelMatrix;
|
||||
m_shaderProgram->setUniform("u_modelViewProjMatrix", modelViewProj);
|
||||
m_shaderProgram->setUniform("u_modelMatrix", m_modelMatrix);
|
||||
m_shaderProgram.setUniform("u_modelViewProjMatrix", modelViewProj);
|
||||
m_shaderProgram.setUniform("u_modelMatrix", m_modelMatrix);
|
||||
|
||||
glm::mat3 normalMatrix = glm::mat3(m_modelMatrix);
|
||||
normalMatrix = glm::transpose(glm::inverse(normalMatrix));
|
||||
m_shaderProgram->setUniform("u_normalMatrix", normalMatrix);
|
||||
m_shaderProgram.setUniform("u_normalMatrix", normalMatrix);
|
||||
|
||||
m_shaderProgram->setUniform("u_viewPosition", viewPosition);
|
||||
m_shaderProgram.setUniform("u_viewPosition", viewPosition);
|
||||
|
||||
// Draw the model
|
||||
m_model->draw(m_shaderProgram);
|
||||
m_model.draw(m_shaderProgram);
|
||||
|
||||
m_shaderProgram->unbind();
|
||||
m_shaderProgram.unbind();
|
||||
}
|
||||
|
||||
void ModelEntity::drawDirectionalShadows(glm::mat4 viewProjMatrix, ShaderProgram *shaderProgram)
|
||||
void ModelEntity::drawDirectionalShadows(glm::mat4 viewProjMatrix, ShaderProgram *shaderProgram) const
|
||||
{
|
||||
shaderProgram->bind();
|
||||
|
||||
@@ -129,19 +127,19 @@ void ModelEntity::drawDirectionalShadows(glm::mat4 viewProjMatrix, ShaderProgram
|
||||
shaderProgram->setUniform("u_modelViewProjMatrix", modelViewProj);
|
||||
|
||||
// Draw the model
|
||||
m_model->drawWithoutTextures();
|
||||
m_model.drawWithoutTextures();
|
||||
|
||||
shaderProgram->unbind();
|
||||
}
|
||||
|
||||
void ModelEntity::drawPointShadows(ShaderProgram *shaderProgram)
|
||||
void ModelEntity::drawPointShadows(ShaderProgram *shaderProgram) const
|
||||
{
|
||||
shaderProgram->bind();
|
||||
|
||||
shaderProgram->setUniform("u_modelMatrix", m_modelMatrix);
|
||||
|
||||
// Draw the model
|
||||
m_model->drawWithoutTextures();
|
||||
m_model.drawWithoutTextures();
|
||||
|
||||
shaderProgram->unbind();
|
||||
}
|
||||
|
||||
28
src/Entity.h
28
src/Entity.h
@@ -20,7 +20,8 @@ public:
|
||||
{
|
||||
Prototype(const std::string &_name, glm::vec3 _position, glm::vec3 _rotation, float _scale)
|
||||
: name(_name), position(_position), rotation(_rotation), scale(_scale)
|
||||
{}
|
||||
{
|
||||
}
|
||||
virtual ~Prototype() = default;
|
||||
|
||||
std::string name;
|
||||
@@ -30,7 +31,7 @@ public:
|
||||
};
|
||||
|
||||
Entity(const std::string &name);
|
||||
virtual ~Entity() = 0;
|
||||
virtual ~Entity() = default;
|
||||
|
||||
uint32_t getId() const;
|
||||
const std::string &getUniqueName() const;
|
||||
@@ -64,26 +65,15 @@ protected:
|
||||
class ModelEntity : public Entity
|
||||
{
|
||||
public:
|
||||
struct Prototype : public Entity::Prototype
|
||||
{
|
||||
Prototype(const std::string &_name, glm::vec3 _position, glm::vec3 _rotation, float _scale,
|
||||
std::string _modelName, std::string _shaderProgramName)
|
||||
: Entity::Prototype(_name, _position, _rotation, _scale), modelName(std::move(_modelName)),
|
||||
shaderProgramName(std::move(_shaderProgramName))
|
||||
{}
|
||||
std::string modelName;
|
||||
std::string shaderProgramName;
|
||||
};
|
||||
ModelEntity(Entity::Prototype prototype, Model const &model, ShaderProgram const &shaderProgram);
|
||||
|
||||
ModelEntity(Prototype prototype, const Model *model, ShaderProgram *shaderProgram);
|
||||
|
||||
void draw(glm::mat4 viewProjMatrix, glm::vec3 viewPosition);
|
||||
void drawDirectionalShadows(glm::mat4 viewProjMatrix, ShaderProgram *p_shaderProgram);
|
||||
void drawPointShadows(ShaderProgram *p_shaderProgram);
|
||||
void draw(glm::mat4 viewProjMatrix, glm::vec3 viewPosition) const;
|
||||
void drawDirectionalShadows(glm::mat4 viewProjMatrix, ShaderProgram *p_shaderProgram) const;
|
||||
void drawPointShadows(ShaderProgram *p_shaderProgram) const;
|
||||
|
||||
private:
|
||||
const Model *m_model;
|
||||
ShaderProgram *m_shaderProgram;
|
||||
Model const &m_model;
|
||||
ShaderProgram const &m_shaderProgram;
|
||||
};
|
||||
|
||||
class Skybox
|
||||
|
||||
60
src/Mesh.cpp
60
src/Mesh.cpp
@@ -1,65 +1,57 @@
|
||||
#include "Mesh.h"
|
||||
|
||||
#include "ShaderProgram.h"
|
||||
#include "VertexArray.h"
|
||||
#include "resources/ResourceHandler.h"
|
||||
#include "resources/Texture.h"
|
||||
#include <utility>
|
||||
|
||||
Mesh::Mesh(std::vector<Vertex> vertices, std::vector<uint32_t> indices, std::vector<ResourceId> textures)
|
||||
: m_preInitializationVertexData{vertices, indices}, m_numElements(static_cast<unsigned>(indices.size())),
|
||||
m_textures(textures)
|
||||
Mesh::Mesh(VertexArray vertexArray, std::vector<ResourceId> textures)
|
||||
: m_vertexArray(std::move(vertexArray)), m_textures(std::move(textures))
|
||||
{
|
||||
}
|
||||
|
||||
void Mesh::initializeOnGPU()
|
||||
void Mesh::draw(ShaderProgram const &shaderProgram) const
|
||||
{
|
||||
m_vertexArray = new VertexArray(static_cast<void *>(m_preInitializationVertexData.vertices.data()),
|
||||
static_cast<void *>(m_preInitializationVertexData.indices.data()),
|
||||
static_cast<unsigned>(m_preInitializationVertexData.vertices.size()),
|
||||
static_cast<unsigned>(m_preInitializationVertexData.indices.size()));
|
||||
}
|
||||
std::array<uint8_t, static_cast<std::size_t>(TextureType::TEXTURE_TYPE_NUM_ITEMS)> typeNumberCount{};
|
||||
|
||||
Mesh::~Mesh()
|
||||
{
|
||||
delete m_vertexArray;
|
||||
}
|
||||
|
||||
void Mesh::draw(ShaderProgram *shaderProgram)
|
||||
{
|
||||
uint8_t typeNumberCount[static_cast<int>(TextureType::TEXTURE_TYPE_NUM_ITEMS)]{0};
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
// Bind all textures in order to its texture unit
|
||||
std::size_t i = 0;
|
||||
for (auto it : m_textures) {
|
||||
auto texture = std::static_pointer_cast<Texture>(ResourceHandler::instance().resource(it));
|
||||
std::size_t textureNum = 0;
|
||||
for (auto textureIt : m_textures) {
|
||||
auto texture = std::static_pointer_cast<Texture>(ResourceHandler::instance().resource(textureIt));
|
||||
TextureType currentTextureType = texture->textureType();
|
||||
|
||||
texture->bind(static_cast<uint8_t>(i), shaderProgram, typeNumberCount[static_cast<int>(currentTextureType)]);
|
||||
texture->bind(static_cast<uint8_t>(textureNum), shaderProgram,
|
||||
typeNumberCount.at(static_cast<std::size_t>(currentTextureType)));
|
||||
|
||||
typeNumberCount[static_cast<int>(currentTextureType)] += 1;
|
||||
typeNumberCount.at(static_cast<std::size_t>(currentTextureType)) += 1;
|
||||
|
||||
i++;
|
||||
textureNum++;
|
||||
}
|
||||
|
||||
// Draw elements
|
||||
m_vertexArray->bind();
|
||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(m_numElements), GL_UNSIGNED_INT, 0);
|
||||
m_vertexArray->unbind();
|
||||
m_vertexArray.bind();
|
||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(m_vertexArray.indicesCount()),
|
||||
static_cast<GLenum>(m_vertexArray.indicesType()), nullptr);
|
||||
VertexArray::unbind();
|
||||
|
||||
// Unbind all textures
|
||||
for (auto it : m_textures) {
|
||||
auto texture = std::static_pointer_cast<Texture>(ResourceHandler::instance().resource(it));
|
||||
for (auto textureIt : m_textures) {
|
||||
auto texture = std::static_pointer_cast<Texture>(ResourceHandler::instance().resource(textureIt));
|
||||
texture->unbind();
|
||||
}
|
||||
}
|
||||
|
||||
void Mesh::drawWithoutTextures()
|
||||
void Mesh::drawWithoutTextures() const
|
||||
{
|
||||
m_vertexArray->bind();
|
||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(m_numElements), GL_UNSIGNED_INT, 0);
|
||||
m_vertexArray->unbind();
|
||||
m_vertexArray.bind();
|
||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(m_vertexArray.indicesCount()),
|
||||
static_cast<GLenum>(m_vertexArray.indicesType()), nullptr);
|
||||
VertexArray::unbind();
|
||||
}
|
||||
|
||||
VertexArray *Mesh::getVertexArray()
|
||||
auto Mesh::getVertexArray() -> VertexArray *
|
||||
{
|
||||
return m_vertexArray;
|
||||
return &m_vertexArray;
|
||||
}
|
||||
|
||||
22
src/Mesh.h
22
src/Mesh.h
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "VertexArray.h"
|
||||
#include "definitions/models.h"
|
||||
#include "resources/Resource.h"
|
||||
|
||||
#include <vector>
|
||||
@@ -11,27 +10,14 @@ class ShaderProgram;
|
||||
class Mesh
|
||||
{
|
||||
public:
|
||||
Mesh(std::vector<Vertex> vertices, std::vector<unsigned int> indices, std::vector<ResourceId> textures);
|
||||
~Mesh();
|
||||
Mesh(VertexArray vertexArray, std::vector<ResourceId> textures);
|
||||
|
||||
void initializeOnGPU();
|
||||
|
||||
void draw(ShaderProgram *shaderProgram);
|
||||
void drawWithoutTextures();
|
||||
void draw(ShaderProgram const &shaderProgram) const;
|
||||
void drawWithoutTextures() const;
|
||||
|
||||
auto getVertexArray() -> VertexArray *;
|
||||
|
||||
private:
|
||||
struct PreInitializationVertexData
|
||||
{
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<unsigned int> indices;
|
||||
} m_preInitializationVertexData;
|
||||
|
||||
bool m_isInitialized = false;
|
||||
|
||||
uint32_t m_numElements;
|
||||
VertexArray m_vertexArray;
|
||||
std::vector<ResourceId> m_textures;
|
||||
|
||||
VertexArray *m_vertexArray;
|
||||
};
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
#include "ShaderProgram.h"
|
||||
#include "util/Log.h"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <fstream>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
ShaderProgram::ShaderProgram(Prototype prototype) : m_uniqueName(prototype.name)
|
||||
ShaderProgram::ShaderProgram(Prototype prototype) : m_shaderProgramId(glCreateProgram())
|
||||
{
|
||||
std::string vertexShaderSource = parse(prototype.vertexPath.c_str());
|
||||
std::string fragmentShaderSource = parse(prototype.fragmentPath.c_str());
|
||||
std::string vertexShaderSource = parse(prototype.vertexPath).value();
|
||||
std::string fragmentShaderSource = parse(prototype.fragmentPath).value();
|
||||
|
||||
m_shaderProgramId = glCreateProgram();
|
||||
GLuint vs = compile(vertexShaderSource, GL_VERTEX_SHADER);
|
||||
GLuint fs = compile(fragmentShaderSource, GL_FRAGMENT_SHADER);
|
||||
GLuint vertexShader = compile(vertexShaderSource, GL_VERTEX_SHADER);
|
||||
GLuint fragmentShader = compile(fragmentShaderSource, GL_FRAGMENT_SHADER);
|
||||
|
||||
glAttachShader(m_shaderProgramId, vs);
|
||||
glAttachShader(m_shaderProgramId, fs);
|
||||
glAttachShader(m_shaderProgramId, vertexShader);
|
||||
glAttachShader(m_shaderProgramId, fragmentShader);
|
||||
|
||||
glLinkProgram(m_shaderProgramId);
|
||||
|
||||
GLint isLinked = 0;
|
||||
glGetProgramiv(m_shaderProgramId, GL_LINK_STATUS, &isLinked);
|
||||
if (!isLinked)
|
||||
Log::logger().critical("Failed to link shaderProgram \"{}\", \"{}\"", prototype.vertexPath,
|
||||
prototype.fragmentPath);
|
||||
if (isLinked == 0) {
|
||||
Log::logger().warn(R"(Failed to link shaderProgram "{}", "{}")", prototype.vertexPath, prototype.fragmentPath);
|
||||
}
|
||||
|
||||
#ifdef _RELEASE
|
||||
glDetachShader(program, vs);
|
||||
@@ -32,7 +32,7 @@ ShaderProgram::ShaderProgram(Prototype prototype) : m_uniqueName(prototype.name)
|
||||
glDeleteShader(fs);
|
||||
#endif
|
||||
|
||||
Log::logger().info("Loaded shaderprogram \"{}\"", prototype.name);
|
||||
Log::logger().info(R"(Loaded shaderprogram "{}")", prototype.name);
|
||||
}
|
||||
|
||||
ShaderProgram::~ShaderProgram()
|
||||
@@ -40,7 +40,7 @@ ShaderProgram::~ShaderProgram()
|
||||
glDeleteProgram(m_shaderProgramId);
|
||||
}
|
||||
|
||||
void ShaderProgram::bind()
|
||||
void ShaderProgram::bind() const
|
||||
{
|
||||
glUseProgram(m_shaderProgramId);
|
||||
}
|
||||
@@ -50,14 +50,14 @@ void ShaderProgram::unbind()
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
std::string ShaderProgram::parse(const std::string &filename)
|
||||
auto ShaderProgram::parse(const std::filesystem::path &path) -> std::optional<std::string>
|
||||
{
|
||||
std::fstream shaderfile;
|
||||
shaderfile.open(filename, std::ios::in);
|
||||
shaderfile.open(path, std::ios::in);
|
||||
|
||||
if (!shaderfile.is_open()) {
|
||||
Log::logger().critical("Shader \"{}\" not found", filename);
|
||||
exit(-1);
|
||||
Log::logger().warn("Shader \"{}\" not found", path.c_str());
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string contents((std::istreambuf_iterator<char>(shaderfile)), (std::istreambuf_iterator<char>()));
|
||||
@@ -65,34 +65,40 @@ std::string ShaderProgram::parse(const std::string &filename)
|
||||
return contents;
|
||||
}
|
||||
|
||||
GLuint ShaderProgram::compile(const std::string &shaderSource, GLenum type)
|
||||
auto ShaderProgram::compile(const std::string &shaderSource, GLenum type) -> GLuint
|
||||
{
|
||||
GLuint shaderId = glCreateShader(type);
|
||||
const char *src = shaderSource.c_str();
|
||||
glShaderSource(shaderId, 1, &src, 0);
|
||||
glShaderSource(shaderId, 1, &src, nullptr);
|
||||
glCompileShader(shaderId);
|
||||
|
||||
int result;
|
||||
int result{};
|
||||
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &result);
|
||||
|
||||
if (result != GL_TRUE) {
|
||||
int length;
|
||||
int length{};
|
||||
glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &length);
|
||||
char *message = new char[static_cast<unsigned>(length)];
|
||||
glGetShaderInfoLog(shaderId, length, &length, message);
|
||||
|
||||
std::string message;
|
||||
message.reserve(static_cast<unsigned>(length));
|
||||
|
||||
glGetShaderInfoLog(shaderId, length, &length, message.data());
|
||||
Log::logger().error("Shader compilation failed: {}", message);
|
||||
delete[] message;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return shaderId;
|
||||
}
|
||||
|
||||
GLint ShaderProgram::retrieveUniformLocation(const std::string &name) const
|
||||
auto ShaderProgram::retrieveUniformLocation(std::string_view uniform_name) const -> GLint
|
||||
{
|
||||
if (m_uniformLocationCache.find(name) != m_uniformLocationCache.end())
|
||||
return m_uniformLocationCache[name];
|
||||
if (m_uniformLocationCache.find(uniform_name.data()) != m_uniformLocationCache.end()) {
|
||||
return m_uniformLocationCache[uniform_name.data()];
|
||||
}
|
||||
|
||||
GLint location = glGetUniformLocation(m_shaderProgramId, name.c_str());
|
||||
m_uniformLocationCache[name] = location;
|
||||
GLint location = glGetUniformLocation(m_shaderProgramId, uniform_name.data());
|
||||
m_uniformLocationCache[uniform_name.data()] = location;
|
||||
|
||||
return location;
|
||||
}
|
||||
@@ -139,12 +145,7 @@ void ShaderProgram::setUniform(const std::string &name, glm::mat4 matrix) const
|
||||
glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(matrix));
|
||||
}
|
||||
|
||||
GLuint ShaderProgram::getShaderProgramId()
|
||||
auto ShaderProgram::getShaderProgramId() const -> GLuint
|
||||
{
|
||||
return m_shaderProgramId;
|
||||
}
|
||||
|
||||
const std::string &ShaderProgram::getUniqueName()
|
||||
{
|
||||
return m_uniqueName;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <glad/gl.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
@@ -16,13 +18,13 @@ public:
|
||||
};
|
||||
|
||||
ShaderProgram(Prototype prototype);
|
||||
|
||||
~ShaderProgram();
|
||||
|
||||
void bind();
|
||||
void unbind();
|
||||
void bind() const;
|
||||
static void unbind();
|
||||
|
||||
auto retrieveUniformLocation(std::string_view uniform_name) const -> GLint;
|
||||
|
||||
GLint retrieveUniformLocation(const std::string &name) const;
|
||||
// May be rewritten...
|
||||
void setUniform(const std::string &name, bool value) const;
|
||||
void setUniform(const std::string &name, int value) const;
|
||||
@@ -32,14 +34,12 @@ public:
|
||||
void setUniform(const std::string &name, glm::mat3 matrix) const;
|
||||
void setUniform(const std::string &name, glm::mat4 matrix) const;
|
||||
|
||||
GLuint getShaderProgramId();
|
||||
const std::string &getUniqueName();
|
||||
auto getShaderProgramId() const -> GLuint;
|
||||
|
||||
private:
|
||||
std::string parse(const std::string &filename);
|
||||
GLuint compile(const std::string &shaderSource, GLenum type);
|
||||
static auto parse(const std::filesystem::path &path) -> std::optional<std::string>;
|
||||
static auto compile(const std::string &shaderSource, GLenum type) -> GLuint;
|
||||
|
||||
GLuint m_shaderProgramId;
|
||||
std::string m_uniqueName;
|
||||
mutable std::unordered_map<std::string, GLint> m_uniformLocationCache;
|
||||
};
|
||||
|
||||
@@ -4,51 +4,80 @@
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
VertexArray::VertexArray(void *vertexData, void *indexData, uint32_t numVertices, uint32_t numIndices)
|
||||
VertexArray::VertexArray(tinygltf::Primitive const &primitive, tinygltf::Model const &model, AttributeLocations &locations)
|
||||
{
|
||||
glGenVertexArrays(1, &m_VAO);
|
||||
glBindVertexArray(m_VAO);
|
||||
GLuint vao{};
|
||||
glGenVertexArrays(1, &vao);
|
||||
glBindVertexArray(vao);
|
||||
|
||||
glGenBuffers(1, &m_VBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(Vertex), vertexData, GL_STATIC_DRAW);
|
||||
int position_accessor_id = primitive.attributes.at("POSITION");
|
||||
// int normal_accessor = primitive.attributes.at("NORMAL");
|
||||
// int uv_accessor = primitive.attributes.at("TEXCOORD_0");
|
||||
int indices_accessor_id = primitive.indices;
|
||||
|
||||
glGenBuffers(1, &m_EBO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof(uint32_t), indexData, GL_STATIC_DRAW);
|
||||
auto const &position_accessor = model.accessors.at(position_accessor_id);
|
||||
auto const &indices_accessor = model.accessors.at(indices_accessor_id);
|
||||
|
||||
// Position
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)offsetof(struct Vertex, position));
|
||||
int position_buffer_view_id = model.accessors[position_accessor_id].bufferView;
|
||||
int indices_buffer_view_id = model.accessors[indices_accessor_id].bufferView;
|
||||
|
||||
// UV Texture Mapping
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)offsetof(struct Vertex, textureCoords));
|
||||
auto const &position_buffer_view = model.bufferViews.at(position_buffer_view_id);
|
||||
auto const &indices_buffer_view = model.bufferViews.at(indices_buffer_view_id);
|
||||
|
||||
// Normal vectors
|
||||
glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)offsetof(struct Vertex, normalVec));
|
||||
auto const &position_buffer = model.buffers.at(position_buffer_view.buffer);
|
||||
auto const &indices_buffer = model.buffers.at(indices_buffer_view.buffer);
|
||||
|
||||
// Tangent vectors
|
||||
glEnableVertexAttribArray(3);
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)offsetof(struct Vertex, tangentVec));
|
||||
GLuint positionVbo{};
|
||||
glGenBuffers(1, &positionVbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, positionVbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, position_buffer_view.byteLength,
|
||||
position_buffer.data.data() + position_buffer_view.byteOffset, GL_STATIC_DRAW);
|
||||
|
||||
// Bitangent vectors
|
||||
glEnableVertexAttribArray(4);
|
||||
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)offsetof(struct Vertex, bitangentVec));
|
||||
int size = 1;
|
||||
if (position_accessor.type == TINYGLTF_TYPE_SCALAR) {
|
||||
size = 1;
|
||||
} else if (position_accessor.type == TINYGLTF_TYPE_VEC2) {
|
||||
size = 2;
|
||||
} else if (position_accessor.type == TINYGLTF_TYPE_VEC3) {
|
||||
size = 3;
|
||||
} else if (position_accessor.type == TINYGLTF_TYPE_VEC4) {
|
||||
size = 4;
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
int position_byte_stride = position_accessor.ByteStride(position_buffer_view);
|
||||
glEnableVertexAttribArray(locations.position);
|
||||
glVertexAttribPointer(locations.position, size, position_accessor.componentType,
|
||||
position_accessor.normalized ? GL_TRUE : GL_FALSE, position_byte_stride,
|
||||
(void *)position_accessor.byteOffset);
|
||||
|
||||
GLuint ebo{};
|
||||
glGenBuffers(1, &ebo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_buffer_view.byteLength,
|
||||
indices_buffer.data.data() + indices_buffer_view.byteOffset, GL_STATIC_DRAW);
|
||||
|
||||
// This will also unbind the vertex buffer and index buffer
|
||||
glBindVertexArray(0);
|
||||
|
||||
m_vao = vao;
|
||||
m_ebo = ebo;
|
||||
m_positionVbo = positionVbo;
|
||||
m_indicesCount = indices_accessor.count;
|
||||
m_indicesType = indices_accessor.componentType;
|
||||
}
|
||||
|
||||
VertexArray::~VertexArray()
|
||||
{
|
||||
glDeleteBuffers(1, &m_VBO);
|
||||
glDeleteVertexArrays(1, &m_vao);
|
||||
|
||||
glDeleteBuffers(1, &m_positionVbo);
|
||||
glDeleteBuffers(1, &m_ebo);
|
||||
}
|
||||
|
||||
void VertexArray::bind()
|
||||
void VertexArray::bind() const
|
||||
{
|
||||
glBindVertexArray(m_VAO);
|
||||
glBindVertexArray(m_vao);
|
||||
}
|
||||
|
||||
void VertexArray::unbind()
|
||||
|
||||
@@ -1,19 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include "definitions/attribute_locations.h"
|
||||
|
||||
#include <glad/gl.h>
|
||||
#include <tiny_gltf.h>
|
||||
#include <vector>
|
||||
|
||||
class VertexArray
|
||||
class VertexArray final
|
||||
{
|
||||
public:
|
||||
VertexArray(void *vertexData, void *indexData, uint32_t numVertices, uint32_t numIndices);
|
||||
VertexArray(tinygltf::Primitive const &primitive, tinygltf::Model const &model, AttributeLocations &locations);
|
||||
VertexArray(VertexArray &&other) noexcept
|
||||
: m_indicesCount(other.m_indicesCount),
|
||||
m_indicesType(other.m_indicesType),
|
||||
m_vao(other.m_vao),
|
||||
m_positionVbo(other.m_positionVbo),
|
||||
m_ebo(other.m_ebo)
|
||||
{
|
||||
other.m_ebo = 0;
|
||||
other.m_vao = 0;
|
||||
other.m_positionVbo = 0;
|
||||
}
|
||||
|
||||
auto operator=(VertexArray &&other) noexcept -> VertexArray &
|
||||
{
|
||||
m_indicesCount = other.m_indicesCount;
|
||||
m_indicesType = other.m_indicesType;
|
||||
m_vao = other.m_vao;
|
||||
m_positionVbo = other.m_positionVbo;
|
||||
m_ebo = other.m_ebo;
|
||||
|
||||
other.m_ebo = 0;
|
||||
other.m_vao = 0;
|
||||
other.m_positionVbo = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
VertexArray(VertexArray const &) = delete;
|
||||
auto operator=(VertexArray const &) -> VertexArray & = delete;
|
||||
|
||||
~VertexArray();
|
||||
|
||||
void bind();
|
||||
void unbind();
|
||||
void bind() const;
|
||||
static void unbind();
|
||||
|
||||
[[nodiscard]] auto indicesCount() const -> uint64_t { return m_indicesCount; }
|
||||
[[nodiscard]] auto indicesType() const -> int { return m_indicesType; }
|
||||
|
||||
private:
|
||||
GLuint m_VAO;
|
||||
GLuint m_VBO;
|
||||
GLuint m_EBO;
|
||||
uint64_t m_indicesCount;
|
||||
int m_indicesType;
|
||||
|
||||
GLuint m_vao;
|
||||
|
||||
GLuint m_positionVbo;
|
||||
GLuint m_ebo;
|
||||
};
|
||||
|
||||
9
src/definitions/attribute_locations.h
Normal file
9
src/definitions/attribute_locations.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
struct AttributeLocations
|
||||
{
|
||||
int position;
|
||||
int normal;
|
||||
int uv;
|
||||
int tangent;
|
||||
};
|
||||
@@ -5,8 +5,8 @@
|
||||
class AbstractTexture : public Resource, public GlResource
|
||||
{
|
||||
public:
|
||||
AbstractTexture(const std::string &path) : Resource(path)
|
||||
{}
|
||||
AbstractTexture(const std::string &path) : Resource(path) {}
|
||||
virtual ~AbstractTexture() = default;
|
||||
|
||||
protected:
|
||||
uint32_t m_textureWidth;
|
||||
|
||||
@@ -1,31 +1,15 @@
|
||||
#include "Model.h"
|
||||
#include "../util/Log.h"
|
||||
#include "ResourceHandler.h"
|
||||
#include "Texture.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <future>
|
||||
|
||||
Model::Model(const ModelDescriptor &descriptor) : Resource(descriptor.path), NamedResource(descriptor.name)
|
||||
Model::Model(std::string_view name, std::vector<Mesh> meshes) : m_meshes(std::move(meshes)), m_name(name)
|
||||
{
|
||||
m_workingPath = descriptor.path.substr(0, descriptor.path.find_last_of('/'));
|
||||
|
||||
loadModel(descriptor.path);
|
||||
}
|
||||
|
||||
void Model::initialize()
|
||||
{
|
||||
m_initialized = true;
|
||||
|
||||
for (auto mesh : m_meshes)
|
||||
mesh->initializeOnGPU();
|
||||
}
|
||||
|
||||
void Model::draw(ShaderProgram *shaderProgram) const
|
||||
void Model::draw(ShaderProgram const &shaderProgram) const
|
||||
{
|
||||
// Iterate through every mesh and call the draw function
|
||||
for (const auto &mesh : m_meshes) {
|
||||
mesh->draw(shaderProgram);
|
||||
mesh.draw(shaderProgram);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,126 +17,11 @@ void Model::drawWithoutTextures() const
|
||||
{
|
||||
// Iterate through every mesh and call the draw function
|
||||
for (const auto &mesh : m_meshes) {
|
||||
mesh->drawWithoutTextures();
|
||||
mesh.drawWithoutTextures();
|
||||
}
|
||||
}
|
||||
|
||||
Mesh *Model::getMesh(unsigned int index) const
|
||||
auto Model::getMesh(unsigned int index) -> Mesh *
|
||||
{
|
||||
return m_meshes[index];
|
||||
}
|
||||
|
||||
void Model::loadModel(const std::string &pathToModel)
|
||||
{
|
||||
std::ifstream input(pathToModel, std::ios::in | std::ios::binary);
|
||||
|
||||
if (!input.is_open()) {
|
||||
Log::logger().warn("Could not find model file {}", pathToModel);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t numTextures;
|
||||
input.read((char *)&numTextures, sizeof(uint32_t));
|
||||
|
||||
std::vector<TextureType> textureTypes;
|
||||
for (unsigned int i = 0; i < numTextures; i++) {
|
||||
TextureType currentTextureType;
|
||||
input.read((char *)¤tTextureType, sizeof(uint32_t));
|
||||
textureTypes.push_back(currentTextureType);
|
||||
}
|
||||
|
||||
std::vector<std::string> textureSources;
|
||||
for (unsigned int i = 0; i < numTextures; i++) {
|
||||
std::string currentTextureSource;
|
||||
for (unsigned int k = 0; k < 128; k++) {
|
||||
uint8_t currentChar;
|
||||
input.read((char *)¤tChar, sizeof(uint8_t));
|
||||
|
||||
if (currentChar) {
|
||||
currentTextureSource.push_back(static_cast<char>(currentChar));
|
||||
}
|
||||
}
|
||||
textureSources.push_back(currentTextureSource);
|
||||
}
|
||||
|
||||
// Maybe write a texture loader class in future, that handles all this.
|
||||
{
|
||||
std::vector<std::future<void>> futures;
|
||||
std::mutex mutex;
|
||||
|
||||
for (unsigned int i = 0; i < numTextures; i++) {
|
||||
std::string texturePath = m_workingPath + '/' + textureSources[i].c_str();
|
||||
|
||||
auto loadModel = [=, this, &mutex]() {
|
||||
ResourceId texture = ResourceHandler::instance().registerResource<Texture>(
|
||||
TextureDescriptor{texturePath, textureTypes[i]});
|
||||
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
m_textures.push_back(texture);
|
||||
};
|
||||
|
||||
futures.push_back(std::async(std::launch::async, loadModel));
|
||||
}
|
||||
}
|
||||
|
||||
// When there is no normal map bound, please use fallback texture
|
||||
bool hasNormalMap = false;
|
||||
for (auto it = textureTypes.begin(); it != textureTypes.end(); it++) {
|
||||
if (*it == TextureType::Normal)
|
||||
hasNormalMap = true;
|
||||
}
|
||||
|
||||
if (!hasNormalMap) {
|
||||
ResourceId texture = ResourceHandler::instance().registerResource<Texture>(
|
||||
TextureDescriptor{"data/res/models/tex/fallback_normal.png", TextureType::Normal});
|
||||
|
||||
m_textures.push_back(texture);
|
||||
}
|
||||
|
||||
// Here starts the first mesh
|
||||
uint32_t numMeshes;
|
||||
input.read((char *)&numMeshes, sizeof(uint32_t));
|
||||
|
||||
for (unsigned int j = 0; j < numMeshes; j++) {
|
||||
uint32_t numMeshVertices, numMeshIndices, numMeshTextureIds;
|
||||
|
||||
input.read((char *)&numMeshVertices, sizeof(uint32_t));
|
||||
input.read((char *)&numMeshIndices, sizeof(uint32_t));
|
||||
input.read((char *)&numMeshTextureIds, sizeof(uint32_t));
|
||||
|
||||
uint32_t vertexBlockSize = numMeshVertices * sizeof(Vertex);
|
||||
uint32_t indexBlockSize = numMeshIndices * sizeof(uint32_t);
|
||||
|
||||
// Here starts the first Vertex data
|
||||
|
||||
std::vector<Vertex> meshVertices;
|
||||
meshVertices.resize(numMeshVertices);
|
||||
input.read((char *)meshVertices.data(), vertexBlockSize);
|
||||
|
||||
std::vector<uint32_t> meshIndices;
|
||||
meshIndices.resize(numMeshIndices);
|
||||
input.read((char *)meshIndices.data(), indexBlockSize);
|
||||
|
||||
std::vector<uint32_t> meshTextureIds;
|
||||
std::vector<ResourceId> meshTextures;
|
||||
|
||||
for (unsigned int i = 0; i < numMeshTextureIds; i++) {
|
||||
uint32_t currentTextureId;
|
||||
input.read((char *)¤tTextureId, sizeof(uint32_t));
|
||||
meshTextureIds.push_back(currentTextureId);
|
||||
}
|
||||
|
||||
if (!hasNormalMap) {
|
||||
// This will be the last texture
|
||||
meshTextureIds.push_back(numTextures);
|
||||
}
|
||||
|
||||
for (auto textureId : meshTextureIds) {
|
||||
meshTextures.push_back(m_textures[textureId]);
|
||||
}
|
||||
|
||||
m_meshes.push_back(new Mesh(std::move(meshVertices), std::move(meshIndices), std::move(meshTextures)));
|
||||
}
|
||||
|
||||
input.close();
|
||||
return &m_meshes[index];
|
||||
}
|
||||
|
||||
@@ -6,30 +6,19 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct ModelDescriptor
|
||||
{
|
||||
std::string name;
|
||||
std::string path;
|
||||
};
|
||||
|
||||
class Model : public Resource, public NamedResource
|
||||
class Model
|
||||
{
|
||||
public:
|
||||
Model(const ModelDescriptor &descriptor);
|
||||
Model(std::string_view name, std::vector<Mesh> meshes);
|
||||
|
||||
void draw(ShaderProgram *shaderProgram) const;
|
||||
void draw(ShaderProgram const &shaderProgram) const;
|
||||
void drawWithoutTextures() const;
|
||||
|
||||
Mesh *getMesh(unsigned int index) const; // TODO...
|
||||
|
||||
protected:
|
||||
void initialize() override;
|
||||
auto getMesh(unsigned int index) -> Mesh *; // TODO...
|
||||
|
||||
private:
|
||||
void loadModel(const std::string &pathToModel);
|
||||
|
||||
std::vector<Mesh *> m_meshes;
|
||||
std::vector<Mesh> m_meshes;
|
||||
std::vector<ResourceId> m_textures;
|
||||
|
||||
std::string m_workingPath;
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "ResourceHandler.h"
|
||||
#include "../util/Log.h"
|
||||
#include "CubeMap.h"
|
||||
#include "Model.h"
|
||||
#include "Texture.h"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -24,7 +23,6 @@ auto ResourceHandler::registerResource(Param const &...param) -> ResourceId
|
||||
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 &);
|
||||
|
||||
auto ResourceHandler::resource(const ResourceId resourceId) const -> std::shared_ptr<Resource>
|
||||
{
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "../ShaderProgram.h"
|
||||
#include "../util/Log.h"
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb/stb_image.h>
|
||||
|
||||
Texture::Texture(const TextureDescriptor &descriptor)
|
||||
@@ -20,16 +19,17 @@ Texture::Texture(const TextureDescriptor &descriptor)
|
||||
m_textureHeight = static_cast<unsigned>(textureHeight);
|
||||
m_numComponents = static_cast<unsigned>(numComponents);
|
||||
|
||||
if (!m_textureBuffer)
|
||||
if (m_textureBuffer == nullptr) {
|
||||
Log::logger().warn("Texture {} could not be loaded", resourcePath().string());
|
||||
}
|
||||
}
|
||||
|
||||
void Texture::initialize()
|
||||
{
|
||||
m_initialized = true;
|
||||
|
||||
GLenum internalFormat;
|
||||
GLenum dataFormat;
|
||||
GLenum internalFormat{};
|
||||
GLenum dataFormat{};
|
||||
|
||||
switch (m_numComponents) {
|
||||
case 1:
|
||||
@@ -52,7 +52,7 @@ void Texture::initialize()
|
||||
|
||||
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);
|
||||
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);
|
||||
@@ -66,12 +66,12 @@ void Texture::initialize()
|
||||
stbi_image_free(m_textureBuffer);
|
||||
}
|
||||
|
||||
TextureType Texture::textureType() const
|
||||
auto Texture::textureType() const -> TextureType
|
||||
{
|
||||
return m_textureType;
|
||||
}
|
||||
|
||||
void Texture::bind(uint8_t textureUnit, ShaderProgram *shaderProgram, uint8_t textureTypeNum) const
|
||||
void Texture::bind(uint8_t textureUnit, ShaderProgram const &shaderProgram, uint8_t textureTypeNum) const
|
||||
{
|
||||
std::string uniformName = "texture_";
|
||||
|
||||
@@ -99,7 +99,7 @@ void Texture::bind(uint8_t textureUnit, ShaderProgram *shaderProgram, uint8_t te
|
||||
// Add u_material as we store textures in a struct
|
||||
uniformName = "u_material." + uniformName;
|
||||
|
||||
shaderProgram->setUniform(uniformName.c_str(), textureUnit);
|
||||
shaderProgram.setUniform(uniformName, textureUnit);
|
||||
glActiveTexture(GL_TEXTURE0 + textureUnit);
|
||||
glBindTexture(GL_TEXTURE_2D, m_glId);
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#include "AbstractTexture.h"
|
||||
#include "TextureType.h"
|
||||
|
||||
#include <string>
|
||||
#include <stb/stb_image.h>
|
||||
#include <string>
|
||||
|
||||
class ShaderProgram;
|
||||
|
||||
@@ -19,9 +19,9 @@ class Texture : public AbstractTexture
|
||||
public:
|
||||
Texture(const TextureDescriptor &descriptor);
|
||||
|
||||
TextureType textureType() const;
|
||||
[[nodiscard]] auto textureType() const -> TextureType;
|
||||
|
||||
void bind(uint8_t textureUnit, ShaderProgram *shaderProgram, uint8_t textureTypeNum) const;
|
||||
void bind(uint8_t textureUnit, ShaderProgram const &shaderProgram, uint8_t textureTypeNum) const;
|
||||
void unbind() const override;
|
||||
|
||||
protected:
|
||||
|
||||
Reference in New Issue
Block a user