Dicewars-Siedler/src/engine/renderer/MinimapRenderer.cpp
Sebastian Böckelmann a9b155ffc8
All checks were successful
Tests / test (push) Successful in 2m32s
UPD: Move PlayerID inside Engine
2026-04-20 10:36:12 +02:00

105 lines
3.5 KiB
C++

//
// Created by sebastian on 14.02.26.
//
#include "MinimapRenderer.h"
#include "../../game/GameMode.h"
#include "../../game/hexWorld/MapGenerator.h"
#include "../core/ECS/ModelComponent.h"
#include "../core/ECS/TransformComponent.h"
#include "../toolbox/MathUtils.h"
#include "glm/ext/matrix_clip_space.hpp"
#include "glm/ext/matrix_transform.hpp"
void MinimapRenderer::render(const std::vector<MinimapRenderData> &renderData, std::unordered_map<Engine::PlayerID, glm::vec3> colorMapping) {
minimapFBO->bind();
glViewport(0,0, width, height);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
prepareShader();
for (const MinimapRenderData& renderDatum : renderData) {
prepareInstance(renderDatum, colorMapping);
for (const auto& submodel : renderDatum.modelComponent->getActiveModel()->getSubModels()) {
glBindVertexArray(submodel.rawModel->vaoID);
glEnableVertexAttribArray(0);
glDrawElements(GL_TRIANGLES, submodel.rawModel->vertexCount, GL_UNSIGNED_INT, 0);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
}
}
finalizeShader();
minimapFBO->unbind();
glViewport(0,0, Application::getInstance().getWindow().GetWidth(), Application::getInstance().getWindow().GetHeight());
glEnable(GL_DEPTH_TEST);
}
GLuint MinimapRenderer::getMinimapTexture() {
return minimapFBO->getColorTexture();
}
void MinimapRenderer::prepareShader() {
minimapShader.start();
MapBounds bounds = MapGenerator::getMapBounds();
float mapWidth = bounds.maxX - bounds.minX;
float mapHeight = bounds.maxZ - bounds.minZ;
glm::vec3 mapCenter(
bounds.minX + mapWidth * 0.5f,
50.0f,
bounds.minZ + mapHeight * 0.5f
);
float fboAspect = static_cast<float>(width) / static_cast<float>(height);
float mapAspect = mapWidth / mapHeight;
float left, right, bottom, top;
float zoom = 1.2f; // >1 = weiter raus, <1 = näher ran
if (mapAspect > fboAspect) {
// Map breiter als FBO → FBO horizontal voll, vertikal Padding
float adjustedHeight = mapWidth / fboAspect;
left = -mapWidth * 0.5f * zoom;
right = mapWidth * 0.5f * zoom;
bottom = -adjustedHeight * 0.5f * zoom;
top = adjustedHeight * 0.5f * zoom;
} else {
// Map höher als FBO → FBO vertikal voll, horizontal Padding
float adjustedWidth = mapHeight * fboAspect;
left = -adjustedWidth * 0.5f * zoom;
right = adjustedWidth * 0.5f * zoom;
bottom = -mapHeight * 0.5f * zoom;
top = mapHeight * 0.5f * zoom;
}
glm::mat4 view = glm::lookAt(mapCenter + glm::vec3(0,50,0), mapCenter, glm::vec3(0,0,-1));
glm::mat4 proj = glm::ortho(left, right, bottom, top, -100.f, 100.f);
minimapShader.loadViewProjectionMatrix(proj * view);
}
void MinimapRenderer::finalizeShader() {
minimapShader.stop();
}
void MinimapRenderer::prepareInstance(const MinimapRenderData &data, const std::unordered_map<Engine::PlayerID, glm::vec3>& colorMapping) {
glm::mat4 model = MathUtils::createTransformationMatrix(data.transform->position, data.transform->rotation.x, data.transform->rotation.y, data.transform->rotation.z, data.transform->scale);
minimapShader.loadTransformationMatrix(model);
auto color = glm::vec3(0.5f);
if (data.owner) {
color = colorMapping.at(data.owner->playerID);
}
minimapShader.loadColor(color);
}