[PATCH 6/8] d3drm: Complete Load method by adding normals indices and terminating null DWORD to faces data + tests.

Christian Costa titan.costa at gmail.com
Wed Mar 14 03:06:59 CDT 2012


This fixes bug 8433 and 22451.
---
 dlls/d3drm/meshbuilder.c |   84 +++++++++++++++++++++++++++++++++++++-----
 dlls/d3drm/tests/d3drm.c |   91 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 164 insertions(+), 11 deletions(-)

diff --git a/dlls/d3drm/meshbuilder.c b/dlls/d3drm/meshbuilder.c
index ee6347b..ba8cbf6 100644
--- a/dlls/d3drm/meshbuilder.c
+++ b/dlls/d3drm/meshbuilder.c
@@ -1,7 +1,7 @@
 /*
  * Implementation of IDirect3DRMMeshBuilder2 Interface
  *
- * Copyright 2010 Christian Costa
+ * Copyright 2010, 2012 Christian Costa
  * Copyright 2011 André Hentschel
  *
  * This library is free software; you can redistribute it and/or
@@ -738,7 +738,7 @@ static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_GetVertices(IDirect3DRMMeshBui
     if (face_data_size)
         *face_data_size = This->face_data_size;
     if (face_data && This->face_data_size)
-        memcpy(face_data, This->pFaceData, This->face_data_size);
+        memcpy(face_data, This->pFaceData, This->face_data_size * sizeof(DWORD));
 
     return D3DRM_OK;
 }
@@ -1043,8 +1043,16 @@ static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_Load(IDirect3DRMMeshBuilder3*
     LPBYTE ptr;
     HRESULT hr;
     HRESULT ret = D3DRMERR_BADOBJECT;
+    DWORD* faces_vertex_idx_data = NULL;
+    DWORD* faces_vertex_idx_ptr;
+    DWORD faces_vertex_idx_size;
+    DWORD* faces_normal_idx_data = NULL;
+    DWORD* faces_normal_idx_ptr = NULL;
+    DWORD* faces_data_ptr;
+    DWORD faces_data_size = 0;
+    DWORD i;
 
-    FIXME("(%p)->(%p,%p,%x,%p,%p): partial stub\n", This, filename, name, loadflags, cb, arg);
+    TRACE("(%p)->(%p,%p,%x,%p,%p)\n", This, filename, name, loadflags, cb, arg);
 
     /* First free allocated buffers of previous mesh data */
     HeapFree(GetProcessHeap(), 0, This->pVertices);
@@ -1135,15 +1143,20 @@ static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_Load(IDirect3DRMMeshBuilder3*
 
     This->nb_vertices = *(DWORD*)ptr;
     This->nb_faces = *(DWORD*)(ptr + sizeof(DWORD) + This->nb_vertices * sizeof(D3DVECTOR));
-    This->face_data_size = size - sizeof(DWORD) - This->nb_vertices * sizeof(D3DVECTOR) - sizeof(DWORD);
+    faces_vertex_idx_size = size - sizeof(DWORD) - This->nb_vertices * sizeof(D3DVECTOR) - sizeof(DWORD);
+    faces_vertex_idx_ptr = (DWORD*)(ptr + sizeof(DWORD) + This->nb_vertices * sizeof(D3DVECTOR) + sizeof(DWORD));
 
-    TRACE("Mesh: nb_vertices = %d, nb_faces = %d, face_data_size = %d\n", This->nb_vertices, This->nb_faces, This->face_data_size);
+    TRACE("Mesh: nb_vertices = %d, nb_faces = %d, faces_vertex_idx_size = %d\n", This->nb_vertices, This->nb_faces, faces_vertex_idx_size);
 
     This->pVertices = HeapAlloc(GetProcessHeap(), 0, This->nb_vertices * sizeof(D3DVECTOR));
     memcpy(This->pVertices, ptr + sizeof(DWORD), This->nb_vertices * sizeof(D3DVECTOR));
 
-    This->pFaceData = HeapAlloc(GetProcessHeap(), 0, This->face_data_size);
-    memcpy(This->pFaceData, ptr + sizeof(DWORD) + This->nb_vertices * sizeof(D3DVECTOR) + sizeof(DWORD), This->face_data_size);
+    faces_vertex_idx_ptr = faces_vertex_idx_data = HeapAlloc(GetProcessHeap(), 0, faces_vertex_idx_size);
+    memcpy(faces_vertex_idx_data, ptr + sizeof(DWORD) + This->nb_vertices * sizeof(D3DVECTOR) + sizeof(DWORD), faces_vertex_idx_size);
+
+    /* Each vertex index will have its normal index counterpart so just allocate twice the size */
+    This->pFaceData = HeapAlloc(GetProcessHeap(), 0, faces_vertex_idx_size*2);
+    faces_data_ptr = (DWORD*)This->pFaceData;
 
     while (1)
     {
@@ -1169,19 +1182,26 @@ static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_Load(IDirect3DRMMeshBuilder3*
 
         if (IsEqualGUID(pGuid, &TID_D3DRMMeshNormals))
         {
-            DWORD tmp;
+            DWORD nb_faces_normals;
+            DWORD faces_normal_idx_size;
 
             hr = IDirectXFileData_GetData(pData2, NULL, &size, (void**)&ptr);
             if (hr != DXFILE_OK)
                 goto end;
 
             This->nb_normals = *(DWORD*)ptr;
-            tmp = *(DWORD*)(ptr + sizeof(DWORD) + This->nb_normals * sizeof(D3DVECTOR));
+            nb_faces_normals = *(DWORD*)(ptr + sizeof(DWORD) + This->nb_normals * sizeof(D3DVECTOR));
 
-            TRACE("MeshNormals: nb_normals = %d, nb_faces_normals = %d\n", This->nb_normals, tmp);
+            TRACE("MeshNormals: nb_normals = %d, nb_faces_normals = %d\n", This->nb_normals, nb_faces_normals);
+            if (nb_faces_normals != This->nb_faces)
+                WARN("nb_face_normals (%d) != nb_faces (%d)\n", nb_faces_normals, This->nb_normals);
 
             This->pNormals = HeapAlloc(GetProcessHeap(), 0, This->nb_normals * sizeof(D3DVECTOR));
             memcpy(This->pNormals, ptr + sizeof(DWORD), This->nb_normals * sizeof(D3DVECTOR));
+
+            faces_normal_idx_size = size - (2*sizeof(DWORD) + This->nb_normals * sizeof(D3DVECTOR));
+            faces_normal_idx_ptr = faces_normal_idx_data = HeapAlloc(GetProcessHeap(), 0, faces_normal_idx_size);
+            memcpy(faces_normal_idx_data, ptr + sizeof(DWORD) + This->nb_normals * sizeof(D3DVECTOR) + sizeof(DWORD), faces_normal_idx_size);
         }
         else if (IsEqualGUID(pGuid, &TID_D3DRMMeshTextureCoords))
         {
@@ -1210,9 +1230,53 @@ static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_Load(IDirect3DRMMeshBuilder3*
         pData2 = NULL;
     }
 
+    for (i = 0; i < This->nb_faces; i++)
+    {
+        DWORD j;
+        DWORD nb_face_indexes;
+
+        if (faces_vertex_idx_size < sizeof(DWORD))
+            WARN("Not enough data to read number of indices of face %d\n", i);
+
+        nb_face_indexes  = *(faces_data_ptr + faces_data_size++) = *(faces_vertex_idx_ptr++);
+        faces_vertex_idx_size--;
+        if (faces_normal_idx_data && (*(faces_normal_idx_ptr++) != nb_face_indexes))
+            WARN("Faces indices number mismatch\n");
+
+        if (faces_vertex_idx_size < (nb_face_indexes * sizeof(DWORD)))
+            WARN("Not enough data to read all indices of face %d\n", i);
+
+        for (j = 0; j < nb_face_indexes; j++)
+        {
+            /* Copy vertex index */
+            *(faces_data_ptr + faces_data_size++) = *(faces_vertex_idx_ptr++);
+            /* Copy normal index */
+            if (faces_normal_idx_data)
+            {
+                /* Read from x file */
+                *(faces_data_ptr + faces_data_size++) = *(faces_normal_idx_ptr++);
+            }
+            else
+            {
+                FIXME("No normal available, generate a fake normal index\n");
+                /* Must be generated, put 0 for now */
+                *(faces_data_ptr + faces_data_size++) = 0;
+            }
+        }
+        faces_vertex_idx_size -= nb_face_indexes;
+    }
+
+    /* Last DWORD must be 0 */
+    *(faces_data_ptr + faces_data_size++) = 0;
+
+    /* Set size (in number of DWORD) of all faces data */
+    This->face_data_size = faces_data_size;
+
     ret = D3DRM_OK;
 
 end:
+    HeapFree(GetProcessHeap(), 0, faces_normal_idx_data);
+    HeapFree(GetProcessHeap(), 0, faces_vertex_idx_data);
     if (pData2)
         IDirectXFileData_Release(pData2);
     if (pData)
diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c
index e68d968..1732db6 100644
--- a/dlls/d3drm/tests/d3drm.c
+++ b/dlls/d3drm/tests/d3drm.c
@@ -96,6 +96,44 @@ static char data_ok[] =
 "3; 3, 1, 2;;\n"
 "}\n";
 
+static char data_full[] =
+"xof 0302txt 0064\n"
+"Header { 1; 0; 1; }\n"
+"Mesh {\n"
+" 3;\n"
+" 0.1; 0.2; 0.3;,\n"
+" 0.4; 0.5; 0.6;,\n"
+" 0.7; 0.8; 0.9;;\n"
+" 1;\n"
+" 3; 0, 1, 2;;\n"
+" MeshMaterialList {\n"
+"  1; 1; 0;\n"
+"  Material {\n"
+"   0.0; 1.0; 0.0; 1.0;;\n"
+"   30.0;\n"
+"   1.0; 0.0; 0.0;;\n"
+"   0.5; 0.5; 0.5;;\n"
+"   TextureFileName {\n"
+"    \"Texture.bmp\";\n"
+"   }\n"
+"  }\n"
+" }\n"
+" MeshNormals {\n"
+"  3;\n"
+"  1.1; 1.2; 1.3;,\n"
+"  1.4; 1.5; 1.6;,\n"
+"  1.7; 1.8; 1.9;;\n"
+"  1;"
+"  3; 0, 1, 2;;\n"
+" }\n"
+" MeshTextureCoords {\n"
+"  3;\n"
+"  0.13; 0.17;,\n"
+"  0.23; 0.27;,\n"
+"  0.33; 0.37;;\n"
+" }\n"
+"}\n";
+
 static void test_MeshBuilder(void)
 {
     HRESULT hr;
@@ -105,6 +143,9 @@ static void test_MeshBuilder(void)
     int val;
     DWORD val1, val2, val3;
     D3DVALUE valu, valv;
+    D3DVECTOR v[3];
+    D3DVECTOR n[3];
+    DWORD f[8];
 
     hr = pDirect3DRMCreate(&pD3DRM);
     ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
@@ -137,7 +178,7 @@ static void test_MeshBuilder(void)
     ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
     ok(val1 == 4, "Wrong number of vertices %d (must be 4)\n", val1);
     todo_wine ok(val2 == 4, "Wrong number of normals %d (must be 4)\n", val2);
-    todo_wine ok(val3 == 22, "Wrong number of face data bytes %d (must be 22)\n", val3);
+    ok(val3 == 22, "Wrong number of face data bytes %d (must be 22)\n", val3);
 
     valu = 1.23f;
     valv = 3.21f;
@@ -160,6 +201,54 @@ static void test_MeshBuilder(void)
 
     IDirect3DRMMeshBuilder_Release(pMeshBuilder);
 
+    hr = IDirect3DRM_CreateMeshBuilder(pD3DRM, &pMeshBuilder);
+    ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder interface (hr = %x)\n", hr);
+
+    info.lpMemory = data_full;
+    info.dSize = strlen(data_full);
+    hr = IDirect3DRMMeshBuilder_Load(pMeshBuilder, &info, NULL, D3DRMLOAD_FROMMEMORY, NULL, NULL);
+    ok(hr == D3DRM_OK, "Cannot load mesh data (hr = %x)\n", hr);
+
+    val = IDirect3DRMMeshBuilder_GetVertexCount(pMeshBuilder);
+    ok(val == 3, "Wrong number of vertices %d (must be 3)\n", val);
+
+    val = IDirect3DRMMeshBuilder_GetFaceCount(pMeshBuilder);
+    ok(val == 1, "Wrong number of faces %d (must be 1)\n", val);
+
+    hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, &val3, f);
+    ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
+    ok(val1 == 3, "Wrong number of vertices %d (must be 3)\n", val1);
+    ok(val2 == 3, "Wrong number of normals %d (must be 3)\n", val2);
+    ok(val3 == 8, "Wrong number of face data bytes %d (must be 8)\n", val3);
+    ok(v[0].x == 0.1f, "Wrong component v[0].x = %f (expected 0.1)\n", v[0].x);
+    ok(v[0].y == 0.2f, "Wrong component v[0].y = %f (expected 0.2)\n", v[0].y);
+    ok(v[0].z == 0.3f, "Wrong component v[0].z = %f (expected 0.3)\n", v[0].z);
+    ok(v[1].x == 0.4f, "Wrong component v[1].x = %f (expected 0.4)\n", v[1].x);
+    ok(v[1].y == 0.5f, "Wrong component v[1].y = %f (expected 0.5)\n", v[1].y);
+    ok(v[1].z == 0.6f, "Wrong component v[1].z = %f (expected 0.6)\n", v[1].z);
+    ok(v[2].x == 0.7f, "Wrong component v[2].x = %f (expected 0.7)\n", v[2].x);
+    ok(v[2].y == 0.8f, "Wrong component v[2].y = %f (expected 0.8)\n", v[2].y);
+    ok(v[2].z == 0.9f, "Wrong component v[2].z = %f (expected 0.9)\n", v[2].z);
+    ok(n[0].x == 1.1f, "Wrong component n[0].x = %f (expected 1.1)\n", n[0].x);
+    ok(n[0].y == 1.2f, "Wrong component n[0].y = %f (expected 1.2)\n", n[0].y);
+    ok(n[0].z == 1.3f, "Wrong component n[0].z = %f (expected 1.3)\n", n[0].z);
+    ok(n[1].x == 1.4f, "Wrong component n[1].x = %f (expected 1.4)\n", n[1].x);
+    ok(n[1].y == 1.5f, "Wrong component n[1].y = %f (expected 1.5)\n", n[1].y);
+    ok(n[1].z == 1.6f, "Wrong component n[1].z = %f (expected 1.6)\n", n[1].z);
+    ok(n[2].x == 1.7f, "Wrong component n[2].x = %f (expected 1.7)\n", n[2].x);
+    ok(n[2].y == 1.8f, "Wrong component n[2].y = %f (expected 1.8)\n", n[2].y);
+    ok(n[2].z == 1.9f, "Wrong component n[2].z = %f (expected 1.9)\n", n[2].z);
+    ok(f[0] == 3 , "Wrong component f[0] = %d (expected 3)\n", f[0]);
+    ok(f[1] == 0 , "Wrong component f[1] = %d (expected 0)\n", f[1]);
+    ok(f[2] == 0 , "Wrong component f[2] = %d (expected 0)\n", f[2]);
+    ok(f[3] == 1 , "Wrong component f[3] = %d (expected 1)\n", f[3]);
+    ok(f[4] == 1 , "Wrong component f[4] = %d (expected 1)\n", f[4]);
+    ok(f[5] == 2 , "Wrong component f[5] = %d (expected 2)\n", f[5]);
+    ok(f[6] == 2 , "Wrong component f[6] = %d (expected 2)\n", f[6]);
+    ok(f[7] == 0 , "Wrong component f[7] = %d (expected 0)\n", f[7]);
+
+    IDirect3DRMMeshBuilder_Release(pMeshBuilder);
+
     IDirect3DRM_Release(pD3DRM);
 }
 




More information about the wine-patches mailing list