d3dx9: Implement D3DXDeclaratorFromFVF. (try 2)
Henri Verbeet
hverbeet at gmail.com
Wed Aug 25 05:28:35 CDT 2010
On 25 August 2010 04:04, misha680 <misha680 at gmail.com> wrote:
> What do you think about this one on top of those? I will wait to send to
> wine-patches until your patches have been committed.
> http://wine.1045685.n5.nabble.com/file/n2652101/0004-d3dx9-Implement-D3DXDeclaratorFromFVF.txt
Still not quite right, I'm afraid, although it's a bit closer.
However, as mentioned in
http://www.winehq.org/pipermail/wine-devel/2010-August/086112.html,
since this is about the tenth version of D3DXDeclaratorFromFVF() I'm
seeing (not counting the ones in d3d9 and wined3d...), I went ahead
and just implemented it myself. The patch attached to that mail is the
initial untested version. The patch attached to this mail is what I
think it should look like after doing some tests. I'll probably send
it in tomorrow.
-------------- next part --------------
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);
More information about the wine-devel
mailing list