MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
ComputeMeshBuffer.cpp
Go to the documentation of this file.
2
6
10
11namespace MayaFlux::Buffers {
12
13// ============================================================================
14// Construction
15// ============================================================================
16
18 Config config)
19 : VKBuffer(
20 worst_case_bytes(
21 config.resolution_x, config.resolution_y, config.resolution_z),
22 Usage::VERTEX,
23 Kakshya::DataModality::VERTEX_POSITIONS_3D)
24 , m_res_x(std::max(config.resolution_x, 1U))
25 , m_res_y(std::max(config.resolution_y, 1U))
26 , m_res_z(std::max(config.resolution_z, 1U))
27 , m_bounds_min(config.bounds_min)
28 , m_bounds_max(config.bounds_max)
29 , m_iso_level(config.iso_level)
30{
31 std::visit([this](auto&& source) {
32 using Source = std::remove_cvref_t<decltype(source)>;
33 if constexpr (std::is_same_v<Source, Kinesis::SpatialField>) {
34 m_field = std::move(source);
35 } else if constexpr (std::is_same_v<Source, std::filesystem::path>) {
36 m_gpu_field = true;
37 m_field_shader = std::move(source).string();
38 } else {
39 m_gpu_field = true;
40 m_field_expression = std::move(source.source);
41 }
42 },
43 std::move(config.source));
44
46 "ComputeMeshBuffer{}: {}x{}x{} grid, {:.1f} MB worst-case",
47 m_gpu_field ? " (GPU field)" : "",
49 static_cast<float>(get_size_bytes()) / (1024.F * 1024.F));
50}
51
52// ============================================================================
53// Processor setup
54// ============================================================================
55
57{
58 auto self = std::dynamic_pointer_cast<ComputeMeshBuffer>(shared_from_this());
59
61 layout.vertex_count = static_cast<uint32_t>(
63 set_vertex_layout(layout);
64
66 if (!chain) {
67 chain = std::make_shared<BufferProcessingChain>();
69 }
70 chain->set_preferred_token(token);
71
72 if (m_gpu_field) {
73 m_prep_processor = std::make_shared<SDFPrepProcessor>(m_res_x, m_res_y, m_res_z);
74 m_prep_processor->set_processing_token(token);
76
78 m_field_processor = std::make_shared<SDFFieldProcessor>(
79 m_prep_processor->grid_buf(),
83 } else {
84 m_field_processor = std::make_shared<SDFFieldProcessor>(
85 m_prep_processor->grid_buf(),
89 }
90 m_field_processor->set_processing_token(token);
91 chain->add_preprocessor(m_field_processor, self);
92
93 m_sdf_processor = std::make_shared<SDFMeshProcessor>(
94 m_prep_processor->grid_buf(),
95 m_prep_processor->counter_buf(),
99
100 m_sdf_processor->set_processing_token(token);
101
102 chain->add_processor(m_sdf_processor, self);
103
104 } else {
105 m_sdf_processor = std::make_shared<SDFMeshProcessor>(
106 std::move(m_field),
110 m_sdf_processor->set_processing_token(token);
112 }
113}
114
116{
117 const bool textured = m_diffuse_texture != nullptr
118 || !config.default_texture_binding.empty();
119
120 RenderConfig resolved = config;
122
123 if (resolved.vertex_shader.empty())
124 resolved.vertex_shader = "triangle.vert.spv";
125
126 if (resolved.fragment_shader.empty()) {
127 resolved.fragment_shader = textured
128 ? "mesh_textured.frag.spv"
129 : "triangle.frag.spv";
130 }
131
132 ShaderConfig sc { resolved.vertex_shader };
133
134 if (textured) {
135 const std::string slot = resolved.default_texture_binding.empty()
137 : resolved.default_texture_binding;
138 sc.bindings[slot] = ShaderBinding(0, 1, vk::DescriptorType::eCombinedImageSampler);
139 }
140
141 apply_render_config(resolved, sc);
142
145
146 get_processing_chain()->add_final_processor(
147 m_render_processor, shared_from_this());
148
150 "ComputeMeshBuffer: rendering configured ({}textured)",
151 textured ? "" : "un");
152}
153
154// ============================================================================
155// Field and geometry control
156// ============================================================================
157
159{
160 if (m_sdf_processor) {
161 m_sdf_processor->set_field(std::move(field));
162 } else {
163 m_field = std::move(field);
164 }
165}
166
167void ComputeMeshBuffer::set_bounds(const glm::vec3& bounds_min, const glm::vec3& bounds_max)
168{
169 if (m_sdf_processor) {
170 m_sdf_processor->set_bounds(bounds_min, bounds_max);
171 } else {
172 m_bounds_min = bounds_min;
173 m_bounds_max = bounds_max;
174 }
175 if (m_field_processor) {
176 m_field_processor->set_bounds(bounds_min, bounds_max);
177 }
178}
179
180void ComputeMeshBuffer::set_resolution(uint32_t res_x, uint32_t res_y, uint32_t res_z)
181{
182 m_res_x = std::max(res_x, 1U);
183 m_res_y = std::max(res_y, 1U);
184 m_res_z = std::max(res_z, 1U);
185 if (m_sdf_processor)
186 m_sdf_processor->set_resolution(m_res_x, m_res_y, m_res_z);
187}
188
190{
191 m_iso_level = iso_level;
192 if (m_sdf_processor)
193 m_sdf_processor->set_iso_level(iso_level);
194}
195
197{
198 if (m_sdf_processor)
199 m_sdf_processor->set_dirty();
200}
201
202// ============================================================================
203// Texture
204// ============================================================================
205
206void ComputeMeshBuffer::set_texture(std::shared_ptr<Core::VKImage> image, std::string binding)
207{
208 m_diffuse_texture = std::move(image);
209 m_diffuse_binding = std::move(binding);
210
213}
214
215std::optional<uint32_t> ComputeMeshBuffer::get_live_vertex_count() const
216{
217 return m_sdf_processor ? m_sdf_processor->live_vertex_count() : std::nullopt;
218}
219
220} // namespace MayaFlux::Buffers
#define MF_INFO(comp, ctx,...)
IO::ImageData image
Definition Decoder.cpp:47
BufferProcessingChain * chain
glm::ivec3 max
void set_dirty()
Request a re-dispatch on the next graphics frame.
std::shared_ptr< SDFMeshProcessor > m_sdf_processor
std::shared_ptr< SDFFieldProcessor > m_field_processor
void set_bounds(const glm::vec3 &bounds_min, const glm::vec3 &bounds_max)
Replace the evaluation volume and mark dirty.
void set_texture(std::shared_ptr< Core::VKImage > image, std::string binding="diffuseTex")
Bind a diffuse texture sampled in the fragment shader.
void setup_rendering(const RenderConfig &config)
Create the RenderProcessor and attach it to the processing chain.
static size_t worst_case_bytes(uint32_t res_x, uint32_t res_y, uint32_t res_z) noexcept
std::optional< uint32_t > get_live_vertex_count() const
The live vertex count from the most recent dispatch.
std::shared_ptr< Core::VKImage > m_diffuse_texture
std::shared_ptr< SDFPrepProcessor > m_prep_processor
void set_iso_level(float iso_level)
Replace the iso_level threshold and mark dirty.
void setup_processors(ProcessingToken token) override
Setup processors with a processing token.
void set_resolution(uint32_t res_x, uint32_t res_y, uint32_t res_z)
Replace the grid resolution.
std::optional< Kinesis::FieldSource > m_field_expression
void set_field(Kinesis::SpatialField field)
Replace the scalar field and mark dirty.
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
vk::DeviceSize get_size_bytes() const
Definition VKBuffer.hpp:280
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
Vulkan-backed buffer wrapper used in processing chains.
Definition VKBuffer.hpp:76
ProcessingToken
Bitfield enum defining processing characteristics and backend requirements for buffer operations.
@ Init
Engine/subsystem initialization.
@ Buffers
Buffers, Managers, processors and processing chains.
BufferUsageHint
Semantic usage hint for buffer allocation and memory properties.
Describes how a VKBuffer binds to a shader descriptor.
Vertex type for indexed triangle mesh primitives (TRIANGLE_LIST topology)
static VertexLayout for_meshes(uint32_t stride=60)
Factory: layout for MeshVertex (position, color, weight, uv, normal, tangent)
Typed, composable, stateless callable from domain D to range R.
Definition Tendency.hpp:22
Unified rendering configuration for graphics buffers.