diff --git a/CMakeLists.txt b/CMakeLists.txt index 84095b5..87b4e6e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -321,6 +321,10 @@ if(BUILD_GAME) src/engine/core/scenes/SplashScreenLayer.h src/engine/core/gui/uiComponent/UiProgressbar.cpp src/engine/core/gui/uiComponent/UiProgressbar.h + src/game/scenes/main/MainMenu.cpp + src/game/scenes/main/MainMenu.h + src/game/scenes/main/MainUiLayer.cpp + src/game/scenes/main/MainUiLayer.h ) target_compile_options(Dicewars_Siedler PRIVATE -Wall diff --git a/assets/background.png b/assets/background.png new file mode 100644 index 0000000..caecf8d Binary files /dev/null and b/assets/background.png differ diff --git a/assets/background_square.png b/assets/background_square.png new file mode 100644 index 0000000..eec375f Binary files /dev/null and b/assets/background_square.png differ diff --git a/src/engine/core/gui/uiMain/UiContainer.cpp b/src/engine/core/gui/uiMain/UiContainer.cpp index ef263b8..554e405 100644 --- a/src/engine/core/gui/uiMain/UiContainer.cpp +++ b/src/engine/core/gui/uiMain/UiContainer.cpp @@ -8,6 +8,10 @@ UiContainer::UiContainer(){ uiPositioner.screenSpace.set(0.f, 0.f, 1.f, 1.f); } +void UiContainer::setBackgroundTexture(GLuint textureID) { + backgroundTextureID = textureID; +} + bool UiContainer::isMouseOver(float mouseX, float mouseY) { for (const auto &child : children) { if (child->isMouseOver(mouseX, mouseY)) return true; @@ -19,7 +23,13 @@ void UiContainer::onUpdate(float x) { } -void UiContainer::onCollectRenderData(UiRenderBundle& render_bundle) { - +void UiContainer::onCollectRenderData(UiRenderBundle& renderBundle) { + if (backgroundTextureID.has_value()) { + GUITextureBuilder builder = GUITextureBuilder(); + builder.Foreground(backgroundTextureID.value()); + builder.Scale(glm::vec2(uiPositioner.screenSpace.width, uiPositioner.screenSpace.height)); + builder.Position(glm::vec2(uiPositioner.screenSpace.x, uiPositioner.screenSpace.y)); + renderBundle.addGUITexture(std::make_shared(builder.Build())); + } } diff --git a/src/engine/core/gui/uiMain/UiContainer.h b/src/engine/core/gui/uiMain/UiContainer.h index 486fb22..a626353 100644 --- a/src/engine/core/gui/uiMain/UiContainer.h +++ b/src/engine/core/gui/uiMain/UiContainer.h @@ -4,15 +4,21 @@ #ifndef DICEWARS_SIEDLER_UICONTAINER_H #define DICEWARS_SIEDLER_UICONTAINER_H +#include + #include "../uiComponent/UiComponent.h" class UiContainer : public UiComponent { public: UiContainer(); + void setBackgroundTexture(GLuint textureID); bool isMouseOver(float mouseX, float mouseY) override; void onUpdate(float) override; void onCollectRenderData(UiRenderBundle& renderBundle) override; + +private: + std::optional backgroundTextureID; }; diff --git a/src/engine/core/scenes/SceneManager.cpp b/src/engine/core/scenes/SceneManager.cpp index 61ed7f3..c5b568e 100644 --- a/src/engine/core/scenes/SceneManager.cpp +++ b/src/engine/core/scenes/SceneManager.cpp @@ -7,7 +7,8 @@ #include "Scene.h" #include "spdlog/spdlog.h" -void SceneManager::switchTo(std::unique_ptr next) { +void SceneManager::switchTo(std::unique_ptr next, std::function onLoaded) { + onSceneLoaded = std::move(onLoaded); nextScene = std::move(next); std::vector requestedAssets = nextScene->getRequiredAssets(); spdlog::debug("Required assets: {}", requestedAssets.size()); @@ -30,6 +31,11 @@ void SceneManager::update() { nextScene = nullptr; currentScene->onEnter(); assetLoader.stop(); + + if (onSceneLoaded) { + onSceneLoaded(); + onSceneLoaded = nullptr; + } } } @@ -45,3 +51,11 @@ void SceneManager::render() { } SceneManager::~SceneManager() = default; + +float SceneManager::getTransitionProgress() const { + if (assetLoader.getProgress().isDone()) { + return 1.0f; + } else { + return assetLoader.getProgress().fraction(); + } +} diff --git a/src/engine/core/scenes/SceneManager.h b/src/engine/core/scenes/SceneManager.h index 2621d5c..c3956ac 100644 --- a/src/engine/core/scenes/SceneManager.h +++ b/src/engine/core/scenes/SceneManager.h @@ -11,10 +11,12 @@ class Scene; class SceneManager { public: - void switchTo(std::unique_ptr next); + void switchTo(std::unique_ptr next, std::function onLoaded = nullptr); void update(); void render(); ~SceneManager(); + + float getTransitionProgress() const; private: std::unique_ptr currentScene; std::unique_ptr nextScene; @@ -22,6 +24,8 @@ private: AssetLoader assetLoader; bool isTransitioning = false; + + std::function onSceneLoaded; }; diff --git a/src/engine/core/scenes/SplashScreenLayer.cpp b/src/engine/core/scenes/SplashScreenLayer.cpp index c0da7aa..cb3ddbe 100644 --- a/src/engine/core/scenes/SplashScreenLayer.cpp +++ b/src/engine/core/scenes/SplashScreenLayer.cpp @@ -4,6 +4,7 @@ #include "SplashScreenLayer.h" +#include "SceneManager.h" #include "../../renderer/loader/AssetManager.h" #include "../../renderer/GUIRenderer.h" #include "../gui/uiComponent/UiImage.h" @@ -29,7 +30,8 @@ void SplashScreenLayer::onUpdate() { Dimensions rootParent {0.0, 0.0, 1.0, 1.0f}; rootContainer->uiPositioner.compute(rootParent); - progressbar->setProgress(progressbar->getProgress() + 0.01f); + const auto loadingProgress = Application::getInstance().sceneManager->getTransitionProgress(); + progressbar->setProgress(loadingProgress); } void SplashScreenLayer::onAttach() { diff --git a/src/engine/renderer/loader/async/AssetLoader.cpp b/src/engine/renderer/loader/async/AssetLoader.cpp index e14ecc1..e7b38a8 100644 --- a/src/engine/renderer/loader/async/AssetLoader.cpp +++ b/src/engine/renderer/loader/async/AssetLoader.cpp @@ -37,8 +37,10 @@ void AssetLoader::scheduleAsset(const AssetRequest &assetRequest) { } void AssetLoader::start() { - running = true; - loadingThread = std::thread(&AssetLoader::loadingThreadFunc, this); + if (!running) { + running = true; + loadingThread = std::thread(&AssetLoader::loadingThreadFunc, this); + } } void AssetLoader::stop() { diff --git a/src/game/DicewarsApp.cpp b/src/game/DicewarsApp.cpp index 330359f..e19c482 100644 --- a/src/game/DicewarsApp.cpp +++ b/src/game/DicewarsApp.cpp @@ -6,7 +6,10 @@ #include "../engine/core/scenes/SceneManager.h" #include "../engine/core/scenes/SplashScreen.h" +#include "scenes/main/MainMenu.h" DicewarsApp::DicewarsApp() { - sceneManager->switchTo(std::make_unique()); + sceneManager->switchTo(std::make_unique(), [this]() { + sceneManager->switchTo(std::make_unique()); + }); } diff --git a/src/game/scenes/main/MainMenu.cpp b/src/game/scenes/main/MainMenu.cpp new file mode 100644 index 0000000..74099cd --- /dev/null +++ b/src/game/scenes/main/MainMenu.cpp @@ -0,0 +1,23 @@ +// +// Created by sebastian on 24.04.26. +// + +#include "MainMenu.h" + +#include "MainUiLayer.h" + +void MainMenu::onEnter() { + addLayer(std::make_unique()); +} + +void MainMenu::onExit() { + for (const auto& layer: layers) { + layer->onDetach(); + } +} + +std::vector MainMenu::getRequiredAssets() { + std::vector requests; + requests.emplace_back(TextureRequest("mainCover", "assets/background.png")); + return requests; +} diff --git a/src/game/scenes/main/MainMenu.h b/src/game/scenes/main/MainMenu.h new file mode 100644 index 0000000..0043bba --- /dev/null +++ b/src/game/scenes/main/MainMenu.h @@ -0,0 +1,20 @@ +// +// Created by sebastian on 24.04.26. +// + +#ifndef MAINMENU_H +#define MAINMENU_H +#include "../../../engine/core/scenes/Scene.h" + + +class MainMenu: public Scene { +public: + void onEnter() override; + void onExit() override; + std::vector getRequiredAssets() override; + +}; + + + +#endif //MAINMENU_H diff --git a/src/game/scenes/main/MainUiLayer.cpp b/src/game/scenes/main/MainUiLayer.cpp new file mode 100644 index 0000000..c2c9f40 --- /dev/null +++ b/src/game/scenes/main/MainUiLayer.cpp @@ -0,0 +1,31 @@ +// +// Created by sebastian on 24.04.26. +// + +#include "MainUiLayer.h" +#include "../../../engine/renderer/loader/AssetManager.h" + +void MainUiLayer::onAttach() { + rootContainer = std::make_unique(); + rootContainer->setBackgroundTexture(AssetManager::getTexture("mainCover")->getTextureID()); + +} + +void MainUiLayer::onDetach() { + +} + +void MainUiLayer::onRender() { + UiRenderBundle renderBundle; + if (rootContainer) { + rootContainer->collectRenderData(renderBundle); + } + + auto guis = renderBundle.getGUITextures(); + guiRenderer->render(guis); +} + +void MainUiLayer::onUpdate() { + Dimensions rootParent {0.0, 0.0, 1.0, 1.0f}; + rootContainer->uiPositioner.compute(rootParent); +} diff --git a/src/game/scenes/main/MainUiLayer.h b/src/game/scenes/main/MainUiLayer.h new file mode 100644 index 0000000..6c65adc --- /dev/null +++ b/src/game/scenes/main/MainUiLayer.h @@ -0,0 +1,26 @@ +// +// Created by sebastian on 24.04.26. +// + +#ifndef MAINUILAYER_H +#define MAINUILAYER_H +#include "../../../engine/layer/Layer.h" +#include "../../../engine/renderer/GUIRenderer.h" +#include "../../../engine/renderer/loader/Loader.h" +#include "../../../engine/core/gui/uiMain/UiContainer.h" + +class MainUiLayer: public Layer { +public: + MainUiLayer(): guiRenderer(std::make_unique(Loader::instance())) {} + void onAttach() override; + void onDetach() override; + void onRender() override; + void onUpdate() override; +private: + std::unique_ptr guiRenderer; + std::unique_ptr rootContainer; +}; + + + +#endif //MAINUILAYER_H