Vertex Declarations, buffers, and Index buffers

Started by
6 comments, last by feal87 14 years, 11 months ago
I am in need of some advice on how to setup up vertex declarations, vertex buffers, and index buffers. What I want to achieve is an index structure with an index to position, an index to a normal, and texture coordinates. Is this possible using Direct3D? I would like triangles to be able to share position of vertices, but allow them to have different normals and texture coordinates.
Advertisement
This will be slightly different depending on what version of direct3d you are using, is it 9 or 10?
I am using Direct3D 9
Ok, well first off let's start with vertex declarations in DirectX9. First we need to create an array of D3DVERTEXELEMENT9's, this will contain the information that will be sent to the GPU upon rendering the verticies or indicies, this array can contain information including texture coordinates, position, normals, tangents and many more things (full list here; http://msdn.microsoft.com/en-us/library/bb172534(VS.85).aspx)

Say we just wanted to have position, normal and texture information, we might create something like this:

const D3DVERTEXELEMENT9 g_aVertexDeclaration[4] ={	{0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},	{0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0},	{0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},	D3DDECL_END()};


We only have 2 differnet streams in the array but the size of the array is 4 due to the D3DDECL_END function that tells the computer where the end of the stream is, also it's typically declared as const to make sure you are unable to edit it.
Now let's take a look at the D3DVERTEXELEMENT9 structure a little closer:

typedef struct D3DVERTEXELEMENT9 {    WORD Stream;    WORD Offset;    BYTE Type;    BYTE Method;    BYTE Usage;    BYTE UsageIndex;} D3DVERTEXELEMENT9, *LPD3DVERTEXELEMENT9;


For now we will ignore the stream as you will probably only be using a single stream to start off with. The offset is the offest at the beggining of the vertex declaration, the first object as we can see is at 0, the start, however the second is at 12, this is because the first semantic in the array is a float3 which is 12 bytes, hence the offset is 12. The type determines the format of the data, as in the example above, position and normal are float3's while the texture coordinate is a float2 (full list can be found here: http://msdn.microsoft.com/en-us/library/bb172533(VS.85).aspx).
Method: "Defines the vertex declaration method which is a predefined operation performed by the tessellator (or any procedural geometry routine on the vertex data during tessellation)." best to set to the default for now ;)
Usage is one of the most important, this defines what the information you are passing actually is and helps map the semantics to the registers they require in the vertex or pixel shader code (list here: http://msdn.microsoft.com/en-us/library/bb172534(VS.85).aspx).
the usage index is used for when you pass the same 'Usage' semantic to the stream, for example, if we wanted to send in two float2 D3DDECLUSAGE_TEXCOORD's, we would set the first texcoord simantic's index to 0 and the second to 1 so that the shader knows the difference between them.

Now that we have filled in what we want, we have to create the vertex declaration through the device like so:


IDirect3DVertexDeclaration9* vertexDeclaration = NULL;pd3dDevice->CreateVertexDeclaration(g_aVertexDeclaration, vertexDeclaration);


as you can create as many vertex declarations as you want, direct3d requires that you set the vertex declaration which is done like so:

pd3dDevice->SetVertexDeclaration(vertexDeclaration);



Sorry but I don't know so much about vertex and index buffers, so I'll leave that one to someone else :)

Edit: this link may help with creating and using vertex and index buffers with DirectX9: http://www.chadvernon.com/blog/tutorials/directx9/vertex-and-index-buffers/
Thank you for your detailed response leet-bix, but not quite what I was looking for. I already have my code like this.

I would like to know if it is possible to have a setup where an index can point to multiple sources, eg. position buffer, normal buffer, texcoords buffer.

I will be wanting to use the position values more than once per mesh, but each time they are used they may be required to have different normals and texcoords.

Quote:Original post by MikeyH001
Thank you for your detailed response leet-bix, but not quite what I was looking for. I already have my code like this.

I would like to know if it is possible to have a setup where an index can point to multiple sources, eg. position buffer, normal buffer, texcoords buffer.

I will be wanting to use the position values more than once per mesh, but each time they are used they may be required to have different normals and texcoords.


An Index is a UInt16 or UInt32, you cannot make it point to two different things at the same time. You need to find a workaround.
I have been looking at the documentation for Multi Stream Rendering, http://msdn.microsoft.com/en-us/library/bb205327(VS.85).aspx this is exactly what I want to do, however Direct3D9 samples only show single indexing.

Is this sort of technique common in D3D9 apps (if it is possible)? Or is a vertex created for every possible combination of 'position, normal, uv' that is going to be used?

eg.

Individual Buffers:

Index:
0) 0, 0, 0
1) 0, 1, 1
2) 0, 1, 2

Pos:
0) X: 1.0f, Y: 1.0f, Z: 1.0f

Nor:
0) NX: 1.0f, NY: 1.0f, NZ: 1.0f
1) NX: 2.0f, NY: 2.0f, NZ: 2.0f

Tex:
0) U: 0.0f, V: 1.0f
1) U: 0.5f, V: 1.0f
2) U: 1.0f, V: 0.0f

Single Buffer: (Duplicate Data)

0) X: 1.0f, Y: 1.0f, Z: 1.0f, NX: 1.0f, NY: 1.0f, NZ: 1.0f, U: 0.0f, V: 1.0f
1) X: 1.0f, Y: 1.0f, Z: 1.0f, NX: 2.0f, NY: 2.0f, NZ: 2.0f, U: 0.5f, V: 1.0f
2) X: 1.0f, Y: 1.0f, Z: 1.0f, NX: 2.0f, NY: 2.0f, NZ: 2.0f, U: 1.0f, V: 0.0f
Quote:Original post by MikeyH001
I have been looking at the documentation for Multi Stream Rendering, http://msdn.microsoft.com/en-us/library/bb205327(VS.85).aspx this is exactly what I want to do, however Direct3D9 samples only show single indexing.

Is this sort of technique common in D3D9 apps (if it is possible)? Or is a vertex created for every possible combination of 'position, normal, uv' that is going to be used?

eg.

Individual Buffers:

Index:
0) 0, 0, 0
1) 0, 1, 1
2) 0, 1, 2

Pos:
0) X: 1.0f, Y: 1.0f, Z: 1.0f

Nor:
0) NX: 1.0f, NY: 1.0f, NZ: 1.0f
1) NX: 2.0f, NY: 2.0f, NZ: 2.0f

Tex:
0) U: 0.0f, V: 1.0f
1) U: 0.5f, V: 1.0f
2) U: 1.0f, V: 0.0f

Single Buffer: (Duplicate Data)

0) X: 1.0f, Y: 1.0f, Z: 1.0f, NX: 1.0f, NY: 1.0f, NZ: 1.0f, U: 0.0f, V: 1.0f
1) X: 1.0f, Y: 1.0f, Z: 1.0f, NX: 2.0f, NY: 2.0f, NZ: 2.0f, U: 0.5f, V: 1.0f
2) X: 1.0f, Y: 1.0f, Z: 1.0f, NX: 2.0f, NY: 2.0f, NZ: 2.0f, U: 1.0f, V: 0.0f


Different vertex for every possible combination is the only choice.
With the multistream you can only avoid to change the parts that remain static all the time. Just that.

This topic is closed to new replies.

Advertisement