summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-10-25 20:51:18 +0200
committerStanislaw Halik <sthalik@misaki.pl>2022-10-25 20:51:18 +0200
commit22998e309dcf6c95c36730f86030bece0fca9667 (patch)
treec35f1747655a3112f09ff23372811c8ac0259902
parent343ce367077777dab463816a0d1c5bb9bee9c837 (diff)
a
-rw-r--r--editor/draw.cpp2
-rw-r--r--floormat/main.hpp4
-rw-r--r--main/events.cpp3
-rw-r--r--main/main-impl.cpp79
-rw-r--r--main/main-impl.hpp10
5 files changed, 61 insertions, 37 deletions
diff --git a/editor/draw.cpp b/editor/draw.cpp
index f15a93af..c0ee7d1a 100644
--- a/editor/draw.cpp
+++ b/editor/draw.cpp
@@ -51,7 +51,7 @@ void app::draw()
GL::DebugOutput::setEnabled(GL::DebugOutput::Source::Api, GL::DebugOutput::Type::Other, {131185}, false); // nvidia krap
render_menu();
if (debug)
- GL::DebugOutput::setEnabled(GL::DebugOutput::Source::Api, GL::DebugOutput::Type::Other, {131185}, true); // nvidia krap
+ GL::DebugOutput::setEnabled(GL::DebugOutput::Source::Api, GL::DebugOutput::Type::Other, {131185}, true); // nvidia krap
}
} // namespace floormat
diff --git a/floormat/main.hpp b/floormat/main.hpp
index 6ba3b4c8..da7e59b9 100644
--- a/floormat/main.hpp
+++ b/floormat/main.hpp
@@ -26,7 +26,7 @@ struct floormat_main
virtual Magnum::Math::Vector2<int> window_size() const noexcept = 0;
virtual tile_shader& shader() noexcept = 0;
virtual const tile_shader& shader() const noexcept = 0;
- constexpr float smoothed_dt() const noexcept { return _frame_time; }
+ constexpr float smoothed_dt() const noexcept { return _frame_time1; }
virtual fm_settings& settings() noexcept = 0;
virtual const fm_settings& settings() const noexcept = 0;
@@ -42,7 +42,7 @@ struct floormat_main
[[nodiscard]] static floormat_main* create(floormat_app& app, fm_settings&& options);
protected:
- float _frame_time = 0;
+ float _frame_time1 = 0, _frame_time2 = 0;
};
} // namespace floormat
diff --git a/main/events.cpp b/main/events.cpp
index ac8f0766..35340a21 100644
--- a/main/events.cpp
+++ b/main/events.cpp
@@ -76,6 +76,8 @@ void main_impl::keyReleaseEvent(Platform::Sdl2Application::KeyEvent& event)
void main_impl::anyEvent(SDL_Event& event)
{
if (event.type == SDL_WINDOWEVENT)
+ {
+ update_from_window_flags();
switch (event.window.event)
{
case SDL_WINDOWEVENT_FOCUS_LOST:
@@ -89,6 +91,7 @@ void main_impl::anyEvent(SDL_Event& event)
default:
return app.on_any_event({event});
}
+ }
else
return app.on_any_event({event});
}
diff --git a/main/main-impl.cpp b/main/main-impl.cpp
index 856635d2..66388777 100644
--- a/main/main-impl.cpp
+++ b/main/main-impl.cpp
@@ -6,7 +6,8 @@
#include "src/world.hpp"
#include "src/camera-offset.hpp"
#include <Magnum/GL/DefaultFramebuffer.h>
-#include <cstdlib>
+#include <chrono>
+#include <thread>
//#define FM_SKIP_MSAA
@@ -90,7 +91,6 @@ main_impl::main_impl(floormat_app& app, fm_settings&& s, int& fake_argc) noexcep
if (const auto list = GL::Context::current().extensionStrings();
std::find(list.cbegin(), list.cend(), "EXT_swap_control_tear") != list.cbegin())
(void)setSwapInterval(-1);
- setMinimalLoopPeriod(0);
break;
case fm_tristate::off:
setSwapInterval(0);
@@ -155,14 +155,41 @@ void main_impl::draw_world() noexcept
}
}
+void main_impl::update_from_window_flags()
+{
+ const auto flags = (SDL_WindowFlags)SDL_GetWindowFlags(window());
+
+ dt_expected.do_sleep = true;
+ if (flags & SDL_WINDOW_HIDDEN)
+ dt_expected.value = 1;
+ else if (!(flags & SDL_WINDOW_INPUT_FOCUS))
+ dt_expected.value = 1.f / 30;
+#if 1
+ else if (!(flags & SDL_WINDOW_MOUSE_FOCUS))
+ dt_expected.value = 1.f / 60;
+#endif
+ else
+ {
+ dt_expected.do_sleep = false;
+ dt_expected.value = 1e-1f;
+ }
+}
+
void main_impl::drawEvent()
{
- if (const float dt = timeline.previousFrameDuration(); dt > 0)
+ float dt = timeline.previousFrameDuration();
+ if (dt > 0)
{
- constexpr float RC = 0.1f;
- const float alpha = dt/(dt + RC);
+ const float RC1 = dt_expected.do_sleep ? 1.f : 1.f/15,
+ RC2 = dt_expected.do_sleep ? 1.f/15 : 1.f/60;
+ const float alpha1 = dt/(dt + RC1);
+ const float alpha2 = dt/(dt + RC2);
- _frame_time = _frame_time*(1-alpha) + alpha*dt;
+ _frame_time1 = _frame_time1*(1-alpha1) + alpha1*dt;
+ _frame_time2 = _frame_time1*(1-alpha2) + alpha2*dt;
+ constexpr float max_deviation = 5 * 1e-3f;
+ if (std::fabs(_frame_time1 - _frame_time2) > max_deviation)
+ _frame_time1 = _frame_time2;
}
else
{
@@ -170,33 +197,9 @@ void main_impl::drawEvent()
timeline.nextFrame();
}
- {
- float dt_max;
- unsigned min_loop_period;
-
- if (const auto flags = SDL_GetWindowFlags(window());
- flags & SDL_WINDOW_HIDDEN)
- {
- dt_max = 1 + 1e-3f;
- min_loop_period = 1000;
- }
- else if (!(flags & (SDL_WINDOW_INPUT_FOCUS|SDL_WINDOW_MOUSE_FOCUS)))
- {
- dt_max = 1.f/10;
- min_loop_period = 1000/12;
- }
- else
- {
- dt_max = 1e-1f;
- min_loop_period = 0;
- }
-
- const float dt = std::clamp(timeline.previousFrameDuration(), 1e-6f, dt_max);
- setMinimalLoopPeriod(min_loop_period);
-
- app.update(dt);
- }
+ dt = std::clamp(dt, 1e-5f, dt_expected.value);
+ app.update(dt);
_shader.set_tint({1, 1, 1, 1});
{
@@ -217,6 +220,18 @@ void main_impl::drawEvent()
swapBuffers();
redraw();
+
+ if (dt_expected.do_sleep)
+ {
+ constexpr float jitter_max_seconds = 1 + 1e-3f;
+ const float dt0 = timeline.currentFrameTime(), sleep_secs = dt_expected.value - dt0 - dt_expected.jitter;
+ if (sleep_secs > 0)
+ std::this_thread::sleep_for(std::chrono::nanoseconds((long long)(sleep_secs * 1e9f)));
+ dt_expected.jitter += timeline.currentFrameTime() - dt_expected.value;
+ dt_expected.jitter = std::copysignf(std::fminf(jitter_max_seconds, std::fabsf(dt_expected.jitter)), dt_expected.jitter);
+ }
+ else
+ dt_expected.jitter = 0;
timeline.nextFrame();
}
diff --git a/main/main-impl.hpp b/main/main-impl.hpp
index 964bf1f3..202654db 100644
--- a/main/main-impl.hpp
+++ b/main/main-impl.hpp
@@ -51,6 +51,7 @@ struct main_impl final : Platform::Sdl2Application, floormat_main
[[maybe_unused]] void anyEvent(SDL_Event& event) override;
void drawEvent() override;
+ void update_from_window_flags();
bool is_text_input_active() const noexcept override;
void start_text_input() noexcept override;
@@ -60,13 +61,18 @@ struct main_impl final : Platform::Sdl2Application, floormat_main
private:
fm_settings s;
- char _dummy = maybe_register_debug_callback(s.gpu_debug);
- floormat_app& app;
+ [[maybe_unused]] char _dummy = maybe_register_debug_callback(s.gpu_debug);
+ floormat_app& app; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members)
tile_shader _shader;
struct world _world{};
floor_mesh _floor_mesh;
wall_mesh _wall_mesh;
Magnum::Timeline timeline;
+ struct {
+ float value = 1e-1f;
+ float jitter = 0;
+ bool do_sleep = true;
+ } dt_expected;
struct draw_bounds final { std::int16_t minx, maxx, miny, maxy; };