aboutsummaryrefslogtreecommitdiff
path: root/src/rendering/black_hole_renderer.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/rendering/black_hole_renderer.h')
-rw-r--r--src/rendering/black_hole_renderer.h55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/rendering/black_hole_renderer.h b/src/rendering/black_hole_renderer.h
new file mode 100644
index 0000000..b9c158b
--- /dev/null
+++ b/src/rendering/black_hole_renderer.h
@@ -0,0 +1,55 @@
+#pragma once
+
+#include "rhi.h"
+#include "renderer_backend.h" // BlackHoleParams
+#include <glm/glm.hpp>
+
+namespace Donut
+{
+ // The black-hole view, written ONCE against the RHI. Each frame it ray-traces
+ // the geodesic shader into an off-screen target (progressive resolution: a
+ // small target while the camera moves, a larger one once it settles) and then
+ // upscales that target onto the swapchain. The Application owns the camera and
+ // the HDRI cubemap and passes them in.
+ struct GeodesicView
+ {
+ glm::vec3 position, right, up, forward;
+ float tan_half_fov = 1.0f;
+ float aspect = 16.0f / 9.0f;
+ bool moving = false;
+ float time = 0.0f;
+ };
+
+ class BlackHoleRenderer
+ {
+ public:
+ static constexpr int GEO_LO_W = 480, GEO_LO_H = 270;
+ static constexpr int GEO_HI_W = 960, GEO_HI_H = 540;
+
+ 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.
+ auto render_geodesic(RHI::CommandList& cmd, const GeodesicView& view,
+ const BlackHoleParams& params, RHI::Texture* cubemap) -> void;
+
+ // Upscales the geodesic target onto the swapchain (call inside the open
+ // swapchain render pass, before ImGui).
+ auto blit(RHI::CommandList& cmd, int fb_width, int fb_height) -> void;
+
+ private:
+ RHI::Device* m_device = nullptr;
+
+ Ref<RHI::Pipeline> m_geo_pipeline;
+ Ref<RHI::RenderTarget> m_geo_lo;
+ Ref<RHI::RenderTarget> m_geo_hi;
+ Ref<RHI::Buffer> m_quad_vb;
+ Ref<RHI::Buffer> m_cam_ubo;
+ Ref<RHI::Buffer> m_disk_ubo;
+ Ref<RHI::Buffer> m_obj_ubo;
+ Ref<RHI::Buffer> m_sim_ubo;
+
+ Ref<RHI::Pipeline> m_present_pipeline;
+ RHI::RenderTarget* m_last_target = nullptr; // target chosen this frame
+ };
+}