[2/5] d3dx9: Generate effect instances from materials for mesh loading.

Dylan Smith dylan.ah.smith at gmail.com
Tue May 24 15:10:08 CDT 2011


---
 dlls/d3dx9_36/mesh.c |  117 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 112 insertions(+), 5 deletions(-)

diff --git a/dlls/d3dx9_36/mesh.c b/dlls/d3dx9_36/mesh.c
index fa32797..20b3262 100644
--- a/dlls/d3dx9_36/mesh.c
+++ b/dlls/d3dx9_36/mesh.c
@@ -2267,6 +2267,107 @@ truncated_data_error:
     return E_FAIL;
 }
 
+static HRESULT generate_effects(ID3DXBuffer *materials, DWORD num_materials,
+                                ID3DXBuffer **effects)
+{
+    HRESULT hr;
+    D3DXEFFECTINSTANCE *effect_ptr;
+    BYTE *out_ptr;
+    static const char diffuse_paramname[] = "Diffuse";
+    static const char power_paramname[] = "Power";
+    static const char specular_paramname[] = "Specular";
+    static const char emissive_paramname[] = "Emissive";
+    static const char ambient_paramname[] = "Ambient";
+    static const DWORD basic_paramname_sizes = sizeof(diffuse_paramname) +
+                                               sizeof(power_paramname) +
+                                               sizeof(specular_paramname) +
+                                               sizeof(emissive_paramname) +
+                                               sizeof(ambient_paramname);
+    static const char texture_paramname[] = "Texture0 at Name";
+    D3DXMATERIAL *material_ptr = ID3DXBuffer_GetBufferPointer(materials);
+    DWORD buffer_size = num_materials * sizeof(D3DXEFFECTINSTANCE);
+    int i;
+
+    for (i = 0; i < num_materials; i++)
+    {
+        buffer_size += 5 * sizeof(D3DXEFFECTDEFAULT) + basic_paramname_sizes;
+        buffer_size += 4 * sizeof(D3DCOLORVALUE) + sizeof(FLOAT);
+        if (material_ptr->pTextureFilename) {
+            buffer_size += sizeof(D3DXEFFECTDEFAULT) + strlen(material_ptr->pTextureFilename) + 1;
+            buffer_size += sizeof(texture_paramname);
+        }
+        material_ptr++;
+    }
+
+    hr = D3DXCreateBuffer(buffer_size, effects);
+    if (FAILED(hr)) return hr;
+    effect_ptr = ID3DXBuffer_GetBufferPointer(*effects);
+    out_ptr = (BYTE*)(effect_ptr + num_materials);
+
+    material_ptr = ID3DXBuffer_GetBufferPointer(materials);
+    for (i = 0; i < num_materials; i++)
+    {
+        D3DXEFFECTDEFAULT *defaults = (D3DXEFFECTDEFAULT*)out_ptr;
+        effect_ptr->pDefaults = defaults;
+        effect_ptr->NumDefaults = material_ptr->pTextureFilename ? 6 : 5;
+        defaults->pParamName = (LPSTR)(effect_ptr->pDefaults + effect_ptr->NumDefaults);
+
+        strcpy(defaults->pParamName, diffuse_paramname);
+        defaults->pValue = defaults->pParamName + sizeof(diffuse_paramname);
+        defaults->Type = D3DXEDT_FLOATS;
+        defaults->NumBytes = sizeof(D3DCOLORVALUE);
+        memcpy(defaults->pValue, &material_ptr->MatD3D.Diffuse, sizeof(D3DCOLORVALUE));
+        (defaults + 1)->pParamName = (LPSTR)((D3DCOLORVALUE*)defaults->pValue + 1);
+        defaults++;
+
+        strcpy(defaults->pParamName, power_paramname);
+        defaults->pValue = defaults->pParamName + sizeof(power_paramname);
+        defaults->Type = D3DXEDT_FLOATS;
+        defaults->NumBytes = sizeof(FLOAT);
+        *(FLOAT*)defaults->pValue = material_ptr->MatD3D.Power;
+        (defaults + 1)->pParamName = (LPSTR)((FLOAT*)defaults->pValue + 1);
+        defaults++;
+
+        strcpy(defaults->pParamName, specular_paramname);
+        defaults->pValue = defaults->pParamName + sizeof(specular_paramname);
+        defaults->Type = D3DXEDT_FLOATS;
+        defaults->NumBytes = sizeof(D3DCOLORVALUE);
+        memcpy(defaults->pValue, &material_ptr->MatD3D.Specular, sizeof(D3DCOLORVALUE));
+        (defaults + 1)->pParamName = (LPSTR)((D3DCOLORVALUE*)defaults->pValue + 1);
+        defaults++;
+
+        strcpy(defaults->pParamName, emissive_paramname);
+        defaults->pValue = defaults->pParamName + sizeof(emissive_paramname);
+        defaults->Type = D3DXEDT_FLOATS;
+        defaults->NumBytes = sizeof(D3DCOLORVALUE);
+        memcpy(defaults->pValue, &material_ptr->MatD3D.Emissive, sizeof(D3DCOLORVALUE));
+        (defaults + 1)->pParamName = (LPSTR)((D3DCOLORVALUE*)defaults->pValue + 1);
+        defaults++;
+
+        strcpy(defaults->pParamName, ambient_paramname);
+        defaults->pValue = defaults->pParamName + sizeof(ambient_paramname);
+        defaults->Type = D3DXEDT_FLOATS;
+        defaults->NumBytes = sizeof(D3DCOLORVALUE);
+        memcpy(defaults->pValue, &material_ptr->MatD3D.Ambient, sizeof(D3DCOLORVALUE));
+        out_ptr = (BYTE*)((D3DCOLORVALUE*)defaults->pValue + 1);
+        defaults++;
+
+        if (material_ptr->pTextureFilename) {
+            defaults->pParamName = (LPSTR)out_ptr;
+            strcpy(defaults->pParamName, texture_paramname);
+            defaults->pValue = defaults->pParamName + sizeof(texture_paramname);
+            defaults->Type = D3DXEDT_STRING;
+            defaults->NumBytes = strlen(material_ptr->pTextureFilename) + 1;
+            strcpy(defaults->pValue, material_ptr->pTextureFilename);
+            out_ptr = (BYTE*)defaults->pValue + defaults->NumBytes;
+        }
+        material_ptr++;
+        effect_ptr++;
+    }
+
+    return D3D_OK;
+}
+
 /* change to D3DXLoadSkinMeshFromXof when ID3DXFileData is implemented */
 static HRESULT load_skin_mesh_from_xof(IDirectXFileData *filedata,
                                        DWORD options,
@@ -2285,6 +2386,7 @@ static HRESULT load_skin_mesh_from_xof(IDirectXFileData *filedata,
     ID3DXMesh *d3dxmesh = NULL;
     ID3DXBuffer *adjacency = NULL;
     ID3DXBuffer *materials = NULL;
+    ID3DXBuffer *effects = NULL;
     struct vertex_duplication {
         DWORD normal_index;
         struct list entry;
@@ -2434,7 +2536,7 @@ static HRESULT load_skin_mesh_from_xof(IDirectXFileData *filedata,
         if (FAILED(hr)) goto cleanup;
     }
 
-    if (mesh_data.num_materials && materials_out) {
+    if (mesh_data.num_materials && (materials_out || effects_out)) {
         DWORD buffer_size = mesh_data.num_materials * sizeof(D3DXMATERIAL);
         char *strings_out_ptr;
         D3DXMATERIAL *materials_ptr;
@@ -2460,9 +2562,13 @@ static HRESULT load_skin_mesh_from_xof(IDirectXFileData *filedata,
     }
 
     if (mesh_data.num_materials && effects_out) {
-        FIXME("Effect instance generation not supported.\n");
-        hr = E_NOTIMPL;
-        goto cleanup;
+        hr = generate_effects(materials, mesh_data.num_materials, &effects);
+        if (FAILED(hr)) goto cleanup;
+
+        if (!materials_out) {
+            ID3DXBuffer_Release(materials);
+            materials = NULL;
+        }
     }
 
     if (adjacency_out) {
@@ -2476,7 +2582,7 @@ static HRESULT load_skin_mesh_from_xof(IDirectXFileData *filedata,
     if (adjacency_out) *adjacency_out = adjacency;
     if (num_materials_out) *num_materials_out = mesh_data.num_materials;
     if (materials_out) *materials_out = materials;
-    if (effects_out) *effects_out = NULL;
+    if (effects_out) *effects_out = effects;
     if (skin_info_out) *skin_info_out = NULL;
 
     hr = D3D_OK;
@@ -2485,6 +2591,7 @@ cleanup:
         if (d3dxmesh) IUnknown_Release(d3dxmesh);
         if (adjacency) ID3DXBuffer_Release(adjacency);
         if (materials) ID3DXBuffer_Release(materials);
+        if (effects) ID3DXBuffer_Release(effects);
     }
     HeapFree(GetProcessHeap(), 0, mesh_data.vertices);
     HeapFree(GetProcessHeap(), 0, mesh_data.num_tri_per_face);
-- 
1.7.4.1




More information about the wine-patches mailing list