summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2025-04-18 19:43:44 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2025-04-18 19:43:44 +0100
commit6036877ac4e92da3185f21d5928bf3ed28d685b2 (patch)
tree5e5a5f6ad09e196bbecfbfec2a9a3c8f02262ca3
parentMerge branch 'openmesh-11' (diff)
parentRemember selected asset id and reload/reselect resource file on change (diff)
downloadilt-6036877ac4e92da3185f21d5928bf3ed28d685b2.tar.bz2
ilt-6036877ac4e92da3185f21d5928bf3ed28d685b2.tar.xz
ilt-6036877ac4e92da3185f21d5928bf3ed28d685b2.zip
Merge branch 'resviewer'HEADmain
-rw-r--r--Jamroot.jam11
-rw-r--r--application/main.cpp5
-rw-r--r--application/resviewer.cpp227
-rw-r--r--assetFactory/asset.cpp6
-rw-r--r--assetFactory/asset.h5
-rw-r--r--game/scenary/foliage.cpp10
-rw-r--r--game/scenary/foliage.h2
-rw-r--r--game/scenary/illuminator.cpp10
-rw-r--r--game/scenary/illuminator.h2
-rw-r--r--game/vehicles/railVehicleClass.cpp13
-rw-r--r--game/vehicles/railVehicleClass.h2
-rw-r--r--gfx/gl/sceneProvider.cpp2
-rw-r--r--gfx/gl/sceneRenderer.cpp1
-rw-r--r--test/testMainWindow.cpp2
-rw-r--r--ui/gameMainWindow.cpp6
-rw-r--r--ui/gameMainWindow.h9
-rw-r--r--ui/mainWindow.cpp7
-rw-r--r--ui/mainWindow.h5
-rw-r--r--ui/window.cpp7
-rw-r--r--ui/window.h5
-rw-r--r--ui/windowContent.h2
21 files changed, 300 insertions, 39 deletions
diff --git a/Jamroot.jam b/Jamroot.jam
index 9b589cf..8589861 100644
--- a/Jamroot.jam
+++ b/Jamroot.jam
@@ -12,6 +12,7 @@ pkg-config.import mxml : : <link>shared ;
pkg-config.import assimp : : <link>shared ;
lib pthread : : <link>shared ;
lib OpenMeshCore : : <link>shared ;
+lib boost_program_options : : <link>shared ;
variant coverage : debug ;
project i-like-trains : requirements
@@ -46,15 +47,15 @@ project i-like-trains : requirements
<toolset>tidy:<define>TIDY
;
-exe iliketrains :
- application/main.cpp
- :
- <library>ilt
- ;
+exe iliketrains : application/main.cpp : <library>ilt ;
+exe resviewer : application/resviewer.cpp : <library>ilt <library>boost_program_options ;
explicit main ;
always main ;
run iliketrains : -- : [ sequence.insertion-sort [ glob-tree-ex res : *.* ] ] : : main ;
+explicit runresviewer ;
+always runresviewer ;
+run resviewer : -- : [ sequence.insertion-sort [ glob-tree-ex res : *.xml ] ] : : runresviewer ;
lib ilt :
[ glob-tree *.cpp *.?s *.t?s : application bin test thirdparty ]
diff --git a/application/main.cpp b/application/main.cpp
index 9120376..a0c87c0 100644
--- a/application/main.cpp
+++ b/application/main.cpp
@@ -36,15 +36,14 @@
#include <ui/gameMainWindow.h>
#include <ui/window.h>
-static const int DISPLAY_WIDTH = 1280;
-static const int DISPLAY_HEIGHT = 1024;
+constexpr ScreenAbsCoord DEFAULT_WINDOW_SIZE {1280, 1024};
class DummyMainApplication : public GameState, public MainApplication {
public:
int
run()
{
- windows.create<MainWindow>(DISPLAY_WIDTH, DISPLAY_HEIGHT)->setContent<GameMainWindow>();
+ windows.create<MainWindow>(DEFAULT_WINDOW_SIZE, "I Like Trains")->setContent<GameMainWindow>();
terrain = world.create<Terrain>(GeoData::loadFromAsciiGrid("test/fixtures/height/SD19.asc"));
world.create<Water>(terrain);
diff --git a/application/resviewer.cpp b/application/resviewer.cpp
new file mode 100644
index 0000000..c82017b
--- /dev/null
+++ b/application/resviewer.cpp
@@ -0,0 +1,227 @@
+#include <backends/imgui_impl_opengl3.h>
+#include <backends/imgui_impl_sdl2.h>
+#include <boost/program_options.hpp>
+#include <game/environment.h>
+#include <game/gamestate.h>
+#include <game/terrain.h>
+#include <gfx/gl/sceneProvider.h>
+#include <gfx/gl/sceneRenderer.h>
+#include <gfx/renderable.h>
+#include <location.h>
+#include <ui/applicationBase.h>
+#include <ui/mainApplication.h>
+#include <ui/mainWindow.h>
+
+constexpr ScreenAbsCoord DEFAULT_WINDOW_SIZE {800, 600};
+constexpr GlobalDistance TERRAIN_LIMIT = 1'000'000;
+constexpr GlobalDistance TERRAIN_HEIGHT = 10'000;
+constexpr RelativeDistance DEFAULT_CAMERA_DIST = 7'000;
+constexpr GlobalDistance DEFAULT_CAMERA_HEIGHT = 5'000;
+constexpr GlobalDistance DEFAULT_CAMERA_FOCUS = 3'000;
+constexpr GlobalDistance MAX_CAMERA_HEIGHT = 10'000;
+constexpr GlobalDistance MIN_CAMERA_DIST = 1'000;
+constexpr GlobalDistance MAX_CAMERA_DIST = 30'000;
+
+class ViewerContent : public WindowContent, SceneRenderer, SceneProvider {
+public:
+ ViewerContent(ScreenAbsCoord size, std::span<const std::filesystem::path> files) :
+ SceneRenderer {size, 0}, fileList(files)
+ {
+ camera.setPosition(calcCameraPosition());
+ camera.lookAt({0, 0, TERRAIN_HEIGHT + cameraFocus});
+ gameState->terrain = std::make_shared<Terrain>(
+ GeoData::createFlat({-TERRAIN_LIMIT, -TERRAIN_LIMIT}, {TERRAIN_LIMIT, TERRAIN_LIMIT}, TERRAIN_HEIGHT));
+ }
+
+private:
+ [[nodiscard]]
+ GlobalPosition3D
+ calcCameraPosition() const
+ {
+ return {sincos(cameraAngle) * cameraDistance, TERRAIN_HEIGHT + cameraHeight};
+ }
+
+ void
+ render() override
+ {
+ SceneRenderer::render(*this);
+ controls();
+ }
+
+ void
+ tick(TickDuration tick) override
+ {
+ if (autoRotate != 0) {
+ cameraAngle = normalize(cameraAngle + (autoRotate * tick.count()));
+ camera.setPosition(calcCameraPosition());
+ camera.lookAt({0, 0, TERRAIN_HEIGHT + cameraFocus});
+ }
+ if (selectedFile) {
+ try {
+ if (const auto curmTime = std::filesystem::last_write_time(*selectedFile); curmTime != fileTime) {
+ location.reset();
+ selectedAsset = nullptr;
+ gameState->assets = AssetFactory::loadXML(*selectedFile)->assets;
+ fileTime = curmTime;
+ if (!selectedAssetId.empty() && gameState->assets.contains(selectedAssetId)) {
+ auto asset = gameState->assets.at(selectedAssetId);
+ auto renderable = asset.getAs<const Renderable>();
+ if (renderable) {
+ location = asset->createAt(position);
+ selectedAsset = renderable;
+ }
+ }
+ }
+ }
+ catch (...) {
+ }
+ }
+ }
+
+ bool
+ handleInput(const SDL_Event & event) override
+ {
+ if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED) {
+ SceneRenderer::resize({event.window.data1, event.window.data2});
+ }
+
+ return WindowContent::handleInput(event);
+ }
+
+ void
+ controls()
+ {
+ if (ImGui::Begin("Resource view")) {
+ ImGui::SetWindowSize({});
+ fileSelection();
+ assetSelection();
+ }
+ ImGui::End();
+
+ if (ImGui::Begin("Camera")) {
+ ImGui::SetWindowSize({});
+ if (std::max({ImGui::SliderFloat("Camera position", &cameraAngle, -pi, pi),
+ ImGui::SliderInt("Camera focus", &cameraFocus, 1, MAX_CAMERA_HEIGHT),
+ ImGui::SliderInt("Camera height", &cameraHeight, 1, MAX_CAMERA_HEIGHT),
+ ImGui::SliderFloat("Camera distance", &cameraDistance, MIN_CAMERA_DIST, MAX_CAMERA_DIST)})) {
+ camera.setPosition(calcCameraPosition());
+ camera.lookAt({0, 0, TERRAIN_HEIGHT + cameraFocus});
+ }
+ ImGui::SliderFloat("Auto rotate speed", &autoRotate, -1, 1);
+ }
+ ImGui::End();
+ }
+
+ void
+ fileSelection()
+ {
+ ImGui::BeginListBox("File");
+ for (const auto & file : fileList) {
+ if (ImGui::Selectable(file.c_str(), &file == selectedFile)) {
+ location.reset();
+ selectedAssetId.clear();
+ selectedAsset = nullptr;
+ gameState->assets = AssetFactory::loadXML(file)->assets;
+ fileTime = std::filesystem::last_write_time(file);
+ selectedFile = &file;
+ }
+ }
+ ImGui::EndListBox();
+ }
+
+ void
+ assetSelection()
+ {
+ if (!gameState->assets.empty()) {
+ ImGui::BeginListBox("Asset");
+ for (const auto & asset : gameState->assets) {
+ auto renderable = asset.second.getAs<const Renderable>();
+ if (renderable) {
+ if (ImGui::Selectable(asset.first.c_str(), renderable == selectedAsset)) {
+ selectedAssetId = asset.first;
+ selectedAsset = renderable;
+ location = asset.second->createAt(position);
+ }
+ }
+ }
+ ImGui::EndListBox();
+ }
+ }
+
+ void
+ content(const SceneShader & sceneShader, const Frustum & frustum) const override
+ {
+ gameState->terrain->render(sceneShader, frustum);
+ if (selectedAsset) {
+ selectedAsset->render(sceneShader, frustum);
+ }
+ }
+
+ void
+ lights(const SceneShader & sceneShader) const override
+ {
+ if (selectedAsset) {
+ selectedAsset->lights(sceneShader);
+ }
+ }
+
+ void
+ shadows(const ShadowMapper & mapper, const Frustum & frustum) const override
+ {
+ gameState->terrain->shadows(mapper, frustum);
+ if (selectedAsset) {
+ selectedAsset->shadows(mapper, frustum);
+ }
+ }
+
+ std::span<const std::filesystem::path> fileList;
+ std::filesystem::file_time_type fileTime;
+ const std::filesystem::path * selectedFile {};
+ std::string selectedAssetId;
+ const Renderable * selectedAsset {};
+ Location position {.pos = {0, 0, TERRAIN_HEIGHT}, .rot = {}};
+ std::any location;
+ Angle cameraAngle {0.F};
+ RelativeDistance cameraDistance {DEFAULT_CAMERA_DIST};
+ GlobalDistance cameraHeight {DEFAULT_CAMERA_HEIGHT};
+ GlobalDistance cameraFocus {DEFAULT_CAMERA_FOCUS};
+ float autoRotate {0.F};
+};
+
+int
+main(int argc, char ** argv)
+{
+ class ResViewer : GameState, MainApplication {
+ public:
+ void
+ run(std::span<const std::filesystem::path> fileList)
+ {
+ windows.create<MainWindow>(DEFAULT_WINDOW_SIZE, "ILT - Resource Viewer")
+ ->setContent<ViewerContent>(fileList);
+ mainLoop();
+ }
+ };
+
+ namespace po = boost::program_options;
+ po::options_description opts("ILT - Resource Viewer");
+ std::vector<std::filesystem::path> resources;
+ // clang-format off
+ opts.add_options()
+ ("resource,r", po::value(&resources)->composing(), "Resource file")
+ ("help,h", po::value<bool>()->default_value(false)->zero_tokens(), "Help")
+ ;
+ // clang-format on
+ po::positional_options_description pod;
+ pod.add("resource", -1);
+ po::variables_map varmap;
+ po::store(po::command_line_parser(argc, argv).options(opts).positional(pod).run(), varmap);
+ po::notify(varmap);
+
+ if (varmap.at("help").as<bool>()) {
+ std::cout << opts << '\n';
+ return EXIT_SUCCESS;
+ }
+
+ ResViewer {}.run(resources);
+ return EXIT_SUCCESS;
+}
diff --git a/assetFactory/asset.cpp b/assetFactory/asset.cpp
index e3f5feb..0254943 100644
--- a/assetFactory/asset.cpp
+++ b/assetFactory/asset.cpp
@@ -7,6 +7,12 @@ Asset::persist(Persistence::PersistenceStore & store)
return STORE_MEMBER(id) && STORE_MEMBER(name);
}
+std::any
+Asset::createAt(const Location &) const
+{
+ return {};
+}
+
Asset::TexturePtr
Asset::getTexture() const
{
diff --git a/assetFactory/asset.h b/assetFactory/asset.h
index b5de056..061a7c8 100644
--- a/assetFactory/asset.h
+++ b/assetFactory/asset.h
@@ -2,17 +2,22 @@
#include "factoryMesh.h"
#include "persistence.h"
+#include <any>
#include <manyPtr.h>
#include <stdTypeDefs.h>
class TextureAtlas;
class Renderable;
+class Location;
class Asset : public Persistence::Persistable, public StdTypeDefs<Asset> {
public:
using ManyPtr = ManySharedPtr<Asset, const Renderable>;
using TexturePtr = std::shared_ptr<TextureAtlas>;
+ /// Used only for the asset viewer
+ [[nodiscard]] virtual std::any createAt(const Location &) const;
+
std::string id;
std::string name;
diff --git a/game/scenary/foliage.cpp b/game/scenary/foliage.cpp
index 159a078..140c4e5 100644
--- a/game/scenary/foliage.cpp
+++ b/game/scenary/foliage.cpp
@@ -2,6 +2,16 @@
#include "gfx/gl/sceneShader.h"
#include "gfx/gl/shadowMapper.h"
#include "gfx/gl/vertexArrayObject.h"
+#include <location.h>
+
+static_assert(std::is_constructible_v<Foliage>);
+
+std::any
+Foliage::createAt(const Location & position) const
+{
+ return std::make_shared<InstanceVertices<LocationVertex>::InstanceProxy>(
+ instances.acquire(position.getRotationTransform(), position.rot.y, position.pos));
+}
bool
Foliage::persist(Persistence::PersistenceStore & store)
diff --git a/game/scenary/foliage.h b/game/scenary/foliage.h
index 71bc734..d15a8b0 100644
--- a/game/scenary/foliage.h
+++ b/game/scenary/foliage.h
@@ -17,6 +17,8 @@ class Foliage : public Asset, public Renderable, public StdTypeDefs<Foliage> {
glVertexArray instancePointVAO;
public:
+ [[nodiscard]] std::any createAt(const Location &) const override;
+
struct LocationVertex {
glm::mat3 rotation;
float yaw;
diff --git a/game/scenary/illuminator.cpp b/game/scenary/illuminator.cpp
index f1a02b2..d8e4c4e 100644
--- a/game/scenary/illuminator.cpp
+++ b/game/scenary/illuminator.cpp
@@ -2,6 +2,16 @@
#include "gfx/gl/sceneShader.h"
#include "gfx/gl/vertexArrayObject.h"
#include "gfx/models/texture.h" // IWYU pragma: keep
+#include <location.h>
+
+static_assert(std::is_constructible_v<Illuminator>);
+
+std::any
+Illuminator::createAt(const Location & position) const
+{
+ return std::make_shared<InstanceVertices<LocationVertex>::InstanceProxy>(
+ instances.acquire(position.getRotationTransform(), position.pos));
+}
bool
Illuminator::SpotLight::persist(Persistence::PersistenceStore & store)
diff --git a/game/scenary/illuminator.h b/game/scenary/illuminator.h
index 47ce337..200ba40 100644
--- a/game/scenary/illuminator.h
+++ b/game/scenary/illuminator.h
@@ -15,6 +15,8 @@ class Illuminator : public Asset, public Renderable, public StdTypeDefs<Illumina
std::optional<glVertexArray> instancesSpotLightVAO, instancesPointLightVAO;
public:
+ [[nodiscard]] std::any createAt(const Location &) const override;
+
struct LightCommonVertex {
RelativePosition3D position;
RGB colour;
diff --git a/game/vehicles/railVehicleClass.cpp b/game/vehicles/railVehicleClass.cpp
index 162a29a..21f01c8 100644
--- a/game/vehicles/railVehicleClass.cpp
+++ b/game/vehicles/railVehicleClass.cpp
@@ -17,6 +17,19 @@ RailVehicleClass::persist(Persistence::PersistenceStore & store)
&& STORE_HELPER(bodyMesh, Asset::MeshConstruct) && Asset::persist(store);
}
+std::any
+RailVehicleClass::createAt(const Location & position) const
+{
+ return std::make_shared<InstanceVertices<LocationVertex>::InstanceProxy>(instances.acquire(LocationVertex {
+ .body = position.getRotationTransform(),
+ .front = position.getRotationTransform(),
+ .back = position.getRotationTransform(),
+ .bodyPos = position.pos,
+ .frontPos = {sincos(position.rot.x) * wheelBase * 0.5F, position.pos.z},
+ .backPos = {sincos(position.rot.x) * wheelBase * -0.5F, position.pos.z},
+ }));
+}
+
void
RailVehicleClass::postLoad()
{
diff --git a/game/vehicles/railVehicleClass.h b/game/vehicles/railVehicleClass.h
index 6eb4ca5..ccff3e2 100644
--- a/game/vehicles/railVehicleClass.h
+++ b/game/vehicles/railVehicleClass.h
@@ -17,6 +17,8 @@ public:
void render(const SceneShader & shader, const Frustum &) const override;
void shadows(const ShadowMapper & shadowMapper, const Frustum &) const override;
+ [[nodiscard]] std::any createAt(const Location &) const override;
+
struct LocationVertex {
glm::mat3 body, front, back;
GlobalPosition3D bodyPos, frontPos, backPos;
diff --git a/gfx/gl/sceneProvider.cpp b/gfx/gl/sceneProvider.cpp
index e01532e..3681c60 100644
--- a/gfx/gl/sceneProvider.cpp
+++ b/gfx/gl/sceneProvider.cpp
@@ -5,7 +5,7 @@ void
SceneProvider::environment(const SceneShader &, const SceneRenderer & renderer) const
{
renderer.setAmbientLight({0.5F, 0.5F, 0.5F});
- renderer.setDirectionalLight({0.6F, 0.6F, 0.6F}, {{-quarter_pi, -quarter_pi}}, *this);
+ renderer.setDirectionalLight({0.6F, 0.6F, 0.6F}, {{-quarter_pi, quarter_pi}}, *this);
}
void
diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp
index 5d35d01..9a4d153 100644
--- a/gfx/gl/sceneRenderer.cpp
+++ b/gfx/gl/sceneRenderer.cpp
@@ -71,6 +71,7 @@ SceneRenderer::resize(ScreenAbsCoord newSize)
configuregdata(gIllumination, GL_RGB8, GL_RGB);
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.x, size.y);
+ shader.setViewPort({0, 0, size.x, size.y});
}
void
diff --git a/test/testMainWindow.cpp b/test/testMainWindow.cpp
index 4a76044..d048682 100644
--- a/test/testMainWindow.cpp
+++ b/test/testMainWindow.cpp
@@ -2,7 +2,7 @@
#include <boost/test/test_tools.hpp>
#include <format>
-TestMainWindow::TestMainWindow() : MainWindow {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/ui/gameMainWindow.cpp b/ui/gameMainWindow.cpp
index cc74f66..dbbf8a7 100644
--- a/ui/gameMainWindow.cpp
+++ b/ui/gameMainWindow.cpp
@@ -50,15 +50,13 @@ private:
GameMainSelector * gms;
};
-GameMainWindow::GameMainWindow(size_t w, size_t h) : SceneRenderer {{w, h}, 0}
+GameMainWindow::GameMainWindow(ScreenAbsCoord size) : SceneRenderer {size, 0}
{
uiComponents.create<ManualCameraController>(glm::vec2 {310'727'624, 494'018'810});
auto gms = uiComponents.create<GameMainSelector>(&camera);
uiComponents.create<GameMainToolbar>(gms);
}
-GameMainWindow::~GameMainWindow() { }
-
void
GameMainWindow::tick(TickDuration)
{
@@ -85,7 +83,7 @@ GameMainWindow::handleInput(const SDL_Event & event)
}
void
-GameMainWindow::render() const
+GameMainWindow::render()
{
SceneRenderer::render(*this);
glEnable(GL_BLEND);
diff --git a/ui/gameMainWindow.h b/ui/gameMainWindow.h
index b0f1592..71b6314 100644
--- a/ui/gameMainWindow.h
+++ b/ui/gameMainWindow.h
@@ -3,18 +3,13 @@
#include "chronology.h"
#include "gfx/gl/sceneRenderer.h"
#include "windowContent.h"
-#include <cstddef>
class GameMainWindow : public WindowContent, SceneRenderer, public SceneProvider {
public:
- GameMainWindow(size_t w, size_t h);
- ~GameMainWindow() override;
-
- NO_MOVE(GameMainWindow);
- NO_COPY(GameMainWindow);
+ GameMainWindow(ScreenAbsCoord size);
void tick(TickDuration) override;
- void render() const override;
+ void render() override;
private:
bool handleInput(const SDL_Event &) override;
diff --git a/ui/mainWindow.cpp b/ui/mainWindow.cpp
index 73c0b5b..57dabc0 100644
--- a/ui/mainWindow.cpp
+++ b/ui/mainWindow.cpp
@@ -8,12 +8,7 @@
#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_RESIZABLE | SDL_WINDOW_OPENGL}
-{
-}
-
-MainWindow::MainWindow(size_t w, size_t h, const std::string & title, Uint32 flags) : Window {w, h, title, flags}
+MainWindow::MainWindow(ScreenAbsCoord size, const char * title, Uint32 flags) : Window {size, title, flags}
{
if (const auto version = gladLoadGL(reinterpret_cast<GLADloadfunc>(SDL_GL_GetProcAddress)); version < 30003) {
throw std::runtime_error {std::format("Insufficient OpenGL version: {}", version)};
diff --git a/ui/mainWindow.h b/ui/mainWindow.h
index fe26c5c..d2de9b3 100644
--- a/ui/mainWindow.h
+++ b/ui/mainWindow.h
@@ -5,12 +5,9 @@
class MainWindow : public Window {
public:
- MainWindow(size_t w, size_t h);
+ MainWindow(ScreenAbsCoord size, const char * title, Uint32 flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL);
~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 732e9ef..06857b2 100644
--- a/ui/window.cpp
+++ b/ui/window.cpp
@@ -7,10 +7,9 @@
#include "backends/imgui_impl_sdl2.h"
#pragma GCC diagnostic pop
-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},
+Window::Window(ScreenAbsCoord size, const char * title, Uint32 flags) :
+ m_window {title, static_cast<int>(SDL_WINDOWPOS_CENTERED), static_cast<int>(SDL_WINDOWPOS_CENTERED), size.x, size.y,
+ flags},
glContext {m_window}
{
}
diff --git a/ui/window.h b/ui/window.h
index 62c34de..99a977f 100644
--- a/ui/window.h
+++ b/ui/window.h
@@ -15,7 +15,7 @@ using SDL_GLContextPtr = wrapped_ptrt<GL_Context, SDL_GL_CreateContext, SDL_GL_D
class Window {
public:
- Window(size_t width, size_t height, const std::string & title, Uint32 flags);
+ Window(ScreenAbsCoord size, const char * title, Uint32 flags);
virtual ~Window() = default;
NO_COPY(Window);
@@ -27,7 +27,7 @@ public:
{
glm::ivec2 size {};
SDL_GetWindowSizeInPixels(m_window, &size.x, &size.y);
- content = std::make_unique<C>(size.x, size.y, std::forward<P>(p)...);
+ content = std::make_unique<C>(ScreenAbsCoord {size.x, size.y}, std::forward<P>(p)...);
}
void tick(TickDuration elapsed);
@@ -39,7 +39,6 @@ public:
protected:
void clear(float r, float g, float b, float a) const;
- const ScreenAbsCoord size;
SDL_WindowPtr m_window;
SDL_GLContextPtr glContext;
WindowContent::Ptr content;
diff --git a/ui/windowContent.h b/ui/windowContent.h
index 762d1cc..34cbea3 100644
--- a/ui/windowContent.h
+++ b/ui/windowContent.h
@@ -14,7 +14,7 @@ public:
NO_COPY(WindowContent);
virtual void tick(TickDuration);
- virtual void render() const = 0;
+ virtual void render() = 0;
virtual bool handleInput(const SDL_Event & e);
protected: