I'm looking for an efficient way to render multiple object with unique texture sets each.

Right now I combine multiple objects into a single static vertex and index buffers in the way like this:

std::vector<Verts> v(m_vsize);
std::vector<uint32_t> ind(m_isize);

// SKIPPED: adding vertex and index data to "v" and "ind" vectors

D3D11_BUFFER_DESC vertexBuffer_desc = {};
vertexBuffer_desc.Usage = D3D11_USAGE_IMMUTABLE;
vertexBuffer_desc.ByteWidth = sizeof(Verts) * m_vsize;
vertexBuffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBuffer_desc.CPUAccessFlags = 0;
vertexBuffer_desc.MiscFlags = 0;
vertexBuffer_desc.StructureByteStride = 0;

D3D11_SUBRESOURCE_DATA vertexData = {};
vertexData.pSysMem = &v[0];
vertexData.SysMemPitch = 0;
vertexData.SysMemSlicePitch = 0;

HRESULT hr = m_d3dDevice->CreateBuffer(&vertexBuffer_desc, &vertexData, &m_vertexBuffer);
if (FAILED(hr))

D3D11_BUFFER_DESC indexBuffer_desc = {};
indexBuffer_desc.Usage = D3D11_USAGE_IMMUTABLE;
indexBuffer_desc.ByteWidth = sizeof(uint32_t) * m_isize;
indexBuffer_desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexBuffer_desc.CPUAccessFlags = 0;
indexBuffer_desc.MiscFlags = 0;
indexBuffer_desc.StructureByteStride = 0;

D3D11_SUBRESOURCE_DATA indexData = {};
indexData.pSysMem = &ind[0];
indexData.SysMemPitch = 0;
indexData.SysMemSlicePitch = 0;

hr = m_d3dDevice->CreateBuffer(&indexBuffer_desc, &indexData, &m_indexBuffer);
if (FAILED(hr))

After that I pass my buffers to Render() method and render everything with a single DrawIndexed() call:

// some stuff
m_d3dContext->IASetVertexBuffers(0, 1, m_vertexBuffer.GetAddressOf(), &stride, &offset);
m_d3dContext->IASetIndexBuffer(m_indexBuffer.Get(), DXGI_FORMAT_R32_UINT, offset);
// some more stuff
m_d3dContext->DrawIndexed(m_isize, 0, 0);

Where m_isize is a count of total indices. So what I'm looking for is how do I draw multiple objects separately? - Create individual buffers per each object (object count is unknown at startup)? - Create dynamic buffers and use those? - Keep using static buffers with re-assigning pointers to new objects and call DrawIndexed() per object instead of per frame? - A common solution? (Obviously unknown to me).

Basically all I need to find out is the name of pattern/technique commonly used to draw unknown amount of objects effectively. My approach doesn't work because I merge all groups into single vector variable and so I can't give various texture sets to various objects.


You can just create a unique vertex buffer for each mesh as a simple approach. Then for each mesh instance, you would bind the vertex buffer, set some shader constant buffer with per instance properties, set the textures, material and call Draw(). You can also create one big vertex buffer where you would put each mesh's vertices continuously and then the mesh instances would index that vertex buffer with an offset. You can specify an offset as an argument to the Draw() function. The same is true for DrawIndexed, you can specify an offset into an index buffer as well.

You can use instanced rendering (for example DrawIndexedInstanced function) to render each object in a single draw call, but with unique per instance data. But you can't bind unique textures per instance this way. You can however bind a texture array or texture atlas and have the per instance data index those in some way. In DirectX 12, you can do bindless textures and index textures dynamically which also extends instancing easily.

  • \$\begingroup\$ Your first point is what I would suggest. Begin with separate buffers and separate draw calls per mesh. What does performance look like? If it's OK then job done - nothing to optimize here. \$\endgroup\$ – Maximus Minimus Jan 31 '18 at 21:48
  • \$\begingroup\$ @MaximusMinimus thanks but if the mesh count is unknown to me at launch time, does it mean I will have to make a vector<vector<Mesh>> verticesArray and call DrawIndexed(IndexArray, offset, offset) per Mesh? How many Vertex and Index buffers shall I have this way? Single dynamic? Single static? Few static per mesh? \$\endgroup\$ – Mr Jox Feb 1 '18 at 17:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.