MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
TextureBuffer.hpp
Go to the documentation of this file.
1#pragma once
2
5
6namespace MayaFlux::Buffers {
7
8class TextureProcessor;
9class RenderProcessor;
10
11/**
12 * @class TextureBuffer
13 * @brief A hybrid buffer managing both a textured quad geometry and its pixel data.
14 *
15 * TextureBuffer serves a dual purpose:
16 * 1. Geometry: It acts as a VKBuffer containing vertex data for a 2D quad (Position + UVs).
17 * This geometry can be transformed (translated, scaled, rotated) or customized.
18 * 2. Texture: It manages raw pixel data in system memory and synchronizes it with a
19 * GPU-resident VKImage via the TextureProcessor.
20 *
21 * Unlike a raw texture resource, this class represents a "renderable sprite" or "surface".
22 * The vertex data is dynamic and updates automatically when transforms change.
23 * The pixel data can be static (loaded once) or dynamic (procedural/video), with
24 * dirty-flag tracking to minimize bus traffic.
25 *
26 * Key Features:
27 * - Automatic quad generation based on dimensions.
28 * - Built-in 2D transform support (Position, Scale, Rotation) affecting vertex positions.
29 * - CPU-side pixel storage with automatic upload to GPU VKImage on change.
30 * - Support for custom vertex geometry (e.g., for non-rectangular sprites).
31 */
32class MAYAFLUX_API TextureBuffer : public VKBuffer {
33public:
34 struct RenderConfig {
35 std::shared_ptr<Core::Window> target_window;
36 std::string vertex_shader = "texture.vert.spv";
37 std::string fragment_shader = "texture.frag.spv";
38 std::string default_texture_binding = "texSampler";
39 Portal::Graphics::PrimitiveTopology topology = Portal::Graphics::PrimitiveTopology::TRIANGLE_STRIP;
40
41 // Optional additional texture binding
42 std::vector<std::pair<std::string, std::shared_ptr<Core::VKImage>>> additional_textures;
43 };
44
45 /**
46 * @brief Create texture buffer with dimensions
47 * @param width Texture width in pixels
48 * @param height Texture height in pixels
49 * @param format Pixel format
50 * @param initial_pixel_data Optional initial pixel data (nullptr = uninitialized)
51 *
52 * The VKBuffer itself contains fullscreen quad vertices.
53 * The texture pixels are stored separately and uploaded to VKImage.
54 */
56 uint32_t width,
57 uint32_t height,
59 const void* initial_pixel_data = nullptr);
60
61 ~TextureBuffer() override = default;
62
63 void setup_processors(ProcessingToken token) override;
64
65 // =========================================================================
66 // Texture Metadata
67 // =========================================================================
68
69 [[nodiscard]] uint32_t get_width() const { return m_width; }
70 [[nodiscard]] uint32_t get_height() const { return m_height; }
71 [[nodiscard]] Portal::Graphics::ImageFormat get_format() const { return m_format; }
72
73 // =========================================================================
74 // GPU Texture Access
75 // =========================================================================
76
77 /**
78 * @brief Get GPU texture image
79 * Suitable for binding to shaders via RenderProcessor::bind_texture()
80 */
81 [[nodiscard]] std::shared_ptr<Core::VKImage> get_texture() const { return m_gpu_texture; }
82 [[nodiscard]] bool has_texture() const { return m_gpu_texture != nullptr; }
83 // === Processor Access ===
84 [[nodiscard]] std::shared_ptr<TextureProcessor> get_texture_processor() const
85 {
86 return m_texture_processor;
87 }
88
89 /**
90 * @brief Replace pixel data
91 * @param data Pointer to pixel data (size must match width*height*channels)
92 * @param size Size in bytes
93 *
94 * Marks texture as dirty. TextureProcessor will re-upload on next frame.
95 */
96 void set_pixel_data(const void* data, size_t size);
97
98 /**
99 * @brief Mark pixel data as changed
100 * Use this if you modify pixel data in-place without calling set_pixel_data()
101 */
102 void mark_pixels_dirty();
103
104 // =========================================================================
105 // Display Transform
106 // =========================================================================
107
108 /**
109 * @brief Set screen position (NDC or pixel coords depending on rendering setup)
110 * @param x X position
111 * @param y Y position
112 *
113 * Marks geometry as dirty. TextureProcessor will recalculate vertices on next frame.
114 */
115 void set_position(float x, float y);
116
117 /**
118 * @brief Set display size
119 * @param width Width in pixels/units
120 * @param height Height in pixels/units
121 *
122 * Marks geometry as dirty.
123 */
124 void set_scale(float width, float height);
125
126 /**
127 * @brief Set rotation around center
128 * @param angle_radians Rotation in radians
129 *
130 * Marks geometry as dirty.
131 */
132 void set_rotation(float angle_radians);
133
134 [[nodiscard]] glm::vec2 get_position() const { return m_position; }
135 [[nodiscard]] glm::vec2 get_scale() const { return m_scale; }
136 [[nodiscard]] float get_rotation() const { return m_rotation; }
137
138 // =========================================================================
139 // Advanced: Custom Geometry
140 // =========================================================================
141
142 /**
143 * @brief Use custom vertex geometry instead of default quad
144 * @param vertices Custom quad vertices (must be 4 vertices with position + texcoord)
145 *
146 * For power users who want non-rectangular meshes or different vertex layouts.
147 * Marks geometry as dirty.
148 */
149 struct QuadVertex {
150 glm::vec3 position;
151 glm::vec2 texcoord;
152 };
153
154 void set_custom_vertices(const std::vector<QuadVertex>& vertices);
155
156 /**
157 * @brief Reset to default fullscreen quad
158 * Uses position and scale to generate quad geometry.
159 */
160 void use_default_quad();
161
162 [[nodiscard]] const std::vector<uint8_t>& get_pixel_data() const { return m_pixel_data; }
163
164 void mark_texture_dirty() { m_texture_dirty = true; }
165 [[nodiscard]] bool is_texture_dirty() const { return m_texture_dirty; }
166 void clear_dirty_flag() { m_texture_dirty = false; }
167
168 /**
169 * @brief Setup rendering with RenderProcessor
170 * @param config Rendering configuration
171 */
172 void setup_rendering(const RenderConfig& config);
173
174 std::shared_ptr<RenderProcessor> get_render_processor() const
175 {
176 return m_render_processor;
177 }
178
179private:
180 friend class TextureProcessor;
181
182 std::shared_ptr<RenderProcessor> m_render_processor;
183
184 // Texture metadata
185 uint32_t m_width;
186 uint32_t m_height;
188
189 // Pixel data
190 std::vector<uint8_t> m_pixel_data;
191 bool m_texture_dirty = true;
192
193 // Display transform
194 glm::vec2 m_position { 0.0F, 0.0F };
195 glm::vec2 m_scale { 1.0F, 1.0F };
196 float m_rotation { 0.0F };
197 bool m_geometry_dirty = true;
198
199 // Geometry
200 std::vector<uint8_t> m_vertex_bytes;
201 bool m_uses_custom_vertices = false;
202
203 // GPU resources
204 std::shared_ptr<Core::VKImage> m_gpu_texture;
205 std::shared_ptr<TextureProcessor> m_texture_processor;
206
207 // Geometry generation
208 void generate_default_quad();
209 void generate_quad_with_transform();
210 static size_t calculate_quad_vertex_size();
211};
212
213} // namespace MayaFlux::Buffers
static MayaFlux::Nodes::ProcessingToken token
Definition Timers.cpp:8
std::shared_ptr< TextureProcessor > get_texture_processor() const
std::shared_ptr< TextureProcessor > m_texture_processor
std::shared_ptr< Core::VKImage > m_gpu_texture
Portal::Graphics::ImageFormat get_format() const
std::vector< uint8_t > m_pixel_data
std::shared_ptr< RenderProcessor > m_render_processor
~TextureBuffer() override=default
const std::vector< uint8_t > & get_pixel_data() const
Portal::Graphics::ImageFormat m_format
std::shared_ptr< Core::VKImage > get_texture() const
Get GPU texture image Suitable for binding to shaders via RenderProcessor::bind_texture()
std::vector< uint8_t > m_vertex_bytes
std::shared_ptr< RenderProcessor > get_render_processor() const
A hybrid buffer managing both a textured quad geometry and its pixel data.
Internal processor: handles CPU→GPU transfers for TextureBuffer.
Vulkan-backed buffer wrapper used in processing chains.
Definition VKBuffer.hpp:52
ProcessingToken
Bitfield enum defining processing characteristics and backend requirements for buffer operations.
ImageFormat
User-friendly image format enum.
PrimitiveTopology
Vertex assembly primitive topology.
Use custom vertex geometry instead of default quad.
std::vector< std::pair< std::string, std::shared_ptr< Core::VKImage > > > additional_textures
std::shared_ptr< Core::Window > target_window