Skip to content

Commit

Permalink
Begin separate render thread implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
fleroviux committed Mar 1, 2024
1 parent 7c4a2f9 commit 4085554
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 5 deletions.
4 changes: 4 additions & 0 deletions app/runtime/src/main_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ namespace zephyr {
ZEPHYR_INFO("metalness={}", pbr_material->GetParameter<f32>("metalness"));
ZEPHYR_INFO("roughness={}", pbr_material->GetParameter<f32>("roughness"));
}

m_render_engine = std::make_unique<RenderEngine>();
}

MainWindow::~MainWindow() {
Expand Down Expand Up @@ -84,6 +86,8 @@ namespace zephyr {
return true;
});

m_render_engine->RenderScene(m_scene_root.get());

const Mesh3D* current_mesh = nullptr;
const Material* current_material = nullptr;
GraphicsPipeline* current_pipeline = nullptr;
Expand Down
3 changes: 3 additions & 0 deletions app/runtime/src/main_window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <zephyr/renderer/texture/texture_2D.hpp>
#include <zephyr/renderer/texture/texture_cube.hpp>
#include <zephyr/renderer/mesh.hpp>
#include <zephyr/renderer/render_engine.hpp>
#include <zephyr/scene/mesh.hpp>
#include <zephyr/scene/node.hpp>
#include <zephyr/window/window.hpp>
Expand Down Expand Up @@ -78,6 +79,8 @@ namespace zephyr {

std::unique_ptr<SceneNode> m_scene_root;

std::unique_ptr<RenderEngine> m_render_engine;

Matrix4 m_projection_matrix;
uint m_frame{0};
uint m_frames_in_flight{};
Expand Down
5 changes: 3 additions & 2 deletions zephyr/renderer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

set(SOURCES
src/placeholder.cpp
src/render_engine.cpp
)

set(HEADERS
Expand All @@ -21,11 +21,12 @@ set(HEADERS_PUBLIC
include/zephyr/renderer/texture/texture_cube.hpp
include/zephyr/renderer/texture/texture_resource.hpp
include/zephyr/renderer/mesh.hpp
include/zephyr/renderer/render_engine.hpp
include/zephyr/renderer/resource.hpp
)

add_library(zephyr-renderer ${SOURCES} ${HEADERS} ${HEADERS_PUBLIC})

target_link_libraries(zephyr-renderer PUBLIC zephyr-common zephyr-cxx-opts)
target_link_libraries(zephyr-renderer PUBLIC zephyr-common zephyr-math zephyr-gpu zephyr-scene zephyr-cxx-opts)
target_include_directories(zephyr-renderer PUBLIC include)
target_include_directories(zephyr-renderer PRIVATE src)
39 changes: 39 additions & 0 deletions zephyr/renderer/include/zephyr/renderer/render_engine.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

#pragma once

#include <zephyr/math/matrix4.hpp>
#include <zephyr/scene/node.hpp>
#include <zephyr/scene/mesh.hpp>
#include <atomic>
#include <semaphore>
#include <thread>
#include <vector>

namespace zephyr {

struct RenderObject {
Matrix4 local_to_world_transform;
};

class RenderEngine {
public:
RenderEngine();
~RenderEngine();

void RenderScene(SceneNode* scene_root);

private:
void CreateRenderThread();
void JoinRenderThread();
void RenderThreadMain();

std::thread m_render_thread;
std::atomic_bool m_render_thread_running;
std::atomic_bool m_render_thread_is_waiting;
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

std::vector<RenderObject> m_render_objects;
};

} // namespace zephyr
Empty file.
65 changes: 65 additions & 0 deletions zephyr/renderer/src/render_engine.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@

#include <zephyr/renderer/render_engine.hpp>
#include <fmt/format.h>

namespace zephyr {

RenderEngine::RenderEngine() {
CreateRenderThread();
}

RenderEngine::~RenderEngine() {
JoinRenderThread();
}

void RenderEngine::RenderScene(SceneNode* scene_root) {
// Wait for the render thread to complete reading the internal render structures.
m_render_thread_semaphore.acquire();

m_render_objects.clear();

scene_root->Traverse([&](SceneNode* node) -> bool {
if(!node->IsVisible()) return false;

if(node->HasComponent<MeshComponent>()) {
m_render_objects.push_back({
.local_to_world_transform = node->GetTransform().GetWorld()
});
}

return true;
});

// Signal to the render thread that the next frame is ready
m_caller_thread_semaphore.release();
}

void RenderEngine::CreateRenderThread() {
m_render_thread_running = true;
m_render_thread_is_waiting = false;
m_render_thread = std::thread{[this] { RenderThreadMain(); }};
}

void RenderEngine::JoinRenderThread() {
m_render_thread_running = false;
if(m_render_thread_is_waiting) {
m_caller_thread_semaphore.release();
}
m_render_thread.join();
}

void RenderEngine::RenderThreadMain() {
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;

fmt::print("got {} render objects\n", m_render_objects.size());

// Signal to the caller thread that we are done reading the internal render structures.
m_render_thread_semaphore.release();
}
}

} // namespace zephyr
2 changes: 2 additions & 0 deletions zephyr/scene/include/zephyr/scene/mesh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <zephyr/renderer/mesh.hpp>
#include <memory>

#pragma once

namespace zephyr {

struct MeshComponent : Component {
Expand Down
15 changes: 12 additions & 3 deletions zephyr/scene/include/zephyr/scene/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,19 @@ namespace zephyr {
}

[[nodiscard]] bool IsVisible() const {
return m_visible;
return m_is_visible;
}

void SetVisible(bool visible) {
m_visible = visible;
m_is_visible = visible;
}

[[nodiscard]] bool IsRendererStatic() const {
return m_is_renderer_static;
}

void MakeRendererStatic() {
m_is_renderer_static = true;
}

[[nodiscard]] const Transform3D& GetTransform() const {
Expand Down Expand Up @@ -143,7 +151,8 @@ namespace zephyr {
SceneNode* m_parent{};
std::vector<std::unique_ptr<SceneNode>> m_children;
std::string m_name;
bool m_visible{true};
bool m_is_visible{true};
bool m_is_renderer_static{false};
Transform3D m_transform{this};
std::unordered_map<std::type_index, std::unique_ptr<Component>> m_components;
};
Expand Down

0 comments on commit 4085554

Please sign in to comment.