MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
TextureBuffer.cpp
Go to the documentation of this file.
1#include "TextureBuffer.hpp"
2
7
9
10namespace MayaFlux::Buffers {
11
13 uint32_t width,
14 uint32_t height,
16 const void* initial_pixel_data)
17 : VKBuffer(
18 calculate_quad_vertex_size(),
19 Usage::VERTEX,
20 Kakshya::DataModality::IMAGE_COLOR)
21 , m_width(width)
22 , m_height(height)
23 , m_format(format)
24{
25 RenderConfig default_config;
26 default_config.vertex_shader = "texture.vert.spv";
27 default_config.fragment_shader = "texture.frag.spv";
28 if (format == Portal::Graphics::ImageFormat::R8) {
29 default_config.fragment_shader = "texture_gray.frag.spv";
30 } else if (format == Portal::Graphics::ImageFormat::RG8) {
31 default_config.fragment_shader = "texture_gray_alpha.frag.spv";
32 }
33 default_config.default_texture_binding = "texSampler";
35 set_default_render_config(default_config);
36
37 if (initial_pixel_data) {
38 size_t pixel_bytes = static_cast<size_t>(width) * height * Portal::Graphics::TextureLoom::get_bytes_per_pixel(format);
39 m_pixel_data.resize(pixel_bytes);
40 std::memcpy(m_pixel_data.data(), initial_pixel_data, pixel_bytes);
41 }
42
44
46 "Created TextureBuffer: {}x{} ({} pixel bytes, {} vertex bytes)",
48}
49
51{
52 auto self = std::dynamic_pointer_cast<TextureBuffer>(shared_from_this());
53
54 m_texture_processor = std::make_shared<TextureProcessor>();
55 m_texture_processor->set_processing_token(token);
56
58
60 if (!chain) {
61 chain = std::make_shared<BufferProcessingChain>();
63 }
64 chain->set_preferred_token(token);
65
67 "TextureBuffer setup_processors: TextureProcessor will be attached on first registration");
68}
69
71{
72 if (!user_config.vertex_shader.empty()) {
74 }
75 if (!user_config.fragment_shader.empty()) {
77 }
78 if (!user_config.default_texture_binding.empty()) {
80 }
83 "TextureBuffer only supports TRIANGLE_STRIP topology. Ignoring provided topology.");
84 } else {
85 if (user_config.topology != m_render_config.topology) {
86 m_render_config.topology = user_config.topology;
87 }
88 }
90
91 if (!user_config.additional_textures.empty()) {
92 for (const auto& [name, texture] : user_config.additional_textures) {
93 m_render_config.additional_textures.emplace_back(name, texture);
94 }
95 }
96
99 0, 1, vk::DescriptorType::eCombinedImageSampler);
100
101 uint32_t binding_index = 2;
102 for (const auto& [name, _] : m_render_config.additional_textures) {
103 shader_config.bindings[name] = ShaderBinding(
104 0, binding_index++, vk::DescriptorType::eCombinedImageSampler);
105 }
106
107 apply_render_config(m_render_config, shader_config);
108
110
111 for (const auto& [name, texture] : m_render_config.additional_textures) {
112 m_render_processor->bind_texture(name, texture);
113 }
114
115 get_processing_chain()->add_final_processor(m_render_processor, shared_from_this());
116}
117
118// =========================================================================
119// Pixel Data Management
120// =========================================================================
121
122void TextureBuffer::set_pixel_data(const void* data, size_t size)
123{
124 if (!data || size == 0) {
126 "set_pixel_data called with null or empty data");
127 return;
128 }
129
130 m_pixel_data.resize(size);
131 std::memcpy(m_pixel_data.data(), data, size);
132 m_texture_dirty = true;
133
135 "TextureBuffer: pixel data updated ({} bytes, marked dirty)", size);
136}
137
142
143void TextureBuffer::set_gpu_texture(std::shared_ptr<Core::VKImage> image)
144{
145 m_gpu_texture = std::move(image);
146
148 m_render_processor->bind_texture(
151 }
152}
153
154void TextureBuffer::resize_texture(uint32_t new_width, uint32_t new_height)
155{
156 if (new_width == m_width && new_height == m_height) {
157 return;
158 }
159
160 m_width = new_width;
161 m_height = new_height;
162 m_gpu_texture.reset();
163 m_texture_dirty = true;
164 m_geometry_dirty = true;
165
166 if (auto proc = get_texture_processor()) {
167 proc->invalidate_staging();
168 }
169}
170
171// =========================================================================
172// Display Transform
173// =========================================================================
174
175void TextureBuffer::set_position(float x, float y)
176{
177 if (m_position.x != x || m_position.y != y) {
178 m_position = { x, y };
179 m_geometry_dirty = true;
180
182 "TextureBuffer: position set to ({}, {}), geometry marked dirty", x, y);
183 }
184}
185
187{
188 if (m_scale.x != width || m_scale.y != height) {
189 m_scale = { width, height };
190 m_geometry_dirty = true;
191
193 "TextureBuffer: scale set to ({}, {}), geometry marked dirty", width, height);
194 }
195}
196
197void TextureBuffer::set_rotation(float angle_radians)
198{
199 if (m_rotation != angle_radians) {
200 m_rotation = angle_radians;
201 m_geometry_dirty = true;
202
204 "TextureBuffer: rotation set to {}, geometry marked dirty", angle_radians);
205 }
206}
207
208// =========================================================================
209// Custom Geometry
210// =========================================================================
211
212void TextureBuffer::set_custom_vertices(const std::vector<Kakshya::TextureQuadVertex>& vertices)
213{
214 if (vertices.size() != 4) {
216 "set_custom_vertices: must provide exactly 4 vertices, got {}", vertices.size());
217 return;
218 }
219
220 m_vertex_bytes.resize(vertices.size() * sizeof(Kakshya::TextureQuadVertex));
221 std::memcpy(m_vertex_bytes.data(), vertices.data(), m_vertex_bytes.size());
223 m_geometry_dirty = true;
224
226 "TextureBuffer: custom vertices set, geometry marked dirty");
227}
228
230{
234 m_geometry_dirty = true;
235
237 "TextureBuffer: reset to default quad, geometry marked dirty");
238 }
239}
240
241// =========================================================================
242// Geometry Generation
243// =========================================================================
244
249
251{
253 m_vertex_bytes.resize(geo.vertices.size() * sizeof(Kakshya::TextureQuadVertex));
254 std::memcpy(m_vertex_bytes.data(), geo.vertices.data(), m_vertex_bytes.size());
255 set_vertex_layout(geo.layout);
256
258 "TextureBuffer: generated default quad");
259}
260
262{
265 "TextureBuffer: using custom vertices, skipping transform");
266 return;
267 }
268
270 m_vertex_bytes.resize(geo.vertices.size() * sizeof(Kakshya::TextureQuadVertex));
271 std::memcpy(m_vertex_bytes.data(), geo.vertices.data(), m_vertex_bytes.size());
272
274 "TextureBuffer: regenerated quad with transform (pos={},{}, scale={},{}, rot={})",
276}
277
278} // namespace MayaFlux::Buffers
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
IO::ImageData image
Definition Decoder.cpp:47
bool format
bool size
BufferProcessingChain * chain
std::string name
Definition VKDevice.cpp:123
uint32_t width
uint32_t height
void setup_processors(ProcessingToken token) override
Setup processors with a processing token.
void set_gpu_texture(std::shared_ptr< Core::VKImage > image)
Inject a pre-existing GPU texture, bypassing TextureProcessor allocation.
std::shared_ptr< TextureProcessor > get_texture_processor() const
void use_default_quad()
Reset to default fullscreen quad Uses position and scale to generate quad geometry.
std::shared_ptr< TextureProcessor > m_texture_processor
std::shared_ptr< Core::VKImage > m_gpu_texture
std::vector< uint8_t > m_pixel_data
virtual void setup_rendering(const RenderConfig &config)
Setup rendering with RenderProcessor.
void mark_pixels_dirty()
Mark pixel data as changed Use this if you modify pixel data in-place without calling set_pixel_data(...
void set_position(float x, float y)
Set screen position (NDC or pixel coords depending on rendering setup)
void resize_texture(uint32_t new_width, uint32_t new_height)
Reallocate the GPU texture at new dimensions.
TextureBuffer(uint32_t width, uint32_t height, Portal::Graphics::ImageFormat format, const void *initial_pixel_data=nullptr)
Create texture buffer with dimensions.
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
void set_rotation(float angle_radians)
Set rotation around center.
void set_scale(float width, float height)
Set display size.
void set_custom_vertices(const std::vector< Kakshya::TextureQuadVertex > &vertices)
void set_pixel_data(const void *data, size_t size)
Replace pixel data.
void set_vertex_layout(const Kakshya::VertexLayout &layout)
Set vertex layout for this buffer.
Definition VKBuffer.cpp:453
std::shared_ptr< Buffers::BufferProcessingChain > get_processing_chain() override
Access the buffer's processing chain.
Definition VKBuffer.cpp:271
void set_default_processor(const std::shared_ptr< BufferProcessor > &processor) override
Set the buffer's default processor.
Definition VKBuffer.cpp:255
void set_processing_chain(const std::shared_ptr< BufferProcessingChain > &chain, bool force=false) override
Replace the buffer's processing chain.
Definition VKBuffer.cpp:276
void apply_render_config(const RenderConfig &config, const ShaderConfig &shader_config)
Configure the internal m_render_processor from a RenderConfig.
Definition VKBuffer.cpp:344
std::shared_ptr< RenderProcessor > m_render_processor
Definition VKBuffer.hpp:654
void set_default_render_config(const RenderConfig &config)
Called by derived classes to set their context-specific defaults.
Definition VKBuffer.hpp:631
Vulkan-backed buffer wrapper used in processing chains.
Definition VKBuffer.hpp:76
static size_t get_bytes_per_pixel(ImageFormat format)
Get bytes per pixel for a format.
ProcessingToken
Bitfield enum defining processing characteristics and backend requirements for buffer operations.
@ BufferProcessing
Buffer processing (Buffers::BufferManager, processing chains)
@ Init
Engine/subsystem initialization.
@ Buffers
Buffers, Managers, processors and processing chains.
ImageFormat
User-friendly image format enum.
Definition ImageData.hpp:12
QuadGeometry generate_quad(glm::vec2 position, glm::vec2 scale, float rotation)
Generate a textured quad centred on the origin.
BufferUsageHint
Semantic usage hint for buffer allocation and memory properties.
Describes how a VKBuffer binds to a shader descriptor.
Vertex layout for textured quad geometry (position + UV).
std::shared_ptr< Core::Window > target_window
std::vector< std::pair< std::string, std::shared_ptr< Core::VKImage > > > additional_textures
Unified rendering configuration for graphics buffers.