Jump to content
  • Advertisement
Sign in to follow this  
MikeyH001

Vertex Declarations, buffers, and Index buffers

This topic is 3416 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
Advertisement
This will be slightly different depending on what version of direct3d you are using, is it 9 or 10?

Share this post


Link to post
Share on other sites
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/

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!