Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

Experts,

I`m a DirectX newbie. I`m using DirectX 9 on C# .net VS2008 3.5.

Let`s say I have a Vertex List, with indices 0-99. I use a Vertex Buffer to store these. Now my application requires that after an event the new vertices are added to the same list. Lets say 100-199. So on.

What is the most efficient way to to display the vertices in stages?

For example Step 1. Display 0-99

Step 2. Calculate vertices 100-199 and then display 0-199

Step 3. Calculate vertices 200-299 and then display 0-299

So on.

Do I calculate all the vertices before hand and then display them in stages, or can I calculate the vertices in stages and then display them.

Also, the user should be able to use transformations (rotation, shifting) at any stage.

I`m looking for some guidance with this.

I`m a DirectX newbie. I`m using DirectX 9 on C# .net VS2008 3.5.

Let`s say I have a Vertex List, with indices 0-99. I use a Vertex Buffer to store these. Now my application requires that after an event the new vertices are added to the same list. Lets say 100-199. So on.

What is the most efficient way to to display the vertices in stages?

For example Step 1. Display 0-99

Step 2. Calculate vertices 100-199 and then display 0-199

Step 3. Calculate vertices 200-299 and then display 0-299

So on.

Do I calculate all the vertices before hand and then display them in stages, or can I calculate the vertices in stages and then display them.

Also, the user should be able to use transformations (rotation, shifting) at any stage.

I`m looking for some guidance with this.

It is better to draw as much as possible in one call. However, 99 vertices or 199 vertices is plenty to draw in one go. If I understand the question properly, it's not efficient to draw 0-99, the 0-199 then 0-299, because you're drawing the same vertices many times. It better to draw each vertex once if you can. Unless the list of vertices is growing for some reason?

When you say the user should be able to transform, in what sense do you mean? Moving a camera around? Moving a model? Moving a subset of the vertices?

Any set of vertices you render uses the current render state (world transform, texture, shader etc.). Any need to change to the render state, means you have to render a separate group of vertices. This is why it is more efficient to group vertices according to render state (texture or shader). So if vertices 0-99 use texture A and 100-199 use texture B (or transform B), you have to render them as separate batches.

That said, assuming you're using a dynamic vertex buffer you can calculate vertices 100-199 while rendering vertices 0-99 and this can make things faster in many cases. The hardware can process vertices 0-99 in the same time it takes the CPU to calculate 100-199, so you exploit parallelism.

However, if you only drawing 300 vertices per frame it won't make much difference. This is only a speed up if the vertices change each frame and there are more of them than you can fit in a vertex buffer. If they are static then its much faster to just fill a vertex buffer with vertices and render that.

I realise this might be a bit confusing. If something is not clear I'd be happy to explain more detail if you let me know what applies to this case.

I agree, it`s not efficient to draw 0-99, then 0-199, then 0-299. etc. The reason I was wondering is this - the user can apply transform at any point. Transform here is moving the model. My thinking was (still a newbie with Graphics). Lets say the user wants to rotate the model at 0-199 stage, doesn`t that mean I need to have the vertices 0-199 drawn?

I should have been clear in my initial post - the vertices 0-99 are the same as 100-199 or 200-299 .. each set is offset by an angle. Think of it as a pattern. So, I`ll be saving time on not calculating them again at each step except for the time to calculate new vertices with the offset.

Let me try explaining with a simple group of numbers (each number is a vertex)

Lets say I have a group of numbers : 5 - 10 - 15 Stage 1

Next I apply an offset of 2 to the group : 7 - 12 - 17 Stage 2

Now at this point I have [5 - 10 - 15] - [7 - 12 - 17] which I should draw, and allow the user to move the model.

Next I get [5 - 10 - 15] - [7 - 12 - 17] - [9 - 14 - 19] .etc ..

So, my question is do i add to the vertex buffer at every stage and redraw? What would be the most efficient way to do this. The number of vertices could be quite staggering, so efficiency is important too.

I hope that helps. Any help on this is immensely appreciated.

So, What I`m looking to do is draw batches of geometry using Dynamic Vertex Buffers.

Here is the flow (not working)

```
/// <summary>
/// Calculate and Initialize Vertex Data
/// </summary>
private void InitVertex()
{
Cnt = FX0.Count;
VertexData = new List<CustomVertex.PositionNormalTextured>();
for (i = 0; i < Cnt - 1; i++)
{
//Calculate and fill into Veretex Data
}
Type VBType = typeof(CustomVertex.PositionNormalTextured);
VertexFormats VBFormats = CustomVertex.PositionNormalTextured.Format;
Usage VBUsage = Usage.WriteOnly | Usage.Dynamic; //Dynamic Vertex Buffer
Pool Pl = Pool.Default;
VBuffer = new VertexBuffer(VBType,
VertexData.Length,
GDevice,
VBUsage,
VBFormats,
Pl);
VBuffer.SetData(VertexData.ToArray(), 0, LockFlags.None);
}
```

Now, I have an Add Event which should append the Vertex Data

```
//Here I`m just duplicating the entries. The appended entries will be offset in the final code
private void Add_Click(object sender, EventArgs e)
{
//How do I Lock, Copy and Unlock. I`m lost here.
VertexData.AddRange(VertexData);
Render();
}
```

```
/// <summary>
/// Render
/// </summary>
private void Render()
{
GDevice.Clear(ClearFlags.Target, System.Drawing.Color.FromArgb(0, 0, 0).ToArgb(), 1.0f, 0);
GDevice.BeginScene();
InitDevice();
GDevice.VertexFormat = CustomVertex.PositionNormalTextured.Format;
GDevice.SetStreamSource(0, VFiberBuffer, 0);
GDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (VertexData.Count / 3));
GDevice.EndScene();
GDevice.Present();
}
```

Am I headed in the correct direction? Any sample code will be hugely helpful.

Assuming vertices 0-99 describe a model, and vertices 100-199 would describe the same model, but rotated 5 degrees. The fastest way would normally be to draw vertices 0-99, set the world transform to rotate 5 degrees and draw vertices 0-99 again. You don't need vertices 100-199 at all.

Assuming the vertices of the model don't change, the vertex buffer containing the vertices can stay in GPU ram all the time. You can render it as many times as you want without sending data from CPU to GPU (a fairly slow process). Even if the vertex buffer is not stored in GPU ram, you don't have to recalculate vertices 100-199 so that saves CPU time.

If the model is small, say 16 vertices, the time taken to repeatedly change the transform might exceed the time it takes to calculate new vertices and send the extra data. In that case it might be faster to calculate vertices into a big buffer and render it all in one go. But note, that is quite a few mights, you can only really find out by testing it. As I say, there isn't single answer.

A good way to think about it is anything that changes is slow, vertex, matrix, texture or shader. Speed means changing the smallest amount of things possible. Changing the matrix is less change than making a new set of vertices (unless the set of vertices is very small).

Dynamic vertex buffers are also useful when you are trying to save GPU memory (like on a phone). Instead of storing all the models in static buffers you copy them into the dynamic buffer and render it for each set of data.

I'd suggest a method if I knew exactly what kind of thing you were rendering, I guess theres a reason you've chosen dynamic buffers?

Still, the same answer applies, if all that changes is the transform, you can render the same vertices again and it will save time. Particularly in the case of a dynamic buffer.

Fill buffer with vertices for model A (vertices 0-50)

For each instance of model A set the transform and render vertices 0-50

Fill buffer with vertices of model B (50-120)

For each instance of model B set the transform and render vertices 50-120

Continue this way until all vertices in the buffer are used.

Start again from vertex 0.

If the models in question are small there's no gain from doing the instancing part. This would be the case with something like a particle system, where each item is a quad.

Assuming vertices 0-99 describe a model, and vertices 100-199 would describe the same model, but rotated 5 degrees. The fastest way would normally be to draw vertices 0-99, set the world transform to rotate 5 degrees and draw vertices 0-99 again. You don't need vertices 100-199 at all.

So, lets start with a solution for that.

What I initially did was : Step 1: Display 0-99

Step 2: Set Clear Device to false

Step 3: Rotate by angle

Step 4: Display 0-99

Repeat.

What this is doing is pretty much drawing vertices on top of each other.

This gives me the intended results. But if the user wants to transform the model, lets say he wants to see the side view, all the data is lost except the last set of vertices.

So, my thinking was to have all the vertices drawn.

```
GDevice.Clear(ClearFlags.Target, System.Drawing.Color.FromArgb(0, 0, 0).ToArgb(), 1.0f, 0);
GDevice.BeginScene();
GDevice.VertexFormat = CustomVertex.PositionNormalTextured.Format;
GDevice.SetStreamSource(0, VFiberBuffer, 0);
GDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (VertexData.Count / 3));
GDevice.SetTransform(D3DTS_WORLD, &mtxObject);
GDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (VertexData.Count / 3));
GDevice.EndScene();
GDevice.Present();
```

mtxObject is a D3DMATRIX that transforms the model in some way; rotate, translate or scale. You can repeat the set matrix/draw model process as often as you like. The matrix can be obtained by any means, for example you could put that code in a loop and recalculate a rotation matrix each time around the loop.What normally happens in a game or an editor is that there is an object which represent the location of a model in the world, each object has it own matrix. So if the model is a box of bullets, there can be ten 'bullets' objects, each managing a matrix but all using the same vertices to render. Typically that means there is also a 'model' object, which manages the set of vertices. Is this making sense to you?

So, the idea is to append the vertex buffer which contains the vertices which have been rotated. The below code doesn`t seem to work though, the vertex buffer is not being appended.

Shouldn`t LockFlags.NoOverwrite append new vertices to the vertices already contained in the buffer? What am I missing?

```
VertexBuffer.SetData(NewVertexData.ToArray(), 0, LockFlags.NoOverwrite);
```

However, that might not be the problem. Does the code use an index of zero all the time? Shouldn't the index change according to which vertices you intend to use?

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.

Let me know if this is a good approach and I`m in the right direction

Open in new window

Here is heart of the code, I need to generate the same pattern offset by an angle for every pass.

Open in new window