Create a reliable backup. Make sure you always have dependable copies of your data so you can restore your entire system or individual files.

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.

Experts Exchange Solution brought to you by

Enjoy your complimentary solution view.

Get every solution instantly with Premium.
Start your 7-day free trial.

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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?

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

```
/// <summary>
/// Initialize
/// Set the VetrexBuffer and the IndexBuffer
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Initialize_Click(object sender, EventArgs e)
{
Type VBType = typeof(CustomVertex.PositionNormalTextured);
VertexFormats VBFormats = CustomVertex.PositionNormalTextured.Format;
Usage VBUsage = Usage.WriteOnly | Usage.SoftwareProcessing;
Pool Pl = Pool.Managed;
//Usage VBUsage = Usage.WriteOnly | Usage.Dynamic;
//Pool Pl = Pool.Default;
CVLength = FX0.Count * 3 * 2 * 2; //FX$, FY$ and FZ$ contain the X, Y, Z Values. CVLength will be the number of vertices for a single pass.
VXtrBuffer = new VertexBuffer(VBType,
CVLength * 50, //Have enough for 50 passes, same with index buffer
GDevice,
VBUsage,
VBFormats,
Pl);
IXtrBuffer = new IndexBuffer(GDevice, sizeof(ushort) * CVLength * 50, VBUsage, Pl, true);
InitXtr(); //Xtr
}
```

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

```
/// <summary>
/// Add Pass
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Add_Click(object sender, EventArgs e)
{
AddPass();
}
/// <summary>
/// Add Pass.. See comments within code
/// This works for Pass 1, subsequent passes don`t seem to work.
/// What I`m trying to do, is draw subsequent passes offset by an angle.
/// </summary>
private void AddPass()
{
int Cnt = 0;
int i = 0;
int Ind = 0;
Vector3 V0, V1, V2, V3;
Vector3 N1, N2;
float VertX0 = 0, VertY0 = 0, VertZ0 = 0;
float VertX1 = 0, VertY1 = 0, VertZ1 = 0;
float VertX2 = 0, VertY2 = 0, VertZ2 = 0;
float VertX3 = 0, VertY3 = 0, VertZ3 = 0;
//FX$,FY$, FZ$ are the X, Y, Z coordinates
Cnt = FX0.Count;
//An array to store the vertices for a single Pass
XtrTexture = new CustomVertex.PositionNormalTextured[CVLength];
//For every call of the function, the angle is incremented by 5.
//This means the same pattern is offset by Ang everytime the function is called i,e, every Pass
Ang = Ang + 5;
//This is the main code which generates the pattern to be dispalyed.
//This works good. This is not the most efficient way to do this, but for the sake of simplicity, I`ll go with this for now.
for (i = 0; i < Cnt - 1; i++)
{
//Triangle 1 and 2 [Top]
VertX0 = (float)(FX0[i] * Math.Cos(Ang) - FY0[i] * Math.Sin(Ang));
VertY0 = (float)(FX0[i] * Math.Sin(Ang) + FY0[i] * Math.Cos(Ang));
VertZ0 = (float)(FZ0[i]);
V0 = new Vector3(VertX0, VertY0, VertZ0);
VertX1 = (float)(FX0[i + 1] * Math.Cos(Ang) - FY0[i + 1] * Math.Sin(Ang));
VertY1 = (float)(FX0[i + 1] * Math.Sin(Ang) + FY0[i + 1] * Math.Cos(Ang));
VertZ1 = (float)(FZ0[i + 1]);
V1 = new Vector3(VertX1, VertY1, VertZ1);
VertX2 = (float)(FX1[i + 1] * Math.Cos(Ang) - FY1[i + 1] * Math.Sin(Ang));
VertY2 = (float)(FX1[i + 1] * Math.Sin(Ang) + FY1[i + 1] * Math.Cos(Ang));
VertZ2 = (float)(FZ1[i + 1]);
V2 = new Vector3(VertX2, VertY2, VertZ2);
VertX3 = (float)(FX1[i] * Math.Cos(Ang) - FY1[i] * Math.Sin(Ang));
VertY3 = (float)(FX1[i] * Math.Sin(Ang) + FY1[i] * Math.Cos(Ang));
VertZ3 = (float)(FZ1[i]);
V3 = new Vector3(VertX3, VertY3, VertZ3);
N1 = CalcNormal(V0, V1, V2);
N2 = CalcNormal(V2, V3, V0);
XtrTexture[Ind + 0] = new CustomVertex.PositionNormalTextured(V0, N1, 0f, .5f);
XtrTexture[Ind + 1] = new CustomVertex.PositionNormalTextured(V1, N1, 1.0f, 0.5f);
XtrTexture[Ind + 2] = new CustomVertex.PositionNormalTextured(V2, N1, 1.0f, 1.0f);
XtrTexture[Ind + 3] = new CustomVertex.PositionNormalTextured(V2, N2, 1.0f, 1.0f);
XtrTexture[Ind + 4] = new CustomVertex.PositionNormalTextured(V3, N2, 0.0f, 1.0f);
XtrTexture[Ind + 5] = new CustomVertex.PositionNormalTextured(V0, N2, 0f, 0.5f);
//Triangle 3 and 4 [Bottom]
VertX0 = (float)(FX2[i] * Math.Cos(Ang) - FY2[i] * Math.Sin(Ang));
VertY0 = (float)(FX2[i] * Math.Sin(Ang) + FY2[i] * Math.Cos(Ang));
VertZ0 = (float)(FZ2[i]);
V0 = new Vector3(VertX0, VertY0, VertZ0);
VertX1 = (float)(FX2[i + 1] * Math.Cos(Ang) - FY2[i + 1] * Math.Sin(Ang));
VertY1 = (float)(FX2[i + 1] * Math.Sin(Ang) + FY2[i + 1] * Math.Cos(Ang));
VertZ1 = (float)(FZ2[i + 1]);
V1 = new Vector3(VertX1, VertY1, VertZ1);
VertX2 = (float)(FX0[i + 1] * Math.Cos(Ang) - FY0[i + 1] * Math.Sin(Ang));
VertY2 = (float)(FX0[i + 1] * Math.Sin(Ang) + FY0[i + 1] * Math.Cos(Ang));
VertZ2 = (float)(FZ0[i + 1]);
V2 = new Vector3(VertX2, VertY2, VertZ2);
VertX3 = (float)(FX0[i] * Math.Cos(Ang) - FY0[i] * Math.Sin(Ang));
VertY3 = (float)(FX0[i] * Math.Sin(Ang) + FY0[i] * Math.Cos(Ang));
VertZ3 = (float)(FZ0[i]);
V3 = new Vector3(VertX3, VertY3, VertZ3);
N1 = CalcNormal(V0, V1, V2);
N2 = CalcNormal(V2, V3, V0);
XtrTexture[Ind + 6] = new CustomVertex.PositionNormalTextured(V0, N1, 0.0f, 0.0f);
XtrTexture[Ind + 7] = new CustomVertex.PositionNormalTextured(V1, N1, 1.0f, 0f);
XtrTexture[Ind + 8] = new CustomVertex.PositionNormalTextured(V2, N1, 1.0f, 0.5f);
XtrTexture[Ind + 9] = new CustomVertex.PositionNormalTextured(V2, N2, 1.0f, 0.5f);
XtrTexture[Ind + 10] = new CustomVertex.PositionNormalTextured(V3, N2, 0.0f, 0.5f);
XtrTexture[Ind + 11] = new CustomVertex.PositionNormalTextured(V0, N2, 0.0f, 0.0f);
Ind += 12;
}
//Question
//I want to update the index buffer, I`m not sure if this is the correct way of doing this.
//1st Pass I`m locking and updating from 0 to CVLength
//2nd Pass I`m locking from the CVLength to 2 * CVLength [since the number of indices are doubled, only update the new vertices?]
//3rd Pass.....nth Pass
using (GStream = IXtrBuffer.Lock((Pass * CVLength), ((Pass * CVLength) + CVLength) * sizeof(ushort), LockFlags.None))
{
for (int j = (Pass * CVLength); j < (Pass * CVLength) + CVLength; j += 12)
{
ushort[] Indices = {
(ushort)(j + 0),
(ushort)(j + 1 ),
(ushort)(j + 2),
(ushort)(j + 3),
(ushort)(j + 4),
(ushort)(j + 5),
(ushort)(j + 6),
(ushort)(j + 7),
(ushort)(j + 8),
(ushort)(j + 9),
(ushort)(j + 10),
(ushort)(j + 11)
};
GStream.Write(Indices);
}
IXtrBuffer.Unlock();
}
//Question
//Just like the index buffer, updating the new Vertices here
//Is VXtrBuffer appended with new vertices for each pass (what I`m trying to do) or VXtrbuffer gets reset and get new set of vertices?
GStream = VXtrBuffer.Lock((Pass * CVLength), ((Pass * CVLength) + CVLength) * 32, LockFlags.None);
GStream.Write(XtrTexture);
VXtrBuffer.Unlock();
GDevice.Clear(ClearFlags.Target, System.Drawing.Color.FromArgb(0, 0, 0).ToArgb(), 1.0f, 0);
GDevice.BeginScene();
InitDeviceXtr();
GDevice.VertexFormat = CustomVertex.PositionNormalTextured.Format;
//Question
//The function Setstream, comments in the parameter
GDevice.SetStreamSource(0,
VXtrBuffer, //If the Vertex Buffer is appended, I should offset it for each pass
(Pass * CVLength) * 32); //Offset for each pass
GDevice.Indices = IXtrBuffer;
//Question
//The function DrawIndexPrimitives, comments in the paramter
GDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, //Primitive Type
Pass * CVLength, //Base Vertex - Offset applied?
0, //MinIntVertex - Not sure? Should this point to the index of the next batch of vertices
CVLength, //Number of Vertices
(Pass * CVLength), //Start Index
((Pass * CVLength) + CVLength) / 3); //Primitive Count
//Increment the Pass Number
Pass++;
GDevice.EndScene();
GDevice.Present();
}
```

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Components

From novice to tech pro — start learning today.

Experts Exchange Solution brought to you by

Enjoy your complimentary solution view.

Get every solution instantly with Premium.
Start your 7-day free trial.

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.