MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
GeometryBuffer.hpp
Go to the documentation of this file.
1#pragma once
2
6
7namespace MayaFlux::Buffers {
8
9class RenderProcessor;
10
11/**
12 * @class GeometryBuffer
13 * @brief Specialized buffer for generative geometry from GeometryWriterNode
14 *
15 * Automatically handles CPU→GPU upload of procedurally generated vertices.
16 * Designed for algorithmic geometry generation: particles, simulations,
17 * procedural meshes, data visualizations, etc.
18 *
19 * Philosophy:
20 * - Geometry is GENERATED, not loaded from files
21 * - Data flows from algorithm → GPU → screen
22 * - No primitive worship - users create their own forms
23 *
24 * Usage:
25 * class ParticleSystem : public GeometryWriterNode {
26 * void compute_frame() override {
27 * // Generate 1000 particle positions algorithmically
28 * for (int i = 0; i < 1000; i++) {
29 * positions[i] = simulate_physics(i);
30 * }
31 * update_vertex_buffer(positions);
32 * }
33 * };
34 *
35 * auto particles = std::make_shared<ParticleSystem>(1000);
36 * auto buffer = std::make_shared<GeometryBuffer>(particles);
37 * buffer->setup_rendering({ .target_window = window });
38 *
39 */
40class MAYAFLUX_API GeometryBuffer : public VKBuffer {
41public:
42 /**
43 * @brief Create geometry buffer from generative node
44 * @param node GeometryWriterNode that generates vertices each frame
45 * @param binding_name Logical name for this geometry binding (default: "geometry")
46 * @param over_allocate_factor Buffer size multiplier for dynamic growth (default: 1.5x)
47 *
48 * Buffer size is initially set to node->get_vertex_buffer_size_bytes().
49 * If over_allocate_factor > 1.0, buffer will be larger to accommodate growth
50 * without reallocation.
51 */
52 explicit GeometryBuffer(
53 std::shared_ptr<Nodes::GpuSync::GeometryWriterNode> node,
54 const std::string& binding_name = "geometry",
55 float over_allocate_factor = 1.5F);
56
57 ~GeometryBuffer() override = default;
58
59 /**
60 * @brief Initialize the buffer and its processors
61 */
62 void setup_processors(ProcessingToken token) override;
63
64 /**
65 * @brief Get the geometry node driving this buffer
66 */
67 [[nodiscard]] std::shared_ptr<Nodes::GpuSync::GeometryWriterNode> get_geometry_node() const
68 {
69 return m_geometry_node;
70 }
71
72 /**
73 * @brief Get the bindings processor managing uploads
74 */
75 [[nodiscard]] std::shared_ptr<GeometryBindingsProcessor> get_bindings_processor() const
76 {
77 return m_bindings_processor;
78 }
79
80 /**
81 * @brief Get the logical binding name
82 */
83 [[nodiscard]] const std::string& get_binding_name() const
84 {
85 return m_binding_name;
86 }
87
88 /**
89 * @brief Get current vertex count from node
90 */
91 [[nodiscard]] uint32_t get_vertex_count() const
92 {
93 return m_geometry_node ? m_geometry_node->get_vertex_count() : 0;
94 }
95
96 /**
97 * @brief Trigger vertex computation on the node
98 *
99 * Calls node->compute_frame() to regenerate geometry.
100 * Useful for explicit frame updates when not using domain-driven processing.
101 */
103 {
104 if (m_geometry_node) {
105 m_geometry_node->compute_frame();
106 }
107 }
108
109 /**
110 * @brief Supply a diffuse texture, bound on the next graphics tick.
111 *
112 * Follows the FormaBuffer model: if the bindings processor is not yet
113 * created (setup_processors not called), the texture is queued and applied
114 * in setup_processors. Otherwise it is forwarded to the processor, which
115 * binds it on the next cycle. The descriptor slot is declared in
116 * setup_rendering; call set_texture before setup_rendering, or pass a
117 * default_texture_binding in the RenderConfig, so the slot exists.
118 *
119 * @param image GPU image. nullptr clears the binding.
120 * @param binding Descriptor name (default: "diffuseTex").
121 */
122 void set_texture(std::shared_ptr<Core::VKImage> image, std::string binding = "diffuseTex");
123
124 [[nodiscard]] bool has_texture() const noexcept { return m_diffuse_texture != nullptr; }
125
126 /**
127 * @brief Setup rendering with RenderProcessor
128 * @param config Rendering configuration
129 */
130 void setup_rendering(const RenderConfig& config);
131
132private:
133 std::shared_ptr<Nodes::GpuSync::GeometryWriterNode> m_geometry_node;
134 std::shared_ptr<GeometryBindingsProcessor> m_bindings_processor;
135 std::string m_binding_name;
136
137 std::shared_ptr<Core::VKImage> m_diffuse_texture;
138 std::string m_diffuse_binding { "diffuseTex" };
139 std::vector<std::pair<std::shared_ptr<Core::VKImage>, std::string>> m_pending_textures;
140
141 /**
142 * @brief Calculate initial buffer size with optional over-allocation
143 */
144 static size_t calculate_buffer_size(
145 const std::shared_ptr<Nodes::GpuSync::GeometryWriterNode>& node,
146 float over_allocate_factor);
147};
148
149} // namespace MayaFlux::Buffers
IO::ImageData image
Definition Decoder.cpp:57
std::vector< std::pair< std::shared_ptr< Core::VKImage >, std::string > > m_pending_textures
std::shared_ptr< Nodes::GpuSync::GeometryWriterNode > get_geometry_node() const
Get the geometry node driving this buffer.
const std::string & get_binding_name() const
Get the logical binding name.
std::shared_ptr< Core::VKImage > m_diffuse_texture
std::shared_ptr< Nodes::GpuSync::GeometryWriterNode > m_geometry_node
~GeometryBuffer() override=default
void update_geometry()
Trigger vertex computation on the node.
std::shared_ptr< GeometryBindingsProcessor > m_bindings_processor
std::shared_ptr< GeometryBindingsProcessor > get_bindings_processor() const
Get the bindings processor managing uploads.
uint32_t get_vertex_count() const
Get current vertex count from node.
Specialized buffer for generative geometry from GeometryWriterNode.
Vulkan-backed buffer wrapper used in processing chains.
Definition VKBuffer.hpp:67
ProcessingToken
Bitfield enum defining processing characteristics and backend requirements for buffer operations.