ADD: Highlight hovered Tiles

This commit is contained in:
sebastian 2026-02-08 10:10:38 +01:00
parent 29511deef7
commit 3cc8d6e0b1
13 changed files with 177 additions and 12 deletions

View File

@ -69,6 +69,8 @@ add_executable(Dicewars_Siedler src/main.cpp
src/engine/renderer/MasterRenderer.h src/engine/renderer/MasterRenderer.h
src/engine/renderer/TerrainRenderer.cpp src/engine/renderer/TerrainRenderer.cpp
src/engine/renderer/TerrainRenderer.h src/engine/renderer/TerrainRenderer.h
src/engine/renderer/shaders/TerrainShader.cpp
src/engine/renderer/shaders/TerrainShader.h
) )
target_include_directories(Dicewars_Siedler PRIVATE target_include_directories(Dicewars_Siedler PRIVATE

View File

@ -0,0 +1,28 @@
#version 400 core
in vec2 pass_textureCoords;
in vec3 surfaceNormal;
in vec3 toLightVector;
out vec4 outColor;
uniform sampler2D textureSampler;
uniform vec3 lightColor;
uniform bool isHighlighted;
void main(void) {
vec3 unitNormal = normalize(surfaceNormal);
vec3 unitToLightDir = normalize(toLightVector);
float cosTheta = dot(unitNormal, unitToLightDir);
float brightness = max(cosTheta, 0.2);
vec3 diffuse = brightness * lightColor;
if(isHighlighted) {
outColor = vec4(1.0f, 1.0f, 0.0f, 1.0f);
} else {
outColor = vec4(diffuse, 1.0f) * texture(textureSampler, pass_textureCoords);
}
}

View File

@ -0,0 +1,23 @@
#version 400 core
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() {
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;
}

View File

@ -26,7 +26,7 @@ glm::vec3 MousePicker::calculateMouseRay() {
glm::vec2 MousePicker::getNormalizedDeviceCoords(float mouseX, float mouseY) { glm::vec2 MousePicker::getNormalizedDeviceCoords(float mouseX, float mouseY) {
float x = (2.f * mouseX) / static_cast<float>(Application::getInstance().getWindow().GetWidth()) - 1.f; float x = (2.f * mouseX) / static_cast<float>(Application::getInstance().getWindow().GetWidth()) - 1.f;
float y = (2.f * mouseY) / static_cast<float>(Application::getInstance().getWindow().GetHeight()) - 1.f; float y = 1.f - (2.f * mouseY) / static_cast<float>(Application::getInstance().getWindow().GetHeight());
return {x, y}; return {x, y};
} }

View File

@ -8,9 +8,9 @@
void TerrainRenderer::prepare(const Camera &camera, const Light &light) { void TerrainRenderer::prepare(const Camera &camera, const Light &light) {
const glm::mat4 viewMatrix = MathUtils::createViewMatrix(camera); const glm::mat4 viewMatrix = MathUtils::createViewMatrix(camera);
staticShader.start(); terrainShader.start();
staticShader.loadLight(light.getPosition(), light.getColor()); terrainShader.loadLight(light.getPosition(), light.getColor());
staticShader.loadViewMatrix(viewMatrix); terrainShader.loadViewMatrix(viewMatrix);
} }
void TerrainRenderer::renderTerrainTiles(const std::unordered_map<TexturedModel *, std::vector<HexRenderData *>> &terrainTiles) { void TerrainRenderer::renderTerrainTiles(const std::unordered_map<TexturedModel *, std::vector<HexRenderData *>> &terrainTiles) {
@ -26,7 +26,7 @@ void TerrainRenderer::renderTerrainTiles(const std::unordered_map<TexturedModel
} }
void TerrainRenderer::finalizeFrame() { void TerrainRenderer::finalizeFrame() {
staticShader.stop(); terrainShader.stop();
} }
void TerrainRenderer::prepareTexturedModel(const TexturedModel &texturedModel) { void TerrainRenderer::prepareTexturedModel(const TexturedModel &texturedModel) {
@ -49,5 +49,7 @@ void TerrainRenderer::unbindTexturedModel() {
void TerrainRenderer::prepareInstance(const HexRenderData &hexTile) { void TerrainRenderer::prepareInstance(const HexRenderData &hexTile) {
glm::mat4 transformationMatrix = MathUtils::createTransformationMatrix(hexTile.position, 0,0,0,1); glm::mat4 transformationMatrix = MathUtils::createTransformationMatrix(hexTile.position, 0,0,0,1);
staticShader.loadTransformationMatrix(transformationMatrix); terrainShader.loadTransformationMatrix(transformationMatrix);
terrainShader.loadIsHighlighted(hexTile.highlight);
} }

View File

@ -10,21 +10,22 @@
#include "../layer/entities/Camera.h" #include "../layer/entities/Camera.h"
#include "../layer/entities/Light.h" #include "../layer/entities/Light.h"
#include "shaders/TerrainShader.h"
class TerrainRenderer { class TerrainRenderer {
public: public:
explicit TerrainRenderer(const glm::mat4 &projectionMatrix) { explicit TerrainRenderer(const glm::mat4 &projectionMatrix) {
staticShader.start(); terrainShader.start();
staticShader.loadProjectionMatrix(projectionMatrix); terrainShader.loadProjectionMatrix(projectionMatrix);
staticShader.stop(); terrainShader.stop();
} }
void prepare(const Camera &camera, const Light &light); void prepare(const Camera &camera, const Light &light);
void renderTerrainTiles(const std::unordered_map<TexturedModel*, std::vector<HexRenderData*>>& terrainTiles); void renderTerrainTiles(const std::unordered_map<TexturedModel*, std::vector<HexRenderData*>>& terrainTiles);
void finalizeFrame(); void finalizeFrame();
private: private:
StaticShader staticShader; TerrainShader terrainShader;
void prepareTexturedModel(const TexturedModel &texturedModel); void prepareTexturedModel(const TexturedModel &texturedModel);
void unbindTexturedModel(); void unbindTexturedModel();

View File

@ -57,7 +57,7 @@ void ShaderProgram::loadVector(const int location, const glm::vec3 vector) {
} }
void ShaderProgram::loadBoolean(int location, bool value) { void ShaderProgram::loadBoolean(int location, bool value) {
glUniform1f(location, value ? 1.f: 0.f); glUniform1i(location, value ? 1: 0);
} }
void ShaderProgram::loadMatrix(int location, glm::mat4 matrix) { void ShaderProgram::loadMatrix(int location, glm::mat4 matrix) {

View File

@ -0,0 +1,50 @@
//
// Created by sebastian on 08.02.26.
//
#include "TerrainShader.h"
TerrainShader::TerrainShader(): ShaderProgram(VERTEX_FILE, FRAGMENT_FILE) {
TerrainShader::bindAttributes();
TerrainShader::getAllUniformLocations();
}
void TerrainShader::loadTransformationMatrix(glm::mat4 matrix) {
loadMatrix(location_transformationMatrix, matrix);
}
void TerrainShader::loadProjectionMatrix(glm::mat4 matrix) {
loadMatrix(location_projectionMatrix, matrix);
}
void TerrainShader::loadViewMatrix(glm::mat4 matrix) {
loadMatrix(location_viewMatrix, matrix);
}
void TerrainShader::loadLight(glm::vec3 position, glm::vec3 color) {
loadVector(location_lightPosition, position);
loadVector(location_lightColor, color);
}
void TerrainShader::loadIsHighlighted(bool isHighlighted) {
loadBoolean(location_isHighlighted, isHighlighted);
}
void TerrainShader::bindAttributes() const {
bindAttribute(0, "position");
bindAttribute(1, "textureCoords");
bindAttribute(2, "normal");
}
void TerrainShader::getAllUniformLocations() {
location_transformationMatrix = getUniformLocation("transformationMatrix");
location_projectionMatrix = getUniformLocation("projectionMatrix");
location_viewMatrix = getUniformLocation("viewMatrix");
location_lightPosition = getUniformLocation("lightPosition");
location_lightColor = getUniformLocation("lightColor");
location_isHighlighted = getUniformLocation("isHighlighted");
}

View File

@ -0,0 +1,37 @@
//
// Created by sebastian on 08.02.26.
//
#ifndef TERRAINSHADER_H
#define TERRAINSHADER_H
#include "ShaderProgram.h"
class TerrainShader : public ShaderProgram {
public:
TerrainShader();
void loadTransformationMatrix(glm::mat4 matrix);
void loadProjectionMatrix(glm::mat4 matrix);
void loadViewMatrix(glm::mat4 matrix);
void loadLight(glm::vec3 position, glm::vec3 color);
void loadIsHighlighted(bool isHighlighted);
private:
inline static const std::string VERTEX_FILE = "assets/shaders/terrainVertexShader.glsl";
inline static const std::string FRAGMENT_FILE = "assets/shaders/terrainFragmentShader.glsl";
int location_transformationMatrix;
int location_projectionMatrix;
int location_viewMatrix;
int location_lightPosition;
int location_lightColor;
int location_isHighlighted;
protected:
void bindAttributes() const override;
void getAllUniformLocations() override;
};
#endif //TERRAINSHADER_H

View File

@ -54,6 +54,13 @@ void GameLayer::onUpdate()
camera->move(moveDir, 0.5f); camera->move(moveDir, 0.5f);
renderer->submitEntity(entity.get()); renderer->submitEntity(entity.get());
for (HexTile& tile : map->tiles) {
glm::vec3 intersectionPoint;
bool highlight = tile.intersect(camera->getPosition(), mousePicker->getCurrentRay(), intersectionPoint);
tile.isHighlighted = highlight;
}
std::vector<HexRenderData> terrainRenderData = map->getTerrainRenderData(hexModel); std::vector<HexRenderData> terrainRenderData = map->getTerrainRenderData(hexModel);

View File

@ -7,13 +7,27 @@
#include <memory> #include <memory>
#include "../../engine/renderer/model/TexturedModel.h" #include "../../engine/renderer/model/TexturedModel.h"
#include "glm/vec2.hpp"
#include "glm/vec3.hpp" #include "glm/vec3.hpp"
#include "glm/ext/quaternion_geometric.hpp"
struct HexTile { struct HexTile {
glm::vec3 worldPos; glm::vec3 worldPos;
int q, r; //Axiale Koordinaten (hex-Koordinaten) int q, r; //Axiale Koordinaten (hex-Koordinaten)
int ownerID = -1; int ownerID = -1;
//Later: ResourceType //Later: ResourceType
float radius;
bool isHighlighted = false;
bool intersect(const glm::vec3& rayOrigin, const glm::vec3& rayDirection, glm::vec3& intersectionPoint) const {
float t = -rayOrigin.y / rayDirection.y;
if (t < 0) return false; // Ray zeigt nach oben, nicht getroffen
intersectionPoint = rayOrigin + t * rayDirection;
glm::vec2 diff(intersectionPoint.x - worldPos.x, intersectionPoint.z - worldPos.z);
return glm::length(diff) <= radius -0.1f;
}
}; };
struct HexRenderData { struct HexRenderData {

View File

@ -8,7 +8,7 @@ std::vector<HexRenderData> Map::getTerrainRenderData(const std::shared_ptr<Textu
std::vector<HexRenderData> renderData; std::vector<HexRenderData> renderData;
renderData.reserve(tiles.size()); renderData.reserve(tiles.size());
for (auto& tile : tiles) { for (auto& tile : tiles) {
HexRenderData data = HexRenderData(hexModel, tile.worldPos, false); HexRenderData data = HexRenderData(hexModel, tile.worldPos, tile.isHighlighted);
renderData.push_back(data); renderData.push_back(data);
} }
return renderData; return renderData;

View File

@ -27,6 +27,7 @@ public:
float x = xOffset * (q + 0.5f * (r % 2)); float x = xOffset * (q + 0.5f * (r % 2));
float z = zOffset * r; float z = zOffset * r;
tile.worldPos = glm::vec3(x, 0.0f, z); tile.worldPos = glm::vec3(x, 0.0f, z);
tile.radius = hexRadius;
map.tiles.push_back(tile); map.tiles.push_back(tile);
} }