MayaFlux 0.2.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
CompositeGeometryBuffer.hpp
Go to the documentation of this file.
1#pragma once
2
6
7namespace MayaFlux::Buffers {
8
9class RenderProcessor;
10
11struct RenderData {
12 std::shared_ptr<RenderProcessor> render_processor;
13 uint32_t vertex_offset;
14 uint32_t vertex_count;
15};
16
17/**
18 * @class CompositeGeometryBuffer
19 * @brief Buffer for aggregating multiple geometry nodes with independent topologies
20 *
21 * Allows manual composition of multiple GeometryWriterNodes, each rendered with
22 * its own primitive topology. All geometry is aggregated into a single GPU buffer
23 * for efficient upload, but rendered with separate draw calls per topology.
24 *
25 * Philosophy:
26 * - Manual composition for full control
27 * - Each geometry can have different topology (LINE_STRIP, LINE_LIST, POINT_LIST, etc.)
28 * - Single buffer upload, multiple render passes
29 * - Efficient batching without topology constraints
30 *
31 * Key Differences from GeometryBuffer:
32 * - Accepts multiple nodes (not single GeometryWriterNode)
33 * - Each node can have different topology
34 * - Automatically creates multiple RenderProcessors
35 *
36 * Key Differences from NetworkGeometryBuffer:
37 * - Manual node registration (not NodeNetwork-driven)
38 * - Explicit topology specification per node
39 * - Not tied to network operators or topology inference
40 *
41 * Usage:
42 * ```cpp
43 * auto path_node = vega.PathGeneratorNode(...);
44 * auto normals_node = vega.PointCollectionNode();
45 * // ... populate normals
46 *
47 * auto composite = std::make_shared<CompositeGeometryBuffer>();
48 * composite->add_geometry("path", path_node, PrimitiveTopology::LINE_STRIP);
49 * composite->add_geometry("normals", normals_node, PrimitiveTopology::LINE_LIST);
50 * composite->add_geometry("control_points", points_node, PrimitiveTopology::POINT_LIST);
51 *
52 * composite->setup_processors(ProcessingToken::GRAPHICS_BACKEND);
53 * composite->setup_rendering({.target_window = window});
54 * ```
55 *
56 * Each frame:
57 * 1. CompositeGeometryProcessor aggregates all nodes → single GPU upload
58 * 2. Multiple RenderProcessors draw subsets with different topologies
59 */
60class MAYAFLUX_API CompositeGeometryBuffer : public VKBuffer {
61public:
62 /**
63 * @brief Create empty composite buffer
64 * @param initial_capacity Initial buffer size in bytes (default: 1MB)
65 * @param over_allocate_factor Growth multiplier for dynamic resizing (default: 1.5x)
66 */
68 size_t initial_capacity = 1024 * 1024,
69 float over_allocate_factor = 1.5F);
70
71 ~CompositeGeometryBuffer() override = default;
72
73 /**
74 * @brief Add a geometry collection
75 * @param name Unique identifier for this geometry
76 * @param node GeometryWriterNode to render
77 * @param topology Primitive topology for this geometry
78 * @param target_window Window to render to (used for shader config)
79 *
80 * The node's vertex data will be aggregated with other geometries during upload,
81 * but rendered independently with the specified topology.
82 */
83 void add_geometry(
84 const std::string& name,
85 const std::shared_ptr<Nodes::GpuSync::GeometryWriterNode>& node,
87 const std::shared_ptr<Core::Window>& target_window);
88
89 /**
90 * @brief Add a geometry collection with explicit render config
91 * @param name Unique identifier for this geometry
92 * @param node GeometryWriterNode to render
93 * @param topology Primitive topology for this geometry
94 * @param config Render configuration (shaders, render states)
95 */
96 void add_geometry(
97 const std::string& name,
98 const std::shared_ptr<Nodes::GpuSync::GeometryWriterNode>& node,
100 const RenderConfig& config);
101
102 /**
103 * @brief Remove a geometry collection
104 * @param name Geometry identifier
105 */
106 void remove_geometry(const std::string& name);
107
108 /**
109 * @brief Get geometry collection metadata
110 * @param name Geometry identifier
111 * @return Optional collection if exists
112 */
113 [[nodiscard]] std::optional<CompositeGeometryProcessor::GeometryCollection>
114 get_collection(const std::string& name) const;
115
116 /**
117 * @brief Get number of geometry collections
118 */
119 [[nodiscard]] size_t get_collection_count() const;
120
121 /**
122 * @brief Initialize buffer processors
123 *
124 * Creates CompositeGeometryProcessor as default processor.
125 * Must be called before setup_rendering().
126 */
127 void setup_processors(ProcessingToken token) override;
128
129 /**
130 * @brief Setup rendering (DEPRECATED for CompositeGeometryBuffer)
131 *
132 * For CompositeGeometryBuffer, use add_geometry() with RenderConfig instead.
133 * This method exists for interface compatibility but does nothing.
134 */
135 void setup_rendering(const RenderConfig& config);
136
137 /**
138 * @brief Get the composite processor managing uploads
139 */
140 [[nodiscard]] std::shared_ptr<CompositeGeometryProcessor> get_composite_processor() const
141 {
142 return m_processor;
143 }
144
145 /**
146 * @brief Get all render processors (one per collection)
147 */
148 [[nodiscard]] std::vector<std::shared_ptr<RenderProcessor>> get_render_processors() const
149 {
150 std::vector<std::shared_ptr<RenderProcessor>> renders;
151 renders.reserve(m_render_data.size());
152 for (const auto& [_, data] : m_render_data) {
153 renders.push_back(data.render_processor);
154 }
155 return renders;
156 }
157
158 /**
159 * @brief Update the vertex range for a specific geometry collection's render processor
160 * @param name Geometry identifier
161 * @param vertex_offset Starting vertex offset in the buffer
162 * @param vertex_count Number of vertices to render
163 *
164 * This should be called after processing to ensure each RenderProcessor draws the correct subset.
165 */
166 void update_collection_render_range(
167 const std::string& name,
168 uint32_t vertex_offset,
169 uint32_t vertex_count);
170
171 /**
172 * @brief Push a topology-specific vertex layout to the matching RenderProcessor
173 * @param name Geometry identifier
174 * @param layout VertexLayout belonging exclusively to this collection
175 *
176 * Must be called after update_collection_render_range() so the
177 * RenderProcessor compiles its Vulkan pipeline with the correct
178 * vertex-input stride and attribute offsets for this topology.
179 */
180 void update_collection_vertex_layout(
181 const std::string& name,
182 const Kakshya::VertexLayout& layout);
183
184private:
185 std::shared_ptr<CompositeGeometryProcessor> m_processor;
186 std::unordered_map<std::string, RenderData> m_render_data;
188
189 /**
190 * @brief Calculate initial buffer size
191 */
192 static size_t calculate_initial_size(size_t requested_capacity);
193};
194
195} // namespace MayaFlux::Buffers
std::shared_ptr< CompositeGeometryProcessor > m_processor
std::unordered_map< std::string, RenderData > m_render_data
std::vector< std::shared_ptr< RenderProcessor > > get_render_processors() const
Get all render processors (one per collection)
std::shared_ptr< CompositeGeometryProcessor > get_composite_processor() const
Get the composite processor managing uploads.
Buffer for aggregating multiple geometry nodes with independent topologies.
Vulkan-backed buffer wrapper used in processing chains.
Definition VKBuffer.hpp:52
ProcessingToken
Bitfield enum defining processing characteristics and backend requirements for buffer operations.
PrimitiveTopology
Vertex assembly primitive topology.
std::shared_ptr< RenderProcessor > render_processor
Complete description of vertex data layout in a buffer.
Unified rendering configuration for graphics buffers.