diff options
-rw-r--r-- | application/main.cpp | 3 | ||||
-rw-r--r-- | gfx/gl/uiShader.cpp | 1 | ||||
-rw-r--r-- | test/test-assetFactory.cpp | 4 | ||||
-rw-r--r-- | test/test-glContainer.cpp | 4 | ||||
-rw-r--r-- | test/test-instancing.cpp | 5 | ||||
-rw-r--r-- | test/test-network.cpp | 4 | ||||
-rw-r--r-- | test/test-render.cpp | 3 | ||||
-rw-r--r-- | test/test-text.cpp | 4 | ||||
-rw-r--r-- | test/testMainWindow.cpp | 2 | ||||
-rw-r--r-- | test/testMainWindow.h | 12 | ||||
-rw-r--r-- | ui/applicationBase.cpp | 1 | ||||
-rw-r--r-- | ui/gameMainWindow.cpp | 23 | ||||
-rw-r--r-- | ui/gameMainWindow.h | 11 | ||||
-rw-r--r-- | ui/mainWindow.cpp | 28 | ||||
-rw-r--r-- | ui/mainWindow.h | 16 | ||||
-rw-r--r-- | ui/window.cpp | 53 | ||||
-rw-r--r-- | ui/window.h | 29 | ||||
-rw-r--r-- | ui/windowContent.cpp | 32 | ||||
-rw-r--r-- | ui/windowContent.h | 26 |
19 files changed, 157 insertions, 104 deletions
diff --git a/application/main.cpp b/application/main.cpp index f0ba8bb..04c88f3 100644 --- a/application/main.cpp +++ b/application/main.cpp @@ -1,3 +1,4 @@ +#include "ui/mainWindow.h" #include <array> #include <assetFactory/assetFactory.h> #include <chrono> @@ -41,7 +42,7 @@ public: geoData = std::make_shared<GeoData>(GeoData::loadFromAsciiGrid("test/fixtures/height/SD19.asc")); Windows windows; - windows.create<GameMainWindow>(DISPLAY_WIDTH, DISPLAY_HEIGHT); + windows.create<MainWindow>(DISPLAY_WIDTH, DISPLAY_HEIGHT)->setContent<GameMainWindow>(); world.create<Terrain>(geoData); world.create<Water>(geoData); diff --git a/gfx/gl/uiShader.cpp b/gfx/gl/uiShader.cpp index cf53e2c..bb9570e 100644 --- a/gfx/gl/uiShader.cpp +++ b/gfx/gl/uiShader.cpp @@ -7,7 +7,6 @@ #include <gfx/gl/shaders/vs-uiShader.h> #include <glm/glm.hpp> #include <glm/gtc/type_ptr.hpp> -#include <initializer_list> UIShader::IconProgram::IconProgram(const glm::mat4 & vp) : UIProgram {vp, uiShader_vs, uiShader_fs} { } diff --git a/test/test-assetFactory.cpp b/test/test-assetFactory.cpp index 73370c8..1c2c417 100644 --- a/test/test-assetFactory.cpp +++ b/test/test-assetFactory.cpp @@ -21,10 +21,8 @@ #include "lib/location.h" #include "lib/stream_support.h" #include "testMainWindow.h" -#include "ui/applicationBase.h" -BOOST_GLOBAL_FIXTURE(ApplicationBase); -BOOST_GLOBAL_FIXTURE(TestMainWindow); +BOOST_GLOBAL_FIXTURE(TestMainWindowAppBase); const std::filesystem::path TMP {"/tmp"}; diff --git a/test/test-glContainer.cpp b/test/test-glContainer.cpp index ec1c0d1..332d440 100644 --- a/test/test-glContainer.cpp +++ b/test/test-glContainer.cpp @@ -1,7 +1,6 @@ #define BOOST_TEST_MODULE glContainer #include "testMainWindow.h" -#include "ui/applicationBase.h" #include <boost/test/data/test_case.hpp> #include <boost/test/unit_test.hpp> @@ -15,8 +14,7 @@ BOOST_TEST_DONT_PRINT_LOG_VALUE(glContainer<int>::const_iterator); BOOST_TEST_DONT_PRINT_LOG_VALUE(glContainer<int>::reverse_iterator); BOOST_TEST_DONT_PRINT_LOG_VALUE(glContainer<int>::const_reverse_iterator); -BOOST_GLOBAL_FIXTURE(ApplicationBase); -BOOST_GLOBAL_FIXTURE(TestMainWindow); +BOOST_GLOBAL_FIXTURE(TestMainWindowAppBase); BOOST_FIXTURE_TEST_SUITE(i, glContainer<int>) diff --git a/test/test-instancing.cpp b/test/test-instancing.cpp index c1860a4..3244bad 100644 --- a/test/test-instancing.cpp +++ b/test/test-instancing.cpp @@ -1,17 +1,14 @@ #define BOOST_TEST_MODULE instancing #include "stream_support.h" -#include "testHelpers.h" #include "testMainWindow.h" -#include "ui/applicationBase.h" #include <boost/test/data/test_case.hpp> #include <boost/test/unit_test.hpp> #include <set> #include <gfx/gl/instanceVertices.h> -BOOST_GLOBAL_FIXTURE(ApplicationBase); -BOOST_GLOBAL_FIXTURE(TestMainWindow); +BOOST_GLOBAL_FIXTURE(TestMainWindowAppBase); BOOST_FIXTURE_TEST_SUITE(i, InstanceVertices<int>) diff --git a/test/test-network.cpp b/test/test-network.cpp index 174e2a5..59eebae 100644 --- a/test/test-network.cpp +++ b/test/test-network.cpp @@ -5,7 +5,6 @@ #include <boost/test/unit_test.hpp> #include "testMainWindow.h" -#include "ui/applicationBase.h" #include <array> #include <collection.h> #include <game/network/link.h> @@ -20,8 +19,7 @@ #include <utility> #include <vector> -BOOST_GLOBAL_FIXTURE(ApplicationBase); -BOOST_GLOBAL_FIXTURE(TestMainWindow); +BOOST_GLOBAL_FIXTURE(TestMainWindowAppBase); struct TestLinkS; diff --git a/test/test-render.cpp b/test/test-render.cpp index 79424f5..2c4efea 100644 --- a/test/test-render.cpp +++ b/test/test-render.cpp @@ -69,8 +69,7 @@ public: } }; -BOOST_GLOBAL_FIXTURE(ApplicationBase); -BOOST_GLOBAL_FIXTURE(TestMainWindow); +BOOST_GLOBAL_FIXTURE(TestMainWindowAppBase); BOOST_DATA_TEST_CASE(cam, boost::unit_test::data::xrange(500, 30000, 1300) * boost::unit_test::data::xrange(500, 10000, 300) diff --git a/test/test-text.cpp b/test/test-text.cpp index f185cf5..b0a9503 100644 --- a/test/test-text.cpp +++ b/test/test-text.cpp @@ -7,7 +7,6 @@ #include "testMainWindow.h" #include "testRenderOutput.h" -#include "ui/applicationBase.h" #include "ui/text.h" #include <array> #include <gfx/models/texture.h> @@ -16,8 +15,7 @@ #include <unicode.h> #include <vector> -BOOST_GLOBAL_FIXTURE(ApplicationBase); -BOOST_GLOBAL_FIXTURE(TestMainWindow); +BOOST_GLOBAL_FIXTURE(TestMainWindowAppBase); BOOST_AUTO_TEST_CASE(utf8_string_view_iter) { diff --git a/test/testMainWindow.cpp b/test/testMainWindow.cpp index d0b674c..4a76044 100644 --- a/test/testMainWindow.cpp +++ b/test/testMainWindow.cpp @@ -2,7 +2,7 @@ #include <boost/test/test_tools.hpp> #include <format> -TestMainWindow::TestMainWindow() : Window {1, 1, __FILE__, SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN} +TestMainWindow::TestMainWindow() : MainWindow {1, 1, __FILE__, SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN} { glEnable(GL_DEBUG_OUTPUT); glDebugMessageCallback( diff --git a/test/testMainWindow.h b/test/testMainWindow.h index 445491d..f54eb72 100644 --- a/test/testMainWindow.h +++ b/test/testMainWindow.h @@ -1,15 +1,13 @@ #pragma once -#include "ui/window.h" +#include "ui/applicationBase.h" +#include "ui/mainWindow.h" -class TestMainWindow : public Window { +class TestMainWindow : public MainWindow { // This exists only to hold an OpenGL context open for the duration of the tests, // in the same way a real main window would always exist. public: TestMainWindow(); - - void - tick(TickDuration) override - { - } }; + +class TestMainWindowAppBase : public ApplicationBase, public TestMainWindow { }; diff --git a/ui/applicationBase.cpp b/ui/applicationBase.cpp index 3fa6e2b..c3134b4 100644 --- a/ui/applicationBase.cpp +++ b/ui/applicationBase.cpp @@ -35,6 +35,7 @@ ApplicationBase::initSDL() const void ApplicationBase::initImGUI() const { + puts(__PRETTY_FUNCTION__); // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); diff --git a/ui/gameMainWindow.cpp b/ui/gameMainWindow.cpp index 8e93694..6168504 100644 --- a/ui/gameMainWindow.cpp +++ b/ui/gameMainWindow.cpp @@ -16,12 +16,6 @@ #include <glm/glm.hpp> #include <memory> -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wold-style-cast" -#include "backends/imgui_impl_opengl3.h" -#include "backends/imgui_impl_sdl2.h" -#pragma GCC diagnostic pop - class GameMainToolbar : Mode<decltype(GameMainSelector::target)>, public Toolbar { public: explicit GameMainToolbar(GameMainSelector * gms_) : @@ -33,22 +27,14 @@ public: } }; -GameMainWindow::GameMainWindow(size_t w, size_t h) : - Window {w, h, "I Like Trains", SDL_WINDOW_OPENGL}, SceneRenderer {Window::size, 0} +GameMainWindow::GameMainWindow(size_t w, size_t h) : WindowContent {w, h}, SceneRenderer {{w, h}, 0} { - ImGui_ImplSDL2_InitForOpenGL(m_window, glContext.get()); - ImGui_ImplOpenGL3_Init(); - uiComponents.create<ManualCameraController>(glm::vec2 {310'727'624, 494'018'810}); auto gms = uiComponents.create<GameMainSelector>(&camera, ScreenAbsCoord {w, h}); uiComponents.create<GameMainToolbar>(gms.get()); } -GameMainWindow::~GameMainWindow() -{ - ImGui_ImplOpenGL3_Shutdown(); - ImGui_ImplSDL2_Shutdown(); -} +GameMainWindow::~GameMainWindow() { } void GameMainWindow::tick(TickDuration) @@ -60,7 +46,10 @@ void GameMainWindow::render() const { SceneRenderer::render(*this); - Window::render(); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_DEPTH_TEST); + uiComponents.apply(&UIComponent::render, uiShader, UIComponent::Position {}); } void diff --git a/ui/gameMainWindow.h b/ui/gameMainWindow.h index 594843d..fcbd135 100644 --- a/ui/gameMainWindow.h +++ b/ui/gameMainWindow.h @@ -2,21 +2,20 @@ #include "chronology.h" #include "gfx/gl/sceneRenderer.h" -#include "window.h" +#include "windowContent.h" #include <cstddef> -class GameMainWindow : public Window, SceneRenderer, public SceneProvider { +class GameMainWindow : public WindowContent, SceneRenderer, public SceneProvider { public: GameMainWindow(size_t w, size_t h); ~GameMainWindow() override; - void tick(TickDuration) override; - - void render() const override; - NO_MOVE(GameMainWindow); NO_COPY(GameMainWindow); + void tick(TickDuration) override; + void render() const override; + private: void content(const SceneShader &) const override; void environment(const SceneShader &, const SceneRenderer &) const override; diff --git a/ui/mainWindow.cpp b/ui/mainWindow.cpp new file mode 100644 index 0000000..830dba5 --- /dev/null +++ b/ui/mainWindow.cpp @@ -0,0 +1,28 @@ +#include "mainWindow.h" +#include <format> +#include <stdexcept> + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wold-style-cast" +#include "backends/imgui_impl_opengl3.h" +#include "backends/imgui_impl_sdl2.h" +#pragma GCC diagnostic pop + +MainWindow::MainWindow(size_t w, size_t h) : MainWindow {w, h, "I Like Trains", SDL_WINDOW_OPENGL} { } + +MainWindow::MainWindow(size_t w, size_t h, const std::string & title, Uint32 flags) : Window {w, h, title, flags} +{ + puts(__PRETTY_FUNCTION__); + if (const auto version = gladLoadGL(reinterpret_cast<GLADloadfunc>(SDL_GL_GetProcAddress)); version < 30003) { + throw std::runtime_error {std::format("Insufficient OpenGL version: {}", version)}; + } + + ImGui_ImplSDL2_InitForOpenGL(m_window, glContext.get()); + ImGui_ImplOpenGL3_Init(); +} + +MainWindow::~MainWindow() +{ + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplSDL2_Shutdown(); +} diff --git a/ui/mainWindow.h b/ui/mainWindow.h new file mode 100644 index 0000000..fe26c5c --- /dev/null +++ b/ui/mainWindow.h @@ -0,0 +1,16 @@ +#pragma once + +#include "window.h" +#include <cstddef> + +class MainWindow : public Window { +public: + MainWindow(size_t w, size_t h); + ~MainWindow() override; + + NO_MOVE(MainWindow); + NO_COPY(MainWindow); + +protected: + MainWindow(size_t width, size_t height, const std::string & title, Uint32 flags); +}; diff --git a/ui/window.cpp b/ui/window.cpp index dd488d7..8ceaf49 100644 --- a/ui/window.cpp +++ b/ui/window.cpp @@ -1,28 +1,12 @@ #include "window.h" -#include "uiComponent.h" -#include <format> #include <glad/gl.h> #include <glm/glm.hpp> -#include <stdexcept> - -Window::GLInitHelper::GLInitHelper() -{ - [[maybe_unused]] static auto init = []() { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - if (const auto version = gladLoadGL(reinterpret_cast<GLADloadfunc>(SDL_GL_GetProcAddress)); version < 30003) { - throw std::runtime_error {std::format("Insufficient OpenGL version: {}", version)}; - } - else { - return version; - } - }(); -} Window::Window(size_t width, size_t height, const std::string & title, Uint32 flags) : size {static_cast<int>(width), static_cast<int>(height)}, m_window {title.c_str(), static_cast<int>(SDL_WINDOWPOS_CENTERED), static_cast<int>(SDL_WINDOWPOS_CENTERED), size.x, size.y, flags}, - glContext {m_window}, uiShader {width, height} + glContext {m_window} { } @@ -39,23 +23,21 @@ Window::swapBuffers() const SDL_GL_SwapWindow(m_window); } +void +Window::tick(TickDuration elapsed) +{ + if (content) { + content->tick(elapsed); + } +} + bool Window::handleInput(const SDL_Event & e) { if (SDL_GetWindowID(m_window) == e.window.windowID) { - SDL_Event eAdjusted {e}; - switch (e.type) { - // SDL and OpenGL have coordinates that are vertically opposed. - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - eAdjusted.button.y = size.y - e.button.y; - break; - case SDL_MOUSEMOTION: - eAdjusted.motion.y = size.y - e.motion.y; - break; + if (content) { + return content->handleInput(e); } - uiComponents.rapplyOne(&UIComponent::handleInput, eAdjusted, UIComponent::Position {{}, size}); - return true; } return false; } @@ -66,16 +48,9 @@ Window::refresh() const SDL_GL_MakeCurrent(m_window, glContext); clear(0.0F, 0.0F, 0.0F, 1.0F); - render(); + if (content) { + content->render(); + } swapBuffers(); } - -void -Window::render() const -{ - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_DEPTH_TEST); - uiComponents.apply(&UIComponent::render, uiShader, UIComponent::Position {}); -} diff --git a/ui/window.h b/ui/window.h index 8f2b70b..62c34de 100644 --- a/ui/window.h +++ b/ui/window.h @@ -1,13 +1,12 @@ #pragma once #include "chronology.h" -#include "collection.h" -#include "gfx/gl/uiShader.h" +#include "config/types.h" #include "ptr.h" -#include "uiComponent.h" // IWYU pragma: keep +#include "special_members.h" +#include "windowContent.h" #include <SDL2/SDL.h> #include <cstddef> -#include <special_members.h> #include <string> using SDL_WindowPtr = wrapped_ptrt<SDL_Window, SDL_CreateWindow, SDL_DestroyWindow>; @@ -22,24 +21,26 @@ public: NO_COPY(Window); NO_MOVE(Window); - virtual void tick(TickDuration elapsed) = 0; + template<typename C, typename... P> + void + setContent(P &&... p) + { + glm::ivec2 size {}; + SDL_GetWindowSizeInPixels(m_window, &size.x, &size.y); + content = std::make_unique<C>(size.x, size.y, std::forward<P>(p)...); + } + + void tick(TickDuration elapsed); void refresh() const; bool handleInput(const SDL_Event & e); - void clear(float r, float g, float b, float a) const; void swapBuffers() const; protected: - virtual void render() const; - - struct GLInitHelper { - GLInitHelper(); - }; + void clear(float r, float g, float b, float a) const; const ScreenAbsCoord size; SDL_WindowPtr m_window; SDL_GLContextPtr glContext; - GLInitHelper glInithelper; - Collection<UIComponent> uiComponents; - UIShader uiShader; + WindowContent::Ptr content; }; diff --git a/ui/windowContent.cpp b/ui/windowContent.cpp new file mode 100644 index 0000000..91732a7 --- /dev/null +++ b/ui/windowContent.cpp @@ -0,0 +1,32 @@ +#include "windowContent.h" +#include "SDL_events.h" + +WindowContent::WindowContent(size_t width, size_t height) : uiShader {width, height} { } + +void +WindowContent::tick(TickDuration) +{ +} + +bool +WindowContent::handleInput(const SDL_Event & e) +{ + SDL_Event eAdjusted {e}; + const auto size = [&e] { + glm::ivec2 size {}; + SDL_GetWindowSizeInPixels(SDL_GetWindowFromID(e.window.windowID), &size.x, &size.y); + return size; + }(); + switch (e.type) { + // SDL and OpenGL have coordinates that are vertically opposed. + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + eAdjusted.button.y = size.y - e.button.y; + break; + case SDL_MOUSEMOTION: + eAdjusted.motion.y = size.y - e.motion.y; + break; + } + uiComponents.rapplyOne(&UIComponent::handleInput, eAdjusted, UIComponent::Position {{}, size}); + return true; +} diff --git a/ui/windowContent.h b/ui/windowContent.h new file mode 100644 index 0000000..474445a --- /dev/null +++ b/ui/windowContent.h @@ -0,0 +1,26 @@ +#pragma once + +#include "chronology.h" +#include "collection.h" +#include "gfx/gl/uiShader.h" +#include "special_members.h" +#include "stdTypeDefs.h" +#include "uiComponent.h" // IWYU pragma: keep +#include <functional> + +class WindowContent : public StdTypeDefs<WindowContent> { +public: + using Factory = std::function<Ptr(size_t width, size_t height)>; + WindowContent(size_t width, size_t height); + virtual ~WindowContent() = default; + NO_MOVE(WindowContent); + NO_COPY(WindowContent); + + virtual void tick(TickDuration); + virtual void render() const = 0; + virtual bool handleInput(const SDL_Event & e); + +protected: + ::Collection<UIComponent> uiComponents; + UIShader uiShader; +}; |