# How to draw multiple shapes in one draw call?

I have a misunderstanding about vertex buffers in DirectX. I'm trying to draw infinite vertices that they may represent a line or a circle or a rectangle in a single draw call. I can bind them all together and set a flag for each vertex to determine which shape I have to draw now with DrawPrimitive(), but the questions are:

1. When I first create the vertex buffer, I set a constant length of 1000 for it because I don't know how many vertices I'm going to draw. How can I avoid this?

2. I don't know the proper way of drawing these vertices at all. I mean I can draw them right now with a dynamic VB, but I have no idea on performance and etc.

BTW, I've read this article which is pretty good, but it doesn't apply to my issue.

Edit

For example, I have 6 vertices which 2 of them are shaping a line and the other 4 are shaping a rectangle. I can bind them all together and copy them into the vertex buffer and then draw. Now, what if next time I wanted to draw a line and two rectangles? In this case I have to add 4 other vertices to my current list and we suppose my VB is not big enough to do that. This is my misunderstanding that I don't know if I should reserve enough space at first place for my VB or there is an alternative to pitch the length during runtime.

I'm trying to draw basic 2d shapes here nothing 3d:

// A class member
std::vector<Vertex2D> mVertices;

// Draw method
{
void* buffer = new char[this->mVertices.size() * sizeof(Vertex2D)];

Device()->VertexBuffer()->Lock(0, sizeof(buffer), &buffer, D3DLOCK_DISCARD);
memcpy(buffer, this->mVertices.data(), sizeof(buffer));
Device()->VertexBuffer()->Unlock();

Device()->SetStreamSource(0, Device()->VertexBuffer(), sizeof(Vertex2D), sizeof(Vertex2D));
Device()->SetFVF(D3DFVF_VERTEX2D);
Device()->DrawPrimitive(D3DPT_LINELIST, 0, this->mVertices.size());

delete[] buffer;
}


It's a simple draw call in a bigger loop. mVertices is a collection of different vertices for different shapes. My second question was, how to draw different shapes from one vertex buffer in a single draw call. My first question was, how can I adjust vertex buffer's length with a relevant length to my vertices and not a default value at compile time.

• You may be able to use a pixel shader to take an array of 1000 vertices and shape them that way...look up particle effects... – P. Avery Mar 22 '14 at 18:00
• @P.Avery Well I don't want to set a default 1000 vertices. Isn't there a way to pitch vertex buffer length with your vertices count? – MahanGM Mar 22 '14 at 18:45
• what exactly are you trying to do? a vertex buffer is an array of vertices...you can only resize an array by explicitly telling the application to do that in software...perhaps you can set a maximum sized length and in a draw call set the '#primitives' parameter to a desired length...your method will depend on what you are trying to accomplish... – P. Avery Mar 22 '14 at 19:50
• Why do you only want to use one draw call? What's wrong with multiple buffers/draw calls? – Syntac_ Mar 22 '14 at 21:03
• @Syntac Like I said in my second question, I don't know the proper way of doing this :) this is why I'm asking. Besides, I've read that if we use a dynamic VB, then we can tweak vertices in dynamic mode and I assume this is faster than having multiple buffers and calls. – MahanGM Mar 22 '14 at 21:11

## 2 Answers

The standard way of rendering multiple shapes is to have a vertex buffer for each shape. When you want to draw lots of quads you can set your vertex buffer once and modify the world matrix for each quad you want to draw, i.e. scale, rotation, translation. It's easier to encapsulate this into a class.

I understand that you wish to use one draw call to be efficient but I would hazard a guess that mapping the vertex buffer to main memory every time you wish to change the geometry would be much more time consuming (assuming you do it often).

Direct3D does not provide a way to change the length of a vertex buffer after creation, so if you were to go down this route you would have to create extra buffers when you ran of out space.

Also I'm not sure how efficient this system would be when adding functionality to not render shapes (visibility flag), etc.

Just wanted to add a point on instancing.

You can use hardware instancing as P. Avery mentions. This would allow you to use one draw call per shape. So for instance you have a vertex buffer for a unit quad and then just use an array of matrices to transform the quad into the correct scale, rotation and position. More info can be found here on MSDN.

• If this is the standard way, then both of my questions would be answered. I want to wait and hear from others about this if you don't mind. – MahanGM Mar 22 '14 at 21:35
• I agree with Syntac about maintaining a vertex buffer for each shape and drawing that shape as desired by supplying different transformation matrices...I'm still trying to understand the need for 'infinite' vertices as stated in the first question...the 2nd question is answered with instancing...see MSDN docs or my answer below... – P. Avery Mar 23 '14 at 3:18

maybe instancing is what you want...you can instance a collection of vertices( a single vertex or many vertices, a mesh for example ) many times. This is done in software before the draw call...see this for an example of instancing...

• The thing is my vertices are not in the same shape. As I mentioned before, they're suppose to form different shapes. See my edit. – MahanGM Mar 22 '14 at 20:43
• @MahanGM can you lay out for me what resources you have to use? are they different meshes? are the vertex buffers created programmatically...i need some code to understand what it is you are doing... – P. Avery Mar 22 '14 at 20:45
• OK. Let me see what I can put. – MahanGM Mar 22 '14 at 20:50