From 1686a01b6ae7467e71eac247078248de4a3b3423 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 13 Dec 2021 23:47:30 +0000 Subject: Refactor to start splitting out UI components --- application/main.cpp | 75 +++--------- game/network/rail.cpp | 1 + game/vehicles/railVehicleClass.cpp | 1 + game/vehicles/vehicle.cpp | 2 +- gfx/camera_controller.h | 8 +- gfx/followCameraController.h | 3 - gfx/gl/glSource.cpp | 2 + gfx/gl/glSource.h | 1 + gfx/gl/shader.cpp | 3 +- gfx/gl/shader.h | 2 - gfx/gl/uiShader.cpp | 4 +- gfx/gl/uiShader.h | 3 +- gfx/inputHandler.h | 18 --- gfx/manualCameraController.cpp | 67 ----------- gfx/manualCameraController.h | 29 ----- gfx/window.cpp | 32 ----- gfx/window.h | 29 ----- iwyu.json | 240 ++++++++++++++++++++----------------- lib/jsonParse.ll | 1 + ui/gameMainWindow.cpp | 43 +++++++ ui/gameMainWindow.h | 27 +++++ ui/inputHandler.h | 18 +++ ui/manualCameraController.cpp | 67 +++++++++++ ui/manualCameraController.h | 26 ++++ ui/window.cpp | 42 +++++++ ui/window.h | 38 ++++++ 26 files changed, 427 insertions(+), 355 deletions(-) delete mode 100644 gfx/inputHandler.h delete mode 100644 gfx/manualCameraController.cpp delete mode 100644 gfx/manualCameraController.h delete mode 100644 gfx/window.cpp delete mode 100644 gfx/window.h create mode 100644 ui/gameMainWindow.cpp create mode 100644 ui/gameMainWindow.h create mode 100644 ui/inputHandler.h create mode 100644 ui/manualCameraController.cpp create mode 100644 ui/manualCameraController.h create mode 100644 ui/window.cpp create mode 100644 ui/window.h diff --git a/application/main.cpp b/application/main.cpp index 07a593b..9992ec0 100644 --- a/application/main.cpp +++ b/application/main.cpp @@ -16,22 +16,19 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include #include +#include // IWYU pragma: keep #include #include +#include +#include +#include #include static const int DISPLAY_WIDTH = 1280; static const int DISPLAY_HEIGHT = 1024; -class SDL_Application : public InputHandler, public std::enable_shared_from_this, GameState { +class SDL_Application : public GameState { public: SDL_Application() { @@ -46,7 +43,7 @@ public: SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); } - ~SDL_Application() override + ~SDL_Application() { SDL_Quit(); } @@ -54,35 +51,12 @@ public: NO_COPY(SDL_Application); NO_MOVE(SDL_Application); - std::shared_ptr train; - bool - handleInput(SDL_Event & e) override - { - switch (e.type) { - case SDL_QUIT: - isRunning = false; - return true; - case SDL_KEYUP: - switch (e.key.keysym.scancode) { - case SDL_SCANCODE_G: - train->currentActivity = std::make_unique(); - break; - case SDL_SCANCODE_I: - train->currentActivity = std::make_unique(); - break; - default: - return false; - } - return true; - } - return false; - } - + using Windows = Collection; int run() { - Collection windows; - windows.create(DISPLAY_WIDTH, DISPLAY_HEIGHT, "OpenGL"); + Windows windows; + windows.create(DISPLAY_WIDTH, DISPLAY_HEIGHT); world.create(); @@ -109,7 +83,7 @@ public: rl->addLinksBetween(l, s); rl->addLinksBetween(t, u); rl->addLinksBetween(u, m); - train = world.create(l3); + std::shared_ptr train = world.create(l3); auto b47 = std::make_shared("brush47"); for (int N = 0; N < 6; N++) { train->create(b47); @@ -119,49 +93,38 @@ public: train->currentActivity = train->orders.current()->createActivity(); } - Shader shader; - Camera camera({-1250.0F, -1250.0F, 35.0F}, 70.0F, rdiv(DISPLAY_WIDTH, DISPLAY_HEIGHT), 0.1F, 10000.0F); - shader.setView(camera.GetViewProjection()); - shader.setUniform("lightDirection", glm::normalize(glm::vec3 {1, 0, -1})); - shader.setUniform("lightColor", {.6, .6, .6}); - shader.setUniform("ambientColor", {0.5, 0.5, 0.5}); - auto t_start = std::chrono::high_resolution_clock::now(); - - inputStack.objects.push_back(shared_from_this()); - inputStack.objects.insert( - inputStack.objects.begin(), world.create(glm::vec2 {-1150, -1150})); - while (isRunning) { - processInputs(); + processInputs(windows); const auto t_end = std::chrono::high_resolution_clock::now(); const auto t_passed = std::chrono::duration_cast(t_end - t_start); world.apply(&WorldObject::tick, t_passed); - world.apply(&CameraController::updateCamera, &camera); - shader.setView(camera.GetViewProjection()); + windows.apply(&Window::tick, t_passed); windows.apply(&Window::Clear, 0.0F, 0.0F, 0.0F, 1.0F); - world.apply(&Renderable::render, shader); + windows.apply(&Window::Refresh, this); windows.apply(&Window::SwapBuffers); t_start = t_end; } - inputStack.removeAll(); return 0; } private: void - processInputs() + processInputs(const Windows & windows) { for (SDL_Event e; SDL_PollEvent(&e);) { - inputStack.applyOne(&InputHandler::handleInput, e); + if (e.type == SDL_QUIT) { + isRunning = false; + return; + } + windows.applyOne(&Window::handleInput, e); } } bool isRunning {true}; - Collection inputStack; }; int diff --git a/game/network/rail.cpp b/game/network/rail.cpp index d7f95a8..73ab3bf 100644 --- a/game/network/rail.cpp +++ b/game/network/rail.cpp @@ -2,6 +2,7 @@ #include "network.h" #include #include +#include #include #include #include diff --git a/game/vehicles/railVehicleClass.cpp b/game/vehicles/railVehicleClass.cpp index 8fd504f..689e1e6 100644 --- a/game/vehicles/railVehicleClass.cpp +++ b/game/vehicles/railVehicleClass.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/game/vehicles/vehicle.cpp b/game/vehicles/vehicle.cpp index 8730d6d..53450f6 100644 --- a/game/vehicles/vehicle.cpp +++ b/game/vehicles/vehicle.cpp @@ -7,7 +7,7 @@ #include "game/vehicles/linkHistory.h" #include #include -#include +#include #include #include #include diff --git a/gfx/camera_controller.h b/gfx/camera_controller.h index 926c93b..e6fc16d 100644 --- a/gfx/camera_controller.h +++ b/gfx/camera_controller.h @@ -1,12 +1,16 @@ #ifndef CAMERA_CONTROLLER_H #define CAMERA_CONTROLLER_H -#include +#include class Camera; -class CameraController : public WorldObject { +class CameraController { public: + CameraController() = default; + virtual ~CameraController() = default; + DEFAULT_MOVE_COPY(CameraController); + virtual void updateCamera(Camera *) const = 0; }; diff --git a/gfx/followCameraController.h b/gfx/followCameraController.h index ef2000d..cfe70c2 100644 --- a/gfx/followCameraController.h +++ b/gfx/followCameraController.h @@ -1,7 +1,6 @@ #ifndef FOLLOW_CAMERA_CONTROLLER_H #define FOLLOW_CAMERA_CONTROLLER_H -#include "game/worldobject.h" #include #include @@ -12,8 +11,6 @@ public: enum class Mode { Pan, Ride, ISO }; explicit FollowCameraController(VehicleWPtr, Mode = Mode::Pan); - void tick(TickDuration) override { } - void updateCamera(Camera * camera) const override; private: diff --git a/gfx/gl/glSource.cpp b/gfx/gl/glSource.cpp index 13686ae..49773d0 100644 --- a/gfx/gl/glSource.cpp +++ b/gfx/gl/glSource.cpp @@ -1,5 +1,7 @@ #include "glSource.h" #include +#include +#include GLsource::ShaderRef GLsource::compile() const diff --git a/gfx/gl/glSource.h b/gfx/gl/glSource.h index 53c221b..e44c5a2 100644 --- a/gfx/gl/glSource.h +++ b/gfx/gl/glSource.h @@ -3,6 +3,7 @@ #include #include +#include struct GLsource { using ShaderRef = glRef; diff --git a/gfx/gl/shader.cpp b/gfx/gl/shader.cpp index 03e7899..a196e07 100644 --- a/gfx/gl/shader.cpp +++ b/gfx/gl/shader.cpp @@ -2,6 +2,7 @@ #include "gfx/gl/glSource.h" #include #include +#include #include #include #include @@ -13,8 +14,6 @@ #include #include #include -#include -#include Shader::ProgramHandle::ProgramHandle(GLuint vs, GLuint fs) : ProgramHandleBase {vs, fs} { diff --git a/gfx/gl/shader.h b/gfx/gl/shader.h index 249b2f4..7df7a07 100644 --- a/gfx/gl/shader.h +++ b/gfx/gl/shader.h @@ -4,9 +4,7 @@ #include "programHandle.h" #include #include -#include #include -#include class Location; diff --git a/gfx/gl/uiShader.cpp b/gfx/gl/uiShader.cpp index 2fbb0d4..b3fee14 100644 --- a/gfx/gl/uiShader.cpp +++ b/gfx/gl/uiShader.cpp @@ -1,8 +1,10 @@ #include "uiShader.h" +#include +#include #include #include +#include #include -#include UIShader::UIShader(size_t width, size_t height) : program {uiShader_vs.compile(), uiShader_fs.compile()} { diff --git a/gfx/gl/uiShader.h b/gfx/gl/uiShader.h index ff0e96d..b251136 100644 --- a/gfx/gl/uiShader.h +++ b/gfx/gl/uiShader.h @@ -2,7 +2,8 @@ #define UISHADER_H #include "programHandle.h" -#include +#include +#include class UIShader { public: diff --git a/gfx/inputHandler.h b/gfx/inputHandler.h deleted file mode 100644 index 5b426c7..0000000 --- a/gfx/inputHandler.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef INPUT_HANDLER_H -#define INPUT_HANDLER_H - -#include - -union SDL_Event; - -class InputHandler { -public: - InputHandler() = default; - virtual ~InputHandler() = default; - - DEFAULT_MOVE_COPY(InputHandler); - - virtual bool handleInput(SDL_Event &) = 0; -}; - -#endif diff --git a/gfx/manualCameraController.cpp b/gfx/manualCameraController.cpp deleted file mode 100644 index cacf6ac..0000000 --- a/gfx/manualCameraController.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "manualCameraController.h" -#include -#include -#include -#include - -bool -ManualCameraController::handleInput(SDL_Event & e) -{ - switch (e.type) { - case SDL_KEYDOWN: - switch (e.key.keysym.sym) { - case SDLK_LCTRL: - case SDLK_RCTRL: - ctrl = true; - return true; - } - break; - case SDL_KEYUP: - switch (e.key.keysym.sym) { - case SDLK_LCTRL: - case SDLK_RCTRL: - ctrl = false; - return true; - } - break; - case SDL_MOUSEBUTTONDOWN: - switch (e.button.button) { - case SDL_BUTTON_RIGHT: - SDL_SetRelativeMouseMode(SDL_TRUE); - mrb = true; - return true; - } - break; - case SDL_MOUSEBUTTONUP: - switch (e.button.button) { - case SDL_BUTTON_RIGHT: - SDL_SetRelativeMouseMode(SDL_FALSE); - mrb = false; - return true; - } - break; - case SDL_MOUSEMOTION: - if (mrb) { - if (ctrl) { - direction -= 0.01F * static_cast(e.motion.xrel); - pitch = std::clamp(pitch - 0.01F * static_cast(e.motion.yrel), 0.1F, half_pi); - } - else { - focus += rotate_flat(-direction) * glm::vec2 {-e.motion.xrel, e.motion.yrel}; - } - } - return true; - case SDL_MOUSEWHEEL: - dist = std::clamp(dist - static_cast(e.wheel.y) * 4.F, 5.F, 200.F); - break; - } - return false; -} - -void -ManualCameraController::updateCamera(Camera * camera) const -{ - camera->forward = glm::normalize(sincosf(direction) ^ -sin(pitch)); - camera->pos = !focus + up * 3.F - (camera->forward * std::pow(dist, 1.3F)); - camera->up = up; -} diff --git a/gfx/manualCameraController.h b/gfx/manualCameraController.h deleted file mode 100644 index f2141a4..0000000 --- a/gfx/manualCameraController.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef MANUAL_CAMERA_CONTROLLER_H -#define MANUAL_CAMERA_CONTROLLER_H - -#include "game/worldobject.h" -#include "inputHandler.h" -#include -#include -#include -#include - -class Camera; - -class ManualCameraController : public CameraController, public InputHandler { -public: - explicit ManualCameraController(glm::vec2 f) : focus {f} { } - - bool handleInput(SDL_Event & e) override; - - void tick(TickDuration) override { } - - void updateCamera(Camera * camera) const override; - -private: - bool ctrl {false}, mrb {false}; - glm::vec2 focus; - float direction {quarter_pi}; - float dist {40}, pitch {quarter_pi}; -}; -#endif diff --git a/gfx/window.cpp b/gfx/window.cpp deleted file mode 100644 index dd300a7..0000000 --- a/gfx/window.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "window.h" -#include -#include - -Window::Window(int width, int height, const std::string & title) : - m_window {title.c_str(), static_cast(SDL_WINDOWPOS_CENTERED), static_cast(SDL_WINDOWPOS_CENTERED), width, - height, static_cast(SDL_WINDOW_OPENGL)}, - m_glContext {m_window} -{ - if (glewInit() != GLEW_OK) { - throw std::runtime_error {"Glew failed to initialize!"}; - } - - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -} - -void -Window::Clear(float r, float g, float b, float a) const -{ - glClearColor(r, g, b, a); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); -} - -void -Window::SwapBuffers() const -{ - SDL_GL_SwapWindow(m_window); -} diff --git a/gfx/window.h b/gfx/window.h deleted file mode 100644 index 252ccaa..0000000 --- a/gfx/window.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef DISPLAY_INCLUDED_H -#define DISPLAY_INCLUDED_H - -#include "ptr.hpp" -#include -#include -#include -#include - -class Window { -public: - Window(int width, int height, const std::string & title); - ~Window() = default; - - NO_COPY(Window); - NO_MOVE(Window); - - void Clear(float r, float g, float b, float a) const; - void SwapBuffers() const; - -private: - using GL_Context = std::remove_pointer_t; - using SDL_WindowPtr = wrapped_ptrt; - using SDL_GLContextPtr = wrapped_ptrt; - SDL_WindowPtr m_window; - SDL_GLContextPtr m_glContext; -}; - -#endif diff --git a/iwyu.json b/iwyu.json index 54e4e0c..515ab21 100644 --- a/iwyu.json +++ b/iwyu.json @@ -1,114 +1,130 @@ [ - { - "include": [ - "", - "private", - "", - "public" - ] - }, - { - "include": [ - "@\"SDL.*.h\"", - "private", - "", - "public" - ] - }, - { - "include": [ - "@", - "private", - "", - "public" - ] - }, - { - "include": [ - "@", - "private", - "", - "public" - ] - }, - { - "include": [ - "@", - "private", - "", - "public" - ] - }, - { - "include": [ - "@", - "private", - "", - "public" - ] - }, - { - "include": [ - "@", - "private", - "", - "public" - ] - }, - { - "include": [ - "@", - "private", - "", - "public" - ] - }, - { - "include": [ - "", - "private", - "", - "public" - ] - }, - { - "include": [ - "@", - "private", - "", - "public" - ] - }, - { - "include": [ - "@", - "private", - "", - "public" - ] - }, - { - "include": [ - "@", - "private", - "", - "public" - ] - }, - { - "include": [ - "@", - "private", - "", - "public" - ] - }, - { - "symbol": [ - "std::__atomic_wait", - "private", - "", - "public" - ] - } + { + "include": [ + "", + "private", + "", + "public" + ] + }, + { + "include": [ + "@\"SDL.*.h\"", + "private", + "", + "public" + ] + }, + { + "include": [ + "@", + "private", + "", + "public" + ] + }, + { + "include": [ + "@", + "private", + "", + "public" + ] + }, + { + "include": [ + "@", + "private", + "", + "public" + ] + }, + { + "include": [ + "@", + "private", + "", + "public" + ] + }, + { + "include": [ + "@", + "private", + "", + "public" + ] + }, + { + "include": [ + "@", + "private", + "", + "public" + ] + }, + { + "include": [ + "@", + "private", + "", + "public" + ] + }, + { + "include": [ + "", + "private", + "", + "public" + ] + }, + { + "include": [ + "@", + "private", + "", + "public" + ] + }, + { + "include": [ + "@", + "private", + "", + "public" + ] + }, + { + "include": [ + "@", + "private", + "", + "public" + ] + }, + { + "include": [ + "@", + "private", + "", + "public" + ] + }, + { + "symbol": [ + "std::abs", + "private", + "", + "public" + ] + }, + { + "symbol": [ + "std::__atomic_wait", + "private", + "", + "public" + ] + } ] diff --git a/lib/jsonParse.ll b/lib/jsonParse.ll index c646044..8029830 100644 --- a/lib/jsonParse.ll +++ b/lib/jsonParse.ll @@ -151,4 +151,5 @@ text [^\\\"]* LexerError("Unexpected input"); // Make iwyu think unistd.h is required [[maybe_unused]]static constexpr auto x=getpid; + [[maybe_unused]]static constexpr auto y=printf; } diff --git a/ui/gameMainWindow.cpp b/ui/gameMainWindow.cpp new file mode 100644 index 0000000..4421098 --- /dev/null +++ b/ui/gameMainWindow.cpp @@ -0,0 +1,43 @@ +#include "gameMainWindow.h" +#include "collection.hpp" +#include "gfx/camera_controller.h" +#include "manualCameraController.h" +#include "ui/window.h" +#include +#include +#include +#include // IWYU pragma: keep +#include +#include +#include +#include + +GameMainWindow::GameMainWindow(size_t w, size_t h) : + Window {static_cast(w), static_cast(h), "I Like Trains"}, uiShader {w, h}, camera {{-1250.0F, -1250.0F, + 35.0F}, + 70.0F, rdiv(w, h), + 0.1F, 10000.0F} +{ + inputStack.create(glm::vec2 {-1150, -1150}); + + shader.setUniform("lightDirection", glm::normalize(glm::vec3 {1, 0, -1})); + shader.setUniform("lightColor", {.6, .6, .6}); + shader.setUniform("ambientColor", {0.5, 0.5, 0.5}); +} + +void +GameMainWindow::tick(TickDuration) +{ + inputStack.apply(&CameraController::updateCamera, &camera); + shader.setView(camera.GetViewProjection()); +} + +void +GameMainWindow::Refresh(const GameState * gameState) const +{ + SDL_GL_MakeCurrent(m_window, m_glContext); + glEnable(GL_DEPTH_TEST); + gameState->world.apply(&Renderable::render, shader); + glDisable(GL_DEPTH_TEST); + // do ui bits +} diff --git a/ui/gameMainWindow.h b/ui/gameMainWindow.h new file mode 100644 index 0000000..affb389 --- /dev/null +++ b/ui/gameMainWindow.h @@ -0,0 +1,27 @@ +#ifndef UI_GAMEMAINWINDOW_H +#define UI_GAMEMAINWINDOW_H + +#include "chronology.hpp" +#include "gfx/gl/camera.h" +#include "gfx/gl/shader.h" +#include "gfx/gl/uiShader.h" +#include "window.h" +#include + +class GameState; + +class GameMainWindow : public Window { +public: + GameMainWindow(size_t w, size_t h); + + void tick(TickDuration) override; + + void Refresh(const GameState * gameState) const override; + +private: + UIShader uiShader; + Shader shader; + Camera camera; +}; + +#endif diff --git a/ui/inputHandler.h b/ui/inputHandler.h new file mode 100644 index 0000000..aac323b --- /dev/null +++ b/ui/inputHandler.h @@ -0,0 +1,18 @@ +#ifndef INPUT_HANDLER_H +#define INPUT_HANDLER_H + +#include + +union SDL_Event; + +class InputHandler { +public: + InputHandler() = default; + virtual ~InputHandler() = default; + + DEFAULT_MOVE_COPY(InputHandler); + + virtual bool handleInput(const SDL_Event &) = 0; +}; + +#endif diff --git a/ui/manualCameraController.cpp b/ui/manualCameraController.cpp new file mode 100644 index 0000000..1d3a067 --- /dev/null +++ b/ui/manualCameraController.cpp @@ -0,0 +1,67 @@ +#include "manualCameraController.h" +#include +#include +#include +#include + +bool +ManualCameraController::handleInput(const SDL_Event & e) +{ + switch (e.type) { + case SDL_KEYDOWN: + switch (e.key.keysym.sym) { + case SDLK_LCTRL: + case SDLK_RCTRL: + ctrl = true; + return true; + } + break; + case SDL_KEYUP: + switch (e.key.keysym.sym) { + case SDLK_LCTRL: + case SDLK_RCTRL: + ctrl = false; + return true; + } + break; + case SDL_MOUSEBUTTONDOWN: + switch (e.button.button) { + case SDL_BUTTON_RIGHT: + SDL_SetRelativeMouseMode(SDL_TRUE); + mrb = true; + return true; + } + break; + case SDL_MOUSEBUTTONUP: + switch (e.button.button) { + case SDL_BUTTON_RIGHT: + SDL_SetRelativeMouseMode(SDL_FALSE); + mrb = false; + return true; + } + break; + case SDL_MOUSEMOTION: + if (mrb) { + if (ctrl) { + direction -= 0.01F * static_cast(e.motion.xrel); + pitch = std::clamp(pitch - 0.01F * static_cast(e.motion.yrel), 0.1F, half_pi); + } + else { + focus += rotate_flat(-direction) * glm::vec2 {-e.motion.xrel, e.motion.yrel}; + } + } + return true; + case SDL_MOUSEWHEEL: + dist = std::clamp(dist - static_cast(e.wheel.y) * 4.F, 5.F, 200.F); + break; + } + return false; +} + +void +ManualCameraController::updateCamera(Camera * camera) const +{ + camera->forward = glm::normalize(sincosf(direction) ^ -sin(pitch)); + camera->pos = !focus + up * 3.F - (camera->forward * std::pow(dist, 1.3F)); + camera->up = up; +} diff --git a/ui/manualCameraController.h b/ui/manualCameraController.h new file mode 100644 index 0000000..ceff9ac --- /dev/null +++ b/ui/manualCameraController.h @@ -0,0 +1,26 @@ +#ifndef MANUAL_CAMERA_CONTROLLER_H +#define MANUAL_CAMERA_CONTROLLER_H + +#include "inputHandler.h" +#include +#include +#include +#include + +class Camera; + +class ManualCameraController : public CameraController, public InputHandler { +public: + explicit ManualCameraController(glm::vec2 f) : focus {f} { } + + bool handleInput(const SDL_Event & e) override; + + void updateCamera(Camera * camera) const override; + +private: + bool ctrl {false}, mrb {false}; + glm::vec2 focus; + float direction {quarter_pi}; + float dist {40}, pitch {quarter_pi}; +}; +#endif diff --git a/ui/window.cpp b/ui/window.cpp new file mode 100644 index 0000000..c451367 --- /dev/null +++ b/ui/window.cpp @@ -0,0 +1,42 @@ +#include "window.h" +#include "ui/inputHandler.h" +#include +#include + +Window::Window(int width, int height, const std::string & title) : + m_window {title.c_str(), static_cast(SDL_WINDOWPOS_CENTERED), static_cast(SDL_WINDOWPOS_CENTERED), width, + height, static_cast(SDL_WINDOW_OPENGL)}, + m_glContext {m_window} +{ + if (glewInit() != GLEW_OK) { + throw std::runtime_error {"Glew failed to initialize!"}; + } + + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +void +Window::Clear(float r, float g, float b, float a) const +{ + glClearColor(r, g, b, a); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +void +Window::SwapBuffers() const +{ + SDL_GL_SwapWindow(m_window); +} + +bool +Window::handleInput(const SDL_Event & e) +{ + if (SDL_GetWindowID(m_window) == e.window.windowID) { + inputStack.applyOne(&InputHandler::handleInput, e); + return true; + } + return false; +} diff --git a/ui/window.h b/ui/window.h new file mode 100644 index 0000000..f6279e2 --- /dev/null +++ b/ui/window.h @@ -0,0 +1,38 @@ +#ifndef DISPLAY_INCLUDED_H +#define DISPLAY_INCLUDED_H + +#include "chronology.hpp" +#include "collection.hpp" +#include "inputHandler.h" // IWYU pragma: keep +#include "ptr.hpp" +#include +#include +#include +#include + +class GameState; + +class Window { +public: + Window(int width, int height, const std::string & title); + virtual ~Window() = default; + + NO_COPY(Window); + NO_MOVE(Window); + + void Clear(float r, float g, float b, float a) const; + void SwapBuffers() const; + virtual void tick(TickDuration elapsed) = 0; + virtual void Refresh(const GameState *) const = 0; + bool handleInput(const SDL_Event & e); + +protected: + using GL_Context = std::remove_pointer_t; + using SDL_WindowPtr = wrapped_ptrt; + using SDL_GLContextPtr = wrapped_ptrt; + SDL_WindowPtr m_window; + SDL_GLContextPtr m_glContext; + Collection inputStack; +}; + +#endif -- cgit v1.2.3