Christian Costa : d3drm: Handle material list in mesh.

Alexandre Julliard julliard at winehq.org
Fri Jun 1 13:25:59 CDT 2012


Module: wine
Branch: master
Commit: 84f2e0e9ac30fbd2ca2bf9ea3ebca24789908490
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=84f2e0e9ac30fbd2ca2bf9ea3ebca24789908490

Author: Christian Costa <titan.costa at gmail.com>
Date:   Thu May 31 18:47:50 2012 +0200

d3drm: Handle material list in mesh.

---

 dlls/d3drm/meshbuilder.c |   85 +++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 84 insertions(+), 1 deletions(-)

diff --git a/dlls/d3drm/meshbuilder.c b/dlls/d3drm/meshbuilder.c
index 22aec7e..146450c 100644
--- a/dlls/d3drm/meshbuilder.c
+++ b/dlls/d3drm/meshbuilder.c
@@ -74,6 +74,7 @@ typedef struct {
     LPVOID pFaceData;
     DWORD nb_coords2d;
     Coords2d* pCoords2d;
+    IDirect3DRMMaterial2* material;
 } IDirect3DRMMeshBuilderImpl;
 
 char templates[] = {
@@ -361,6 +362,8 @@ static ULONG WINAPI IDirect3DRMMeshBuilder2Impl_Release(IDirect3DRMMeshBuilder2*
 
     if (!ref)
     {
+        if (This->material)
+            IDirect3DRMMaterial2_Release(This->material);
         HeapFree(GetProcessHeap(), 0, This->name);
         HeapFree(GetProcessHeap(), 0, This->pVertices);
         HeapFree(GetProcessHeap(), 0, This->pNormals);
@@ -1202,7 +1205,87 @@ HRESULT load_mesh_data(IDirect3DRMMeshBuilder3* iface, LPDIRECTXFILEDATA pData)
         }
         else if (IsEqualGUID(pGuid, &TID_D3DRMMeshMaterialList))
         {
-            FIXME("MeshMaterialList not supported yet, ignoring...\n");
+            DWORD nb_materials;
+            DWORD nb_face_indices;
+            DWORD data_size;
+            LPDIRECTXFILEOBJECT child;
+            DWORD i = 0;
+            float* values;
+
+            TRACE("Process MeshMaterialList\n");
+
+            hr = IDirectXFileData_GetData(pData2, NULL, &size, (void**)&ptr);
+            if (hr != DXFILE_OK)
+                goto end;
+
+            nb_materials = *(DWORD*)ptr;
+            nb_face_indices = *(DWORD*)(ptr + sizeof(DWORD));
+            data_size = 2 * sizeof(DWORD) + nb_face_indices * sizeof(DWORD);
+
+            TRACE("nMaterials = %u, nFaceIndexes = %u\n", nb_materials, nb_face_indices);
+
+            if (size != data_size)
+                WARN("Returned size %u does not match expected one %u\n", size, data_size);
+
+            if (nb_materials > 2)
+            {
+                FIXME("Only one material per mesh supported, first one applies to all faces\n");
+                nb_materials = 1;
+            }
+
+            while (SUCCEEDED(hr = IDirectXFileData_GetNextObject(pData2, &child)) && (i < nb_materials))
+            {
+                LPDIRECTXFILEDATA data;
+                LPDIRECTXFILEDATAREFERENCE reference;
+                LPDIRECT3DRMMATERIAL2 material;
+
+                hr = IDirectXFileObject_QueryInterface(child, &IID_IDirectXFileData, (void **)&data);
+                if (FAILED(hr))
+                {
+                    hr = IDirectXFileObject_QueryInterface(child, &IID_IDirectXFileDataReference, (void **)&reference);
+                    if (FAILED(hr))
+                        goto end;
+
+                    hr = IDirectXFileDataReference_Resolve(reference, &data);
+                    IDirectXFileDataReference_Release(reference);
+                    if (FAILED(hr))
+                        goto end;
+                }
+
+                hr = Direct3DRMMaterial_create(&material);
+                if (FAILED(hr))
+                {
+                    IDirectXFileData_Release(data);
+                    goto end;
+                }
+
+                hr = IDirectXFileData_GetData(data, NULL, &size, (void**)&ptr);
+                if (hr != DXFILE_OK)
+                {
+                    IDirectXFileData_Release(data);
+                    goto end;
+                }
+
+                if (size != 44)
+                    WARN("Material size %u does not match expected one %u\n", size, 44);
+
+                values = (float*)ptr;
+
+                IDirect3DRMMaterial2_SetAmbient(material, values[0], values [1], values[2]); /* Alpha ignored */
+                IDirect3DRMMaterial2_SetPower(material, values[4]);
+                IDirect3DRMMaterial2_SetSpecular(material, values[5], values[6], values[7]);
+                IDirect3DRMMaterial2_SetEmissive(material, values[8], values[9], values[10]);
+
+                This->material = material;
+
+                IDirectXFileData_Release(data);
+                i++;
+            }
+            if (hr == S_OK)
+                WARN("Found more sub-objects than expected\n");
+            else if (hr != DXFILEERR_NOMOREOBJECTS)
+                goto end;
+            hr = S_OK;
         }
         else
         {




More information about the wine-cvs mailing list