@@ -29,18 +29,18 @@ namespace Tkge::Graphics
2929 return true ;
3030 }
3131
32- void Renderer::SetWireframe (const bool wireframe) { _polygonMode = wireframe ? vk::PolygonMode::eLine : vk::PolygonMode::eFill; }
33-
3432 void Renderer::SetLineWidth (const float width)
3533 {
3634 if (_renderPass == nullptr ) { return ; }
3735 const auto limits = _renderPass->get_render_device ().get_gpu ().properties .limits .lineWidthRange ;
3836 _lineWidth = std::clamp (width, limits[0 ], limits[1 ]);
3937 }
4038
41- void Renderer::Draw (const Primitive& primitive)
39+ void Renderer::SetWireframe (const bool wireframe) { _polygonMode = wireframe ? vk::PolygonMode::eLine : vk::PolygonMode::eFill; }
40+
41+ void Renderer::Draw (const Primitive& primitive, std::span<const RenderInstance> instances)
4242 {
43- if (!IsRendering () || _shader == nullptr || primitive.vertices .empty ()) { return ; }
43+ if (!IsRendering () || _shader == nullptr || primitive.vertices .empty () || instances. empty () ) { return ; }
4444
4545 const auto fixedState = PipelineFixedState{
4646 .colourFormat = _renderPass->get_color_format (),
@@ -56,11 +56,22 @@ namespace Tkge::Graphics
5656 _renderPass->bind_pipeline (_pipeline);
5757 }
5858
59+ UpdateInstances (instances);
5960 if (!WriteSets ()) { return ; }
6061
6162 _renderPass->get_command_buffer ().setViewport (0 , _viewport);
6263
63- BindVboAndDraw (primitive);
64+ BindVboAndDraw (primitive, std::uint32_t (instances.size ()));
65+ }
66+
67+ void Renderer::UpdateInstances (std::span<const RenderInstance> instances)
68+ {
69+ _instances.clear ();
70+ _instances.reserve (instances.size ());
71+ for (const auto & instance : instances)
72+ {
73+ _instances.push_back (Std430Instance{.model = instance.transform .ToModel (), .tint = instance.tint .to_linear ()});
74+ }
6475 }
6576
6677 bool Renderer::WriteSets () const
@@ -91,6 +102,11 @@ namespace Tkge::Graphics
91102 kvf::util::overwrite (ubo00, matVP);
92103 pushBufferWrite (descriptorSets[0 ], 0 , ubo00, vk::DescriptorType::eUniformBuffer);
93104
105+ const auto instanceSpan = std::span{_instances};
106+ auto & ssbo01 = _resourcePool->AllocateBuffer (vk::BufferUsageFlagBits::eStorageBuffer, instanceSpan.size_bytes ());
107+ kvf::util::overwrite (ssbo01, instanceSpan);
108+ pushBufferWrite (descriptorSets[0 ], 1 , ssbo01, vk::DescriptorType::eStorageBuffer);
109+
94110 const auto writeSpan = std::span{descriptorWrites.data (), descriptorWrites.size ()};
95111 renderDevice.get_device ().updateDescriptorSets (writeSpan, {});
96112
@@ -100,7 +116,7 @@ namespace Tkge::Graphics
100116 return true ;
101117 }
102118
103- void Renderer::BindVboAndDraw (const Primitive& primitive) const
119+ void Renderer::BindVboAndDraw (const Primitive& primitive, const std:: uint32_t instances ) const
104120 {
105121 const auto vertSize = primitive.vertices .size_bytes ();
106122 const auto vboSize = vertSize + primitive.indices .size_bytes ();
@@ -112,11 +128,11 @@ namespace Tkge::Graphics
112128 commandBuffer.setLineWidth (_lineWidth);
113129
114130 commandBuffer.bindVertexBuffers (0 , vertexBuffer.get_buffer (), vk::DeviceSize{});
115- if (primitive.indices .empty ()) { commandBuffer.draw (std::uint32_t (primitive.vertices .size ()), 1 , 0 , 0 ); }
131+ if (primitive.indices .empty ()) { commandBuffer.draw (std::uint32_t (primitive.vertices .size ()), instances , 0 , 0 ); }
116132 else
117133 {
118134 commandBuffer.bindIndexBuffer (vertexBuffer.get_buffer (), vertSize, vk::IndexType::eUint32);
119- commandBuffer.drawIndexed (std::uint32_t (primitive.indices .size ()), 1 , 0 , 0 , 0 );
135+ commandBuffer.drawIndexed (std::uint32_t (primitive.indices .size ()), instances , 0 , 0 , 0 );
120136 }
121137 }
122138} // namespace Tkge::Graphics
0 commit comments