diff --git a/CMakeLists.txt b/CMakeLists.txt index 26f5b89..df79a04 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,7 +53,9 @@ add_executable(Dicewars_Siedler src/main.cpp src/engine/platform/glfw/InputManager.cpp src/engine/platform/glfw/InputManager.h src/engine/renderer/loader/OBJLoader.cpp - src/engine/renderer/loader/OBJLoader.h) + src/engine/renderer/loader/OBJLoader.h + src/engine/layer/entities/Light.cpp + src/engine/layer/entities/Light.h) target_include_directories(Dicewars_Siedler PRIVATE lib/glfw/include diff --git a/assets/shaders/fragmentShader.glsl b/assets/shaders/fragmentShader.glsl index 564dbc3..c8552da 100644 --- a/assets/shaders/fragmentShader.glsl +++ b/assets/shaders/fragmentShader.glsl @@ -1,11 +1,22 @@ #version 400 core in vec2 pass_textureCoords; +in vec3 surfaceNormal; +in vec3 toLightVector; out vec4 outColor; uniform sampler2D textureSampler; +uniform vec3 lightColor; void main(void) { - outColor = texture(textureSampler, pass_textureCoords); + + + vec3 unitNormal = normalize(surfaceNormal); + vec3 unitToLightDir = normalize(toLightVector); + + float cosTheta = dot(unitNormal, unitToLightDir); + float brightness = max(cosTheta, 0.0); + vec3 diffuse = brightness * lightColor; + outColor = vec4(diffuse, 1.0f) * texture(textureSampler, pass_textureCoords); } \ No newline at end of file diff --git a/assets/shaders/vertexShader.glsl b/assets/shaders/vertexShader.glsl index cc5825b..02ffb90 100644 --- a/assets/shaders/vertexShader.glsl +++ b/assets/shaders/vertexShader.glsl @@ -2,15 +2,22 @@ in vec3 position; in vec2 textureCoords; +in vec3 normal; out vec2 pass_textureCoords; +out vec3 surfaceNormal; +out vec3 toLightVector; uniform mat4 transformationMatrix; uniform mat4 projectionMatrix; uniform mat4 viewMatrix; +uniform vec3 lightPosition; -void main() -{ - gl_Position = projectionMatrix * viewMatrix * transformationMatrix * vec4(position, 1.0f); +void main() { + vec4 worldPosition = transformationMatrix * vec4(position, 1.0f); + gl_Position = projectionMatrix * viewMatrix * worldPosition; pass_textureCoords = textureCoords; + + surfaceNormal = (transformationMatrix * vec4(normal, 0.0f)).xyz; + toLightVector = lightPosition - worldPosition.xyz; } diff --git a/src/engine/layer/GameLayer.cpp b/src/engine/layer/GameLayer.cpp index db137bf..39631ff 100644 --- a/src/engine/layer/GameLayer.cpp +++ b/src/engine/layer/GameLayer.cpp @@ -9,6 +9,7 @@ #include "../renderer/loader/OBJLoader.h" #include "../renderer/model/TexturedModel.h" #include "../renderer/textures/ModelTexture.h" +#include "entities/Light.h" GameLayer::GameLayer() :texturedModel(0,0) //Platzhalter, echtes Model kommt in onAttach { @@ -35,9 +36,10 @@ void GameLayer::onAttach() 1,0 //v3 }; - texturedModel = *OBJLoader::loadModel("assets/stall/stall.obj", "assets/stall/stallTexture.png", loader); - entity = std::make_unique(Entity(std::make_shared(texturedModel), glm::vec3(0,0,-50), 0,0,0, 1.f)); + texturedModel = *OBJLoader::loadModel("assets/dragon/dragon.obj", "assets/dragon/dragon.png", loader); + entity = std::make_unique(Entity(std::make_shared(texturedModel), glm::vec3(0,0,-25), 0,0,0, 1.f)); camera = std::make_unique(); + light = std::make_unique(glm::vec3(0,0,-20), glm::vec3(1,1,1)); } void GameLayer::onDetach() @@ -54,8 +56,8 @@ void GameLayer::onUpdate() if (InputManager::isKeyPressed(GLFW_KEY_D)) moveDir.x += 1.0f; entity->increaseRotation(0,1,0); - camera->move(moveDir, 0.02f); - renderer.renderFrame(*entity, *camera); + camera->move(moveDir, 0.5f); + renderer.renderFrame(*entity, *camera, *light); } diff --git a/src/engine/layer/GameLayer.h b/src/engine/layer/GameLayer.h index df16fb1..abaa49a 100644 --- a/src/engine/layer/GameLayer.h +++ b/src/engine/layer/GameLayer.h @@ -25,6 +25,7 @@ private: TexturedModel texturedModel; std::unique_ptr entity; std::unique_ptr camera; + std::unique_ptr light; Renderer renderer; }; diff --git a/src/engine/layer/entities/Light.cpp b/src/engine/layer/entities/Light.cpp new file mode 100644 index 0000000..401b948 --- /dev/null +++ b/src/engine/layer/entities/Light.cpp @@ -0,0 +1,5 @@ +// +// Created by sebastian on 07.02.26. +// + +#include "Light.h" diff --git a/src/engine/layer/entities/Light.h b/src/engine/layer/entities/Light.h new file mode 100644 index 0000000..0694a84 --- /dev/null +++ b/src/engine/layer/entities/Light.h @@ -0,0 +1,26 @@ +// +// Created by sebastian on 07.02.26. +// + +#ifndef LIGHT_H +#define LIGHT_H +#include "glm/vec3.hpp" + + +class Light { +private: + glm::vec3 position; + glm::vec3 color; + +public: + Light(glm::vec3 position, glm::vec3 color) : position(position), color(color) {}; + + [[nodiscard]] glm::vec3 getPosition() const {return position;} + [[nodiscard]] glm::vec3 getColor() const {return color;} + void setPosition(glm::vec3 position) {this->position = position;} + void setColor(glm::vec3 color) {this->color = color;} +}; + + + +#endif //LIGHT_H diff --git a/src/engine/renderer/Renderer.cpp b/src/engine/renderer/Renderer.cpp index 87bf48c..e860658 100644 --- a/src/engine/renderer/Renderer.cpp +++ b/src/engine/renderer/Renderer.cpp @@ -5,24 +5,28 @@ #include "Renderer.h" #include "../core/Application.h" +#include "../layer/entities/Light.h" #include "../toolbox/MathUtils.h" #include "glad/glad.h" #include "glm/ext/matrix_clip_space.hpp" #include "model/TexturedModel.h" -void Renderer::prepare(const Camera& camera) { + + +void Renderer::prepare(const Camera& camera, const Light& light) { glEnable(GL_DEPTH_TEST); glClearColor(1.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); const glm::mat4 viewMatrix = MathUtils::createViewMatrix(camera); staticShader.start(); + staticShader.loadLight(light.getPosition(), light.getColor()); staticShader.loadViewMatrix(viewMatrix); staticShader.stop(); } -void Renderer::renderFrame(const Entity &entity, const Camera& camera) { - prepare(camera); +void Renderer::renderFrame(const Entity &entity, const Camera& camera, const Light& light) { + prepare(camera, light); staticShader.start(); renderRawModel(entity); staticShader.stop(); @@ -34,6 +38,7 @@ void Renderer::renderRawModel(const Entity& entity) { glBindVertexArray(model->vaoID); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); + glEnableVertexAttribArray(2); glm::mat4 transformationMatrix = MathUtils::createTransformationMatrix(entity.getPosition(), entity.getRotX(), entity.getRotY(), entity.getRotZ(), entity.getScale()); staticShader.loadTransformationMatrix(transformationMatrix); @@ -43,6 +48,7 @@ void Renderer::renderRawModel(const Entity& entity) { glDrawElements(GL_TRIANGLES , model->vertexCount, GL_UNSIGNED_INT, 0); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); + glDisableVertexAttribArray(2); glBindVertexArray(0); } diff --git a/src/engine/renderer/Renderer.h b/src/engine/renderer/Renderer.h index 1c3b77a..849e338 100644 --- a/src/engine/renderer/Renderer.h +++ b/src/engine/renderer/Renderer.h @@ -10,6 +10,7 @@ #include "shaders/StaticShader.h" +class Light; class Camera; class Renderer { @@ -19,8 +20,8 @@ public: staticShader.loadProjectionMatrix(projectionMatrix); staticShader.stop(); }; - void prepare(const Camera& camera); - void renderFrame(const ::Entity &entity, const Camera& camera); + void prepare(const ::Camera &camera, const Light& light); + void renderFrame(const ::Entity &entity, const ::Camera &camera, const Light& light); private: void renderRawModel(const Entity &entity); StaticShader staticShader; diff --git a/src/engine/renderer/loader/Loader.cpp b/src/engine/renderer/loader/Loader.cpp index 620ff75..209d956 100644 --- a/src/engine/renderer/loader/Loader.cpp +++ b/src/engine/renderer/loader/Loader.cpp @@ -7,10 +7,11 @@ #include "Texture2D.h" #include "TextureLoader.h" -RawModel Loader::loadToVAO(const std::vector &vertices, const std::vector &textureCoords, const std::vector &indices) { +RawModel Loader::loadToVAO(const std::vector &vertices, const std::vector& normals, const std::vector &textureCoords, const std::vector &indices) { GLuint vaoID = createVAO(); storeDataInAttributeList(0, 3, vertices); storeDataInAttributeList(1, 2, textureCoords); + storeDataInAttributeList(2, 3, normals); bindIndicesBuffer(indices); unbindVAO(); return {vaoID, static_cast(indices.size())}; diff --git a/src/engine/renderer/loader/Loader.h b/src/engine/renderer/loader/Loader.h index e58a9a7..1a4ebf9 100644 --- a/src/engine/renderer/loader/Loader.h +++ b/src/engine/renderer/loader/Loader.h @@ -15,7 +15,8 @@ class Loader { public: - RawModel loadToVAO(const std::vector& vertices, const std::vector& textureCoords, const std::vector& indices); + RawModel loadToVAO(const std::vector &vertices, const std::vector &normals, const std::vector &textureCoords, const + std::vector &indices); ~Loader(); void cleanUp(); diff --git a/src/engine/renderer/loader/OBJLoader.cpp b/src/engine/renderer/loader/OBJLoader.cpp index 5fbbd13..cf9c606 100644 --- a/src/engine/renderer/loader/OBJLoader.cpp +++ b/src/engine/renderer/loader/OBJLoader.cpp @@ -5,6 +5,8 @@ #include "OBJLoader.h" #define TINYOBJLOADER_IMPLEMENTATION +#include + #include "tiny_obj_loader.h" std::shared_ptr OBJLoader::loadModel(const std::string &modelPath, const std::string& texturePath, Loader &loader) { @@ -21,6 +23,7 @@ std::shared_ptr OBJLoader::loadModel(const std::string &modelPath } std::vector vertices; + std::vector normals; std::vector uvs; std::vector indices; @@ -41,13 +44,17 @@ std::shared_ptr OBJLoader::loadModel(const std::string &modelPath uvs.push_back(0.0f); } + normals.push_back(attrib.normals[3*index.normal_index + 0]); + normals.push_back(attrib.normals[3*index.normal_index + 1]); + normals.push_back(attrib.normals[3*index.normal_index + 2]); + // Index indices.push_back(indexOffset); indexOffset++; } } - RawModel rawModel = loader.loadToVAO(vertices, uvs, indices); + RawModel rawModel = loader.loadToVAO(vertices, normals, uvs, indices); ModelTexture modelTexture = loader.loadTextureFromFile(texturePath); TexturedModel texturedModel = TexturedModel(std::make_shared(rawModel), std::make_shared(modelTexture)); return std::make_shared(texturedModel); diff --git a/src/engine/renderer/shaders/StaticShader.cpp b/src/engine/renderer/shaders/StaticShader.cpp index 5a45e57..11de371 100644 --- a/src/engine/renderer/shaders/StaticShader.cpp +++ b/src/engine/renderer/shaders/StaticShader.cpp @@ -21,15 +21,23 @@ void StaticShader::loadViewMatrix(glm::mat4 matrix) { loadMatrix(location_viewMatrix, matrix); } +void StaticShader::loadLight(glm::vec3 position, glm::vec3 color) { + loadVector(location_lightPosition, position); + loadVector(location_lightColor, color); +} + void StaticShader::bindAttributes() const { bindAttribute(0, "position"); bindAttribute(1, "textureCoords"); + bindAttribute(2, "normal"); } void StaticShader::getAllUniformLocations() { location_transformationMatrix = getUniformLocation("transformationMatrix"); location_projectionMatrix = getUniformLocation("projectionMatrix"); location_viewMatrix = getUniformLocation("viewMatrix"); + location_lightPosition = getUniformLocation("lightPosition"); + location_lightColor = getUniformLocation("lightColor"); } diff --git a/src/engine/renderer/shaders/StaticShader.h b/src/engine/renderer/shaders/StaticShader.h index e60351c..14afc4f 100644 --- a/src/engine/renderer/shaders/StaticShader.h +++ b/src/engine/renderer/shaders/StaticShader.h @@ -14,6 +14,7 @@ public: void loadTransformationMatrix(glm::mat4 matrix); void loadProjectionMatrix(glm::mat4 matrix); void loadViewMatrix(glm::mat4 matrix); + void loadLight(glm::vec3 position, glm::vec3 color); private: inline static const std::string VERTEX_FILE = "assets/shaders/vertexShader.glsl"; inline static const std::string FRAGMENT_FILE = "assets/shaders/fragmentShader.glsl"; @@ -21,6 +22,8 @@ private: int location_transformationMatrix; int location_projectionMatrix; int location_viewMatrix; + int location_lightPosition; + int location_lightColor; protected: void bindAttributes() const override;