MayaFlux 0.3.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
NodeTextureBuffer.hpp
Go to the documentation of this file.
1#pragma once
2
6
7namespace MayaFlux::Buffers {
8
9class RenderProcessor;
10
11/**
12 * @class NodeTextureBuffer
13 * @brief Staging buffer for uploading TextureNode pixel data to GPU textures
14 *
15 * Bridges CPU-side texture generation (TextureNode) to GPU-resident textures (VKImage).
16 * The VKBuffer part serves as staging memory for efficient CPU→GPU transfers.
17 *
18 * Philosophy:
19 * - Textures are GENERATED by nodes, not loaded from files
20 * - Data flows: Node::compute_frame() → staging buffer → GPU VKImage
21 * - Supports both single and multiple texture node bindings
22 * - Clean separation: staging (VKBuffer) vs target (VKImage)
23 *
24 * Usage (single texture):
25 * auto noise_node = std::make_shared<PerlinNoiseNode>(512, 512);
26 * auto buffer = std::make_shared<NodeTextureBuffer>(noise_node, "perlin");
27 * buffer->setup_processors(Graphics);
28 *
29 * // Access GPU texture for shader binding:
30 * auto texture = buffer->get_gpu_texture();
31 * render_processor->bind_texture("perlin", texture);
32 *
33 * Usage (multiple textures via processor):
34 * auto staging = std::make_shared<NodeTextureBuffer>(primary_node, "primary");
35 * auto processor = staging->get_texture_processor();
36 *
37 * processor->bind_texture_node("secondary", secondary_node, secondary_texture);
38 * processor->bind_texture_node("tertiary", tertiary_node, tertiary_texture);
39 *
40 * staging->setup_processors(Graphics);
41 * // Now all three textures upload through shared staging buffer
42 */
43class MAYAFLUX_API NodeTextureBuffer : public VKBuffer {
44public:
45 /**
46 * @brief Create texture staging buffer from generative node
47 * @param node TextureNode that generates pixels each frame
48 * @param binding_name Logical name for this texture binding (default: "texture")
49 *
50 * Buffer size is automatically calculated from texture dimensions:
51 * width * height * 4 channels * sizeof(float) = RGBA32F format
52 */
53 explicit NodeTextureBuffer(
54 std::shared_ptr<Nodes::GpuSync::TextureNode> node,
55 std::string binding_name = "texture");
56
57 ~NodeTextureBuffer() override = default;
58
59 /**
60 * @brief Initialize the buffer, create GPU texture, and setup processors
61 */
62 void setup_processors(ProcessingToken token) override;
63
64 /**
65 * @brief Setup rendering with RenderProcessor
66 * @param config Rendering configuration
67 *
68 * Configures the buffer for direct rendering to screen.
69 * The GPU texture will be bound and drawn automatically.
70 */
71 void setup_rendering(const RenderConfig& config);
72
73 /**
74 * @brief Get the GPU-resident texture (VKImage)
75 * @return Shared pointer to VKImage suitable for shader binding
76 */
77 [[nodiscard]] std::shared_ptr<Core::VKImage> get_gpu_texture() const
78 {
79 return m_gpu_texture;
80 }
81
82 /**
83 * @brief Get the texture node driving this buffer
84 */
85 [[nodiscard]] std::shared_ptr<Nodes::GpuSync::TextureNode> get_texture_node() const
86 {
87 return m_texture_node;
88 }
89
90 /**
91 * @brief Get the processor managing uploads
92 * @return Processor that can bind additional texture nodes
93 */
94 [[nodiscard]] std::shared_ptr<NodeTextureProcessor> get_texture_processor() const
95 {
96 return m_texture_processor;
97 }
98
99 /**
100 * @brief Get the logical binding name
101 */
102 [[nodiscard]] const std::string& get_binding_name() const
103 {
104 return m_binding_name;
105 }
106
107 /**
108 * @brief Get texture dimensions from node
109 */
110 [[nodiscard]] std::pair<uint32_t, uint32_t> get_dimensions() const
111 {
112 return m_texture_node
113 ? std::make_pair(m_texture_node->get_width(), m_texture_node->get_height())
114 : std::make_pair(0U, 0U);
115 }
116
117 /**
118 * @brief Trigger pixel computation on the node
119 *
120 * Calls node->compute_frame() to regenerate pixels.
121 * Useful for explicit frame updates when not using domain-driven processing.
122 */
124 {
125 if (m_texture_node) {
126 m_texture_node->compute_frame();
127 }
128 }
129
130 /**
131 * @brief Get the render processor (if rendering is setup)
132 */
133 std::shared_ptr<RenderProcessor> get_render_processor() const
134 {
135 return m_render_processor;
136 }
137
138 void generate_fullscreen_quad();
139
140 size_t calculate_quad_vertex_size();
141
142private:
143 std::shared_ptr<Nodes::GpuSync::TextureNode> m_texture_node;
144 std::shared_ptr<Core::VKImage> m_gpu_texture;
145 std::shared_ptr<NodeTextureProcessor> m_texture_processor;
146 std::string m_binding_name;
147 std::shared_ptr<RenderProcessor> m_render_processor;
148
149 std::vector<uint8_t> m_vertex_bytes;
150
151 /**
152 * @brief Calculate staging buffer size from node dimensions
153 * @note Assumes RGBA32F format (4 channels * sizeof(float))
154 */
155 static size_t calculate_buffer_size(
156 const std::shared_ptr<Nodes::GpuSync::TextureNode>& node);
157
159};
160
161} // namespace MayaFlux::Buffers
std::shared_ptr< Nodes::GpuSync::TextureNode > m_texture_node
std::shared_ptr< Core::VKImage > get_gpu_texture() const
Get the GPU-resident texture (VKImage)
const std::string & get_binding_name() const
Get the logical binding name.
std::shared_ptr< Nodes::GpuSync::TextureNode > get_texture_node() const
Get the texture node driving this buffer.
std::shared_ptr< NodeTextureProcessor > get_texture_processor() const
Get the processor managing uploads.
std::shared_ptr< Core::VKImage > m_gpu_texture
std::pair< uint32_t, uint32_t > get_dimensions() const
Get texture dimensions from node.
std::shared_ptr< RenderProcessor > m_render_processor
void update_texture()
Trigger pixel computation on the node.
std::shared_ptr< RenderProcessor > get_render_processor() const
Get the render processor (if rendering is setup)
std::shared_ptr< NodeTextureProcessor > m_texture_processor
Staging buffer for uploading TextureNode pixel data to GPU textures.
Uploads TextureNode pixel data to GPU textures via TextureLoom.
Vulkan-backed buffer wrapper used in processing chains.
Definition VKBuffer.hpp:52
ProcessingToken
Bitfield enum defining processing characteristics and backend requirements for buffer operations.
Unified rendering configuration for graphics buffers.