diff --git a/dlls/d3dx9_36/d3dx9_36.spec b/dlls/d3dx9_36/d3dx9_36.spec index 1c8eecbf77c..9721fc4141e 100644 --- a/dlls/d3dx9_36/d3dx9_36.spec +++ b/dlls/d3dx9_36/d3dx9_36.spec @@ -148,7 +148,7 @@ @ stub D3DXGenerateOutputDecl @ stdcall D3DXGeneratePMesh(ptr ptr ptr ptr long long ptr) d3dx8.D3DXGeneratePMesh @ stub D3DXGetDeclLength -@ stub D3DXGetDeclVertexSize +@ stdcall D3DXGetDeclVertexSize(ptr long) @ stdcall D3DXGetDriverLevel(ptr) @ stdcall D3DXGetFVFVertexSize(long) @ stdcall D3DXGetImageInfoFromFileA(str ptr) diff --git a/dlls/d3dx9_36/mesh.c b/dlls/d3dx9_36/mesh.c index 0d3eb2ced1f..9b54ce03492 100644 --- a/dlls/d3dx9_36/mesh.c +++ b/dlls/d3dx9_36/mesh.c @@ -19,10 +19,13 @@ */ #include "config.h" +#include "wine/port.h" +#include "wine/debug.h" #include "windef.h" #include "wingdi.h" #include "d3dx9.h" +WINE_DEFAULT_DEBUG_CHANNEL(d3dx); /************************************************************************* * D3DXComputeBoundingBox @@ -127,6 +130,55 @@ UINT WINAPI D3DXGetFVFVertexSize(DWORD FVF) return size; } +/************************************************************************* + * D3DXGetFVFVertexSize + */ +UINT WINAPI D3DXGetDeclVertexSize(const D3DVERTEXELEMENT9 *decl, DWORD stream_idx) +{ + const D3DVERTEXELEMENT9 *element; + UINT size = 0; + + TRACE("decl %p, stream_idx %u\n", decl, stream_idx); + + if (!decl) return 0; + + for (element = decl; element->Stream != 0xff; ++element) + { + UINT type_size; + + if (element->Stream != stream_idx) continue; + + switch (element->Type) + { + case D3DDECLTYPE_FLOAT1: type_size = 1 * 4; break; + case D3DDECLTYPE_FLOAT2: type_size = 2 * 4; break; + case D3DDECLTYPE_FLOAT3: type_size = 3 * 4; break; + case D3DDECLTYPE_FLOAT4: type_size = 4 * 4; break; + case D3DDECLTYPE_D3DCOLOR: type_size = 4 * 1; break; + case D3DDECLTYPE_UBYTE4: type_size = 4 * 1; break; + case D3DDECLTYPE_SHORT2: type_size = 2 * 2; break; + case D3DDECLTYPE_SHORT4: type_size = 4 * 2; break; + case D3DDECLTYPE_UBYTE4N: type_size = 4 * 1; break; + case D3DDECLTYPE_SHORT2N: type_size = 2 * 2; break; + case D3DDECLTYPE_SHORT4N: type_size = 4 * 2; break; + case D3DDECLTYPE_USHORT2N: type_size = 2 * 2; break; + case D3DDECLTYPE_USHORT4N: type_size = 4 * 2; break; + case D3DDECLTYPE_UDEC3: type_size = 4; break; /* 3 * 10 bits + 2 padding */ + case D3DDECLTYPE_DEC3N: type_size = 4; break; + case D3DDECLTYPE_FLOAT16_2: type_size = 2 * 2; break; + case D3DDECLTYPE_FLOAT16_4: type_size = 4 * 2; break; + default: + FIXME("Unhandled element type %#x, size will be incorrect.\n", element->Type); + type_size = 0; + break; + } + + if (element->Offset + type_size > size) size = element->Offset + type_size; + } + + return size; +} + /************************************************************************* * D3DXIntersectTri */ diff --git a/include/d3dx9mesh.h b/include/d3dx9mesh.h index 39ad28a5d89..9e0b333024a 100644 --- a/include/d3dx9mesh.h +++ b/include/d3dx9mesh.h @@ -26,6 +26,7 @@ extern "C" { #endif HRESULT WINAPI D3DXCreateBuffer(DWORD, LPD3DXBUFFER*); +UINT WINAPI D3DXGetDeclVertexSize(const D3DVERTEXELEMENT9 *decl, DWORD stream_idx); UINT WINAPI D3DXGetFVFVertexSize(DWORD); BOOL WINAPI D3DXBoxBoundProbe(CONST D3DXVECTOR3 *, CONST D3DXVECTOR3 *, CONST D3DXVECTOR3 *, CONST D3DXVECTOR3 *); BOOL WINAPI D3DXSphereBoundProbe(CONST D3DXVECTOR3 *,FLOAT,CONST D3DXVECTOR3 *,CONST D3DXVECTOR3 *);