Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am using DirectX and C++. I never understood how my VertexDeclaration knew what variables were the UV map and which were linked to the position. I have in my shader Position : POSITION and Texture : TEXCOORD1

In my variables for vertex format I have int X, Y, Z, U, V.

In my declaration I have

    D3DVERTEXELEMENT9 Decl[] =
    {
        {
            0,
            0,
            D3DDECLTYPE_FLOAT3,
            D3DDECLMETHOD_DEFAULT,
            D3DDECLUSAGE_POSITION,
            0
        },
        {
            0,
            0,
            D3DDECLTYPE_FLOAT2,
            D3DDECLMETHOD_DEFAULT,
            D3DDECLUSAGE_TEXCOORD,
            0
        },
      D3DDECL_END()
   };

My FVF is D3DFVF_XYZ | D3DFVF_TEX1

How does it know to link X, Y, Z with position? and U, V with the first texcoord? What would the variables for the second texcoord be? Is there some pattern?

share|improve this question
    
Did you really mean "X,Y,U,V" in the second paragraph? Two-component positions were never expressable in FVFs to my knowledge. I assume it's "X,Y,Z,U,V" for my answer. –  Lars Viklund Aug 22 '12 at 18:38
    
you are correct I meant XYZ –  dvds414 Aug 22 '12 at 19:42
add comment

2 Answers

FVF flags are mapped 1:1 to interleaved elements of the vertices in your stream source. The order is a bit undocumented and seems to be assumed to be the same order as the FVF flags are defined in the headers.

They're tightly packed with alignment constraints, and as such, if you have (D3DFVF_XYZ | D3DFVF_TEX1), for each vertex, it expects three position floats, followed by two (by default) texture coordinate floats.

It expects attributes to be tightly packed, with some additional restrictions on which elements may appear on some shader models (if you're

There's no "linking of variables" to be made, it just expects things at offsets computable from the FVF flag set.

For a tabular mapping of individual FVF flags to elements, see this MSDN page.

For texture coordinate sets, the FVF_TEXn flag indicates the number of texture coordinate sets you provide. If you want 2 sets of texture coordinates, you use FVF_TEX2 only, and at the texture coordinate part of your vertex struct, you have two texture coordinate set worth of values.

That is, the following FVF part indicates that you have two texture coordinate parts

  • the first (#0) with 3 elements (S,T,P),
  • the second (#1) with two (S,T):

    D3DFVF_TEX2 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE2(1)

mapping to a struct that has (S0,T0,P0,S1,T1) at the end.

I echo the sentiment of the other answers, however. Avoid FVFs if you target D3D9, there's no reason to have them outside of legacy code.

share|improve this answer
    
Your answer somewhat makes sense.. but if I were to add another TEXCOORD variable what would my FVF and my declaration then look like? and what would the new variables names be? –  dvds414 Aug 22 '12 at 19:37
add comment

You shouldn't mix vertex declarations with FVF codes - it's a case of use either but not both. Vertex declarations are highly recommended for the additional flexibility they offer.

For a declaration it matches the HLSL semantic with the Usage and UsageIndex members of your D3DVERTEXELEMENT9 declaration. So for a semantic of TEXCOORD0 we're looking for a D3DDECLUSAGE_TEXCOORD at UsageIndex 0.

When matching these to your vertex struct the Stream and Offset members of D3DVERTEXELEMENT9 are used.

Update

More info is needed, so here we go.

Let's say that we have a struct declared like so:

struct myVertex
{
    float position[3];
    float texcoord[2];
};

In order to map this to a vertex declaration, you use an array of 2 D3DVERTEXELEMENT9 when creating the declaration. The first one looks like this:

{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}

Stream 0 we'll ignore for now.

Offset 0 means that position starts 0 bytes from the beginning of the vertex data. That's right at the start of "float position[3]" in your struct.

We'll also ignore D3DDECLTYPE_FLOAT3 (that's just telling D3D that it's 3 floats) and D3DDECLMETHOD_DEFAULT.

D3DDECLUSAGE_POSITION means that it maps to the "POSITION" semantic in your HLSL, and the final 0 means that it maps specifically to "POSITION0".

On to the second one (texcoords) and here it is:

{0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}

Again we've got Stream 0 and we'll ignore it for now.

Offset 12 - this is where it tells D3D which struct members to use for texcoords. This is now 12 bytes from the beginning of the vertex data, and - looking back at our struct definition - we see that the first member is "float position[3]". Assuming that a float is 4 bytes (it always will be on Windows), 3 floats is 12 bytes, so also assuming that the struct is tightly packed, we then know that texcoords begin at the 12th byte of the vertex data, which is "float texcoord[2]".

Again, D3DDECLTYPE_FLOAT2 just says that this is two floats, and we'll ignore D3DDECLMETHOD_DEFAULT.

D3DDECLUSAGE_TEXCOORD is here and it has UsageIndex 0 so that maps to the "TEXCOORD0" HLSL semantic (if UsageIndex was 1 it would be "TEXCOORD1").

For FVF codes D3D does it's own work behind the scenes in a similar manner, but you shouldn't be using FVF codes at all.

share|improve this answer
    
but how does it know that the U and V variables are linked to the TEXCOORD0? I don't have anywhere that U and V are linked to the TEXCOORD0 so how does it know?? –  dvds414 Aug 22 '12 at 18:24
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.