aboutsummaryrefslogtreecommitdiff
path: root/src/rendering
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-08-23 22:39:47 +0200
committerhachem <im@hachem.wtf>2026-08-23 22:39:47 +0200
commit90ff03c2fdffc09ddb26bdc7e32c3968a6d274fb (patch)
tree2fdb1b6f54c4e380af43c75f1051935587a87faa /src/rendering
parent5ea6c14c0e14bacee766ce1280ab2c71564e05ec (diff)
[feat]: wire in scene into the simulation engine
Diffstat (limited to 'src/rendering')
-rw-r--r--src/rendering/black_hole_renderer.cpp30
-rw-r--r--src/rendering/black_hole_renderer.h10
-rw-r--r--src/rendering/render_path.cpp5
-rw-r--r--src/rendering/rhi.h4
-rw-r--r--src/rendering/scene_renderer.cpp25
-rw-r--r--src/rendering/scene_renderer.h1
6 files changed, 63 insertions, 12 deletions
diff --git a/src/rendering/black_hole_renderer.cpp b/src/rendering/black_hole_renderer.cpp
index e4bc2a4..5916171 100644
--- a/src/rendering/black_hole_renderer.cpp
+++ b/src/rendering/black_hole_renderer.cpp
@@ -42,11 +42,9 @@ namespace Donut
m_obj_ubo = device.create_buffer(BufferType::Uniform, 800);
m_sim_ubo = device.create_buffer(BufferType::Uniform, 16);
- // The single "object" is the black hole itself (position 0, radius = r_s).
- std::vector<uint8_t> obj(800, 0);
- int num_objects = 1; std::memcpy(obj.data() + 0, &num_objects, 4);
- float pos_radius[4] = { 0, 0, 0, SagA_rs }; std::memcpy(obj.data() + 16, pos_radius, 16);
- float color[4] = { 0, 0, 0, 1 }; std::memcpy(obj.data() + 272, color, 16);
+ // The hole itself is the hardcoded singularity in the shader; the Objects
+ // UBO carries the Scene's spheres, refilled each frame in render_geodesic.
+ std::vector<uint8_t> obj(800, 0); // numObjects = 0 until the first frame
m_obj_ubo->update(obj.data(), obj.size());
{
@@ -80,7 +78,8 @@ namespace Donut
}
auto BlackHoleRenderer::render_geodesic(RHI::CommandList& cmd, const GeodesicView& view,
- const BlackHoleParams& params, RHI::Texture* cubemap) -> void
+ const BlackHoleParams& params,
+ const std::vector<SceneObject>& objects, RHI::Texture* cubemap) -> void
{
CamUBO cam{};
cam.pos = view.position; cam.right = view.right; cam.up = view.up; cam.fwd = view.forward;
@@ -113,6 +112,25 @@ namespace Donut
};
m_disk_ubo->update(disk, sizeof(disk));
+ // Scene objects → the geodesic's Objects UBO (std140: numObjects@0,
+ // objPosRadius[i]@16+16i, objColor[i]@272+16i). They render as spheres the
+ // curved rays intersect, so the hole lenses them. 1 scene unit = 1 r_s.
+ {
+ const float k = SagA_rs / SCENE_UNITS_PER_RS; // scene units -> metres
+ std::vector<uint8_t> objbuf(800, 0);
+ int n = std::min((int)objects.size(), 16);
+ std::memcpy(objbuf.data(), &n, 4);
+ for (int i = 0; i < n; ++i)
+ {
+ const SceneObject& o = objects[i];
+ float pr[4] = { o.position.x * k, o.position.y * k, o.position.z * k, o.radius * k };
+ float col[4] = { o.color.r, o.color.g, o.color.b, 1.0f };
+ std::memcpy(objbuf.data() + 16 + 16 * i, pr, 16);
+ std::memcpy(objbuf.data() + 272 + 16 * i, col, 16);
+ }
+ m_obj_ubo->update(objbuf.data(), objbuf.size());
+ }
+
// Progressive resolution: small target while moving, large once settled.
RenderTarget* target = view.moving ? m_geo_lo.get() : m_geo_hi.get();
m_last_target = target;
diff --git a/src/rendering/black_hole_renderer.h b/src/rendering/black_hole_renderer.h
index 63c5aa2..2ae03dd 100644
--- a/src/rendering/black_hole_renderer.h
+++ b/src/rendering/black_hole_renderer.h
@@ -1,8 +1,9 @@
#pragma once
#include "rhi.h"
-#include "scene/scene_types.h" // BlackHoleParams
+#include "scene/scene_types.h" // BlackHoleParams, SceneObject
#include <glm/glm.hpp>
+#include <vector>
namespace Donut
{
@@ -29,9 +30,12 @@ namespace Donut
auto init(RHI::Device& device) -> bool;
// Off-screen geodesic pass (opens/closes its own render pass). Call before
- // the swapchain pass; `cubemap` is the shared HDRI environment.
+ // the swapchain pass; `cubemap` is the shared HDRI environment. `objects`
+ // are the Scene's spheres — ray-traced as lensed spheres around the hole
+ // (1 scene unit = 1 Schwarzschild radius). Grid units == r_s.
auto render_geodesic(RHI::CommandList& cmd, const GeodesicView& view,
- const BlackHoleParams& params, RHI::Texture* cubemap) -> void;
+ const BlackHoleParams& params,
+ const std::vector<SceneObject>& objects, RHI::Texture* cubemap) -> void;
// Upscales the geodesic target onto the swapchain (call inside the open
// swapchain render pass, before ImGui).
diff --git a/src/rendering/render_path.cpp b/src/rendering/render_path.cpp
index 172e13c..115d182 100644
--- a/src/rendering/render_path.cpp
+++ b/src/rendering/render_path.cpp
@@ -42,8 +42,7 @@ namespace Donut
cmd.begin_render_pass(nullptr, clear);
if (view == View::Scene)
{
- float aspect = (float)fb_width / (float)std::max(fb_height, 1);
- scene.scene_camera.set_projection(45.0f, aspect, 0.1f, 1000.0f);
+ // Projection was set by the Application this frame (shared with the gizmo).
CameraView cv;
cv.view = scene.scene_camera.get_view_matrix();
cv.projection = scene.scene_camera.get_projection_matrix();
@@ -75,7 +74,7 @@ namespace Donut
gv.moving = moving;
gv.time = time;
- m_black_hole_renderer->render_geodesic(cmd, gv, scene.black_hole, m_cubemap.get());
+ m_black_hole_renderer->render_geodesic(cmd, gv, scene.black_hole, scene.objects, m_cubemap.get());
cmd.begin_render_pass(nullptr, clear);
m_black_hole_renderer->blit(cmd, fb_width, fb_height);
m_device->imgui_render(cmd);
diff --git a/src/rendering/rhi.h b/src/rendering/rhi.h
index 2110926..e4e7e62 100644
--- a/src/rendering/rhi.h
+++ b/src/rendering/rhi.h
@@ -128,6 +128,10 @@ namespace Donut::RHI
virtual auto resize(int width, int height) -> void = 0;
virtual auto wait_idle() -> void = 0;
+ // Present pacing: GL toggles the swap interval; Vulkan swaps the present
+ // mode (FIFO vs IMMEDIATE) and rebuilds the swapchain. Default: no-op.
+ virtual auto set_vsync(bool enabled) -> void { (void)enabled; }
+
virtual auto create_buffer(BufferType type, size_t size, const void* data = nullptr) -> Ref<Buffer> = 0;
virtual auto create_texture(int width, int height, Format format, Filter filter, const void* data = nullptr) -> Ref<Texture> = 0;
virtual auto create_cubemap_from_hdri(const std::string& equirect_path) -> Ref<Texture> = 0;
diff --git a/src/rendering/scene_renderer.cpp b/src/rendering/scene_renderer.cpp
index 5ee7657..50b666d 100644
--- a/src/rendering/scene_renderer.cpp
+++ b/src/rendering/scene_renderer.cpp
@@ -42,6 +42,9 @@ namespace Donut
struct SkyboxUBO { glm::mat4 projection; glm::mat4 view; };
static_assert(sizeof(SkyboxUBO) == 128, "SkyboxUBO std140 layout mismatch");
+
+ // The hole's event horizon (1 r_s) as a marker at the origin.
+ constexpr float BH_SCENE_RADIUS = SCENE_UNITS_PER_RS;
}
auto SceneRenderer::init(RHI::Device& device) -> bool
@@ -137,6 +140,8 @@ namespace Donut
m_skybox_pipeline = device.create_pipeline(d);
}
+ m_bh_ubo = device.create_buffer(BufferType::Uniform, sizeof(SphereUBO));
+
DONUT_INFO("SceneRenderer ready ({} grid verts, {} sphere indices, skybox)",
m_grid_vertex_count, m_sphere_index_count);
return true;
@@ -196,6 +201,26 @@ namespace Donut
cmd.bind_index_buffer(m_sphere_ib.get());
cmd.draw_indexed(m_sphere_index_count);
}
+
+ // Black-hole marker: a near-black sphere at the origin (radius = r_s in
+ // scene units), so the Scene shows where the hole the Simulation renders
+ // sits. 1 grid unit == 1 Schwarzschild radius.
+ SphereUBO bh{};
+ bh.view_projection = vp;
+ bh.transform = glm::scale(glm::mat4(1.0f), glm::vec3(BH_SCENE_RADIUS));
+ bh.color = glm::vec3(0.02f); // near-black event horizon
+ bh.specular = 0.10f;
+ bh.light_pos = glm::vec3(10.0f, 20.0f, 10.0f);
+ bh.camera_pos = cam.position;
+ bh.is_selected = 1; // reuse the rim as an
+ bh.outline_color = glm::vec3(0.98f, 0.62f, 0.20f); // amber accretion glow
+ bh.outline_width = 0.30f;
+ m_bh_ubo->update(&bh, sizeof(bh));
+ cmd.bind_uniform(0, m_bh_ubo.get());
+ cmd.bind_texture(1, cubemap);
+ cmd.bind_vertex_buffer(m_sphere_vb.get());
+ cmd.bind_index_buffer(m_sphere_ib.get());
+ cmd.draw_indexed(m_sphere_index_count);
}
// Transparent grid on top (tests depth, doesn't write).
diff --git a/src/rendering/scene_renderer.h b/src/rendering/scene_renderer.h
index c3ee02f..f7ff992 100644
--- a/src/rendering/scene_renderer.h
+++ b/src/rendering/scene_renderer.h
@@ -48,6 +48,7 @@ namespace Donut
Ref<RHI::Buffer> m_sphere_ib;
int m_sphere_index_count = 0;
std::vector<Ref<RHI::Buffer>> m_sphere_ubos; // one per object slot
+ Ref<RHI::Buffer> m_bh_ubo; // the black-hole marker sphere at the origin
Ref<RHI::Pipeline> m_skybox_pipeline;
Ref<RHI::Buffer> m_skybox_vb;