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