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