You can definitely put multiple objects in a vertex buffer, even with different numbers of vertices. A vertex buffer doesn't know or care where the "objects" are in it - it's nothing more than a list of vertices. If you have a fixed set of objects you want to draw, you can simply concatenate all your vertices together and put them in one big vertex buffer; when you do your Draw()
call, you'll specify the range of vertices to draw from the buffer. Or if you use index buffers and DrawIndexed()
, the same applies.
All the vertices in a buffer have to be the same format, though (i.e. the same size and order of components like position, normal, UV etc). You can't mix and match different vertex formats in one buffer. Well, technically perhaps you could, but you'd have to re-call IASetVertexBuffers()
with different strides and offsets, and do a separate draw call, for each format. That would pretty much negate the point of putting everything in one big vertex buffer; it would be simpler just to have several buffers.
Now, you brought up instancing, so I'll say a little about that. Instancing is designed to let you repeat an "inner" vertex buffer many times, each time pairing it with a different "outer vertex" (i.e. an instance). Across all the instances drawn in a single draw call, the inner vertex buffer must be the same. So if you have triangles in one buffer and squares in another, you would not be able to draw multiple instances of both of them in one draw call, using hardware instancing. You would have to do one draw call for all the triangles, and one for all the squares.
You have a couple options here. First, you could do the instancing manually, by constructing a huge vertex buffer and copying in the triangle vertices as many times as you have triangles, and the square vertices as many times as you have squares, etc.
The other option, which is advanced, is to use some tricks in the vertex shader to look up the inner vertices from a different place in the buffer depending on a value set in the outer vertex data. This requires all the different instance meshes to be padded out to a common vertex size by adding degenerate triangles. This approach was used in Just Cause 2. For more information see Emil Persson's presentation Graphics Gems for Games (slides 19-24).