summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Render.cpp23
-rw-r--r--src/Render.hpp2
-rw-r--r--src/Time.cpp5
-rw-r--r--src/Time.hpp7
4 files changed, 36 insertions, 1 deletions
diff --git a/src/Render.cpp b/src/Render.cpp
index 2b16ed0..caebc29 100644
--- a/src/Render.cpp
+++ b/src/Render.cpp
@@ -7,6 +7,9 @@
#include "GFX/Image/PPMParser.hpp"
#include "GFX/Shading/Program.hpp"
#include "Math/MVP.hpp"
+#include <thread>
+
+#define FPS_LIMIT 30
namespace MC {
@@ -36,12 +39,22 @@ void Render::run() {
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
+ Time render_time{};
+
while (!m_window.should_close()) {
Scene scene = m_control->wait_for_render_data();
+ render_time.start_frame();
m_window.start_render();
render_scene(scene, texture);
+ render_time.end_frame();
+ wait_until_next_frame_start(render_time.delta_raw());
+
+ // This signal has to be the last thing in the loop,
+ // otherwise the logic thread could be blocked during
+ // it's `wait_for_render_finish` call.
+ // Still weird though, maybe there's a better way?
m_control->finish_render();
}
}
@@ -102,4 +115,14 @@ void Render::setup_gl() {
}
}
+void Render::wait_until_next_frame_start(Real spent_time_budget) const {
+ constexpr Real total_frame_time_budget = 1.0 / FPS_LIMIT;
+ Real remaining_time_budget = total_frame_time_budget - spent_time_budget;
+
+ if (remaining_time_budget > 0) {
+ auto frame_end = Time::now() + TO(U64, remaining_time_budget * 1000);
+ while (Time::now() < frame_end) std::this_thread::yield();
+ }
+}
+
}
diff --git a/src/Render.hpp b/src/Render.hpp
index 09c6fee..6670858 100644
--- a/src/Render.hpp
+++ b/src/Render.hpp
@@ -80,6 +80,8 @@ private:
void render_scene(Scene const& actions, GFX::Texture const& texture) const;
static void setup_gl();
+ void wait_until_next_frame_start(Real spent_time_budget) const;
+
GFX::Resources m_resources;
GFX::Window& m_window;
std::shared_ptr<Control> m_control;
diff --git a/src/Time.cpp b/src/Time.cpp
index 1953fed..a9608cc 100644
--- a/src/Time.cpp
+++ b/src/Time.cpp
@@ -12,7 +12,6 @@ void Time::start_frame() {
void Time::end_frame() {
auto frame_end = now();
m_delta = TO(Real, frame_end - m_current_frame_start) / 1000.0;
- m_delta = std::clamp(m_delta, delta_min, delta_max);
m_total_frames++;
}
@@ -26,6 +25,10 @@ Time::Tick Time::tick() const {
}
Real Time::delta() const {
+ return std::clamp(m_delta, delta_min, delta_max);
+}
+
+Real Time::delta_raw() const {
return m_delta;
}
diff --git a/src/Time.hpp b/src/Time.hpp
index 64ab4a2..62e2809 100644
--- a/src/Time.hpp
+++ b/src/Time.hpp
@@ -7,8 +7,10 @@ namespace MC {
class Time {
public:
+ // TODO: Document exact units of types.
using Timestamp = U64;
using Tick = U64;
+ // TODO: Create `Time::Duration` type.
Time() = default;
@@ -23,7 +25,12 @@ public:
// This is the same as total_frames(), but is more descriptive, sometimes.
// :)
PURE Tick tick() const;
+ // The time in seconds that has passed since the last frame.
+ // This is always a value between `0.001` and `0.1`.
PURE Real delta() const;
+ // The time in seconds that has passed since the last frame.
+ // Unlike `delta()`, this value is not clamped, and can be any positive value.
+ PURE Real delta_raw() const;
PURE Timestamp frame_start() const;