72 lines
3.8 KiB
C++
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"
|