Files
Aethera/render_3D/render_3D/scene/Render_Scene_3D.hpp
T
2026-08-22 21:36:21 +08:00

72 lines
3.8 KiB
C++

#pragma once
#include "../axis/Axes_3D.hpp"
#include "../base/Frame_3D.hpp"
#include "../camera/Camera_3D.hpp"
#include "../detail/Backend_Types.hpp"
#include "../visual/Visuals.hpp"
#include <scene.hpp>
#include <array>
#include <expected>
#include <functional>
#include <memory>
#include <vector>
namespace aethera::render_3d {
/* 三维 Prepare 完成后的异步后端提交阶段标签。 */
struct Submit_Tag {};
/* 执行共有 Prepare 图,并把三维 Submit 阶段无等待地提交给 Datoviz 渲染域。 */
struct Render_Scene_3D : Def<Render_Scene_3D, Scene, Dependency_Graph_Type<Submit_Tag, Renderable>> {
struct Prop : Prev_Prop {
Extent viewport{560, 320}; /* 离屏渲染目标尺寸,单位为像素。 */
Linear_Color clear_color{}; /* 每帧开始时写入的线性背景色。 */
bool view_active{true}; /* 是否接受 render(frame*) 产生新的完成帧。 */
bool operator==(const Prop&) const;
};
struct State : Prev_State {
bool operator==(const State&) const;
};
struct Private;
template <typename Object>
struct Builder : Prev_Builder<Object> {
using Base = Prev_Builder<Object>;
using Final_Builder = typename Object::Builder;
Builder();
template <Attached Visual_Object>
Final_Builder& add_renderable(Visual_Object* visual);
template <Attached Camera_Object>
requires std::derived_from<Camera_Object, Camera_3D>
Final_Builder& add_camera(Camera_Object* camera);
template <Attached Axes_Object>
requires std::derived_from<Axes_Object, Axes_3D>
Final_Builder& add_axes(Axes_Object* axes);
Final_Builder& use_gpu(std::uint32_t gpu_index, bool validation_enabled = false);
[[nodiscard]] std::expected<std::unique_ptr<Object>, Dependency_Graph_Error> build();
private:
struct Visual_Binding {
Root* object{}; /* 不拥有;生命周期必须覆盖 Scene。 */
Visual_Family family{Visual_Family::point}; /* 创建对应 Datoviz Visual 的 family。 */
void (*bind)(Root*, std::shared_ptr<void>){}; /* 绑定 Scene 拥有的发布上下文。 */
};
std::vector<Visual_Binding> visuals{}; /* 本 Scene 的全部 Visual,注册顺序保持稳定。 */
Root* camera{}; /* 不拥有的 Camera 组件;生命周期必须覆盖 Scene。 */
Root* axes{}; /* 不拥有的三轴组件;生命周期必须覆盖 Scene。 */
using Camera_Read = plot::Camera_Descriptor (*)(const Root*);
using Axes_Read = std::array<plot::Axis_Descriptor, 3> (*)(const Root*);
Camera_Read read_camera{};
Axes_Read read_axes{};
std::uint32_t gpu_index{}; /* Datoviz 使用的物理 GPU 下标。 */
bool validation_enabled{}; /* 是否启用 Vulkan 验证。 */
};
enum class Render_Result { submitted, view_inactive, empty_viewport, backend_unavailable };
using Frame_Callback = std::function<void(Frame_3D*)>;
/* 无等待提交到调用方拥有的帧;frame 必须存活到完成回调返回。 */
[[nodiscard]] Render_Result render(Frame_3D* frame);
/* 安装完成帧回调;回调由 Datoviz Render Domain 线程传回同一外部帧。 */
void set_frame_callback(Frame_Callback callback);
/* 无锁提交事件所有权;下一次 Prepare 开始时无等待转交 Datoviz 渲染域。 */
void dispatch_event(std::unique_ptr<Event> event);
void activate_view();
void deactivate_view();
};
}
#include "Render_Scene_3D.ipp"