I have several draw functions in my renderer to draw primitives e.g.:
Drawing a Quad:
void Renderer::DrawQuad2D(float left, float bottom, float right, float top, const Rgba& color /*= Rgba::WHITE*/, const Vector4& texCoords /*= Vector4::ZW_AXIS*/) noexcept {
Vector3 v_lb = Vector3(left, bottom, 0.0f);
Vector3 v_rt = Vector3(right, top, 0.0f);
Vector3 v_lt = Vector3(left, top, 0.0f);
Vector3 v_rb = Vector3(right, bottom, 0.0f);
Vector2 uv_lt = Vector2(texCoords.x, texCoords.y);
Vector2 uv_lb = Vector2(texCoords.x, texCoords.w);
Vector2 uv_rt = Vector2(texCoords.z, texCoords.y);
Vector2 uv_rb = Vector2(texCoords.z, texCoords.w);
std::vector<Vertex3D> vbo = {
Vertex3D(v_lb, color, uv_lb)
,Vertex3D(v_lt, color, uv_lt)
,Vertex3D(v_rt, color, uv_rt)
,Vertex3D(v_rb, color, uv_rb)
};
std::vector<unsigned int> ibo = {
0, 1, 2
, 0, 2, 3
};
DrawIndexed(PrimitiveType::Triangles, vbo, ibo);
}
Sending the verts and indexes to the GPU
void Renderer::DrawIndexed(const PrimitiveType& topology, const std::vector<Vertex3D>& vbo, const std::vector<unsigned int>& ibo) noexcept {
UpdateVbo(vbo);
UpdateIbo(ibo);
DrawIndexed(topology, _temp_vbo.get(), _temp_ibo.get(), ibo.size());
}
Setup and call DrawIndex on immediate context.
void Renderer::DrawIndexed(const PrimitiveType& topology, VertexBuffer* vbo, IndexBuffer* ibo, std::size_t index_count, std::size_t startVertex /*= 0*/, std::size_t baseVertexLocation /*= 0*/) noexcept {
GUARANTEE_OR_DIE(_current_material, "Attempting to call Draw function without a material set!\n");
D3D11_PRIMITIVE_TOPOLOGY d3d_prim = PrimitiveTypeToD3dTopology(topology);
_rhi_context->GetDxContext()->IASetPrimitiveTopology(d3d_prim);
unsigned int stride = sizeof(VertexBuffer::arraybuffer_t);
unsigned int offsets = 0;
ID3D11Buffer* dx_vbo_buffer = vbo->GetDxBuffer();
ID3D11Buffer* dx_ibo_buffer = ibo->GetDxBuffer();
_rhi_context->GetDxContext()->IASetVertexBuffers(0, 1, &dx_vbo_buffer, &stride, &offsets);
_rhi_context->GetDxContext()->IASetIndexBuffer(dx_ibo_buffer, DXGI_FORMAT_R32_UINT, offsets);
_rhi_context->DrawIndexed(index_count, startVertex, baseVertexLocation);
}
The most noticeable problem is each function issues a draw call. Doing this enough per frame (about 100) causes massive lag. How would I implement a batching such that each of these functions, instead of emitting a draw call immediately, collects all the verts/indexes and doesn't draw until the end of the frame?