#pragma once #include "rhi.h" #include "view.h" #include "scene_renderer.h" #include "black_hole_renderer.h" #include "export_config.h" #include "core/memory.h" #include namespace Donut { class Scene; // Owns the device-side rendering: the two portable renderers, the shared HDRI // cubemap, and the per-frame composition (off-screen geodesic pass -> present, // or the scene pass), with ImGui drawn on top inside the swapchain pass. The // Application hands it a Scene + View each frame; it knows nothing about the UI. class RenderPath { public: auto init(RHI::Device& device, const std::string& hdri_path) -> bool; auto shutdown() -> void; // Rebuilds the environment cubemap if the path changed (device-idle). auto sync_hdri(const std::string& hdri_path) -> void; // Composes one frame's viewport into the swapchain command list. `moving` // drives the black hole's progressive resolution; `time` animates the disk. auto render(RHI::CommandList& cmd, Scene& scene, View view, int fb_width, int fb_height, bool moving, float time) -> void; // Renders the requested export channels off-screen at cfg.width x cfg.height // and writes one PNG per channel. Returns the number of files written. auto export_frame(Scene& scene, const ExportConfig& cfg) -> int; private: RHI::Device* m_device = nullptr; Scope m_scene_renderer; Scope m_black_hole_renderer; Ref m_cubemap; std::string m_hdri_path; }; }