Module: wine Branch: master Commit: ff7dc445256442069f7330b7d6557479c96b8851 URL: http://source.winehq.org/git/wine.git/?a=commit;h=ff7dc445256442069f7330b7d6...
Author: Henri Verbeet hverbeet@codeweavers.com Date: Thu Aug 26 19:05:20 2010 +0200
d3dx9_36: Implement D3DXDeclaratorFromFVF().
---
dlls/d3dx9_36/mesh.c | 106 ++++++++++++++++++++++++++++++++++++++++++- dlls/d3dx9_36/tests/mesh.c | 2 +- 2 files changed, 104 insertions(+), 4 deletions(-)
diff --git a/dlls/d3dx9_36/mesh.c b/dlls/d3dx9_36/mesh.c index cc22107..ed7f9a8 100644 --- a/dlls/d3dx9_36/mesh.c +++ b/dlls/d3dx9_36/mesh.c @@ -190,14 +190,114 @@ static const UINT d3dx_decltype_size[D3DDECLTYPE_UNUSED] = /* D3DDECLTYPE_FLOAT16_4 */ 4 * 2, };
+static void append_decl_element(D3DVERTEXELEMENT9 *declaration, UINT *idx, UINT *offset, + D3DDECLTYPE type, D3DDECLUSAGE usage, UINT usage_idx) +{ + declaration[*idx].Stream = 0; + declaration[*idx].Offset = *offset; + declaration[*idx].Type = type; + declaration[*idx].Method = D3DDECLMETHOD_DEFAULT; + declaration[*idx].Usage = usage; + declaration[*idx].UsageIndex = usage_idx; + + *offset += d3dx_decltype_size[type]; + ++(*idx); +} + /************************************************************************* * D3DXDeclaratorFromFVF */ -HRESULT WINAPI D3DXDeclaratorFromFVF(DWORD fvf, D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) +HRESULT WINAPI D3DXDeclaratorFromFVF(DWORD fvf, D3DVERTEXELEMENT9 declaration[MAX_FVF_DECL_SIZE]) { - FIXME("(%d, %p): stub\n", fvf, Declaration); + static const D3DVERTEXELEMENT9 end_element = D3DDECL_END(); + DWORD tex_count = (fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT; + unsigned int offset = 0; + unsigned int idx = 0; + unsigned int i;
- return E_NOTIMPL; + TRACE("fvf %#x, declaration %p.\n", fvf, declaration); + + if (fvf & D3DFVF_POSITION_MASK) + { + BOOL has_blend = (fvf & D3DFVF_XYZB5) >= D3DFVF_XYZB1; + DWORD blend_count = 1 + (((fvf & D3DFVF_XYZB5) - D3DFVF_XYZB1) >> 1); + BOOL has_blend_idx = (fvf & D3DFVF_LASTBETA_D3DCOLOR) || (fvf & D3DFVF_LASTBETA_UBYTE4); + + if (has_blend_idx) --blend_count; + + if ((fvf & D3DFVF_POSITION_MASK) == D3DFVF_XYZW + || (has_blend && blend_count > 4)) + return D3DERR_INVALIDCALL; + + if ((fvf & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) + append_decl_element(declaration, &idx, &offset, D3DDECLTYPE_FLOAT4, D3DDECLUSAGE_POSITIONT, 0); + else + append_decl_element(declaration, &idx, &offset, D3DDECLTYPE_FLOAT3, D3DDECLUSAGE_POSITION, 0); + + if (has_blend) + { + switch (blend_count) + { + case 0: + break; + case 1: + append_decl_element(declaration, &idx, &offset, D3DDECLTYPE_FLOAT1, D3DDECLUSAGE_BLENDWEIGHT, 0); + break; + case 2: + append_decl_element(declaration, &idx, &offset, D3DDECLTYPE_FLOAT2, D3DDECLUSAGE_BLENDWEIGHT, 0); + break; + case 3: + append_decl_element(declaration, &idx, &offset, D3DDECLTYPE_FLOAT3, D3DDECLUSAGE_BLENDWEIGHT, 0); + break; + case 4: + append_decl_element(declaration, &idx, &offset, D3DDECLTYPE_FLOAT4, D3DDECLUSAGE_BLENDWEIGHT, 0); + break; + default: + ERR("Invalid blend count %u.\n", blend_count); + break; + } + + if (has_blend_idx) + { + if (fvf & D3DFVF_LASTBETA_UBYTE4) + append_decl_element(declaration, &idx, &offset, D3DDECLTYPE_UBYTE4, D3DDECLUSAGE_BLENDINDICES, 0); + else if (fvf & D3DFVF_LASTBETA_D3DCOLOR) + append_decl_element(declaration, &idx, &offset, D3DDECLTYPE_D3DCOLOR, D3DDECLUSAGE_BLENDINDICES, 0); + } + } + } + + if (fvf & D3DFVF_NORMAL) + append_decl_element(declaration, &idx, &offset, D3DDECLTYPE_FLOAT3, D3DDECLUSAGE_NORMAL, 0); + if (fvf & D3DFVF_PSIZE) + append_decl_element(declaration, &idx, &offset, D3DDECLTYPE_FLOAT1, D3DDECLUSAGE_PSIZE, 0); + if (fvf & D3DFVF_DIFFUSE) + append_decl_element(declaration, &idx, &offset, D3DDECLTYPE_D3DCOLOR, D3DDECLUSAGE_COLOR, 0); + if (fvf & D3DFVF_SPECULAR) + append_decl_element(declaration, &idx, &offset, D3DDECLTYPE_D3DCOLOR, D3DDECLUSAGE_COLOR, 1); + + for (i = 0; i < tex_count; ++i) + { + switch ((fvf >> (16 + 2 * i)) & 0x03) + { + case D3DFVF_TEXTUREFORMAT1: + append_decl_element(declaration, &idx, &offset, D3DDECLTYPE_FLOAT1, D3DDECLUSAGE_TEXCOORD, i); + break; + case D3DFVF_TEXTUREFORMAT2: + append_decl_element(declaration, &idx, &offset, D3DDECLTYPE_FLOAT2, D3DDECLUSAGE_TEXCOORD, i); + break; + case D3DFVF_TEXTUREFORMAT3: + append_decl_element(declaration, &idx, &offset, D3DDECLTYPE_FLOAT3, D3DDECLUSAGE_TEXCOORD, i); + break; + case D3DFVF_TEXTUREFORMAT4: + append_decl_element(declaration, &idx, &offset, D3DDECLTYPE_FLOAT4, D3DDECLUSAGE_TEXCOORD, i); + break; + } + } + + declaration[idx] = end_element; + + return D3D_OK; }
/************************************************************************* diff --git a/dlls/d3dx9_36/tests/mesh.c b/dlls/d3dx9_36/tests/mesh.c index 882323b..221c81a 100644 --- a/dlls/d3dx9_36/tests/mesh.c +++ b/dlls/d3dx9_36/tests/mesh.c @@ -469,7 +469,7 @@ static void test_fvf_to_decl(DWORD test_fvf, const D3DVERTEXELEMENT9 expected_el D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE];
hr = D3DXDeclaratorFromFVF(test_fvf, decl); - todo_wine ok(hr == expected_hr, + ok(hr == expected_hr, "Line %u, test %u: D3DXDeclaratorFromFVF returned %#x, expected %#x.\n", line, test_id, hr, expected_hr); if (SUCCEEDED(hr)) compare_elements(decl, expected_elements, line, test_id);