From c8082104db804f9a6320ff0d79f8976d7dadd08e Mon Sep 17 00:00:00 2001 From: fleroviux Date: Wed, 1 May 2024 13:33:16 +0200 Subject: [PATCH] Zephyr: Renderer: introduce intermediate game thread render objects --- .../include/zephyr/renderer/render_engine.hpp | 8 +++++ zephyr/renderer/src/render_engine.cpp | 33 +++++++++++++------ 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/zephyr/renderer/include/zephyr/renderer/render_engine.hpp b/zephyr/renderer/include/zephyr/renderer/render_engine.hpp index 6497545..8c4d263 100644 --- a/zephyr/renderer/include/zephyr/renderer/render_engine.hpp +++ b/zephyr/renderer/include/zephyr/renderer/render_engine.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -22,6 +23,7 @@ namespace zephyr { void CreateRenderThread(); void JoinRenderThread(); void RenderThreadMain(); + void ReadyRenderThreadData(); std::shared_ptr m_render_backend; @@ -31,6 +33,12 @@ namespace zephyr { std::binary_semaphore m_caller_thread_semaphore{0}; //> Semaphore signalled by the calling thread std::binary_semaphore m_render_thread_semaphore{1}; //> Semaphore signalled by the rendering thread + struct GameThreadRenderObject { + Matrix4 local_to_world; + Geometry* geometry; + }; + std::vector m_game_thread_render_objects; + std::vector m_render_objects; }; diff --git a/zephyr/renderer/src/render_engine.cpp b/zephyr/renderer/src/render_engine.cpp index b896343..e2b794f 100644 --- a/zephyr/renderer/src/render_engine.cpp +++ b/zephyr/renderer/src/render_engine.cpp @@ -18,7 +18,7 @@ namespace zephyr { // Wait for the render thread to complete reading the internal render structures. m_render_thread_semaphore.acquire(); - m_render_objects.clear(); + m_game_thread_render_objects.clear(); scene_root->Traverse([&](SceneNode* node) -> bool { if(!node->IsVisible()) return false; @@ -28,8 +28,9 @@ namespace zephyr { const auto& geometry = mesh_component.geometry; if(geometry) { - m_render_objects.push_back({ - .local_to_world = node->GetTransform().GetWorld() + m_game_thread_render_objects.push_back({ + .local_to_world = node->GetTransform().GetWorld(), + .geometry = geometry.get() }); } } @@ -59,21 +60,33 @@ namespace zephyr { m_render_backend->InitializeContext(); while(m_render_thread_running) { - // Wait for the caller thread to prepare the internal render structures for the next frame. - m_render_thread_is_waiting = true; - m_caller_thread_semaphore.acquire(); - m_render_thread_is_waiting = false; + ReadyRenderThreadData(); // TODO(fleroviux): do not hardcode the aspect ratio. const Matrix4 projection = Matrix4::PerspectiveVK(45.0f, 16.0f/9.0, 0.01f, 100.0f); m_render_backend->Render(projection, m_render_objects); m_render_backend->SwapBuffers(); - - // Signal to the caller thread that we are done reading the internal render structures. - m_render_thread_semaphore.release(); } m_render_backend->DestroyContext(); } + void RenderEngine::ReadyRenderThreadData() { + // Wait for the caller thread to prepare the internal render structures for the next frame. + m_render_thread_is_waiting = true; + m_caller_thread_semaphore.acquire(); + m_render_thread_is_waiting = false; + + m_render_objects.clear(); + + for(const auto& game_thread_render_object : m_game_thread_render_objects) { + m_render_objects.push_back({ + .local_to_world = game_thread_render_object.local_to_world + }); + } + + // Signal to the caller thread that we are done reading the internal render structures. + m_render_thread_semaphore.release(); + } + } // namespace zephyr \ No newline at end of file