Dylan Smith : d3dx9: Add support for loading vertex colors from X files.

Alexandre Julliard julliard at winehq.org
Tue Jun 7 12:02:37 CDT 2011


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

Author: Dylan Smith <dylan.ah.smith at gmail.com>
Date:   Mon Jun  6 12:54:38 2011 -0400

d3dx9: Add support for loading vertex colors from X files.

---

 dlls/d3dx9_36/mesh.c |   77 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 75 insertions(+), 2 deletions(-)

diff --git a/dlls/d3dx9_36/mesh.c b/dlls/d3dx9_36/mesh.c
index d0ee9b7..da40402 100644
--- a/dlls/d3dx9_36/mesh.c
+++ b/dlls/d3dx9_36/mesh.c
@@ -1833,6 +1833,8 @@ struct mesh_data {
 
     D3DXVECTOR2 *tex_coords;
 
+    DWORD *vertex_colors;
+
     DWORD num_materials;
     D3DXMATERIAL *materials;
     DWORD *material_indices;
@@ -2100,6 +2102,73 @@ truncated_data_error:
     return E_FAIL;
 }
 
+static HRESULT parse_vertex_colors(IDirectXFileData *filedata, struct mesh_data *mesh)
+{
+    HRESULT hr;
+    DWORD data_size;
+    BYTE *data;
+    DWORD num_colors;
+    int i;
+
+    HeapFree(GetProcessHeap(), 0, mesh->vertex_colors);
+    mesh->vertex_colors = NULL;
+
+    hr = IDirectXFileData_GetData(filedata, NULL, &data_size, (void**)&data);
+    if (FAILED(hr)) return hr;
+
+    /* template IndexedColor {
+     *     DWORD index;
+     *     ColorRGBA indexColor;
+     * }
+     * template MeshVertexColors {
+     *     DWORD nVertexColors;
+     *     array IndexedColor vertexColors[nVertexColors];
+     * }
+     */
+
+    if (data_size < sizeof(DWORD))
+        goto truncated_data_error;
+    num_colors = *(DWORD*)data;
+    data += sizeof(DWORD);
+    if (data_size < sizeof(DWORD) + num_colors * (sizeof(DWORD) + sizeof(D3DCOLORVALUE)))
+        goto truncated_data_error;
+
+    mesh->vertex_colors = HeapAlloc(GetProcessHeap(), 0, mesh->num_vertices * sizeof(DWORD));
+    if (!mesh->vertex_colors)
+        return E_OUTOFMEMORY;
+
+    for (i = 0; i < mesh->num_vertices; i++)
+        mesh->vertex_colors[i] = D3DCOLOR_ARGB(0, 0xff, 0xff, 0xff);
+    for (i = 0; i < num_colors; i++)
+    {
+        D3DCOLORVALUE color;
+        DWORD index = *(DWORD*)data;
+        data += sizeof(DWORD);
+        if (index >= mesh->num_vertices) {
+            WARN("vertex color %u references undefined vertex %u (only %u vertices)\n",
+                 i, index, mesh->num_vertices);
+            return E_FAIL;
+        }
+        memcpy(&color, data, sizeof(color));
+        data += sizeof(color);
+        color.r = fminf(1.0f, fmaxf(0.0f, color.r));
+        color.g = fminf(1.0f, fmaxf(0.0f, color.g));
+        color.b = fminf(1.0f, fmaxf(0.0f, color.b));
+        color.a = fminf(1.0f, fmaxf(0.0f, color.a));
+        mesh->vertex_colors[index] = D3DCOLOR_ARGB((BYTE)(color.a * 255.0f + 0.5f),
+                                                   (BYTE)(color.r * 255.0f + 0.5f),
+                                                   (BYTE)(color.g * 255.0f + 0.5f),
+                                                   (BYTE)(color.b * 255.0f + 0.5f));
+    }
+
+    mesh->fvf |= D3DFVF_DIFFUSE;
+
+    return D3D_OK;
+truncated_data_error:
+    WARN("truncated data (%u bytes)\n", data_size);
+    return E_FAIL;
+}
+
 static HRESULT parse_normals(IDirectXFileData *filedata, struct mesh_data *mesh)
 {
     HRESULT hr;
@@ -2289,8 +2358,7 @@ static HRESULT parse_mesh(IDirectXFileData *filedata, struct mesh_data *mesh_dat
         if (IsEqualGUID(type, &TID_D3DRMMeshNormals)) {
             hr = parse_normals(child, mesh_data);
         } else if (IsEqualGUID(type, &TID_D3DRMMeshVertexColors)) {
-            FIXME("Mesh vertex color loading not implemented.\n");
-            hr = E_NOTIMPL;
+            hr = parse_vertex_colors(child, mesh_data);
         } else if (IsEqualGUID(type, &TID_D3DRMMeshTextureCoords)) {
             hr = parse_texture_coords(child, mesh_data);
         } else if (IsEqualGUID(type, &TID_D3DRMMeshMaterialList) &&
@@ -2514,6 +2582,10 @@ static HRESULT load_skin_mesh_from_xof(IDirectXFileData *filedata,
                 *(D3DXVECTOR3*)out_ptr = mesh_data.normals[duplications[i].normal_index];
             out_ptr += sizeof(D3DXVECTOR3);
         }
+        if (mesh_data.fvf & D3DFVF_DIFFUSE) {
+            *(DWORD*)out_ptr = mesh_data.vertex_colors[i];
+            out_ptr += sizeof(DWORD);
+        }
         if (mesh_data.fvf & D3DFVF_TEX1) {
             *(D3DXVECTOR2*)out_ptr = mesh_data.tex_coords[i];
             out_ptr += sizeof(D3DXVECTOR2);
@@ -2647,6 +2719,7 @@ cleanup:
     HeapFree(GetProcessHeap(), 0, mesh_data.normal_indices);
     destroy_materials(&mesh_data);
     HeapFree(GetProcessHeap(), 0, mesh_data.tex_coords);
+    HeapFree(GetProcessHeap(), 0, mesh_data.vertex_colors);
     HeapFree(GetProcessHeap(), 0, duplications);
     return hr;
 }




More information about the wine-cvs mailing list