summaryrefslogtreecommitdiffhomepage
path: root/main/floormat-main-impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'main/floormat-main-impl.cpp')
-rw-r--r--main/floormat-main-impl.cpp106
1 files changed, 106 insertions, 0 deletions
diff --git a/main/floormat-main-impl.cpp b/main/floormat-main-impl.cpp
new file mode 100644
index 00000000..56c19882
--- /dev/null
+++ b/main/floormat-main-impl.cpp
@@ -0,0 +1,106 @@
+#include "floormat-main-impl.hpp"
+#include "floormat.hpp"
+#include "floormat-app.hpp"
+#include "compat/assert.hpp"
+#include "compat/fpu.hpp"
+
+namespace floormat {
+
+floormat_main::floormat_main() noexcept = default;
+floormat_main::~floormat_main() noexcept = default;
+
+static const char* const fm_fake_argv[] = { "floormat", nullptr };
+
+auto main_impl::make_window_flags(const fm_options& s) -> Configuration::WindowFlags
+{
+ using flag = Configuration::WindowFlag;
+ Configuration::WindowFlags flags{};
+ if (s.resizable)
+ flags |= flag::Resizable;
+ if (s.fullscreen)
+ flags |= flag::Fullscreen;
+ if (s.fullscreen_desktop)
+ flags |= flag::FullscreenDesktop;
+ if (s.borderless)
+ flags |= flag::Borderless;
+ if (s.maximized)
+ flags |= flag::Maximized;
+ return flags;
+}
+
+void main_impl::recalc_viewport(Vector2i size)
+{
+ GL::defaultFramebuffer.setViewport({{}, size });
+#ifdef FM_MSAA
+ _msaa_framebuffer.detach(GL::Framebuffer::ColorAttachment{0});
+ _msaa_renderbuffer = Magnum::GL::Renderbuffer{};
+ _msaa_renderbuffer.setStorageMultisample(s.msaa_samples, GL::RenderbufferFormat::RGBA8, size);
+ _msaa_framebuffer.setViewport({{}, size });
+ _msaa_framebuffer.attachRenderbuffer(GL::Framebuffer::ColorAttachment{0}, _msaa_renderbuffer);
+#endif
+ _shader.set_scale(Vector2(size));
+ app.on_viewport_event(size);
+ setMinimalLoopPeriod(5);
+}
+
+auto main_impl::make_conf(const fm_options& s) -> Configuration
+{
+ return Configuration{}
+ .setTitle(s.title)
+ .setSize(s.resolution)
+ .setWindowFlags(make_window_flags(s));
+}
+
+main_impl::main_impl(floormat_app& app, const fm_options& s) :
+ Platform::Sdl2Application{Arguments{fake_argc, fm_fake_argv},
+ make_conf(s), make_gl_conf(s)},
+ app{app}, s{s}
+{
+ switch (s.vsync)
+ {
+ case fm_tristate::on:
+ (void)setSwapInterval(1);
+ if (const auto list = GL::Context::current().extensionStrings();
+ std::find(list.cbegin(), list.cend(), "EXT_swap_control_tear") != list.cbegin())
+ (void)setSwapInterval(-1);
+ break;
+ case fm_tristate::off:
+ setSwapInterval(0);
+ break;
+ default: break;
+ }
+ set_fp_mask();
+ fm_assert(framebufferSize() == windowSize());
+ recalc_viewport(windowSize());
+ timeline.start();
+}
+
+main_impl::~main_impl() = default;
+
+void main_impl::drawEvent()
+{
+ if (const float dt = timeline.previousFrameDuration(); dt > 0)
+ {
+ constexpr float RC = 0.1f;
+ const float alpha = dt/(dt + RC);
+
+ _frame_time = _frame_time*(1-alpha) + alpha*dt;
+ }
+ else
+ swapBuffers();
+ timeline.nextFrame();
+
+ const auto dt = std::clamp((double)timeline.previousFrameDuration(), 1e-6, 1e-1);
+ app.update(dt);
+
+ _shader.set_tint({1, 1, 1, 1});
+}
+
+floormat_main* floormat_main::create(floormat_app& app, const fm_options& options)
+{
+ auto* ret = new main_impl(app, options);
+ fm_assert(ret);
+ return ret;
+}
+
+} // namespace floormat