From 1923da23394d3359d6d3950871c4ee3e3f9ce68b Mon Sep 17 00:00:00 2001 From: sebastian Date: Tue, 4 Aug 2026 16:12:32 +0200 Subject: [PATCH] ADD: HighlightSystem --- CMakeLists.txt | 2 +- assets/shaders/basic.frag | 6 +++++ .../standardComponents}/HighlightComponent.h | 7 +++--- engine/src/renderer/DebugRenderer.cpp | 2 +- engine/src/renderer/MeshRenderSystem.cpp | 9 ++++++- engine/src/renderer/MeshRenderer.cpp | 4 ++-- engine/src/renderer/RenderQueue.h | 2 ++ engine/src/renderer/shader/StaticShader.h | 9 +++++++ .../ludo/ecs/highlight/HighlightSystem.cpp | 24 ++++++++++++++----- game/src/ludo/ecs/highlight/HighlightSystem.h | 1 + 10 files changed, 52 insertions(+), 14 deletions(-) rename {game/src/ludo/ecs/highlight => engine/src/ecs/standardComponents}/HighlightComponent.h (78%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 024d4a5..99112c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -169,6 +169,7 @@ add_library(Engine STATIC engine/src/loader/models/AABB.cpp engine/src/loader/models/AABB.h engine/src/loader/models/Ray.h + engine/src/ecs/standardComponents/HighlightComponent.h ) target_include_directories(Engine PUBLIC engine/src) target_link_libraries(Engine PUBLIC OpenGL::GL glfw glad glm::glm imgui spdlog::spdlog tinyobjloader stb_image) @@ -227,7 +228,6 @@ add_executable(ColorRace game/src/ludo/LudoAiController.h game/src/ludo/ecs/highlight/HighlightSystem.cpp game/src/ludo/ecs/highlight/HighlightSystem.h - game/src/ludo/ecs/highlight/HighlightComponent.h ) diff --git a/assets/shaders/basic.frag b/assets/shaders/basic.frag index 9091bef..415c258 100644 --- a/assets/shaders/basic.frag +++ b/assets/shaders/basic.frag @@ -12,6 +12,9 @@ uniform vec3 lightPosition; uniform vec3 lightColor; uniform vec3 cameraPosition; +uniform vec3 highlightColor; +uniform float highlightIntensity; + out vec4 fragColor; @@ -32,4 +35,7 @@ void main() { vec4 texColor = texture(diffuseSampler, pass_textureCoords); fragColor = vec4((ambient + diffuse + specular) * texColor.rgb, texColor.a * opacity); + float intensity = clamp(highlightIntensity, 0.0, 1.0); + + fragColor.rgb += highlightColor * intensity; } \ No newline at end of file diff --git a/game/src/ludo/ecs/highlight/HighlightComponent.h b/engine/src/ecs/standardComponents/HighlightComponent.h similarity index 78% rename from game/src/ludo/ecs/highlight/HighlightComponent.h rename to engine/src/ecs/standardComponents/HighlightComponent.h index 5298353..2700bc2 100644 --- a/game/src/ludo/ecs/highlight/HighlightComponent.h +++ b/engine/src/ecs/standardComponents/HighlightComponent.h @@ -4,12 +4,13 @@ #ifndef COLORRACE_HIGHLIGHTCOMPONENT_H #define COLORRACE_HIGHLIGHTCOMPONENT_H -#include "glm/vec3.hpp" +#include "glm/glm.hpp" -namespace ludo { +namespace engine { struct HighlightComponent { glm::vec3 highlightColor; + float intensity; }; - } + #endif //COLORRACE_HIGHLIGHTCOMPONENT_H diff --git a/engine/src/renderer/DebugRenderer.cpp b/engine/src/renderer/DebugRenderer.cpp index 472a165..2d6a18d 100644 --- a/engine/src/renderer/DebugRenderer.cpp +++ b/engine/src/renderer/DebugRenderer.cpp @@ -11,7 +11,7 @@ void engine::DebugRenderer::render(RenderQueue &queue, const Camera &camera) { m_shader->loadColor(debugColor); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - for (const auto&[mesh, transformationMatrix] : queue.getRenderCommands()) { + for (const auto&[mesh, transformationMatrix, highlightColor, highlightIntensity] : queue.getRenderCommands()) { m_shader->loadTransformationMatrix(transformationMatrix); mesh->bind(); mesh->draw(); diff --git a/engine/src/renderer/MeshRenderSystem.cpp b/engine/src/renderer/MeshRenderSystem.cpp index e010f3d..1748679 100644 --- a/engine/src/renderer/MeshRenderSystem.cpp +++ b/engine/src/renderer/MeshRenderSystem.cpp @@ -4,6 +4,7 @@ #include "MeshRenderSystem.h" +#include "ecs/standardComponents/HighlightComponent.h" #include "ecs/standardComponents/MeshComponent.h" #include "ecs/standardComponents/TransformComponent.h" @@ -20,7 +21,13 @@ void engine::MeshRenderSystem::update(engine::EntityRegistry ®istry, engine:: auto& transform = transforms.get(entity); - renderQueue.submit(engine::RenderCommand(mesh.model, transform.computeModelMatrix())); + RenderCommand renderCommand(mesh.model, transform.computeModelMatrix()); + if (registry.hasComponent(entity)) { + auto hightlightComponent = registry.getComponent(entity); + renderCommand.tintColor = hightlightComponent.highlightColor; + renderCommand.tintIntensity = hightlightComponent.intensity; + } + renderQueue.submit(renderCommand); } diff --git a/engine/src/renderer/MeshRenderer.cpp b/engine/src/renderer/MeshRenderer.cpp index 973d9ff..e8f19db 100644 --- a/engine/src/renderer/MeshRenderer.cpp +++ b/engine/src/renderer/MeshRenderer.cpp @@ -13,9 +13,9 @@ void engine::MeshRenderer::render(RenderQueue &queue, const Camera &camera, cons m_shader->loadCameraPosition(camera.getPosition()); m_shader->loadLight(light.position, light.color); - for (const auto&[mesh, transformationMatrix] : queue.getRenderCommands()) { + for (const auto&[mesh, transformationMatrix, tintColor, tintIntensity] : queue.getRenderCommands()) { m_shader->loadTransformationMatrix(transformationMatrix); - + m_shader->loadHighlightEffect(tintColor, tintIntensity); mesh->bind(); if (mesh->hasSections()) { for (const auto& section : mesh->getSections()) { diff --git a/engine/src/renderer/RenderQueue.h b/engine/src/renderer/RenderQueue.h index d6a84eb..5891608 100644 --- a/engine/src/renderer/RenderQueue.h +++ b/engine/src/renderer/RenderQueue.h @@ -16,6 +16,8 @@ namespace engine { struct RenderCommand { std::shared_ptr mesh; glm::mat4 transformationMatrix; + glm::vec3 tintColor{0.0}; + float tintIntensity{0.f}; }; class RenderQueue { diff --git a/engine/src/renderer/shader/StaticShader.h b/engine/src/renderer/shader/StaticShader.h index cd3dcb6..44d548c 100644 --- a/engine/src/renderer/shader/StaticShader.h +++ b/engine/src/renderer/shader/StaticShader.h @@ -24,6 +24,8 @@ namespace engine { std::ref(lightColor), std::ref(cameraPosition), std::ref(shininess), + std::ref(highlightColor), + std::ref(highlightIntensity) }); }; @@ -44,6 +46,11 @@ namespace engine { //opacity.load(material.getOpacity()); } + void loadHighlightEffect(glm::vec3 color, float intensity) { + highlightIntensity.load(intensity); + highlightColor.load(color); + } + void loadLight(const glm::vec3& position, const glm::vec3& color) { lightPosition.load(position); lightColor.load(color); @@ -61,6 +68,8 @@ namespace engine { engine::UniformValue lightPosition{"lightPosition"}; engine::UniformValue lightColor{"lightColor"}; engine::UniformValue cameraPosition{"cameraPosition"}; + engine::UniformValue highlightColor{"highlightColor"}; + engine::UniformValue highlightIntensity{"highlightIntensity"}; }; } diff --git a/game/src/ludo/ecs/highlight/HighlightSystem.cpp b/game/src/ludo/ecs/highlight/HighlightSystem.cpp index 1106e45..67df770 100644 --- a/game/src/ludo/ecs/highlight/HighlightSystem.cpp +++ b/game/src/ludo/ecs/highlight/HighlightSystem.cpp @@ -4,7 +4,8 @@ #include "HighlightSystem.h" -#include "HighlightComponent.h" + +#include "ecs/standardComponents/HighlightComponent.h" #include "ecs/systems/PickingSystem.h" void ludo::HighlightSystem::update(const engine::Mouse& mouse, engine::EntityRegistry ®istry) { @@ -12,15 +13,26 @@ void ludo::HighlightSystem::update(const engine::Mouse& mouse, engine::EntityReg float closestT = std::numeric_limits::max(); std::optional hit; + for (const auto& entity : m_highlightedEntities) { + registry.removeComponent(entity); + } + m_highlightedEntities.clear(); + for (const auto& [entity, pickable] : registry.getPool()) { const auto transform = registry.getComponent(entity); - // if (float t; engine::PickingSystem::raySphereIntersect(origin, dir, transform.m_position, pickable.radius, t) && t < closestT) { - // closestT = t; - // hit = entity; - // } + const auto mesh = registry.getComponent(entity); + + engine::AABB transformedAABB = mesh.model->getAABB().transformed(transform.computeModelMatrix()); + engine::Ray ray = engine::Ray(origin, dir); + std::optional ray_hit = transformedAABB.intersects(engine::Ray(origin, dir), closestT); + if (transformedAABB.intersects(ray, closestT).has_value()) { + closestT = ray_hit.value().distance; + hit = entity; + } } if (hit.has_value()) { - registry.addComponent(hit.value(), HighlightComponent({1.0, 1.0f, 1.0})); + registry.addComponent(hit.value(), engine::HighlightComponent({1.0, 1.0f, 1.0}, 0.4f)); + m_highlightedEntities.push_back(hit.value()); } } diff --git a/game/src/ludo/ecs/highlight/HighlightSystem.h b/game/src/ludo/ecs/highlight/HighlightSystem.h index 21989fa..eb4ac70 100644 --- a/game/src/ludo/ecs/highlight/HighlightSystem.h +++ b/game/src/ludo/ecs/highlight/HighlightSystem.h @@ -16,6 +16,7 @@ namespace ludo { void update(const engine::Mouse& mouse, engine::EntityRegistry& registry); private: engine::Camera& m_camera; + std::vector m_highlightedEntities; }; }