ADD: Dimming Text
All checks were successful
Tests / test (push) Successful in 2m38s

This commit is contained in:
Sebastian Böckelmann 2026-04-25 10:51:48 +02:00
parent 5923f53ce4
commit 8d6a314a3c
27 changed files with 186 additions and 34 deletions

View File

@ -326,6 +326,12 @@ if(BUILD_GAME)
src/game/scenes/main/MainUiLayer.cpp src/game/scenes/main/MainUiLayer.cpp
src/game/scenes/main/MainUiLayer.h src/game/scenes/main/MainUiLayer.h
src/game/scenes/main/events/QuitEvent.h src/game/scenes/main/events/QuitEvent.h
src/engine/core/gui/uiMain/UiStack.cpp
src/engine/core/gui/uiMain/UiStack.h
src/engine/core/EngineContext.cpp
src/engine/core/EngineContext.h
src/engine/core/gui/uiMain/UiConfig.h
src/engine/renderer/RenderContext.h
) )
target_compile_options(Dicewars_Siedler PRIVATE target_compile_options(Dicewars_Siedler PRIVATE
-Wall -Wall

View File

@ -6,8 +6,10 @@ out vec4 outColor;
uniform sampler2D text; uniform sampler2D text;
uniform vec3 textColor; uniform vec3 textColor;
uniform float dimFactor;
void main() { void main() {
float alpha = texture(text, pass_texCoords).r; float alpha = texture(text, pass_texCoords).r;
outColor = vec4(textColor, alpha); outColor = vec4(textColor, alpha);
outColor *= dimFactor;
} }

View File

@ -24,7 +24,8 @@ void Application::updateTime() {
Application::Application() Application::Application()
{ {
instance = this; instance = this;
sceneManager = std::make_unique<SceneManager>(); context = std::make_unique<EngineContext>();
sceneManager = std::make_unique<SceneManager>(*context.get());
WindowProps window_props = WindowProps(); WindowProps window_props = WindowProps();
window_props.Width = 1280; window_props.Width = 1280;

View File

@ -7,6 +7,7 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "EngineContext.h"
#include "Window.h" #include "Window.h"
#include "events/EventBus.h" #include "events/EventBus.h"
#include "inputsOutputs/inputs/Keyboard.h" #include "inputsOutputs/inputs/Keyboard.h"
@ -34,6 +35,7 @@ public:
std::unique_ptr<StateManager> stateManager; std::unique_ptr<StateManager> stateManager;
std::shared_ptr<GameState> gameState; std::shared_ptr<GameState> gameState;
std::unique_ptr<SceneManager> sceneManager; std::unique_ptr<SceneManager> sceneManager;
std::unique_ptr<EngineContext> context;
private: private:
bool running = true; bool running = true;
std::unique_ptr<Window> window; std::unique_ptr<Window> window;

View File

@ -0,0 +1,5 @@
//
// Created by sebastian on 25.04.26.
//
#include "EngineContext.h"

View File

@ -0,0 +1,18 @@
//
// Created by sebastian on 25.04.26.
//
#ifndef ENGINECONTEXT_H
#define ENGINECONTEXT_H
#include "gui/uiMain/UiConfig.h"
class EngineContext {
public:
UiConfig uiConfig = UiConfig();
};
#endif //ENGINECONTEXT_H

View File

@ -0,0 +1,19 @@
//
// Created by sebastian on 25.04.26.
//
#ifndef UICONFIG_H
#define UICONFIG_H
#include "json.hpp"
struct UiConfig {
float backgroundDim = 0.6f;
static UiConfig fromJson(const nlohmann::json & j) {
UiConfig cfg;
cfg.backgroundDim = j.at("backgroundDim").get<float>();
return cfg;
}
};
#endif //UICONFIG_H

View File

@ -24,6 +24,7 @@ void UiContainer::onUpdate(float x) {
} }
void UiContainer::onCollectRenderData(UiRenderBundle& renderBundle) { void UiContainer::onCollectRenderData(UiRenderBundle& renderBundle) {
if (backgroundTextureID.has_value()) { if (backgroundTextureID.has_value()) {
GUITextureBuilder builder = GUITextureBuilder(); GUITextureBuilder builder = GUITextureBuilder();
builder.Foreground(backgroundTextureID.value()); builder.Foreground(backgroundTextureID.value());

View File

@ -0,0 +1,25 @@
//
// Created by sebastian on 25.04.26.
//
#include "UiStack.h"
void UiStack::push(std::unique_ptr<UiContainer> panel) {
panels.push_back(std::move(panel));
}
void UiStack::pop() {
panels.pop_back();
}
UiContainer * UiStack::top() {
return panels.empty() ? nullptr : panels.back().get();
}
const std::vector<std::unique_ptr<UiContainer>> & UiStack::getPanels() const {
return panels;
}
bool UiStack::isTop(const UiContainer *panel) const {
return !panels.empty() && panels.back().get() == panel;
}

View File

@ -0,0 +1,26 @@
//
// Created by sebastian on 25.04.26.
//
#ifndef UISTACK_H
#define UISTACK_H
#include <memory>
#include "UiContainer.h"
class UiStack {
public:
void push(std::unique_ptr<UiContainer> panel);
void pop();
UiContainer* top();
const std::vector<std::unique_ptr<UiContainer>>& getPanels() const;
bool isTop(const UiContainer* panel) const;
private:
std::vector<std::unique_ptr<UiContainer>> panels;
};
#endif //UISTACK_H

View File

@ -14,7 +14,7 @@
class Scene { class Scene {
public: public:
virtual ~Scene() = default; virtual ~Scene() = default;
virtual void onEnter() {} //Layer registrieren virtual void onEnter(EngineContext& ctx) {} //Layer registrieren
virtual void onExit() { virtual void onExit() {
for (const auto& layer : layers) { for (const auto& layer : layers) {
layer->onDetach(); layer->onDetach();

View File

@ -4,7 +4,6 @@
#include "SceneManager.h" #include "SceneManager.h"
#include "Scene.h"
#include "spdlog/spdlog.h" #include "spdlog/spdlog.h"
void SceneManager::switchTo(std::unique_ptr<Scene> next, std::function<void()> onLoaded) { void SceneManager::switchTo(std::unique_ptr<Scene> next, std::function<void()> onLoaded) {
@ -29,7 +28,7 @@ void SceneManager::update() {
} }
currentScene = std::move(nextScene); currentScene = std::move(nextScene);
nextScene = nullptr; nextScene = nullptr;
currentScene->onEnter(); currentScene->onEnter(ctx);
assetLoader.stop(); assetLoader.stop();
if (onSceneLoaded) { if (onSceneLoaded) {

View File

@ -6,11 +6,13 @@
#define SCENEMANAGER_H #define SCENEMANAGER_H
#include <memory> #include <memory>
#include "../../renderer/loader/async/AssetLoader.h"" #include "../../renderer/loader/async/AssetLoader.h"
class Scene; #include "../EngineContext.h"
#include "Scene.h"
class SceneManager { class SceneManager {
public: public:
explicit SceneManager(EngineContext& ctx) : ctx(ctx) {}
void switchTo(std::unique_ptr<Scene> next, std::function<void()> onLoaded = nullptr); void switchTo(std::unique_ptr<Scene> next, std::function<void()> onLoaded = nullptr);
void update(); void update();
void render(); void render();
@ -20,6 +22,7 @@ public:
private: private:
std::unique_ptr<Scene> currentScene; std::unique_ptr<Scene> currentScene;
std::unique_ptr<Scene> nextScene; std::unique_ptr<Scene> nextScene;
EngineContext& ctx;
AssetLoader assetLoader; AssetLoader assetLoader;

View File

@ -14,7 +14,7 @@ std::vector<AssetRequest> SplashScreen::getRequiredAssets() {
return requests; return requests;
} }
void SplashScreen::onEnter() { void SplashScreen::onEnter(EngineContext& ctx) {
addLayer(std::make_unique<SplashScreenLayer>()); addLayer(std::make_unique<SplashScreenLayer>());
} }

View File

@ -10,7 +10,7 @@
class SplashScreen : public Scene { class SplashScreen : public Scene {
public: public:
std::vector<AssetRequest> getRequiredAssets() override; std::vector<AssetRequest> getRequiredAssets() override;
void onEnter() override; void onEnter(EngineContext& ctx) override;
void onExit() override; void onExit() override;
}; };

View File

@ -12,7 +12,7 @@
#include "../gui/uiMain/UiContainer.h" #include "../gui/uiMain/UiContainer.h"
#include "spdlog/spdlog.h" #include "spdlog/spdlog.h"
SplashScreenLayer::SplashScreenLayer() { SplashScreenLayer::SplashScreenLayer(): progressbar(nullptr) {
guiRenderer = std::make_unique<GUIRenderer>(Loader::instance()); guiRenderer = std::make_unique<GUIRenderer>(Loader::instance());
} }

View File

@ -12,7 +12,7 @@
class SplashScreenLayer: public Layer { class SplashScreenLayer: public Layer {
public: public:
SplashScreenLayer(); explicit SplashScreenLayer();
virtual void onRender() override; virtual void onRender() override;
virtual void onUpdate() override; virtual void onUpdate() override;
virtual void onAttach() override; virtual void onAttach() override;

View File

@ -0,0 +1,21 @@
//
// Created by sebastian on 25.04.26.
//
#ifndef RENDERCONTEXT_H
#define RENDERCONTEXT_H
struct RenderContext {
float dimFactor = 1.0f;
// später einfach erweiterbar:
// float colorTint = 1.0f;
// glm::vec4 clipRect = ...;
static RenderContext Default() {
return RenderContext{};
}
static RenderContext Dimmed(float factor) {
return RenderContext{ factor };
}
};
#endif //RENDERCONTEXT_H

View File

@ -9,9 +9,10 @@
#include "../core/gui/text/Font.h" #include "../core/gui/text/Font.h"
#include "glm/ext/matrix_clip_space.hpp" #include "glm/ext/matrix_clip_space.hpp"
void TextRenderer::renderGuiTexts(const std::vector<std::shared_ptr<GUIText>> &texts, const float width, const float height) { void TextRenderer::renderGuiTexts(const std::vector<std::shared_ptr<GUIText>> &texts, const float width, const float height, RenderContext& ctx) {
shader.start(); shader.start();
shader.loadProjectionMatrix(calculateOrthographicProjectionMatrix(width, height)); shader.loadProjectionMatrix(calculateOrthographicProjectionMatrix(width, height));
shader.loadDimFactor(ctx.dimFactor);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

View File

@ -6,6 +6,7 @@
#define DICEWARS_SIEDLER_TEXTRENDERER_H #define DICEWARS_SIEDLER_TEXTRENDERER_H
#include <memory> #include <memory>
#include "RenderContext.h"
#include "../core/gui/uiComponent/UiText.h" #include "../core/gui/uiComponent/UiText.h"
#include "loader/Loader.h" #include "loader/Loader.h"
#include "model/RawModel.h" #include "model/RawModel.h"
@ -16,12 +17,13 @@
class TextRenderer { class TextRenderer {
public: public:
TextRenderer() : textModel(Loader::instance().loadTextModel()) {}; TextRenderer() : textModel(Loader::instance().loadTextModel()) {};
void renderGuiTexts(const std::vector<std::shared_ptr<GUIText>> & texts, float width, float height); void renderGuiTexts(const std::vector<std::shared_ptr<GUIText>> & texts, float width, float height, RenderContext& ctx);
void renderGuiText(const GUIText& text, float width, float height); void renderGuiText(const GUIText& text, float width, float height);
void setDimFactor(const float dimFactor) {this->dimFactor = dimFactor;}
private: private:
TextShader shader; TextShader shader;
TextQuadModel textModel; TextQuadModel textModel;
float dimFactor = 1.0f;
static glm::mat4 calculateOrthographicProjectionMatrix(float width, float height); static glm::mat4 calculateOrthographicProjectionMatrix(float width, float height);
}; };

View File

@ -12,6 +12,10 @@ void TextShader::loadTextColor(glm::vec3 color) {
ShaderProgram::loadVector(getUniformLocation("textColor"), color); ShaderProgram::loadVector(getUniformLocation("textColor"), color);
} }
void TextShader::loadDimFactor(float dimFactor) {
ShaderProgram::loadFloat(getUniformLocation("dimFactor"), dimFactor);
}
void TextShader::bindAttributes() const { void TextShader::bindAttributes() const {
ShaderProgram::bindAttribute(0, "vertices"); ShaderProgram::bindAttribute(0, "vertices");

View File

@ -14,6 +14,7 @@ public :
} }
void loadProjectionMatrix(glm::mat4 matrix); void loadProjectionMatrix(glm::mat4 matrix);
void loadTextColor(glm::vec3 color); void loadTextColor(glm::vec3 color);
void loadDimFactor(float dimFactor);
protected: protected:
void bindAttributes() const override; void bindAttributes() const override;

View File

@ -161,5 +161,6 @@ void UILayer::onRender() {
guiRenderer->render(guis); guiRenderer->render(guis);
auto renderTexts = renderBundle.getGUITexts(); auto renderTexts = renderBundle.getGUITexts();
textRenderer->renderGuiTexts(renderTexts, Application::getInstance().getWindow().GetWidth(), Application::getInstance().getWindow().GetHeight()); RenderContext ctx = RenderContext::Default();
textRenderer->renderGuiTexts(renderTexts, Application::getInstance().getWindow().GetWidth(), Application::getInstance().getWindow().GetHeight(), ctx);
} }

View File

@ -6,8 +6,8 @@
#include "MainUiLayer.h" #include "MainUiLayer.h"
void MainMenu::onEnter() { void MainMenu::onEnter(EngineContext& ctx) {
addLayer(std::make_unique<MainUiLayer>()); addLayer(std::make_unique<MainUiLayer>(ctx.uiConfig));
} }
void MainMenu::onExit() { void MainMenu::onExit() {

View File

@ -8,7 +8,7 @@
class MainMenu: public Scene { class MainMenu: public Scene {
public: public:
void onEnter() override; void onEnter(EngineContext& ctx) override;
void onExit() override; void onExit() override;
std::vector<AssetRequest> getRequiredAssets() override; std::vector<AssetRequest> getRequiredAssets() override;

View File

@ -12,7 +12,7 @@
void MainUiLayer::onAttach() { void MainUiLayer::onAttach() {
AssetManager::loadUiTheme("default", "assets/ui/uiTheme.json"); //Todo: Move to AssetLoader AssetManager::loadUiTheme("default", "assets/ui/uiTheme.json"); //Todo: Move to AssetLoader
rootContainer = std::make_unique<UiContainer>(); auto rootContainer = std::make_unique<UiContainer>();
rootContainer->setBackgroundTexture(AssetManager::getTexture("mainCover")->getTextureID()); rootContainer->setBackgroundTexture(AssetManager::getTexture("mainCover")->getTextureID());
LayoutStyle btnStyle; LayoutStyle btnStyle;
@ -55,7 +55,8 @@ void MainUiLayer::onAttach() {
EventBus::getInstance().emit(QuitEvent{}); EventBus::getInstance().emit(QuitEvent{});
} }
}); });
uiStack = std::make_unique<UiStack>();
uiStack->push(std::move(rootContainer));
} }
void MainUiLayer::onDetach() { void MainUiLayer::onDetach() {
@ -63,22 +64,34 @@ void MainUiLayer::onDetach() {
} }
void MainUiLayer::onRender() { void MainUiLayer::onRender() {
UiRenderBundle renderBundle;
if (rootContainer) { if (uiStack) {
rootContainer->collectRenderData(renderBundle); for (const auto& panel : uiStack->getPanels()) {
RenderContext ctx;
if (!uiStack->isTop(panel.get())) {
ctx = RenderContext::Default();
} else {
ctx = RenderContext::Dimmed(uiConfig.backgroundDim);
} }
UiRenderBundle renderBundle;
panel->collectRenderData(renderBundle);
auto guis = renderBundle.getGUITextures(); auto guis = renderBundle.getGUITextures();
guiRenderer->render(guis); guiRenderer->render(guis);
const auto renderTexts = renderBundle.getGUITexts(); const auto renderTexts = renderBundle.getGUITexts();
textRenderer->renderGuiTexts(renderTexts, static_cast<float>(Application::getInstance().getWindow().GetWidth()), textRenderer->renderGuiTexts(renderTexts, static_cast<float>(Application::getInstance().getWindow().GetWidth()),
static_cast<float>(Application::getInstance().getWindow().GetHeight())); static_cast<float>(Application::getInstance().getWindow().GetHeight()), ctx);
}
}
} }
void MainUiLayer::onUpdate() { void MainUiLayer::onUpdate() {
Dimensions rootParent {0.0, 0.0, 1.0, 1.0f}; Dimensions rootParent {0.0, 0.0, 1.0, 1.0f};
rootContainer->uiPositioner.compute(rootParent); for (const auto& panel : uiStack->getPanels()) {
panel->uiPositioner.compute(rootParent);
rootContainer->update(EngineTime::deltaTime); }
uiStack->top()->update(EngineTime::deltaTime);
} }

View File

@ -8,19 +8,21 @@
#include "../../../engine/renderer/GUIRenderer.h" #include "../../../engine/renderer/GUIRenderer.h"
#include "../../../engine/renderer/loader/Loader.h" #include "../../../engine/renderer/loader/Loader.h"
#include "../../../engine/core/gui/uiMain/UiContainer.h" #include "../../../engine/core/gui/uiMain/UiContainer.h"
#include "../../../engine/core/gui/uiMain/UiStack.h"
#include "../../../engine/renderer/TextRenderer.h" #include "../../../engine/renderer/TextRenderer.h"
class MainUiLayer: public Layer { class MainUiLayer: public Layer {
public: public:
MainUiLayer(): guiRenderer(std::make_unique<GUIRenderer>(Loader::instance())), textRenderer(std::make_unique<TextRenderer>()) {} explicit MainUiLayer(UiConfig& config): uiConfig(config), guiRenderer(std::make_unique<GUIRenderer>(Loader::instance())), textRenderer(std::make_unique<TextRenderer>()) {}
void onAttach() override; void onAttach() override;
void onDetach() override; void onDetach() override;
void onRender() override; void onRender() override;
void onUpdate() override; void onUpdate() override;
private: private:
UiConfig& uiConfig;
std::unique_ptr<GUIRenderer> guiRenderer; std::unique_ptr<GUIRenderer> guiRenderer;
std::unique_ptr<TextRenderer> textRenderer; std::unique_ptr<TextRenderer> textRenderer;
std::unique_ptr<UiContainer> rootContainer; std::unique_ptr<UiStack> uiStack;
}; };