ADD: HighlightSystem

This commit is contained in:
sebastian 2026-08-04 16:12:32 +02:00
parent f6096e2889
commit 1923da2339
10 changed files with 52 additions and 14 deletions

View File

@ -169,6 +169,7 @@ add_library(Engine STATIC
engine/src/loader/models/AABB.cpp engine/src/loader/models/AABB.cpp
engine/src/loader/models/AABB.h engine/src/loader/models/AABB.h
engine/src/loader/models/Ray.h engine/src/loader/models/Ray.h
engine/src/ecs/standardComponents/HighlightComponent.h
) )
target_include_directories(Engine PUBLIC engine/src) target_include_directories(Engine PUBLIC engine/src)
target_link_libraries(Engine PUBLIC OpenGL::GL glfw glad glm::glm imgui spdlog::spdlog tinyobjloader stb_image) 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/LudoAiController.h
game/src/ludo/ecs/highlight/HighlightSystem.cpp game/src/ludo/ecs/highlight/HighlightSystem.cpp
game/src/ludo/ecs/highlight/HighlightSystem.h game/src/ludo/ecs/highlight/HighlightSystem.h
game/src/ludo/ecs/highlight/HighlightComponent.h
) )

View File

@ -12,6 +12,9 @@ uniform vec3 lightPosition;
uniform vec3 lightColor; uniform vec3 lightColor;
uniform vec3 cameraPosition; uniform vec3 cameraPosition;
uniform vec3 highlightColor;
uniform float highlightIntensity;
out vec4 fragColor; out vec4 fragColor;
@ -32,4 +35,7 @@ void main() {
vec4 texColor = texture(diffuseSampler, pass_textureCoords); vec4 texColor = texture(diffuseSampler, pass_textureCoords);
fragColor = vec4((ambient + diffuse + specular) * texColor.rgb, texColor.a * opacity); fragColor = vec4((ambient + diffuse + specular) * texColor.rgb, texColor.a * opacity);
float intensity = clamp(highlightIntensity, 0.0, 1.0);
fragColor.rgb += highlightColor * intensity;
} }

View File

@ -4,12 +4,13 @@
#ifndef COLORRACE_HIGHLIGHTCOMPONENT_H #ifndef COLORRACE_HIGHLIGHTCOMPONENT_H
#define COLORRACE_HIGHLIGHTCOMPONENT_H #define COLORRACE_HIGHLIGHTCOMPONENT_H
#include "glm/vec3.hpp" #include "glm/glm.hpp"
namespace ludo { namespace engine {
struct HighlightComponent { struct HighlightComponent {
glm::vec3 highlightColor; glm::vec3 highlightColor;
float intensity;
}; };
} }
#endif //COLORRACE_HIGHLIGHTCOMPONENT_H #endif //COLORRACE_HIGHLIGHTCOMPONENT_H

View File

@ -11,7 +11,7 @@ void engine::DebugRenderer::render(RenderQueue &queue, const Camera &camera) {
m_shader->loadColor(debugColor); m_shader->loadColor(debugColor);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 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); m_shader->loadTransformationMatrix(transformationMatrix);
mesh->bind(); mesh->bind();
mesh->draw(); mesh->draw();

View File

@ -4,6 +4,7 @@
#include "MeshRenderSystem.h" #include "MeshRenderSystem.h"
#include "ecs/standardComponents/HighlightComponent.h"
#include "ecs/standardComponents/MeshComponent.h" #include "ecs/standardComponents/MeshComponent.h"
#include "ecs/standardComponents/TransformComponent.h" #include "ecs/standardComponents/TransformComponent.h"
@ -20,7 +21,13 @@ void engine::MeshRenderSystem::update(engine::EntityRegistry &registry, engine::
auto& transform = transforms.get(entity); auto& transform = transforms.get(entity);
renderQueue.submit(engine::RenderCommand(mesh.model, transform.computeModelMatrix())); RenderCommand renderCommand(mesh.model, transform.computeModelMatrix());
if (registry.hasComponent<HighlightComponent>(entity)) {
auto hightlightComponent = registry.getComponent<HighlightComponent>(entity);
renderCommand.tintColor = hightlightComponent.highlightColor;
renderCommand.tintIntensity = hightlightComponent.intensity;
}
renderQueue.submit(renderCommand);
} }

View File

@ -13,9 +13,9 @@ void engine::MeshRenderer::render(RenderQueue &queue, const Camera &camera, cons
m_shader->loadCameraPosition(camera.getPosition()); m_shader->loadCameraPosition(camera.getPosition());
m_shader->loadLight(light.position, light.color); 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->loadTransformationMatrix(transformationMatrix);
m_shader->loadHighlightEffect(tintColor, tintIntensity);
mesh->bind(); mesh->bind();
if (mesh->hasSections()) { if (mesh->hasSections()) {
for (const auto& section : mesh->getSections()) { for (const auto& section : mesh->getSections()) {

View File

@ -16,6 +16,8 @@ namespace engine {
struct RenderCommand { struct RenderCommand {
std::shared_ptr<engine::Model> mesh; std::shared_ptr<engine::Model> mesh;
glm::mat4 transformationMatrix; glm::mat4 transformationMatrix;
glm::vec3 tintColor{0.0};
float tintIntensity{0.f};
}; };
class RenderQueue { class RenderQueue {

View File

@ -24,6 +24,8 @@ namespace engine {
std::ref(lightColor), std::ref(lightColor),
std::ref(cameraPosition), std::ref(cameraPosition),
std::ref(shininess), std::ref(shininess),
std::ref(highlightColor),
std::ref(highlightIntensity)
}); });
}; };
@ -44,6 +46,11 @@ namespace engine {
//opacity.load(material.getOpacity()); //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) { void loadLight(const glm::vec3& position, const glm::vec3& color) {
lightPosition.load(position); lightPosition.load(position);
lightColor.load(color); lightColor.load(color);
@ -61,6 +68,8 @@ namespace engine {
engine::UniformValue<glm::vec3> lightPosition{"lightPosition"}; engine::UniformValue<glm::vec3> lightPosition{"lightPosition"};
engine::UniformValue<glm::vec3> lightColor{"lightColor"}; engine::UniformValue<glm::vec3> lightColor{"lightColor"};
engine::UniformValue<glm::vec3> cameraPosition{"cameraPosition"}; engine::UniformValue<glm::vec3> cameraPosition{"cameraPosition"};
engine::UniformValue<glm::vec3> highlightColor{"highlightColor"};
engine::UniformValue<float> highlightIntensity{"highlightIntensity"};
}; };
} }

View File

@ -4,7 +4,8 @@
#include "HighlightSystem.h" #include "HighlightSystem.h"
#include "HighlightComponent.h"
#include "ecs/standardComponents/HighlightComponent.h"
#include "ecs/systems/PickingSystem.h" #include "ecs/systems/PickingSystem.h"
void ludo::HighlightSystem::update(const engine::Mouse& mouse, engine::EntityRegistry &registry) { void ludo::HighlightSystem::update(const engine::Mouse& mouse, engine::EntityRegistry &registry) {
@ -12,15 +13,26 @@ void ludo::HighlightSystem::update(const engine::Mouse& mouse, engine::EntityReg
float closestT = std::numeric_limits<float>::max(); float closestT = std::numeric_limits<float>::max();
std::optional<engine::Entity> hit; std::optional<engine::Entity> hit;
for (const auto& entity : m_highlightedEntities) {
registry.removeComponent<engine::HighlightComponent>(entity);
}
m_highlightedEntities.clear();
for (const auto& [entity, pickable] : registry.getPool<engine::PickableComponent>()) { for (const auto& [entity, pickable] : registry.getPool<engine::PickableComponent>()) {
const auto transform = registry.getComponent<engine::TransformComponent>(entity); const auto transform = registry.getComponent<engine::TransformComponent>(entity);
// if (float t; engine::PickingSystem::raySphereIntersect(origin, dir, transform.m_position, pickable.radius, t) && t < closestT) { const auto mesh = registry.getComponent<engine::MeshComponent>(entity);
// closestT = t;
// hit = entity; engine::AABB transformedAABB = mesh.model->getAABB().transformed(transform.computeModelMatrix());
// } engine::Ray ray = engine::Ray(origin, dir);
std::optional<engine::RayHit> 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()) { if (hit.has_value()) {
registry.addComponent<HighlightComponent>(hit.value(), HighlightComponent({1.0, 1.0f, 1.0})); registry.addComponent<engine::HighlightComponent>(hit.value(), engine::HighlightComponent({1.0, 1.0f, 1.0}, 0.4f));
m_highlightedEntities.push_back(hit.value());
} }
} }

View File

@ -16,6 +16,7 @@ namespace ludo {
void update(const engine::Mouse& mouse, engine::EntityRegistry& registry); void update(const engine::Mouse& mouse, engine::EntityRegistry& registry);
private: private:
engine::Camera& m_camera; engine::Camera& m_camera;
std::vector<engine::Entity> m_highlightedEntities;
}; };
} }