diff --git a/CMakeLists.txt b/CMakeLists.txt index f365313..c00f1f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -213,8 +213,8 @@ add_executable(Dicewars_Siedler src/main.cpp src/engine/renderer/model/RenderTargets.h src/engine/renderer/model/GuiTextureBuilder.cpp src/engine/renderer/model/GuiTextureBuilder.h - src/game/ui/components/UiBuildingMenuContainer.cpp - src/game/ui/components/UiBuildingMenuContainer.h + src/game/ui/components/buildingMenu/UiBuildingMenuContainer.cpp + src/game/ui/components/buildingMenu/UiBuildingMenuContainer.h src/engine/core/inputsOutputs/stateControl/states/IState.cpp src/engine/core/inputsOutputs/stateControl/states/IState.h 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/gui/uiComponent/EventData.cpp 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 diff --git a/assets/buildings/forest_hut/textures/icon.png b/assets/buildings/forest_hut/textures/icon.png index 3d90b50..ec012bc 100644 Binary files a/assets/buildings/forest_hut/textures/icon.png and b/assets/buildings/forest_hut/textures/icon.png differ diff --git a/assets/buildings/stone_mason/textures/icon.png b/assets/buildings/stone_mason/textures/icon.png index da7b3b1..295d5f1 100644 Binary files a/assets/buildings/stone_mason/textures/icon.png and b/assets/buildings/stone_mason/textures/icon.png differ diff --git a/src/engine/renderer/GUIRenderer.cpp b/src/engine/renderer/GUIRenderer.cpp index 872ecc7..27a5aad 100644 --- a/src/engine/renderer/GUIRenderer.cpp +++ b/src/engine/renderer/GUIRenderer.cpp @@ -25,6 +25,11 @@ void GUIRenderer::render(std::vector>& gui_textures) glBindVertexArray(rawModel->vaoID); glEnableVertexAttribArray(0); 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); glBindTexture(GL_TEXTURE_2D, texture->getTextureID()); guiShader.loadForegroundTexture(0, true); diff --git a/src/engine/renderer/GUIRenderer.h b/src/engine/renderer/GUIRenderer.h index 6b10014..d03ac4f 100644 --- a/src/engine/renderer/GUIRenderer.h +++ b/src/engine/renderer/GUIRenderer.h @@ -13,6 +13,7 @@ #include "shaders/GUIShader.h" + class Loader; class GUIRenderer { diff --git a/src/engine/renderer/model/GUITexture.cpp b/src/engine/renderer/model/GUITexture.cpp index fe2de3a..51fe50e 100644 --- a/src/engine/renderer/model/GUITexture.cpp +++ b/src/engine/renderer/model/GUITexture.cpp @@ -4,4 +4,28 @@ #include "GUITexture.h" +#include "../../core/Application.h" + +ClipRect GUITexture::getClipRect() const { + const float screenW = static_cast(Application::getInstance().getWindow().GetWidth()); + const float screenH = static_cast(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(leftPx); + int y = static_cast(screenH - (topPx + heightPx)); + int w = static_cast(widthPx); + int h = static_cast(heightPx); + + return { x, y, w, h }; +} diff --git a/src/engine/renderer/model/GUITexture.h b/src/engine/renderer/model/GUITexture.h index 509111a..b6a5e54 100644 --- a/src/engine/renderer/model/GUITexture.h +++ b/src/engine/renderer/model/GUITexture.h @@ -11,6 +11,10 @@ #include "GuiTextureBuilder.h" +struct ClipRect { + int x, y, w, h; // in Pixeln, OpenGL-Koordinaten (unten links) +}; + class GUITexture { private: const GLuint textureID; @@ -45,6 +49,8 @@ public: [[nodiscard]] float getTintStrength() const {return tintStrength;} [[nodiscard]] bool hasBackground() const {return useBackground;} + ClipRect getClipRect() const; + }; diff --git a/src/game/UILayer.cpp b/src/game/UILayer.cpp index 2f275c2..8735654 100644 --- a/src/game/UILayer.cpp +++ b/src/game/UILayer.cpp @@ -18,7 +18,7 @@ #include "../engine/renderer/model/GUITexture.h" #include "../engine/renderer/model/RenderTargets.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/UiRessourceWidget.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("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("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(); rootContainer->getLayoutStyle().flexDirection = FlexDirection::Column; @@ -53,11 +58,11 @@ void UILayer::onAttach() { auto inventoryContainer = std::make_unique(*smallFont); - inventoryContainer->addRessource("assets/ui/ressource-icons/wood-log.png", "background", 10, RessourceType::WOOD); - inventoryContainer->addRessource("assets/ui/ressource-icons/granite.png","background", 1139, RessourceType::STONE); - inventoryContainer->addRessource("assets/ui/ressource-icons/humans.png","background", 523, RessourceType::PEOPLE); - inventoryContainer->addRessource("assets/ui/ressource-icons/bread.png","background", 89, RessourceType::FOOD); - inventoryContainer->addRessource("assets/ui/ressource-icons/swords.png", "background",45, RessourceType::SOLDIERS); + inventoryContainer->addRessource("wood_icon", "background", 10, RessourceType::WOOD); + inventoryContainer->addRessource("stone_icon","background", 1139, RessourceType::STONE); + inventoryContainer->addRessource("people_icon","background", 523, RessourceType::PEOPLE); + inventoryContainer->addRessource("food_icon","background", 89, RessourceType::FOOD); + inventoryContainer->addRessource("soldiers_icon", "background",45, RessourceType::SOLDIERS); auto uiContainer = std::make_unique(); uiContainer->getLayoutStyle().width = SizeValue(1.f, SizeUnit::Percent); @@ -109,7 +114,7 @@ void UILayer::onAttach() { }); rootContainer->addChild(std::move(uiButton)); - auto buildingMenuContainer = std::make_unique(); + auto buildingMenuContainer = std::make_unique(*smallFont); auto buildingMenuContainerContainer = std::make_unique(); buildingMenuContainerContainer->getLayoutStyle().width = SizeValue(1.f, SizeUnit::Percent); buildingMenuContainerContainer->getLayoutStyle().height = SizeValue(200, SizeUnit::Pixels); diff --git a/src/game/ui/components/UiInventoryContainer.h b/src/game/ui/components/UiInventoryContainer.h index 71f1346..a3bf3c9 100644 --- a/src/game/ui/components/UiInventoryContainer.h +++ b/src/game/ui/components/UiInventoryContainer.h @@ -24,9 +24,9 @@ public: 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; - auto widget = RessourceWidgetFactory::create(iconPath, textureName, amount, font, marginLeft); + auto widget = RessourceWidgetFactory::create(iconName, textureName, amount, font, marginLeft); widgets.emplace(widgetID, widget.get()); addChild(std::move(widget)); } diff --git a/src/game/ui/components/buildingMenu/UiBuildingMenuButton.cpp b/src/game/ui/components/buildingMenu/UiBuildingMenuButton.cpp new file mode 100644 index 0000000..fe87fa4 --- /dev/null +++ b/src/game/ui/components/buildingMenu/UiBuildingMenuButton.cpp @@ -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(textureBuilder.Build())); + +} diff --git a/src/game/ui/components/buildingMenu/UiBuildingMenuButton.h b/src/game/ui/components/buildingMenu/UiBuildingMenuButton.h new file mode 100644 index 0000000..31393da --- /dev/null +++ b/src/game/ui/components/buildingMenu/UiBuildingMenuButton.h @@ -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(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("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 \ No newline at end of file diff --git a/src/game/ui/components/UiBuildingMenuContainer.cpp b/src/game/ui/components/buildingMenu/UiBuildingMenuContainer.cpp similarity index 52% rename from src/game/ui/components/UiBuildingMenuContainer.cpp rename to src/game/ui/components/buildingMenu/UiBuildingMenuContainer.cpp index 6836fb5..88378bb 100644 --- a/src/game/ui/components/UiBuildingMenuContainer.cpp +++ b/src/game/ui/components/buildingMenu/UiBuildingMenuContainer.cpp @@ -4,25 +4,39 @@ #include "UiBuildingMenuContainer.h" -#include "../../../engine/core/gui/uiComponent/UiImage.h" -#include "../../../engine/renderer/loader/AssetManager.h" +#include -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().width = SizeValue(.6f, SizeUnit::Percent); uiPositioner.getLayout().flexDirection = FlexDirection::Row; uiPositioner.getLayout().justifyContent = JustifyContent::Start; uiPositioner.getLayout().alignItems = AlignItems::Center; - LayoutStyle iconStyle; - iconStyle.width = SizeValue(150, SizeUnit::Pixels); - iconStyle.height = SizeValue(150.f, SizeUnit::Pixels); + LayoutStyle buttonStyle; - auto forest_icon = std::make_unique(AssetManager::getTexture("forest_hut_icon")->getTextureID(), AssetManager::getTexture("background")->getTextureID(), iconStyle); + auto forest_icon = std::make_unique("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)); - auto stone_mason_icon = std::make_unique(AssetManager::getTexture("stone_mason_icon")->getTextureID(), AssetManager::getTexture("background")->getTextureID(), iconStyle); - addChild(std::move(stone_mason_icon)); + LayoutStyle buttonStyle2; + + auto stone_icon = std::make_unique("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) { diff --git a/src/game/ui/components/UiBuildingMenuContainer.h b/src/game/ui/components/buildingMenu/UiBuildingMenuContainer.h similarity index 65% rename from src/game/ui/components/UiBuildingMenuContainer.h rename to src/game/ui/components/buildingMenu/UiBuildingMenuContainer.h index 978c1d7..04810dc 100644 --- a/src/game/ui/components/UiBuildingMenuContainer.h +++ b/src/game/ui/components/buildingMenu/UiBuildingMenuContainer.h @@ -4,12 +4,12 @@ #ifndef 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 { public: - UiBuildingMenuContainer(); + UiBuildingMenuContainer(Font& font); protected: void onCollectRenderData(UiRenderBundle &uiRenderBundle) override; }; diff --git a/src/game/ui/components/buildingMenu/UiBuildingMenuCostContainer.cpp b/src/game/ui/components/buildingMenu/UiBuildingMenuCostContainer.cpp new file mode 100644 index 0000000..cb043ff --- /dev/null +++ b/src/game/ui/components/buildingMenu/UiBuildingMenuCostContainer.cpp @@ -0,0 +1,5 @@ +// +// Created by sebastian on 15.02.26. +// + +#include "UiBuildingMenuCostContainer.h" \ No newline at end of file diff --git a/src/game/ui/components/buildingMenu/UiBuildingMenuCostContainer.h b/src/game/ui/components/buildingMenu/UiBuildingMenuCostContainer.h new file mode 100644 index 0000000..947afab --- /dev/null +++ b/src/game/ui/components/buildingMenu/UiBuildingMenuCostContainer.h @@ -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(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(font, "13", textStyle, glm::vec3(0.f)); + addChild(std::move(costText)); + } +}; + + +#endif //DICEWARS_SIEDLER_UIBUILDINGMENUCOSTCONTAINER_H \ No newline at end of file diff --git a/src/game/ui/components/factorys/RessourceWidgetFactory.cpp b/src/game/ui/components/factorys/RessourceWidgetFactory.cpp index 0c90fa4..a42dabc 100644 --- a/src/game/ui/components/factorys/RessourceWidgetFactory.cpp +++ b/src/game/ui/components/factorys/RessourceWidgetFactory.cpp @@ -7,7 +7,7 @@ #include "../../../../engine/renderer/loader/AssetManager.h" #include "../../../../engine/renderer/loader/Loader.h" -std::unique_ptr RessourceWidgetFactory::create(const std::string &iconPath, const std::string& textureName, int amount, Font &font, float marginLeft) { +std::unique_ptr RessourceWidgetFactory::create(const std::string &iconName, const std::string& textureName, int amount, Font &font, float marginLeft) { LayoutStyle iconStyle; iconStyle.width = SizeValue(40.f, SizeUnit::Pixels); iconStyle.height = SizeValue(40.f,SizeUnit::Pixels); @@ -27,7 +27,7 @@ std::unique_ptr RessourceWidgetFactory::create(const std::str 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(); return std::make_unique(textureID, backgroundTextureID, amount, font, containerStyle, iconStyle, textStyle diff --git a/src/game/ui/components/factorys/RessourceWidgetFactory.h b/src/game/ui/components/factorys/RessourceWidgetFactory.h index 009c839..97de505 100644 --- a/src/game/ui/components/factorys/RessourceWidgetFactory.h +++ b/src/game/ui/components/factorys/RessourceWidgetFactory.h @@ -12,7 +12,7 @@ class Font; class RessourceWidgetFactory { public: - static std::unique_ptr create(const std::string &iconPath, const std::string &textureName, int amount, Font &font, float marginLeft = 0.0); + static std::unique_ptr create(const std::string &iconName, const std::string &textureName, int amount, Font &font, float marginLeft = 0.0); };