ADD: BuildingMenuButtons

This commit is contained in:
sebastian 2026-02-15 19:06:40 +01:00
parent 968485ec1b
commit caf2cbd42a
17 changed files with 193 additions and 26 deletions

View File

@ -213,8 +213,8 @@ add_executable(Dicewars_Siedler src/main.cpp
src/engine/renderer/model/RenderTargets.h src/engine/renderer/model/RenderTargets.h
src/engine/renderer/model/GuiTextureBuilder.cpp src/engine/renderer/model/GuiTextureBuilder.cpp
src/engine/renderer/model/GuiTextureBuilder.h src/engine/renderer/model/GuiTextureBuilder.h
src/game/ui/components/UiBuildingMenuContainer.cpp src/game/ui/components/buildingMenu/UiBuildingMenuContainer.cpp
src/game/ui/components/UiBuildingMenuContainer.h src/game/ui/components/buildingMenu/UiBuildingMenuContainer.h
src/engine/core/inputsOutputs/stateControl/states/IState.cpp src/engine/core/inputsOutputs/stateControl/states/IState.cpp
src/engine/core/inputsOutputs/stateControl/states/IState.h src/engine/core/inputsOutputs/stateControl/states/IState.h
src/engine/core/inputsOutputs/stateControl/InputUser.cpp src/engine/core/inputsOutputs/stateControl/InputUser.cpp
@ -242,6 +242,10 @@ add_executable(Dicewars_Siedler src/main.cpp
src/engine/core/inputsOutputs/stateControl/inputUser/UiInputUser.h src/engine/core/inputsOutputs/stateControl/inputUser/UiInputUser.h
src/engine/core/gui/uiComponent/EventData.cpp src/engine/core/gui/uiComponent/EventData.cpp
src/engine/core/gui/uiComponent/EventData.h src/engine/core/gui/uiComponent/EventData.h
src/game/ui/components/buildingMenu/UiBuildingMenuButton.cpp
src/game/ui/components/buildingMenu/UiBuildingMenuButton.h
src/game/ui/components/buildingMenu/UiBuildingMenuCostContainer.cpp
src/game/ui/components/buildingMenu/UiBuildingMenuCostContainer.h
) )
target_compile_options(Dicewars_Siedler PRIVATE target_compile_options(Dicewars_Siedler PRIVATE

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 KiB

After

Width:  |  Height:  |  Size: 106 KiB

View File

@ -25,6 +25,11 @@ void GUIRenderer::render(std::vector<std::shared_ptr<GUITexture>>& gui_textures)
glBindVertexArray(rawModel->vaoID); glBindVertexArray(rawModel->vaoID);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
for (auto texture : gui_textures) { for (auto texture : gui_textures) {
glEnable(GL_SCISSOR_TEST);
const auto& r = texture->getClipRect();
glScissor(r.x, r.y, r.w, r.h);
glDisable(GL_SCISSOR_TEST);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture->getTextureID()); glBindTexture(GL_TEXTURE_2D, texture->getTextureID());
guiShader.loadForegroundTexture(0, true); guiShader.loadForegroundTexture(0, true);

View File

@ -13,6 +13,7 @@
#include "shaders/GUIShader.h" #include "shaders/GUIShader.h"
class Loader; class Loader;
class GUIRenderer { class GUIRenderer {

View File

@ -4,4 +4,28 @@
#include "GUITexture.h" #include "GUITexture.h"
#include "../../core/Application.h"
ClipRect GUITexture::getClipRect() const {
const float screenW = static_cast<float>(Application::getInstance().getWindow().GetWidth());
const float screenH = static_cast<float>(Application::getInstance().getWindow().GetHeight());
glm::vec2 ndcPos = getPosition(); // [-1 .. 1]
glm::vec2 ndcSize = getScale(); // Größe in NDC
// 🔁 NDC -> Pixel (Top-Left)
float leftPx = (ndcPos.x * 0.5f + 0.5f) * screenW;
float topPx = (1.0f - (ndcPos.y * 0.5f + 0.5f)) * screenH;
float widthPx = ndcSize.x * 0.5f * screenW;
float heightPx = ndcSize.y * 0.5f * screenH;
// 🔥 OpenGL erwartet Bottom-Left
int x = static_cast<int>(leftPx);
int y = static_cast<int>(screenH - (topPx + heightPx));
int w = static_cast<int>(widthPx);
int h = static_cast<int>(heightPx);
return { x, y, w, h };
}

View File

@ -11,6 +11,10 @@
#include "GuiTextureBuilder.h" #include "GuiTextureBuilder.h"
struct ClipRect {
int x, y, w, h; // in Pixeln, OpenGL-Koordinaten (unten links)
};
class GUITexture { class GUITexture {
private: private:
const GLuint textureID; const GLuint textureID;
@ -45,6 +49,8 @@ public:
[[nodiscard]] float getTintStrength() const {return tintStrength;} [[nodiscard]] float getTintStrength() const {return tintStrength;}
[[nodiscard]] bool hasBackground() const {return useBackground;} [[nodiscard]] bool hasBackground() const {return useBackground;}
ClipRect getClipRect() const;
}; };

View File

@ -18,7 +18,7 @@
#include "../engine/renderer/model/GUITexture.h" #include "../engine/renderer/model/GUITexture.h"
#include "../engine/renderer/model/RenderTargets.h" #include "../engine/renderer/model/RenderTargets.h"
#include "hexWorld/events/TurnChangedEvent.h" #include "hexWorld/events/TurnChangedEvent.h"
#include "ui/components/UiBuildingMenuContainer.h" #include "ui/components/buildingMenu/UiBuildingMenuContainer.h"
#include "ui/components/UiInventoryContainer.h" #include "ui/components/UiInventoryContainer.h"
#include "ui/components/UiRessourceWidget.h" #include "ui/components/UiRessourceWidget.h"
#include "ui/components/factorys/RessourceWidgetFactory.h" #include "ui/components/factorys/RessourceWidgetFactory.h"
@ -37,7 +37,12 @@ void UILayer::onAttach() {
AssetManager::loadTexture("inventory_background", "assets/textures/inventory_background.png", Loader::instance()); AssetManager::loadTexture("inventory_background", "assets/textures/inventory_background.png", Loader::instance());
AssetManager::loadTexture("forest_hut_icon", "assets/buildings/forest_hut/textures/icon.png", Loader::instance()); AssetManager::loadTexture("forest_hut_icon", "assets/buildings/forest_hut/textures/icon.png", Loader::instance());
AssetManager::loadTexture("stone_mason_icon", "assets/buildings/stone_mason/textures/icon.png", Loader::instance()); AssetManager::loadTexture("stone_mason_icon", "assets/buildings/stone_mason/textures/icon.png", Loader::instance());
AssetManager::loadTexture("building_menu_btn_bg", "assets/textures/building-menu-button-background.png", Loader::instance());
AssetManager::loadTexture("wood_icon", "assets/ui/ressource-icons/wood-log.png", Loader::instance());
AssetManager::loadTexture("stone_icon", "assets/ui/ressource-icons/granite.png", Loader::instance());
AssetManager::loadTexture("people_icon", "assets/ui/ressource-icons/humans.png", Loader::instance());
AssetManager::loadTexture("food_icon", "assets/ui/ressource-icons/bread.png", Loader::instance());
AssetManager::loadTexture("soldiers_icon", "assets/ui/ressource-icons/swords.png", Loader::instance());
rootContainer = std::make_unique<UiContainer>(); rootContainer = std::make_unique<UiContainer>();
rootContainer->getLayoutStyle().flexDirection = FlexDirection::Column; rootContainer->getLayoutStyle().flexDirection = FlexDirection::Column;
@ -53,11 +58,11 @@ void UILayer::onAttach() {
auto inventoryContainer = std::make_unique<UiInventoryContainer>(*smallFont); auto inventoryContainer = std::make_unique<UiInventoryContainer>(*smallFont);
inventoryContainer->addRessource("assets/ui/ressource-icons/wood-log.png", "background", 10, RessourceType::WOOD); inventoryContainer->addRessource("wood_icon", "background", 10, RessourceType::WOOD);
inventoryContainer->addRessource("assets/ui/ressource-icons/granite.png","background", 1139, RessourceType::STONE); inventoryContainer->addRessource("stone_icon","background", 1139, RessourceType::STONE);
inventoryContainer->addRessource("assets/ui/ressource-icons/humans.png","background", 523, RessourceType::PEOPLE); inventoryContainer->addRessource("people_icon","background", 523, RessourceType::PEOPLE);
inventoryContainer->addRessource("assets/ui/ressource-icons/bread.png","background", 89, RessourceType::FOOD); inventoryContainer->addRessource("food_icon","background", 89, RessourceType::FOOD);
inventoryContainer->addRessource("assets/ui/ressource-icons/swords.png", "background",45, RessourceType::SOLDIERS); inventoryContainer->addRessource("soldiers_icon", "background",45, RessourceType::SOLDIERS);
auto uiContainer = std::make_unique<UiContainer>(); auto uiContainer = std::make_unique<UiContainer>();
uiContainer->getLayoutStyle().width = SizeValue(1.f, SizeUnit::Percent); uiContainer->getLayoutStyle().width = SizeValue(1.f, SizeUnit::Percent);
@ -109,7 +114,7 @@ void UILayer::onAttach() {
}); });
rootContainer->addChild(std::move(uiButton)); rootContainer->addChild(std::move(uiButton));
auto buildingMenuContainer = std::make_unique<UiBuildingMenuContainer>(); auto buildingMenuContainer = std::make_unique<UiBuildingMenuContainer>(*smallFont);
auto buildingMenuContainerContainer = std::make_unique<UiContainer>(); auto buildingMenuContainerContainer = std::make_unique<UiContainer>();
buildingMenuContainerContainer->getLayoutStyle().width = SizeValue(1.f, SizeUnit::Percent); buildingMenuContainerContainer->getLayoutStyle().width = SizeValue(1.f, SizeUnit::Percent);
buildingMenuContainerContainer->getLayoutStyle().height = SizeValue(200, SizeUnit::Pixels); buildingMenuContainerContainer->getLayoutStyle().height = SizeValue(200, SizeUnit::Pixels);

View File

@ -24,9 +24,9 @@ public:
uiPositioner.setLayout(containerStyle); uiPositioner.setLayout(containerStyle);
} }
void addRessource(const std::string& iconPath, const std::string& textureName, int amount, RessourceType widgetID) { void addRessource(const std::string& iconName, const std::string& textureName, int amount, RessourceType widgetID) {
float marginLeft = (widgets.empty()) ? 0.0f : 10.0f; float marginLeft = (widgets.empty()) ? 0.0f : 10.0f;
auto widget = RessourceWidgetFactory::create(iconPath, textureName, amount, font, marginLeft); auto widget = RessourceWidgetFactory::create(iconName, textureName, amount, font, marginLeft);
widgets.emplace(widgetID, widget.get()); widgets.emplace(widgetID, widget.get());
addChild(std::move(widget)); addChild(std::move(widget));
} }

View File

@ -0,0 +1,18 @@
//
// Created by sebastian on 15.02.26.
//
#include "UiBuildingMenuButton.h"
void UiBuildingMenuButton::onCollectRenderData(UiRenderBundle &uiRenderBundle) {
GUITextureBuilder textureBuilder;
textureBuilder = textureBuilder.Foreground(AssetManager::getTexture("building_menu_btn_bg")->getTextureID());
textureBuilder = textureBuilder.Position(glm::vec2(uiPositioner.screenSpace.x, uiPositioner.screenSpace.y));
textureBuilder = textureBuilder.Scale(glm::vec2(uiPositioner.screenSpace.width, uiPositioner.screenSpace.height));
textureBuilder = textureBuilder.Tint(currentVisualStyle.tintColor, currentVisualStyle.tintStrength);
textureBuilder = textureBuilder.Brightness(currentVisualStyle.brightness);
uiRenderBundle.addGUITexture(std::make_shared<GUITexture>(textureBuilder.Build()));
}

View File

@ -0,0 +1,49 @@
//
// Created by sebastian on 15.02.26.
//
#ifndef DICEWARS_SIEDLER_UIBUILDINGMENUBUTTON_H
#define DICEWARS_SIEDLER_UIBUILDINGMENUBUTTON_H
#include "UiBuildingMenuCostContainer.h"
#include "../../../../engine/core/gui/uiComponent/ClickableUiComponent.h"
#include "../../../../engine/core/gui/uiComponent/UiImage.h"
#include "../../../../engine/renderer/loader/AssetManager.h"
class UiBuildingMenuButton :public ClickableUiComponent {
public:
UiBuildingMenuButton(const std::string& iconName, LayoutStyle& style, Font& font) : ClickableUiComponent(style) {
LayoutStyle iconStyle;
iconStyle.width = SizeValue(0.75, SizeUnit::Percent);
iconStyle.height = SizeValue(0.75f, SizeUnit::Percent);
getLayoutStyle().width = SizeValue(143, SizeUnit::Pixels);
getLayoutStyle().height = SizeValue(200.f, SizeUnit::Pixels);
getLayoutStyle().margin.left = {10.f, SizeUnit::Pixels};
getLayoutStyle().alignItems = AlignItems::Center;
auto icon = std::make_unique<UiImage>(AssetManager::getTexture(iconName)->getTextureID(), iconStyle);
iconImageID = addChild(std::move(icon));
LayoutStyle costContainerStyle;
costContainerStyle.width = SizeValue(1.f, SizeUnit::Percent);
costContainerStyle.height = SizeValue(35, SizeUnit::Pixels);
costContainerStyle.margin.top = {10.f, SizeUnit::Pixels};
auto costContainer = std::make_unique<UiBuildingMenuCostContainer>("wood_icon", costContainerStyle, font);
addChild(std::move(costContainer));
visualStyles[UiEventType::NONE] = {1.0f, glm::vec3(0.0f), 0.0f};
visualStyles[UiEventType::MOUSE_OVER] = {1.15f, glm::vec3(0.0f), 0.0f};
visualStyles[UiEventType::MOUSE_CLICK] = {1.0f, glm::vec3(0.3f, 0.6f, 1.0f), 0.15f};
};
protected:
void onCollectRenderData(UiRenderBundle &uiRenderBundle) override;
private:
size_t iconImageID;
};
#endif //DICEWARS_SIEDLER_UIBUILDINGMENUBUTTON_H

View File

@ -4,25 +4,39 @@
#include "UiBuildingMenuContainer.h" #include "UiBuildingMenuContainer.h"
#include "../../../engine/core/gui/uiComponent/UiImage.h" #include <iostream>
#include "../../../engine/renderer/loader/AssetManager.h"
UiBuildingMenuContainer::UiBuildingMenuContainer() { #include "UiBuildingMenuButton.h"
#include "../../../../engine/core/gui/uiComponent/UiImage.h"
#include "../../../../engine/core/inputsOutputs/inputs/MouseButton.h"
#include "../../../../engine/renderer/loader/AssetManager.h"
UiBuildingMenuContainer::UiBuildingMenuContainer(Font& font) {
uiPositioner.getLayout().height = SizeValue(200.f, SizeUnit::Pixels); uiPositioner.getLayout().height = SizeValue(200.f, SizeUnit::Pixels);
uiPositioner.getLayout().width = SizeValue(.6f, SizeUnit::Percent); uiPositioner.getLayout().width = SizeValue(.6f, SizeUnit::Percent);
uiPositioner.getLayout().flexDirection = FlexDirection::Row; uiPositioner.getLayout().flexDirection = FlexDirection::Row;
uiPositioner.getLayout().justifyContent = JustifyContent::Start; uiPositioner.getLayout().justifyContent = JustifyContent::Start;
uiPositioner.getLayout().alignItems = AlignItems::Center; uiPositioner.getLayout().alignItems = AlignItems::Center;
LayoutStyle iconStyle; LayoutStyle buttonStyle;
iconStyle.width = SizeValue(150, SizeUnit::Pixels);
iconStyle.height = SizeValue(150.f, SizeUnit::Pixels);
auto forest_icon = std::make_unique<UiImage>(AssetManager::getTexture("forest_hut_icon")->getTextureID(), AssetManager::getTexture("background")->getTextureID(), iconStyle); auto forest_icon = std::make_unique<UiBuildingMenuButton>("forest_hut_icon", buttonStyle, font);
forest_icon->addMouseListener([](const MouseEventData& e) {
if (e.isClick(MouseButton::LEFT)) {
std::cout << "Forest hut clicked!" << std::endl;
}
});
addChild(std::move(forest_icon)); addChild(std::move(forest_icon));
auto stone_mason_icon = std::make_unique<UiImage>(AssetManager::getTexture("stone_mason_icon")->getTextureID(), AssetManager::getTexture("background")->getTextureID(), iconStyle); LayoutStyle buttonStyle2;
addChild(std::move(stone_mason_icon));
auto stone_icon = std::make_unique<UiBuildingMenuButton>("stone_mason_icon", buttonStyle2, font);
stone_icon->addMouseListener([](const MouseEventData& e) {
if (e.isClick(MouseButton::LEFT)) {
std::cout << "Stone hut clicked!" << std::endl;
}
});
addChild(std::move(stone_icon));
} }
void UiBuildingMenuContainer::onCollectRenderData(UiRenderBundle &uiRenderBundle) { void UiBuildingMenuContainer::onCollectRenderData(UiRenderBundle &uiRenderBundle) {

View File

@ -4,12 +4,12 @@
#ifndef DICEWARS_SIEDLER_UIBUILDINGMENUCONTAINER_H #ifndef DICEWARS_SIEDLER_UIBUILDINGMENUCONTAINER_H
#define DICEWARS_SIEDLER_UIBUILDINGMENUCONTAINER_H #define DICEWARS_SIEDLER_UIBUILDINGMENUCONTAINER_H
#include "../../../engine/core/gui/uiComponent/UiComponent.h" #include "../../../../engine/core/gui/uiComponent/UiComponent.h"
class UiBuildingMenuContainer : public UiComponent { class UiBuildingMenuContainer : public UiComponent {
public: public:
UiBuildingMenuContainer(); UiBuildingMenuContainer(Font& font);
protected: protected:
void onCollectRenderData(UiRenderBundle &uiRenderBundle) override; void onCollectRenderData(UiRenderBundle &uiRenderBundle) override;
}; };

View File

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

View File

@ -0,0 +1,36 @@
//
// Created by sebastian on 15.02.26.
//
#ifndef DICEWARS_SIEDLER_UIBUILDINGMENUCOSTCONTAINER_H
#define DICEWARS_SIEDLER_UIBUILDINGMENUCOSTCONTAINER_H
#include "../../../../engine/core/gui/uiComponent/UiComponent.h"
#include "../../../../engine/core/gui/uiComponent/UiImage.h"
#include "../../../../engine/core/gui/uiComponent/UiText.h"
#include "../../../../engine/renderer/loader/AssetManager.h"
class UiBuildingMenuCostContainer: public UiComponent {
public:
UiBuildingMenuCostContainer(const std::string& resourceIconName, LayoutStyle& style, Font& font) : UiComponent(style) {
LayoutStyle iconStyle;
iconStyle.width = SizeValue(30, SizeUnit::Pixels);
iconStyle.height = SizeValue(30, SizeUnit::Pixels);
getLayoutStyle().flexDirection = FlexDirection::Row;
getLayoutStyle().justifyContent = JustifyContent::SpaceBetween;
auto iconImage = std::make_unique<UiImage>(AssetManager::getTexture(resourceIconName)->getTextureID(), iconStyle);
addChild(std::move(iconImage));
LayoutStyle textStyle;
textStyle.width = SizeValue(123, SizeUnit::Pixels);
textStyle.height = SizeValue(30, SizeUnit::Pixels);
auto costText = std::make_unique<UiText>(font, "13", textStyle, glm::vec3(0.f));
addChild(std::move(costText));
}
};
#endif //DICEWARS_SIEDLER_UIBUILDINGMENUCOSTCONTAINER_H

View File

@ -7,7 +7,7 @@
#include "../../../../engine/renderer/loader/AssetManager.h" #include "../../../../engine/renderer/loader/AssetManager.h"
#include "../../../../engine/renderer/loader/Loader.h" #include "../../../../engine/renderer/loader/Loader.h"
std::unique_ptr<UiRessourceWidget> RessourceWidgetFactory::create(const std::string &iconPath, const std::string& textureName, int amount, Font &font, float marginLeft) { std::unique_ptr<UiRessourceWidget> RessourceWidgetFactory::create(const std::string &iconName, const std::string& textureName, int amount, Font &font, float marginLeft) {
LayoutStyle iconStyle; LayoutStyle iconStyle;
iconStyle.width = SizeValue(40.f, SizeUnit::Pixels); iconStyle.width = SizeValue(40.f, SizeUnit::Pixels);
iconStyle.height = SizeValue(40.f,SizeUnit::Pixels); iconStyle.height = SizeValue(40.f,SizeUnit::Pixels);
@ -27,7 +27,7 @@ std::unique_ptr<UiRessourceWidget> RessourceWidgetFactory::create(const std::str
containerStyle.margin.left = {marginLeft, SizeUnit::Pixels}; containerStyle.margin.left = {marginLeft, SizeUnit::Pixels};
} }
GLuint textureID = Loader::instance().loadTextureFromFile(iconPath).getTextureID(); GLuint textureID =AssetManager::getTexture(iconName)->getTextureID();;
GLuint backgroundTextureID = AssetManager::getTexture(textureName)->getTextureID(); GLuint backgroundTextureID = AssetManager::getTexture(textureName)->getTextureID();
return std::make_unique<UiRessourceWidget>(textureID, backgroundTextureID, return std::make_unique<UiRessourceWidget>(textureID, backgroundTextureID,
amount, font, containerStyle, iconStyle, textStyle amount, font, containerStyle, iconStyle, textStyle

View File

@ -12,7 +12,7 @@ class Font;
class RessourceWidgetFactory { class RessourceWidgetFactory {
public: public:
static std::unique_ptr<UiRessourceWidget> create(const std::string &iconPath, const std::string &textureName, int amount, Font &font, float marginLeft = 0.0); static std::unique_ptr<UiRessourceWidget> create(const std::string &iconName, const std::string &textureName, int amount, Font &font, float marginLeft = 0.0);
}; };