summary refs log tree commit diff
path: root/src/Render.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Render.cpp')
-rw-r--r--src/Render.cpp23
1 files changed, 23 insertions, 0 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();
+    }
+}
+
 }