MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
MeshNetworkBuffer.cpp
Go to the documentation of this file.
2
6
8
10
11namespace MayaFlux::Buffers {
12
13// =============================================================================
14// Construction
15// =============================================================================
16
18 std::shared_ptr<Nodes::Network::MeshNetwork> network,
19 float over_allocate_factor)
20 : VKBuffer(
21 estimate_vertex_bytes(network, over_allocate_factor),
22 Usage::VERTEX,
23 Kakshya::DataModality::VERTEX_POSITIONS_3D)
24 , m_network(std::move(network))
25{
26 if (!m_network) {
27 error<std::invalid_argument>(
29 std::source_location::current(),
30 "MeshNetworkBuffer: null MeshNetwork");
31 }
32
33 RenderConfig defaults;
37
38 m_render_config = defaults;
39
41 "MeshNetworkBuffer: {} slots, {} bytes estimated",
42 m_network->slot_count(), get_size_bytes());
43}
44
45// =============================================================================
46// setup_processors
47// =============================================================================
48
50{
51 m_processor = std::make_shared<MeshNetworkProcessor>(m_network);
52 m_processor->set_processing_token(token);
54
55 auto chain = get_processing_chain();
56 if (!chain) {
57 chain = std::make_shared<BufferProcessingChain>();
59 }
60 chain->set_preferred_token(token);
61
63 "MeshNetworkBuffer::setup_processors with token {}",
64 static_cast<int>(token));
65}
66
67// =============================================================================
68// setup_rendering
69// =============================================================================
70
72{
73 if (!config.vertex_shader.empty())
75 if (!config.fragment_shader.empty())
77 if (!config.default_texture_binding.empty()) {
80 }
81
86
87 for (const auto& [name, tex] : config.additional_textures)
88 m_render_config.additional_textures.emplace_back(name, tex);
89
90 const auto slot_count = static_cast<uint32_t>(m_network->slot_count());
91
92 const bool has_slot_textures = std::ranges::any_of(
93 m_network->slots(),
94 [](const auto& slot) { return slot.diffuse_texture != nullptr; });
95
96 const bool textured = m_diffuse_texture != nullptr
98 || has_slot_textures;
99
100 if (textured && m_render_config.default_texture_binding.empty())
102
103 if (m_render_config.vertex_shader.empty())
104 m_render_config.vertex_shader = "mesh_network.vert.spv";
105
106 if (m_render_config.fragment_shader.empty()) {
108 ? "mesh_network_textured.frag.spv"
109 : "mesh_network.frag.spv";
110 }
111
113
114 sc.bindings["modelMatrices"] = ShaderBinding(0, 1, vk::DescriptorType::eStorageBuffer);
115 sc.bindings["slotIndices"] = ShaderBinding(0, 2, vk::DescriptorType::eStorageBuffer);
116
117 if (has_slot_textures) {
118 sc.bindings["diffuseTex"] = ShaderBinding(
119 0, 3, vk::DescriptorType::eCombinedImageSampler, slot_count);
120 } else if (textured && !m_render_config.default_texture_binding.empty()) {
122 0, 3, vk::DescriptorType::eCombinedImageSampler);
123 }
124
125 uint32_t binding_idx = 0;
126 for (const auto& [name, _] : m_render_config.additional_textures)
127 sc.bindings[name] = ShaderBinding(1, binding_idx++, vk::DescriptorType::eCombinedImageSampler);
128
130
131 if (has_slot_textures) {
132 const auto& slots = m_network->slots();
133 const auto& order = m_network->sorted_indices();
134 for (uint32_t i = 0; i < static_cast<uint32_t>(order.size()); ++i) {
135 const auto& slot = slots[order[i]];
136 if (slot.diffuse_texture)
137 m_render_processor->bind_texture(3 + i, slot.diffuse_texture);
138 }
141 }
142
143 for (const auto& [name, tex] : m_render_config.additional_textures)
144 m_render_processor->bind_texture(name, tex);
145
146 get_processing_chain()->add_final_processor(
148 shared_from_this());
149
151 "MeshNetworkBuffer::setup_rendering: vert={} frag={} textured={}",
154 textured);
155}
156
157// =============================================================================
158// bind_diffuse_texture
159// =============================================================================
160
162 std::shared_ptr<Core::VKImage> image,
163 std::string_view binding_name)
164{
165 m_diffuse_texture = std::move(image);
166 m_diffuse_binding = std::string(binding_name);
167
168 if (m_render_processor) {
171 } else {
173 "MeshNetworkBuffer::bind_diffuse_texture: pipeline compiled without "
174 "binding '{}' — call before setup_rendering() for correct results",
176 }
177 }
178}
179
180// =============================================================================
181// Private helpers
182// =============================================================================
183
185 const std::shared_ptr<Nodes::Network::MeshNetwork>& network,
186 float over_allocate_factor)
187{
188 constexpr size_t k_min = 4096;
189 if (!network || network->slot_count() == 0)
190 return k_min;
191
192 size_t total = 0;
193 for (const auto& slot : network->slots()) {
194 if (slot.node)
195 total += slot.node->get_mesh_vertex_count() * sizeof(Kakshya::MeshVertex);
196 }
197
198 if (total == 0)
199 return k_min;
200
201 return static_cast<size_t>(static_cast<float>(total) * over_allocate_factor);
202}
203
204} // namespace MayaFlux::Buffers
#define MF_INFO(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
Core::GlobalNetworkConfig network
Definition Config.cpp:37
IO::ImageData image
Definition Decoder.cpp:57
std::shared_ptr< Core::VKImage > m_diffuse_texture
void setup_rendering(const RenderConfig &config)
Attach a RenderProcessor with optional texture support.
void setup_processors(ProcessingToken token) override
Create and attach MeshNetworkProcessor as the default processor.
MeshNetworkBuffer(std::shared_ptr< Nodes::Network::MeshNetwork > network, float over_allocate_factor=1.5F)
Construct from an existing MeshNetwork.
std::shared_ptr< MeshNetworkProcessor > m_processor
std::shared_ptr< Nodes::Network::MeshNetwork > m_network
static size_t estimate_vertex_bytes(const std::shared_ptr< Nodes::Network::MeshNetwork > &network, float over_allocate_factor)
void bind_diffuse_texture(std::shared_ptr< Core::VKImage > image, std::string_view binding_name="diffuseTex")
Bind a single shared diffuse texture for all slots.
std::shared_ptr< Buffers::BufferProcessingChain > get_processing_chain() override
Access the buffer's processing chain.
Definition VKBuffer.cpp:286
void set_default_processor(const std::shared_ptr< BufferProcessor > &processor) override
Set the buffer's default processor.
Definition VKBuffer.cpp:270
vk::DeviceSize get_size_bytes() const
Definition VKBuffer.hpp:279
void set_processing_chain(const std::shared_ptr< BufferProcessingChain > &chain, bool force=false) override
Replace the buffer's processing chain.
Definition VKBuffer.cpp:291
void set_needs_depth_attachment(bool needs)
Mark this buffer as requiring depth testing when rendered.
Definition VKBuffer.hpp:565
void apply_render_config(const RenderConfig &config, const ShaderConfig &shader_config)
Configure the internal m_render_processor from a RenderConfig.
Definition VKBuffer.cpp:359
std::shared_ptr< RenderProcessor > m_render_processor
Definition VKBuffer.hpp:618
void set_default_render_config(const RenderConfig &config)
Called by derived classes to set their context-specific defaults.
Definition VKBuffer.hpp:595
Vulkan-backed buffer wrapper used in processing chains.
Definition VKBuffer.hpp:67
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.
Describes how a VKBuffer binds to a shader descriptor.
Vertex type for indexed triangle mesh primitives (TRIANGLE_LIST topology)
std::shared_ptr< Core::Window > target_window
std::vector< std::pair< std::string, std::shared_ptr< Core::VKImage > > > additional_textures
For child-specific fields.
Unified rendering configuration for graphics buffers.