diff --git a/data/shaders/basic.frag b/data/shaders/basic.frag index 518e535..25921d7 100644 --- a/data/shaders/basic.frag +++ b/data/shaders/basic.frag @@ -69,7 +69,6 @@ void main() fragmentColor += pointLightContribution(u_pointLight[i], normal, v_fragmentPosition, viewDir); } - fragmentColor = vec3(1.,1.,1.); f_color = vec4(fragmentColor, 1.0f); } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f2d715a..5c04295 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,20 +3,16 @@ add_library(fever_engine Controller.cpp Window.cpp ShaderProgram.cpp - VertexArray.cpp Camera.cpp - Mesh.cpp - Entity.cpp Light.cpp Scene.cpp FrameBuffer.cpp Helper.cpp - resources/Texture.cpp - resources/Model.cpp util/Log.cpp image.cpp mesh.cpp gltf_loader.cpp + material.cpp ) target_compile_features(fever_engine PUBLIC cxx_std_20) diff --git a/src/Controller.cpp b/src/Controller.cpp index c4b0509..712d63f 100644 --- a/src/Controller.cpp +++ b/src/Controller.cpp @@ -3,12 +3,9 @@ #include "FrameBuffer.h" #include "Helper.h" #include "Light.h" -#include "Mesh.h" #include "ShaderProgram.h" #include "Window.h" -#include "definitions/attribute_locations.h" #include "gltf_loader.h" -#include "resources/Model.h" #include "util/Log.h" #include @@ -31,30 +28,6 @@ Controller::Controller() m_gameWindow->dimensions().second, postProcessingProgram) { - // fx::gltf::ReadQuotas read_quotas{.MaxFileSize = 512 * 1024 * 1024, - // .MaxBufferByteLength = 512 * 1024 * 1024}; - - // // auto gltf_path = std::filesystem::path("Lantern/glTF/Lantern.gltf"); - // // auto gltf_path = std::filesystem::path("WaterBottle/glTF/WaterBottle.gltf"); - // auto gltf_path = std::filesystem::path("ABeautifulGame.glb"); - // auto gltf = [&]() { - // if (gltf_path.extension() == ".gltf") { - // return fx::gltf::LoadFromText(gltf_path, read_quotas); - // } - - // return fx::gltf::LoadFromBinary(gltf_path, read_quotas); - // }(); - - // 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"); - // locations.tangent = glGetAttribLocation(defaultProgram.getShaderProgramId(), "a_tangent"); - - // ShaderProgram::unbind(); - // if (!gltf.cameras.empty()) { // auto const &gltf_camera = gltf.cameras.at(0); @@ -65,90 +38,6 @@ Controller::Controller() // } else { m_camera = std::make_shared(90., m_gameWindow->aspectRatio()); // } - - // std::vector models; - // for (auto const &mesh : gltf.meshes) { - // std::vector meshes; - // for (auto const &primitive : mesh.primitives) { - // auto const &material = gltf.materials.at(primitive.material); - // auto baseColorTexture = material.pbrMetallicRoughness.baseColorTexture.index; - // auto normalTexture = material.normalTexture.index; - - // std::vector> primitive_textures; - - // // Check if texture already exists, if not load it. - // if (baseColorTexture != -1 && !m_textures.contains(baseColorTexture)) { - // auto const &gltf_texture = gltf.textures.at(baseColorTexture); - // m_textures.emplace(baseColorTexture, - // Texture(gltf_texture, - // gltf_path.parent_path(), - // gltf.images, - // gltf.bufferViews, - // gltf.buffers, - // gltf.samplers, - // TextureType::Diffuse)); - - // primitive_textures.emplace_back(m_textures.at(baseColorTexture)); - // } - - // if (normalTexture != -1 && !m_textures.contains(normalTexture)) { - // auto const &gltf_texture = gltf.textures.at(normalTexture); - // m_textures.emplace(normalTexture, - // Texture(gltf_texture, - // gltf_path.parent_path(), - // gltf.images, - // gltf.bufferViews, - // gltf.buffers, - // gltf.samplers, - // TextureType::Normal)); - - // primitive_textures.emplace_back(m_textures.at(normalTexture)); - // } - - // meshes.emplace_back(Mesh_({primitive, gltf, locations}, primitive_textures)); - // } - // models.emplace_back(Model(mesh.name, std::move(meshes))); - // } - // m_models = std::move(models); - - // std::vector entities; - // for (auto const &node : gltf.nodes) { - // if (node.mesh == -1) { - // continue; - // } - - // ModelEntity entity(Entity::Prototype(node.name, {}, {}, 1.0F), - // m_models[static_cast(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 &node : gltf.nodes) { - // for (auto const &child : node.children) { - // if (!node.translation.empty()) { - // entities[child].translate( - // glm::vec3(node.translation[0], node.translation[1], node.translation[2])); - // } - // } - // } - - // m_entities = std::move(entities); } void Controller::run() @@ -191,13 +80,6 @@ void Controller::run() m_camera->getViewProj(), m_camera->getPosition()); - // 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(); diff --git a/src/Controller.h b/src/Controller.h index 99b0b87..f44a1a3 100644 --- a/src/Controller.h +++ b/src/Controller.h @@ -2,10 +2,6 @@ #include "FrameBuffer.h" #include "ShaderProgram.h" -#include "VertexArray.h" -#include "resources/Model.h" -#include "Entity.h" -#include "resources/Texture.h" #include "Scene.h" #include @@ -45,10 +41,6 @@ private: Scene m_scene; - std::vector m_entities; - std::vector m_models; - std::unordered_map m_textures; - double m_deltaTime{}; float m_exposure = 1.0; }; diff --git a/src/Entity.cpp b/src/Entity.cpp deleted file mode 100644 index dbce217..0000000 --- a/src/Entity.cpp +++ /dev/null @@ -1,161 +0,0 @@ -#include "Entity.h" -#include "Mesh.h" -#include "ShaderProgram.h" -#include "VertexArray.h" -#include "resources/Model.h" - -#include -#include - -uint32_t Entity::s_idCounter = 0; - -Entity::Entity(const std::string &name) : m_id(s_idCounter++), m_uniqueName(name) -{ -} - -uint32_t Entity::getId() const -{ - return m_id; -} - -const std::string &Entity::getUniqueName() const -{ - return m_uniqueName; -} - -void Entity::translate(glm::vec3 vector) -{ - m_position += vector; - - updateModelMatrix(); -} - -void Entity::rotate(glm::vec3 axis, float radians) -{ - glm::quat rotation = glm::angleAxis(radians, axis); - m_quaternion = rotation * m_quaternion; - - updateModelMatrix(); -} - -void Entity::setPosition(glm::vec3 position) -{ - m_position = position; - updateModelMatrix(); -} - -void Entity::setRotation(glm::vec3 eulerAngles) -{ - m_quaternion = glm::quat(eulerAngles); - updateModelMatrix(); -} - -void Entity::setRotation(glm::vec3 axis, float radians) -{ - m_quaternion = glm::angleAxis(radians, axis); - updateModelMatrix(); -} - -void Entity::setScale(float scale) -{ - m_scale = scale; - updateModelMatrix(); -} - -void Entity::updateModelMatrix() -{ - // Translate * Rotate * Scale * vertex_vec; - // First scaling, then rotation, then translation - - // Translate - glm::mat4 translationMatrix = glm::translate(glm::mat4(1.0f), m_position); - - // Rotate - glm::mat4 rotationMatrix = glm::toMat4(m_quaternion); - - // Scale - glm::mat4 scaleMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(m_scale, m_scale, m_scale)); - - m_modelMatrix = translationMatrix * rotationMatrix * scaleMatrix; -} - -glm::vec3 Entity::getPosition() const -{ - return m_position; -} - -glm::mat4 Entity::getModelMatrix() const -{ - return m_modelMatrix; -} - -ModelEntity::ModelEntity(Entity::Prototype prototype, Model const &model, ShaderProgram const &shaderProgram) - : Entity(prototype.name), m_model(model), m_shaderProgram(shaderProgram) -{ - setPosition(prototype.position); - setRotation(prototype.rotation); - setScale(prototype.scale); -} - -void ModelEntity::draw(glm::mat4 viewProjMatrix, glm::vec3 viewPosition) const -{ - 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_viewPosition", viewPosition); - - // Draw the model - m_model.draw(m_shaderProgram); - - m_shaderProgram.unbind(); -} - -Skybox::Skybox(Prototype prototype, Model *cubeModel, ShaderProgram *shaderProgram) - : m_cubeModel(cubeModel), m_shaderProgram(shaderProgram), m_vertexArray(cubeModel->getMesh(0)->getVertexArray()) -{ - // m_cubeMap = - // ResourceHandler::instance().registerResource(TextureCubeMapDescriptor{prototype.texturePath}); -} - -Skybox::~Skybox() -{ - // delete m_cubeMap; -} - -void Skybox::initializeOnGPU() -{ - // m_cubeMap->initializeOnGPU(); -} - -void Skybox::draw(glm::mat4 viewMatrix, glm::mat4 projectionMatrix) -{ - // To disable face culling first get current state - GLboolean active; - glGetBooleanv(GL_CULL_FACE_MODE, &active); - glDisable(GL_CULL_FACE); - - glDepthMask(GL_FALSE); - m_shaderProgram->bind(); - - // Delete any translation from the skybox cube - glm::mat4 viewProjectionMatrix = projectionMatrix * glm::mat4(glm::mat3(viewMatrix)); - - m_shaderProgram->setUniform("u_viewProjectionMatrix", viewProjectionMatrix); - - // auto cubeMap = std::static_pointer_cast(ResourceHandler::instance().resource(m_cubeMap)); - // cubeMap->bind(m_shaderProgram); - // m_cubeModel->getMesh(0)->drawWithoutTextures(); - // cubeMap->unbind(); - - m_shaderProgram->unbind(); - glDepthMask(GL_TRUE); - - // Restore face culling - if (active) { - glEnable(GL_CULL_FACE); - } else { - glDisable(GL_CULL_FACE); - } -} diff --git a/src/Entity.h b/src/Entity.h deleted file mode 100644 index 69540fd..0000000 --- a/src/Entity.h +++ /dev/null @@ -1,100 +0,0 @@ -#pragma once - -#include "resources/Resource.h" - -#include -#include -#include -#include -#include - -class VertexArray; -class ShaderProgram; -class Model; -class TextureCubeMap; - -class Entity -{ -public: - struct Prototype - { - Prototype(const std::string &_name, glm::vec3 _position, glm::vec3 _rotation, float _scale) - : name(_name), position(_position), rotation(_rotation), scale(_scale) - { - } - - std::string name; - glm::vec3 position; - glm::vec3 rotation; - float scale; - }; - - Entity(const std::string &name); - virtual ~Entity() = default; - - uint32_t getId() const; - const std::string &getUniqueName() const; - - void translate(glm::vec3 vector); - void rotate(glm::vec3 axis, float radians); - - void setPosition(glm::vec3 position); - void setRotation(glm::vec3 eulerAngles); - void setRotation(glm::vec3 axis, float radians); - void setScale(float scale); - - glm::vec3 getPosition() const; - glm::mat4 getModelMatrix() const; - -protected: - void updateModelMatrix(); - - const uint32_t m_id; - static uint32_t s_idCounter; - - std::string m_uniqueName; - - glm::mat4 m_modelMatrix = glm::mat4(1.0f); - glm::vec3 m_position = glm::vec3(0.0f, 0.0f, 0.0f); - glm::vec3 m_velocity = glm::vec3(0.0f, 0.0f, 0.0f); - glm::quat m_quaternion; - float m_scale = 1.0f; -}; - -class ModelEntity : public Entity -{ -public: - ModelEntity(Entity::Prototype prototype, Model const &model, ShaderProgram const &shaderProgram); - - void draw(glm::mat4 viewProjMatrix, glm::vec3 viewPosition) const; - -private: - Model const &m_model; - ShaderProgram const &m_shaderProgram; -}; - -class Skybox -{ -public: - 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; - - ResourceId m_cubeMap; - - VertexArray *m_vertexArray; -}; diff --git a/src/FrameBuffer.cpp b/src/FrameBuffer.cpp index 27a8d71..1e34378 100644 --- a/src/FrameBuffer.cpp +++ b/src/FrameBuffer.cpp @@ -4,19 +4,17 @@ #include -AbstractFrameBuffer::~AbstractFrameBuffer() = default; - -void AbstractFrameBuffer::bind() const +void Framebuffer::bind() const { glBindFramebuffer(GL_FRAMEBUFFER, m_FBO); } -void AbstractFrameBuffer::unbind() const +void Framebuffer::unbind() { glBindFramebuffer(GL_FRAMEBUFFER, 0); } -GLuint AbstractFrameBuffer::getFBO() const +GLuint Framebuffer::getFBO() const { return m_FBO; } diff --git a/src/FrameBuffer.h b/src/FrameBuffer.h index 09b8caa..7ffd7d3 100644 --- a/src/FrameBuffer.h +++ b/src/FrameBuffer.h @@ -1,31 +1,19 @@ #pragma once -#include "resources/Resource.h" - #include class ShaderProgram; -class CubeMap; -class AbstractFrameBuffer -{ -public: - virtual ~AbstractFrameBuffer() = 0; - - void bind() const; - void unbind() const; - GLuint getFBO() const; - -protected: - GLuint m_FBO; -}; - -class Framebuffer : public AbstractFrameBuffer +class Framebuffer { public: Framebuffer(uint32_t width, uint32_t height, ShaderProgram &shaderProgram); ~Framebuffer(); + void bind() const; + static void unbind(); + GLuint getFBO() const; + void drawOnEntireScreen() const; void changeDimensions(uint32_t width, uint32_t height); @@ -39,6 +27,7 @@ private: GLuint m_colorBuffer; GLuint m_depthStencilBuffer; + GLuint m_FBO; ShaderProgram &m_shaderProgram; }; diff --git a/src/Light.cpp b/src/Light.cpp index a0b2849..65d9893 100644 --- a/src/Light.cpp +++ b/src/Light.cpp @@ -6,7 +6,7 @@ uint32_t Light::s_idCounter = 0; Light::Light(const std::string &name, glm::vec3 color, float intensity, ShaderProgram *shaderProgram) - : Entity(name), m_shaderProgram(shaderProgram), m_intensity(intensity), m_lightColor(color * intensity) + : m_shaderProgram(shaderProgram), m_intensity(intensity), m_lightColor(color * intensity) { m_id = s_idCounter++; } diff --git a/src/Light.h b/src/Light.h index dedc3fd..1128e19 100644 --- a/src/Light.h +++ b/src/Light.h @@ -1,15 +1,11 @@ #pragma once -#include "Entity.h" - #include #include -#define NUM_POINT_LIGHTS 1 - class ShaderProgram; -class Light : public Entity +class Light { public: struct Prototype diff --git a/src/Mesh.cpp b/src/Mesh.cpp deleted file mode 100644 index 63caebd..0000000 --- a/src/Mesh.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "Mesh.h" - -#include "ShaderProgram.h" -#include "VertexArray.h" -#include "resources/Texture.h" -#include - -Mesh_::Mesh_(VertexArray vertexArray, std::vector> textures) - : m_vertexArray(std::move(vertexArray)), m_textures(std::move(textures)) -{ -} - -void Mesh_::draw(ShaderProgram const &shaderProgram) const -{ - // Bind all textures in order to its texture unit - std::size_t textureNum = 0; - for (auto textureIt : m_textures) { - textureIt.get().bind(static_cast(textureNum), shaderProgram); - textureNum++; - } - - // Draw elements - m_vertexArray.bind(); - glDrawElements(GL_TRIANGLES, static_cast(m_vertexArray.indicesCount()), - static_cast(m_vertexArray.indicesType()), nullptr); - VertexArray::unbind(); - - // Unbind all textures - for (auto textureIt : m_textures) { - textureIt.get().unbind(); - } -} - -void Mesh_::drawWithoutTextures() const -{ - m_vertexArray.bind(); - - glDrawElements(GL_TRIANGLES, static_cast(m_vertexArray.indicesCount()), - static_cast(m_vertexArray.indicesType()), nullptr); - - VertexArray::unbind(); -} - -auto Mesh_::getVertexArray() -> VertexArray * -{ - return &m_vertexArray; -} diff --git a/src/Mesh.h b/src/Mesh.h deleted file mode 100644 index ea09962..0000000 --- a/src/Mesh.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "VertexArray.h" -#include "resources/Texture.h" - -#include - -class ShaderProgram; - -class Mesh_ -{ -public: - Mesh_(VertexArray vertexArray, std::vector> textures); - - void draw(ShaderProgram const &shaderProgram) const; - void drawWithoutTextures() const; - - auto getVertexArray() -> VertexArray *; - -private: - VertexArray m_vertexArray; - std::vector> m_textures; -}; diff --git a/src/Scene.cpp b/src/Scene.cpp index cf752b3..0f8605d 100644 --- a/src/Scene.cpp +++ b/src/Scene.cpp @@ -72,18 +72,21 @@ Scene::Scene() spawn_node(node, {}); } - auto name_view = m_registry.view(); - for (auto [entity, name] : name_view.each()) { - Log::logger().info("Hello entity {}!", name); - } - auto mesh_view = m_registry.view>(); for (auto [entity, mesh] : mesh_view.each()) { - m_registry.emplace(entity, GpuMesh{mesh}); + m_registry.emplace(entity, GpuMesh(mesh)); // Remove Mesh resource as it is no longer needed. m_registry.erase>(entity); } + + auto material_view = m_registry.view>(); + for (auto [entity, material] : material_view.each()) { + m_registry.emplace(entity, GpuMaterial(material)); + + // Remove Material resource as it is no longer needed. + m_registry.erase>(entity); + } } void Scene::update(std::chrono::duration delta, @@ -123,16 +126,19 @@ void Scene::update(std::chrono::duration delta, } } - auto mesh_view = m_registry.view(); - for (auto [entity, mesh, transform] : mesh_view.each()) { + auto mesh_view = m_registry.view(); + for (auto [entity, mesh, material, transform] : mesh_view.each()) { shaderprogram->bind(); + // Bind textures + material.bind(*shaderprogram); + // Bind modelview matrix uniform { glm::mat4 modelViewProj = viewProjMatrix * transform.transform; shaderprogram->setUniform("u_modelViewProjMatrix", modelViewProj); - // shaderprogram->setUniform("u_modelMatrix", modelMatrix); - // shaderprogram->setUniform("u_viewPosition", viewPosition); + shaderprogram->setUniform("u_modelMatrix", transform.transform); + shaderprogram->setUniform("u_viewPosition", viewPosition); } glBindVertexArray(mesh.vao); diff --git a/src/ShaderProgram.cpp b/src/ShaderProgram.cpp index b6ecb52..3c69006 100644 --- a/src/ShaderProgram.cpp +++ b/src/ShaderProgram.cpp @@ -120,6 +120,12 @@ void ShaderProgram::setUniform(const std::string &name, int value) const glUniform1i(location, value); } +void ShaderProgram::setUniform(const std::string &name, unsigned int value) const +{ + GLint location = retrieveUniformLocation(name); + glUniform1ui(location, value); +} + void ShaderProgram::setUniform(const std::string &name, float value) const { GLint location = retrieveUniformLocation(name); diff --git a/src/ShaderProgram.h b/src/ShaderProgram.h index e1c49e3..eb3177d 100644 --- a/src/ShaderProgram.h +++ b/src/ShaderProgram.h @@ -28,6 +28,7 @@ public: // May be rewritten... void setUniform(const std::string &name, bool value) const; void setUniform(const std::string &name, int value) const; + void setUniform(const std::string &name, unsigned int value) const; void setUniform(const std::string &name, float value) const; void setUniform(const std::string &name, glm::vec2 vector) const; void setUniform(const std::string &name, glm::vec3 vector) const; diff --git a/src/VertexArray.cpp b/src/VertexArray.cpp deleted file mode 100644 index c88a03c..0000000 --- a/src/VertexArray.cpp +++ /dev/null @@ -1,183 +0,0 @@ -#include "VertexArray.h" -#include "definitions/models.h" -#include "util/Log.h" - -#include -#include - -static auto accessor_byte_size(fx::gltf::Accessor::Type accessor_type) -> std::size_t -{ - switch (accessor_type) { - case fx::gltf::Accessor::Type::Scalar: - return 1; - case fx::gltf::Accessor::Type::Vec2: - return 2; - case fx::gltf::Accessor::Type::Vec3: - return 3; - case fx::gltf::Accessor::Type::Vec4: - return 4; - default: - Log::logger().warn("Unexpected accessor type: {}", static_cast(accessor_type)); - return 0; - } -} - -VertexArray::VertexArray(fx::gltf::Primitive const &primitive, - fx::gltf::Document const &model, - AttributeLocations &locations) -{ - GLuint vao{}; - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - - if (!primitive.attributes.contains("TANGENT") || !primitive.attributes.contains("NORMAL")) { - Log::logger().critical("glTF scene has to include tangent and normal components!"); - std::terminate(); - } - - int position_accessor_id = primitive.attributes.at("POSITION"); - int normal_accessor_id = primitive.attributes.at("NORMAL"); - int uv_accessor_id = primitive.attributes.at("TEXCOORD_0"); - int tangent_accessor_id = primitive.attributes.at("TANGENT"); - int indices_accessor_id = primitive.indices; - - auto const &position_accessor = model.accessors.at(position_accessor_id); - auto const &normal_accessor = model.accessors.at(normal_accessor_id); - auto const &uv_accessor = model.accessors.at(uv_accessor_id); - auto const &tangent_accessor = model.accessors.at(tangent_accessor_id); - auto const &indices_accessor = model.accessors.at(indices_accessor_id); - - int position_buffer_view_id = model.accessors[position_accessor_id].bufferView; - int normal_buffer_view_id = model.accessors[normal_accessor_id].bufferView; - int uv_buffer_view_id = model.accessors[uv_accessor_id].bufferView; - int tangent_buffer_view_id = model.accessors[tangent_accessor_id].bufferView; - int indices_buffer_view_id = model.accessors[indices_accessor_id].bufferView; - - auto const &position_buffer_view = model.bufferViews.at(position_buffer_view_id); - auto const &normal_buffer_view = model.bufferViews.at(normal_buffer_view_id); - auto const &uv_buffer_view = model.bufferViews.at(uv_buffer_view_id); - auto const &tangent_buffer_view = model.bufferViews.at(tangent_buffer_view_id); - auto const &indices_buffer_view = model.bufferViews.at(indices_buffer_view_id); - - auto const &position_buffer = model.buffers.at(position_buffer_view.buffer); - auto const &normal_buffer = model.buffers.at(normal_buffer_view.buffer); - auto const &uv_buffer = model.buffers.at(uv_buffer_view.buffer); - auto const &tangent_buffer = model.buffers.at(tangent_buffer_view.buffer); - auto const &indices_buffer = model.buffers.at(indices_buffer_view.buffer); - - 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); - - glEnableVertexAttribArray(locations.position); - glVertexAttribPointer(locations.position, - accessor_byte_size(position_accessor.type), - static_cast(position_accessor.componentType), - position_accessor.normalized ? GL_TRUE : GL_FALSE, - position_buffer_view.byteStride, - reinterpret_cast(position_accessor.byteOffset)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast, - // performance-no-int-to-ptr) - } - - GLuint normalVbo{}; - { - glGenBuffers(1, &normalVbo); - glBindBuffer(GL_ARRAY_BUFFER, normalVbo); - glBufferData(GL_ARRAY_BUFFER, - normal_buffer_view.byteLength, - normal_buffer.data.data() + normal_buffer_view.byteOffset, - GL_STATIC_DRAW); - - glEnableVertexAttribArray(locations.normal); - glVertexAttribPointer(locations.normal, - accessor_byte_size(normal_accessor.type), - static_cast(normal_accessor.componentType), - normal_accessor.normalized ? GL_TRUE : GL_FALSE, - normal_buffer_view.byteStride, - reinterpret_cast(normal_accessor.byteOffset)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast, - // performance-no-int-to-ptr) - } - - GLuint uvVbo{}; - { - glGenBuffers(1, &uvVbo); - glBindBuffer(GL_ARRAY_BUFFER, uvVbo); - glBufferData(GL_ARRAY_BUFFER, - uv_buffer_view.byteLength, - uv_buffer.data.data() + uv_buffer_view.byteOffset, - GL_STATIC_DRAW); - - glEnableVertexAttribArray(locations.uv); - glVertexAttribPointer(locations.uv, - accessor_byte_size(uv_accessor.type), - static_cast(uv_accessor.componentType), - uv_accessor.normalized ? GL_TRUE : GL_FALSE, - uv_buffer_view.byteStride, - reinterpret_cast(uv_accessor.byteOffset)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast, - // performance-no-int-to-ptr) - } - - GLuint tangentVbo{}; - { - glGenBuffers(1, &tangentVbo); - glBindBuffer(GL_ARRAY_BUFFER, tangentVbo); - glBufferData(GL_ARRAY_BUFFER, - tangent_buffer_view.byteLength, - tangent_buffer.data.data() + tangent_buffer_view.byteOffset, - GL_STATIC_DRAW); - - glEnableVertexAttribArray(locations.tangent); - glVertexAttribPointer(locations.tangent, - accessor_byte_size(tangent_accessor.type), - static_cast(tangent_accessor.componentType), - tangent_accessor.normalized ? GL_TRUE : GL_FALSE, - tangent_buffer_view.byteStride, - reinterpret_cast(tangent_accessor.byteOffset)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast, - // performance-no-int-to-ptr) - } - - 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); - - glBindVertexArray(0); - - m_vao = vao; - m_ebo = ebo; - m_positionVbo = positionVbo; - m_normalVbo = normalVbo; - m_uvVbo = uvVbo; - m_tangentVbo = tangentVbo; - m_indicesCount = indices_accessor.count; - m_indicesType = indices_accessor.componentType; -} - -VertexArray::~VertexArray() -{ - glDeleteVertexArrays(1, &m_vao); - - glDeleteBuffers(1, &m_positionVbo); - glDeleteBuffers(1, &m_normalVbo); - glDeleteBuffers(1, &m_uvVbo); - glDeleteBuffers(1, &m_tangentVbo); - glDeleteBuffers(1, &m_ebo); -} - -void VertexArray::bind() const -{ - glBindVertexArray(m_vao); -} - -void VertexArray::unbind() -{ - glBindVertexArray(0); -} diff --git a/src/VertexArray.h b/src/VertexArray.h deleted file mode 100644 index 8fd61df..0000000 --- a/src/VertexArray.h +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -#include "definitions/attribute_locations.h" - -#include -#include -#include - -class VertexArray final -{ -public: - VertexArray(fx::gltf::Primitive const &primitive, fx::gltf::Document 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_normalVbo(other.m_normalVbo), - m_uvVbo(other.m_uvVbo), - m_tangentVbo(other.m_tangentVbo), - m_ebo(other.m_ebo) - { - other.m_ebo = 0; - other.m_vao = 0; - other.m_positionVbo = 0; - other.m_normalVbo = 0; - other.m_uvVbo = 0; - other.m_tangentVbo = 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_normalVbo = other.m_normalVbo; - m_uvVbo = other.m_uvVbo; - m_tangentVbo = other.m_tangentVbo; - m_ebo = other.m_ebo; - - other.m_ebo = 0; - other.m_vao = 0; - other.m_positionVbo = 0; - other.m_normalVbo = 0; - other.m_uvVbo = 0; - other.m_tangentVbo = 0; - - return *this; - } - - VertexArray(VertexArray const &) = delete; - auto operator=(VertexArray const &) -> VertexArray & = delete; - - ~VertexArray(); - - void bind() const; - static void unbind(); - - [[nodiscard]] auto indicesCount() const -> uint64_t { return m_indicesCount; } - [[nodiscard]] auto indicesType() const -> fx::gltf::Accessor::ComponentType { return m_indicesType; } - -private: - uint64_t m_indicesCount; - fx::gltf::Accessor::ComponentType m_indicesType; - - GLuint m_vao; - - GLuint m_positionVbo; - GLuint m_normalVbo; - GLuint m_uvVbo; - GLuint m_tangentVbo; - GLuint m_ebo; -}; diff --git a/src/definitions/attribute_locations.h b/src/definitions/attribute_locations.h index 337fbfb..fcb587f 100644 --- a/src/definitions/attribute_locations.h +++ b/src/definitions/attribute_locations.h @@ -2,8 +2,10 @@ struct AttributeLocations { - int position; - int normal; - int uv; - int tangent; + int position = 0; + int uv = 1; + int normal = 2; + int tangent = 3; }; + +static constexpr AttributeLocations ATTRIBUTE_LOCATION; diff --git a/src/definitions/models.h b/src/definitions/models.h deleted file mode 100644 index 80855c1..0000000 --- a/src/definitions/models.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -struct Vertex -{ - // Postition - glm::vec3 position; - - // UV Texture Mapping - glm::vec2 textureCoords; - - // Normal vector - glm::vec3 normalVec; - - // Tangent vector - glm::vec3 tangentVec; - - // Bittangent vector - glm::vec3 bitangentVec; -}; diff --git a/src/gltf_loader.cpp b/src/gltf_loader.cpp index c974783..7960141 100644 --- a/src/gltf_loader.cpp +++ b/src/gltf_loader.cpp @@ -1,5 +1,6 @@ #include "gltf_loader.h" #include "util/Log.h" +#include "definitions/attribute_locations.h" #include @@ -117,16 +118,16 @@ static auto load_attribute(std::string_view attribute_name, auto vertex_attribute_id = [attribute_name]() -> std::optional { if (attribute_name == "POSITION") { - return 0; + return ATTRIBUTE_LOCATION.position; } if (attribute_name == "TEXCOORD_0") { - return 1; + return ATTRIBUTE_LOCATION.uv; } if (attribute_name == "NORMAL") { - return 2; + return ATTRIBUTE_LOCATION.normal; } if (attribute_name == "TANGENT") { - return 3; + return ATTRIBUTE_LOCATION.tangent; } return {}; diff --git a/src/material.cpp b/src/material.cpp new file mode 100644 index 0000000..f0bf21b --- /dev/null +++ b/src/material.cpp @@ -0,0 +1,32 @@ +#include "material.h" +#include "ShaderProgram.h" + +GpuMaterial::GpuMaterial(Material const &material) +{ + int texture_unit_counter = 0; + + if (material.base_color_texture.has_value()) { + Binding binding{.uniform_name = "u_material.texture_diffuse", + .texture_unit = texture_unit_counter++}; + base_color_texture = std::make_pair(GpuImage(material.base_color_texture.value()), binding); + } + + if (material.normal_map_texture.has_value()) { + Binding binding{.uniform_name = "u_material.texture_normal", + .texture_unit = texture_unit_counter++}; + normal_map_texture = std::make_pair(GpuImage(material.normal_map_texture.value()), binding); + } +} +void GpuMaterial::bind(ShaderProgram const &shader_program) const +{ + auto bind_texture = [&shader_program](auto const &texture) { + if (texture.has_value()) { + shader_program.setUniform(texture->second.uniform_name, texture->second.texture_unit); + glActiveTexture(GL_TEXTURE0 + texture->second.texture_unit); + glBindTexture(GL_TEXTURE_2D, texture->first.texture); + } + }; + + bind_texture(base_color_texture); + bind_texture(normal_map_texture); +} diff --git a/src/material.h b/src/material.h index 27dd731..700f301 100644 --- a/src/material.h +++ b/src/material.h @@ -5,8 +5,26 @@ #include #include +class ShaderProgram; + struct Material { std::optional> base_color_texture; std::optional> normal_map_texture; }; + +struct GpuMaterial +{ + GpuMaterial(Material const &material); + + void bind(ShaderProgram const &shader_program) const; + + struct Binding + { + std::string uniform_name; + int texture_unit; + }; + + std::optional> base_color_texture; + std::optional> normal_map_texture; +}; diff --git a/src/mesh.h b/src/mesh.h index a88dabd..ce767cb 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -50,6 +50,7 @@ struct GpuMesh { other.vao = 0; } + auto operator=(GpuMesh &&other) noexcept -> GpuMesh & { vao = other.vao; diff --git a/src/name.h b/src/name.h index fc41130..c5370c0 100644 --- a/src/name.h +++ b/src/name.h @@ -2,4 +2,7 @@ #include -using Name = std::string; +struct Name +{ + std::string name; +}; diff --git a/src/resources/Model.cpp b/src/resources/Model.cpp deleted file mode 100644 index 65c2b81..0000000 --- a/src/resources/Model.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "Model.h" -#include "Texture.h" -#include "../util/Log.h" - -Model::Model(std::string_view name, std::vector meshes) : m_meshes(std::move(meshes)), m_name(name) -{ - Log::logger().trace(R"(Loaded model "{}".)", name); -} - -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); - } -} - -void Model::drawWithoutTextures() const -{ - // Iterate through every mesh and call the draw function - for (const auto &mesh : m_meshes) { - mesh.drawWithoutTextures(); - } -} - -auto Model::getMesh(unsigned int index) -> Mesh_ * -{ - return &m_meshes[index]; -} diff --git a/src/resources/Model.h b/src/resources/Model.h deleted file mode 100644 index 16d08c4..0000000 --- a/src/resources/Model.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "../Mesh.h" -#include "Resource.h" - -#include -#include - -class Model -{ -public: - Model(std::string_view name, std::vector meshes); - - void draw(ShaderProgram const &shaderProgram) const; - void drawWithoutTextures() const; - - auto getMesh(unsigned int index) -> Mesh_ *; // TODO... - -private: - std::vector m_meshes; - std::vector m_textures; - - std::string m_name; -}; diff --git a/src/resources/Resource.cpp b/src/resources/Resource.cpp deleted file mode 100644 index 95aad75..0000000 --- a/src/resources/Resource.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "Resource.h" -#include "../util/Log.h" - -ResourceId Resource::s_idCounter = 0; - -Resource::Resource(std::filesystem::path path) : m_id(s_idCounter++), m_path(std::move(path)) -{ - Log::logger().info("Resource \"{}\" with id {} created", m_path.string(), m_id); -} - -auto Resource::id() const -> ResourceId -{ - return m_id; -} - -auto Resource::resourcePath() const -> const std::filesystem::path & -{ - return m_path; -} - -auto GlResource::glId() const -> GLuint -{ - return m_glId; -} - -NamedResource::NamedResource(std::string name) : m_name(std::move(name)) -{ -} - -auto NamedResource::name() const -> const std::string & -{ - return m_name; -} - -NamedResource::~NamedResource() = default; diff --git a/src/resources/Resource.h b/src/resources/Resource.h deleted file mode 100644 index 220cf0e..0000000 --- a/src/resources/Resource.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -using ResourceId = uint64_t; - -class Resource -{ -public: - Resource(std::filesystem::path path); - Resource(const Resource &other) = delete; - Resource(Resource &&other) = delete; - auto operator=(const Resource &other) -> Resource & = delete; - auto operator=(Resource &&other) -> Resource & = delete; - - [[nodiscard]] auto id() const -> ResourceId; - [[nodiscard]] auto resourcePath() const -> const std::filesystem::path &; - -private: - ResourceId m_id; - static ResourceId s_idCounter; - - std::filesystem::path m_path; - - friend class ResourceHandler; -}; - -class GlResource -{ -public: - // virtual ~GlResource() = 0; TODO!! - virtual void unbind() const = 0; - - auto glId() const -> GLuint; - -protected: - GLuint m_glId; -}; - -class NamedResource -{ -public: - NamedResource(std::string name); - virtual ~NamedResource() = 0; - - [[nodiscard]] auto name() const -> const std::string &; - -private: - const std::string m_name; -}; diff --git a/src/resources/ResourceHandler.cpp b/src/resources/ResourceHandler.cpp deleted file mode 100644 index 8e3b3b0..0000000 --- a/src/resources/ResourceHandler.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "ResourceHandler.h" -#include "../util/Log.h" -#include "CubeMap.h" - -#include - -ResourceHandler ResourceHandler::s_instance; - -auto ResourceHandler::instance() -> ResourceHandler & -{ - return s_instance; -} - -template -auto ResourceHandler::registerResource(Param const &...param) -> ResourceId -{ - auto resource = std::make_shared(param...); - m_resources.emplace(resource->id(), resource); - return resource->id(); -} - -template ResourceId ResourceHandler::registerResource(TextureCubeMapDescriptor const &); -template ResourceId ResourceHandler::registerResource(int const &); - -auto ResourceHandler::resource(const ResourceId resourceId) const -> std::shared_ptr -{ - auto resourceIt = m_resources.find(resourceId); - - if (resourceIt != m_resources.end()) { - auto resource = resourceIt->second; - return resource; - } - - Log::logger().warn("Could not find resource with id {}", resourceId); - return {}; -} diff --git a/src/resources/ResourceHandler.h b/src/resources/ResourceHandler.h deleted file mode 100644 index 8f484fc..0000000 --- a/src/resources/ResourceHandler.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "Resource.h" - -#include -#include - -class ResourceHandler -{ -public: - static auto instance() -> ResourceHandler &; - - template - auto registerResource(Param const &...param) -> ResourceId; - - [[nodiscard]] auto resource(ResourceId resourceId) const -> std::shared_ptr; - -private: - ResourceHandler() = default; - - static ResourceHandler s_instance; - - std::map> m_resources; -}; diff --git a/src/resources/ShaderProgram.h b/src/resources/ShaderProgram.h deleted file mode 100644 index 765d751..0000000 --- a/src/resources/ShaderProgram.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include "Resource.h" - -class ShaderProgram : public GlResource, public NamedResource -{ -public: - ShaderProgram(); - - void bind() const; - void unbind() const override; -} \ No newline at end of file diff --git a/src/resources/Texture.cpp b/src/resources/Texture.cpp deleted file mode 100644 index 823d163..0000000 --- a/src/resources/Texture.cpp +++ /dev/null @@ -1,129 +0,0 @@ -#include "Texture.h" -#include "../ShaderProgram.h" -#include "../util/Log.h" - -// #define STB_IMAGE_IMPLEMENTATION -#include - -Texture::Texture(fx::gltf::Texture const &texture, - std::filesystem::path const &working_directory, - std::span images, - std::span bufferViews, - std::span buffers, - std::span samplers, - TextureType textureType) - : m_textureType(textureType) -{ - auto sampler_id = texture.sampler; - - auto sampler = [samplers, sampler_id]() { - if (sampler_id != -1) { - return samplers[static_cast(sampler_id)]; - } - - return fx::gltf::Sampler{.magFilter = fx::gltf::Sampler::MagFilter::Linear, - .minFilter = fx::gltf::Sampler::MinFilter::LinearMipMapLinear, - .wrapS = fx::gltf::Sampler::WrappingMode::Repeat, - .wrapT = fx::gltf::Sampler::WrappingMode::Repeat}; - }(); - - auto const &image = images[static_cast(texture.source)]; - auto const &imageBufferView = bufferViews[static_cast(image.bufferView)]; - auto const &imageBuffer = buffers[static_cast(imageBufferView.buffer)]; - - int width{}; - int height{}; - int components{}; - - auto *stbi_image = [&]() { - if (!image.uri.empty()) { - auto image_path = working_directory / image.uri; - return stbi_load(image_path.c_str(), &width, &height, &components, 0); - } - - return stbi_load_from_memory(&imageBuffer.data[imageBufferView.byteOffset], - static_cast(imageBufferView.byteOffset), - &width, - &height, - &components, - 0); - }(); - - GLenum internalFormat{}; - GLenum dataFormat{}; - - switch (components) { - 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; - } - - glGenTextures(1, &m_glId); - glBindTexture(GL_TEXTURE_2D, m_glId); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, static_cast(sampler.magFilter)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, static_cast(sampler.minFilter)); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -2.0F); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, static_cast(sampler.wrapS)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, static_cast(sampler.wrapT)); - - glTexImage2D(GL_TEXTURE_2D, - 0, - static_cast(internalFormat), - static_cast(width), - static_cast(height), - 0, - dataFormat, - GL_UNSIGNED_BYTE, - stbi_image); - glGenerateMipmap(GL_TEXTURE_2D); - - glBindTexture(GL_TEXTURE_2D, 0); - - stbi_image_free(stbi_image); - - Log::logger().trace(R"(Loaded texture "{}")", image.name); -} - -auto Texture::textureType() const -> TextureType -{ - return m_textureType; -} - -void Texture::bind(uint8_t textureUnit, ShaderProgram const &shaderProgram) const -{ - std::string uniformName = "texture_"; - - switch (m_textureType) { - case TextureType::Diffuse: - uniformName += "diffuse"; - break; - case TextureType::Normal: - uniformName += "normal"; - break; - default: - break; - } - - // Add u_material as we store textures in a struct - uniformName = "u_material." + uniformName; - - shaderProgram.setUniform(uniformName, textureUnit); - glActiveTexture(GL_TEXTURE0 + textureUnit); - glBindTexture(GL_TEXTURE_2D, m_glId); -} - -void Texture::unbind() -{ - glBindTexture(GL_TEXTURE_2D, 0); -} diff --git a/src/resources/Texture.h b/src/resources/Texture.h deleted file mode 100644 index 5c45d55..0000000 --- a/src/resources/Texture.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "TextureType.h" - -#include -#include -#include -#include -#include - -class ShaderProgram; - -class Texture -{ -public: - Texture(fx::gltf::Texture const &texture, - std::filesystem::path const &working_directory, - std::span images, - std::span bufferViews, - std::span buffers, - std::span samplers, - TextureType textureType); - - [[nodiscard]] auto textureType() const -> TextureType; - - void bind(uint8_t textureUnit, ShaderProgram const &shaderProgram) const; - static void unbind(); - -private: - TextureType m_textureType; - GLuint m_glId = 0; -}; \ No newline at end of file diff --git a/src/resources/TextureType.h b/src/resources/TextureType.h deleted file mode 100644 index febbcd8..0000000 --- a/src/resources/TextureType.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -enum class TextureType -{ - Diffuse, - Normal, - TEXTURE_TYPE_NUM_ITEMS -}; \ No newline at end of file diff --git a/src/resources/VertexArray.h b/src/resources/VertexArray.h deleted file mode 100644 index 7b9637e..0000000 --- a/src/resources/VertexArray.h +++ /dev/null @@ -1 +0,0 @@ -#pragma once \ No newline at end of file