Sign in to follow this  
johnnyBravo

Whats wrong with the vertex element, declaration?

Recommended Posts

johnnyBravo    100
I am using vertex declarations, but there is something wrong, where it does not draw the texture upon a polygon:
D3DVERTEXELEMENT9 particleVertexElem[] = {
	{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
	{0, sizeof(D3DXVECTOR3), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
	D3DDECL_END()
};
	
LPDIRECT3DVERTEXDECLARATION9 particleVertexDecl;
device->CreateVertexDeclaration(particleVertexElem, &particleVertexDecl);
device->SetVertexDeclaration(particleVertexDecl);
particleVertexDecl->Release();
	

Using device->SetFVF(D3DFVF_XYZ|D3DFVF_TEX1); draws the texture upon the polygon fine.

Share this post


Link to post
Share on other sites
johnnyBravo    100
It works now with the usage set to 0,

and also switching the size to D3DDECLTYPE_FLOAT2 works the same as float4, just out of curiousity why do all the examples I found on the net use D3DDECLTYPE_FLOAT4? though float2 makes more sense to me aswell.

thx

Share this post


Link to post
Share on other sites
MePHyst0    232
The float1 through float4 type specifiers ale valid only regarding the vertex size, for the GPU it's always a float4 and the components you do not use are just zeroed out or replicated in some way.

Share this post


Link to post
Share on other sites
johnnyBravo    100
Quote:
Original post by MePHyst0
for the GPU it's always a float4


Ah is that why the offset for the vertex element is usually by 16 in the examples I find? eg from some source I found:

Quote:

{1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
{1, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
{1, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
{1, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},


Also I've decided to use colour on the vertices aswell, but nothing draws and the debug output prints out lots of first chance exceptions, although it doesn't crash.

I added the data type D3DCOLOR to my vertex struct aswell.

D3DVERTEXELEMENT9 particleVertexElem[] = {
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, sizeof(D3DXVECTOR3), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
{0, 32, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0}, //added
D3DDECL_END()
};




I'm not too certain on the offset values...

thx

Share this post


Link to post
Share on other sites
darkelf2k5    286
Lets start with the mistakes in your declaration.

The offset is wrong. FLOAT3 + FLOAT2 is 20 bytes of offset, not 32.

Your version assumes this data in the vertex buffer:
0----------------12----------------20----------------32----------- //Offset
[12byte POSITION][8byte TEXCOORD][12byte whatever][4byte COLOR]

Instead of 32 you could have written sizeof(D3DXVECTOR3) + sizeof(D3DXVECTOR2) for example. So the right offset for the color is 20. Assuming that your vertex data looks something like this:
strucd VD
{
D3DXVECTOR3 Pos;
D3DXVECTOR2 Tex;
D3DCOLOR Color;
}; // Total of 24 bytes

Don't forget that the vertex buffer is just a data pool, it doesn't know what is inside itself. You have to define the declaration correctly or you mightread from the wrong places like before. (with 32 for color offset you were reading from the next vertex already)


Other thing. GPU works internally with float4, but that doesn't mean you should declare every element in your vertex declaration as FLOAT4. It is a waste of bandwidth. Try to keep it as small as possible and multitude of 32. Well, I am sure others can explain it better.

Share this post


Link to post
Share on other sites
MePHyst0    232
Quote:
Original post by darkelf2k5
Other thing. GPU works internally with float4, but that doesn't mean you should declare every element in your vertex declaration as FLOAT4. It is a waste of bandwidth. Try to keep it as small as possible and multitude of 32. Well, I am sure others can explain it better.


darkelf is right here, maybe I expressed myself in a bit confusing-way, but I definetely didn't want to say that it does not matter what type(float1 or float4) the vertex element is! It matters a lot actually, since it defines how big your vertex will be when it travels through the bus to the GPU. The fact that the GPU uses float4's internally doesn't need to bother you at all.
To sum it up:
-size of the vertex matters, since it travel through the bus in the exact same form as you define it in the vertex declaration, the expansion to float4 happens transparently and purely on the GPU
-as darkelf pointed out it is a very good practice to keep you vertex size aligned to a multiple of 32(but 16 is good as well), since then it becomes vertex cache bus line-friendly. There are usually 4(however I'm not sure in here) bus lines in the vertex processor, and every of them is 32(or 16,or 64 on high-end cards) bytes wide, so if your vertex size is 32 it can read 4 vertices in a cycle. However, if the size is 40 it completely crashes the data fetch, because you will be able to read just 3 of them in adn you will left 8 bytes unused.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this