22 const auto* vb =
std::get_if<
std::vector<uint8_t>>(
23 &data.vertex_variant);
24 return vb ? vb->size() : 0;
27 Kakshya::DataModality::VERTEX_POSITIONS_3D)
28 , m_mesh_data(std::move(data))
30 if (!m_mesh_data.is_valid()) {
31 MF_WARN(Journal::Component::Buffers, Journal::Context::Init,
32 "MeshBuffer constructed with invalid MeshData — "
33 "GPU upload will be skipped until valid data is provided");
36 RenderConfig defaults;
37 defaults.vertex_shader =
"triangle.vert.spv";
38 defaults.topology = Portal::Graphics::PrimitiveTopology::TRIANGLE_LIST;
39 set_default_render_config(defaults);
41 set_needs_depth_attachment(
true);
43 MF_INFO(Journal::Component::Buffers, Journal::Context::Init,
44 "MeshBuffer: {} vertices, {} indices ({} faces), stride {} bytes",
45 m_mesh_data.vertex_count(),
47 m_mesh_data.face_count(),
48 m_mesh_data.layout.stride_bytes);
51MeshBuffer::MeshBuffer(std::shared_ptr<Nodes::GpuSync::MeshWriterNode> node)
53 node ? node->get_mesh_vertex_count() * sizeof(Kakshya::MeshVertex) : 0,
55 Kakshya::DataModality::VERTEX_POSITIONS_3D)
56 , m_node(
std::move(node))
60 const auto verts =
m_node->get_mesh_vertices();
61 const auto indices =
m_node->get_mesh_indices();
65 std::span<const uint8_t>(
66 reinterpret_cast<const uint8_t*
>(verts.data()),
68 std::span<const uint32_t>(indices),
71 data.layout.vertex_count =
static_cast<uint32_t
>(verts.size());
94 chain = std::make_shared<BufferProcessingChain>();
97 chain->set_preferred_token(token);
100 "MeshBuffer::setup_processors with token {}",
101 static_cast<int>(token));
143 ?
"mesh_textured.frag.spv"
144 :
"triangle.frag.spv";
151 0, 1, vk::DescriptorType::eCombinedImageSampler);
154 uint32_t binding_index = 1;
157 1, binding_index++, vk::DescriptorType::eCombinedImageSampler);
177 "MeshBuffer::setup_rendering: vert={} frag={} textured={}",
188 std::shared_ptr<Core::VKImage>
image,
189 std::string_view binding_name)
199 "MeshBuffer::bind_diffuse_texture: pipeline was created without "
200 "binding '{}' — call before setup_rendering() for correct results",
215 "MeshBuffer::set_vertex_data: byte count {} not a multiple of stride {}",
230 if (indices.size() % 3 != 0) {
232 "MeshBuffer::set_index_data: index count {} is not a multiple of 3",
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
std::string m_diffuse_binding
std::shared_ptr< Core::VKImage > m_diffuse_texture
std::shared_ptr< Nodes::GpuSync::MeshWriterNode > m_node
void setup_processors(ProcessingToken token) override
Create and attach MeshProcessor as the default processor.
void set_index_data(std::span< const uint32_t > indices)
Replace index data entirely and mark indices dirty.
std::shared_ptr< MeshProcessor > m_mesh_processor
MeshBuffer(Kakshya::MeshData data)
Construct from an owning MeshData.
void bind_diffuse_texture(std::shared_ptr< Core::VKImage > image, std::string_view binding_name="diffuseTex")
Bind a diffuse texture to the render processor, if present.
void set_mesh_data(Kakshya::MeshData data)
Replace both vertex and index data atomically and mark both dirty.
std::atomic< bool > m_indices_dirty
void set_vertex_data(std::span< const uint8_t > bytes)
Replace vertex bytes entirely and mark vertices dirty.
std::atomic< bool > m_vertices_dirty
void setup_rendering(const RenderConfig &config)
Attach a RenderProcessor targeting the given window.
Kakshya::MeshData m_mesh_data
RenderConfig m_render_config
std::shared_ptr< Buffers::BufferProcessingChain > get_processing_chain() override
Access the buffer's processing chain.
void set_default_processor(const std::shared_ptr< BufferProcessor > &processor) override
Set the buffer's default processor.
void set_processing_chain(const std::shared_ptr< BufferProcessingChain > &chain, bool force=false) override
Replace the buffer's processing chain.
void set_needs_depth_attachment(bool needs)
Mark this buffer as requiring depth testing when rendered.
void apply_render_config(const RenderConfig &config, const ShaderConfig &shader_config)
Configure the internal m_render_processor from a RenderConfig.
std::shared_ptr< RenderProcessor > m_render_processor
void set_default_render_config(const RenderConfig &config)
Called by derived classes to set their context-specific defaults.
Vulkan-backed buffer wrapper used in processing chains.
void insert_flat(std::span< const uint8_t > vertex_bytes, std::span< const uint32_t > index_data, const VertexLayout &layout)
Insert a single flat mesh (no submesh tracking).
Write counterpart to MeshAccess.
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.
static MeshData empty()
Construct an empty MeshData with the canonical 60-byte mesh layout.
DataVariant vertex_variant
vector<uint8_t>: interleaved vertex bytes
DataVariant index_variant
vector<uint32_t>: triangle index list
Owning CPU-side representation of a loaded or generated mesh.
Vertex type for indexed triangle mesh primitives (TRIANGLE_LIST topology)
uint32_t stride_bytes
Total bytes per vertex (stride in Vulkan terms) e.g., 3 floats (position) + 3 floats (normal) = 24 by...
uint32_t vertex_count
Total number of vertices in this buffer.
static VertexLayout for_meshes(uint32_t stride=60)
Factory: layout for MeshVertex (position, color, weight, uv, normal, tangent)
std::shared_ptr< Core::Window > target_window
std::vector< std::pair< std::string, std::shared_ptr< Core::VKImage > > > additional_textures
For child-specific fields.
PrimitiveTopology topology
std::string vertex_shader
std::string fragment_shader
std::string default_texture_binding
Unified rendering configuration for graphics buffers.