Sign in to follow this  
Halsafar

Vertex Shader and Vertex declaration question

Recommended Posts

So far my Vertex Shader learning curve has been TERRIBLE. It seems every step through learning it I end up having many questions go unanswered and thus find myself researching the research which is a terrible way to learn one thing... With that said I have come to a point where I create the shader using CreateVertexShader. It seems this function requires a parameter of a DWORD array which resembles the VertexDeclarations. Can anyone walk me through this declaration and give me some insight on what it all means:
 DWORD dwVertexDecl[] =
  {
  	D3DVSD_STREAM( 0 ),
  	D3DVSD_REG(D3DVSDE_POSITION,  D3DVSDT_FLOAT3),
  	D3DVSD_REG(D3DVSDE_BLENDWEIGHT, D3DVSDT_FLOAT2), //blending weight
  	D3DVSD_REG(D3DVSDE_BLENDINDICES, D3DVSDT_FLOAT2), //matrices
  	D3DVSD_REG(D3DVSDE_NORMAL,    D3DVSDT_FLOAT3),
  	D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
  	D3DVSD_END()
  };

I've made vertex declarations before and none of them looked like this, what is this stuff... Now I've used vertex declarations to render instead of the SetFVF, but this same tutorial where the snippet comes from has a FVF declared like this:
  static const int MAX_MATRIX_INDEX=2;
  typedef struct
  {
  	D3DXVECTOR3 p;
  	float		fWeights[MAX_MATRIX_INDEX];	//Weights
  	float		matrixBoneIndicies[MAX_MATRIX_INDEX];	//Weights
  	D3DXVECTOR3 n;
  	D3DXVECTOR2 uv;
  } D3DBlendVertex_t;
  #define D3DFVF_BLENDVERTEX (D3DFVF_XYZ | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE2(2) |  D3DFVF_TEXCOORDSIZE2(1)
  |D3DFVF_NORMAL | D3DFVF_TEXCOORDSIZE2(0) )


Why TEX3? what are these TEXCOORDSIZE macros' doing, why are there two of them declared. This FVF is actually set before rendering. I've researched mostly all this on MSDN and came up with only basic information like a one sentence explanation, return values, etc. Thanks for any help, Halsafar

Share this post


Link to post
Share on other sites
The TEX3 means there are three different sets of texture coordinates with each vertex. There is also the possibility of TEX2 etc. depending on how many you want. I'm not sure I can be any clearer than that.

The TEXCOORDSIZE macros tell D3D how many elements each set of texture coordinates has. For example, you might have 1D, 2D, or 3D texture coordinates. The actual syntax is a little backwards in my opinion, but it works like this:

D3DFVF_TEXCOORDSIZEn(texCoordSet)

So:

D3DFVF_TEXCOORDSIZE2(0)

The first (remembering zero-based index) set of texture coordinates have two components, i.e. standard UV coordinates.

Does that clear things up a bit?

-Mezz

Share this post


Link to post
Share on other sites
That first vertex declaration is the DX8 way of making a shader. In DX8 a shader needed one of these declarations and was tied to that specific vertex format.

In DX9 you can use an FVF or vertex declaration, and as long as it provides the elements the shader wants, it's fine.

The prototype for making a shader in DX9 shouldn't be taking one of those vertex declarations

Share this post


Link to post
Share on other sites
Clears up the FVF part a little bit.
So by declaring TEX3 that vertex struct can have 3 sets of texture coords... Alright thats easy.

D3DFVF_TEXCOORDSIZE2(0) is the standard tu,tv
So what would D3DFVF_TEXCOORDSIZE2(1) be, 3 coords?
How can you have 3D texture coordinates? I didn't think it was possible...


I'd still like to hear whats up with the Vertex declaration above.

Share this post


Link to post
Share on other sites
texcoordsize2(1) would mean UV set 1 (the second set of uvs) is 2d. texcoordsize2 is pretty useless as it's the default anyway.

1D coords are good for nx1 textures. 2D coords are for standard nxn textures. 3D coords are used for volume textures. 1D, 2D, 3D, and 4D texture coords can be used to pass in any arbitrary data to a shader as well. In DX8 you would use a 3D or 4D coordinate to hold tangent vectors for example. In DX9 there is a specific tangent usage enum.

Lets use a good example:

tex1 = struct vertex{float u,v};
tex2 = struct vertex{float u1,v1, u2,v2};
tex2|texcoordsize1(0) = struct vertex{float u1, u2,v2};
tex2|texcoordsize3(1) = struct vertex{float u1,v1, u2,v2,w2};
tex2|texcoordsize3(0)|texcoordsize1(1) = struct vertex{float u1,v1,w1, u2};

texn = number of sets of uvs;
texcoordsizex(y) = uv set y is x dimensional.

Share this post


Link to post
Share on other sites
D3DVSD_STREAM( 0 ):
Direct3D Vertex Shader Declaration Stream 0 - Says the data is coming from stream 0

D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3):
Register 0 is of type float3, and holds a position value.

D3DVSD_REG(D3DVSDE_BLENDWEIGHT, D3DVSDT_FLOAT2):
Register 1 is of type float2, and holds blend weights.

D3DVSD_REG(D3DVSDE_BLENDINDICES, D3DVSDT_FLOAT2):
Register 2 is of type float3, and holds indices to blending matrices.

D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT3):
Register 3 is of type float3, and holds a normal

D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2):
Register 4 is of type float2, and holds a texture coordinate set

D3DVSD_END():
End vertex shader declaration (much like a null terminator in a string)

Share this post


Link to post
Share on other sites
Yes, I examined the HLSL first but figured I'd be best to start with the vs/ps learn.


I am still confused on the tex coord part, lets see if I have it.

D3DFVF_TEXCOORDSIZE2(0) for example sets the second set of texture coords to the regular uv coords.

D3DFVF_TEXCOORDSIZE3(1) sets the third set of textures coords to...

The sample that Namethatnobodyelsetook posted blew my mind, I can't make any sense of it...

Share this post


Link to post
Share on other sites
Not quite, Halsafar...
Quote:

D3DFVF_TEXCOORDSIZE2(0) for example sets the second set of texture coords to the regular uv coords.


The two in the macro does not mean the second set. It's the zero in the brackets which tells you which set we are editing. In this case the first set (since an index of 0 would be the first position of an array).

D3DFVF_TEXCOORDSIZE2(0)

Think of this macro as a function like SetTexCoordSize2D(int indexPosition)
where you pass the index of the set you whish to modify to 2D. Then you can apply the same thinking to the other versions.

D3DFVF_TEXCOORDSIZE3(1) or SetTexCoordsSize3D(int indexPosition)

Now you are giving the macro a set index you wish to convert to 3D tex co-ords.

So in your original example:

#define D3DFVF_BLENDVERTEX (D3DFVF_XYZ | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE2(2) | D3DFVF_TEXCOORDSIZE2(1) |D3DFVF_NORMAL | D3DFVF_TEXCOORDSIZE2(0) )

We can see that the first set (set index 0) is being set to 2D (D3DFVF_TEXCOORDSIZE2(0)), the second set (set index 1) is being set to 2D (D3DFVF_TEXCOORDSIZE2(1)), and the third set (set index 2) is being set to 2D as well (D3DFVF_TEXCOORDSIZE2(2)).

And this makes sense, since that vertex you defined only has UV texture coords, and you'll notice that you defined MAX_MATRIX_INDEX as 2... all 3 positions in that array you have defined as 2D through those macros.

Hope this is a little clearer.

Share this post


Link to post
Share on other sites
Wow that sure did clear it up a ton.
Thank you very much guys for turning the greek into english for me :)

Halsafar

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