From: Matteo Bruni mbruni@codeweavers.com
--- dlls/d3dx9_36/tests/mesh.c | 126 ++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 66 deletions(-)
diff --git a/dlls/d3dx9_36/tests/mesh.c b/dlls/d3dx9_36/tests/mesh.c index e5ba6e24996..7b7bb215b09 100644 --- a/dlls/d3dx9_36/tests/mesh.c +++ b/dlls/d3dx9_36/tests/mesh.c @@ -2383,6 +2383,8 @@ static void D3DXLoadMeshTest(void) D3DXMATRIX transform; struct test_context *test_context; ID3DXAnimationController *controller; + D3DXMESHCONTAINER *container; + unsigned int i;
if (!(test_context = new_test_context())) { @@ -2418,26 +2420,24 @@ static void D3DXLoadMeshTest(void) hr = D3DXLoadMeshHierarchyFromXInMemory(simple_xfile, sizeof(simple_xfile) - 1, D3DXMESH_MANAGED, device, &alloc_hier, NULL, &frame_hier, NULL); ok(hr == D3D_OK, "Expected D3D_OK, got %#lx\n", hr); - if (SUCCEEDED(hr)) { - D3DXMESHCONTAINER *container = frame_hier->pMeshContainer; - - ok(frame_hier->Name == NULL, "Expected NULL, got '%s'\n", frame_hier->Name); - D3DXMatrixIdentity(&transform); - check_matrix(&frame_hier->TransformationMatrix, &transform); - - ok(!strcmp(container->Name, ""), "Expected '', got '%s'\n", container->Name); - ok(container->MeshData.Type == D3DXMESHTYPE_MESH, "Expected %d, got %d\n", - D3DXMESHTYPE_MESH, container->MeshData.Type); - mesh = container->MeshData.pMesh; - check_vertex_buffer(mesh, simple_vertex_buffer, ARRAY_SIZE(simple_vertex_buffer), simple_fvf); - check_index_buffer(mesh, simple_index_buffer, ARRAY_SIZE(simple_index_buffer), sizeof(*simple_index_buffer)); - check_materials(container->pMaterials, container->NumMaterials, NULL, 0); - check_generated_effects(container->pMaterials, container->NumMaterials, container->pEffects); - check_generated_adjacency(mesh, container->pAdjacency, 0.0f); - hr = D3DXFrameDestroy(frame_hier, &alloc_hier); - ok(hr == D3D_OK, "Expected D3D_OK, got %#lx\n", hr); - frame_hier = NULL; - } + container = frame_hier->pMeshContainer; + + ok(frame_hier->Name == NULL, "Expected NULL, got '%s'\n", frame_hier->Name); + D3DXMatrixIdentity(&transform); + check_matrix(&frame_hier->TransformationMatrix, &transform); + + ok(!strcmp(container->Name, ""), "Expected '', got '%s'\n", container->Name); + ok(container->MeshData.Type == D3DXMESHTYPE_MESH, "Expected %d, got %d\n", + D3DXMESHTYPE_MESH, container->MeshData.Type); + mesh = container->MeshData.pMesh; + check_vertex_buffer(mesh, simple_vertex_buffer, ARRAY_SIZE(simple_vertex_buffer), simple_fvf); + check_index_buffer(mesh, simple_index_buffer, ARRAY_SIZE(simple_index_buffer), sizeof(*simple_index_buffer)); + check_materials(container->pMaterials, container->NumMaterials, NULL, 0); + check_generated_effects(container->pMaterials, container->NumMaterials, container->pEffects); + check_generated_adjacency(mesh, container->pAdjacency, 0.0f); + hr = D3DXFrameDestroy(frame_hier, &alloc_hier); + ok(hr == D3D_OK, "Expected D3D_OK, got %#lx\n", hr); + frame_hier = NULL;
controller = (ID3DXAnimationController *)0xdeadbeef; hr = D3DXLoadMeshHierarchyFromXInMemory(box_anim_xfile, sizeof(box_anim_xfile) - 1, @@ -2459,59 +2459,54 @@ static void D3DXLoadMeshTest(void) hr = D3DXLoadMeshHierarchyFromXInMemory(box_xfile, sizeof(box_xfile) - 1, D3DXMESH_MANAGED, device, &alloc_hier, NULL, &frame_hier, &controller); ok(hr == D3D_OK, "Expected D3D_OK, got %#lx\n", hr); - if (SUCCEEDED(hr)) - { - D3DXMESHCONTAINER *container = frame_hier->pMeshContainer; + container = frame_hier->pMeshContainer; + + ok(!controller, "Animation Controller returned.\n"); + ok(frame_hier->Name == NULL, "Expected NULL, got '%s'\n", frame_hier->Name); + D3DXMatrixIdentity(&transform); + check_matrix(&frame_hier->TransformationMatrix, &transform); + + ok(!strcmp(container->Name, ""), "Expected '', got '%s'\n", container->Name); + ok(container->MeshData.Type == D3DXMESHTYPE_MESH, "Expected %d, got %d\n", + D3DXMESHTYPE_MESH, container->MeshData.Type); + mesh = container->MeshData.pMesh; + check_vertex_buffer(mesh, box_vertex_buffer, ARRAY_SIZE(box_vertex_buffer), box_fvf); + check_index_buffer(mesh, box_index_buffer, ARRAY_SIZE(box_index_buffer), sizeof(*box_index_buffer)); + check_materials(container->pMaterials, container->NumMaterials, box_materials, ARRAY_SIZE(box_materials)); + check_generated_effects(container->pMaterials, container->NumMaterials, container->pEffects); + check_generated_adjacency(mesh, container->pAdjacency, 0.0f); + hr = D3DXFrameDestroy(frame_hier, &alloc_hier); + ok(hr == D3D_OK, "Expected D3D_OK, got %#lx\n", hr); + frame_hier = NULL; + + hr = D3DXLoadMeshHierarchyFromXInMemory(framed_xfile, sizeof(framed_xfile) - 1, + D3DXMESH_MANAGED, device, &alloc_hier, NULL, &frame_hier, NULL); + ok(hr == D3D_OK, "Expected D3D_OK, got %#lx\n", hr); + container = frame_hier->pMeshContainer;
- ok(!controller, "Animation Controller returned.\n"); - ok(frame_hier->Name == NULL, "Expected NULL, got '%s'\n", frame_hier->Name); - D3DXMatrixIdentity(&transform); - check_matrix(&frame_hier->TransformationMatrix, &transform); + ok(!strcmp(frame_hier->Name, ""), "Expected '', got '%s'\n", frame_hier->Name); + /* last frame transform replaces the first */ + D3DXMatrixIdentity(&transform); + transform.m[3][2] = 3.0; + check_matrix(&frame_hier->TransformationMatrix, &transform);
+ for (i = 0; i < 3; ++i) + { ok(!strcmp(container->Name, ""), "Expected '', got '%s'\n", container->Name); ok(container->MeshData.Type == D3DXMESHTYPE_MESH, "Expected %d, got %d\n", - D3DXMESHTYPE_MESH, container->MeshData.Type); + D3DXMESHTYPE_MESH, container->MeshData.Type); mesh = container->MeshData.pMesh; - check_vertex_buffer(mesh, box_vertex_buffer, ARRAY_SIZE(box_vertex_buffer), box_fvf); - check_index_buffer(mesh, box_index_buffer, ARRAY_SIZE(box_index_buffer), sizeof(*box_index_buffer)); - check_materials(container->pMaterials, container->NumMaterials, box_materials, ARRAY_SIZE(box_materials)); + check_vertex_buffer(mesh, framed_vertex_buffers[i], ARRAY_SIZE(framed_vertex_buffers[0]), framed_fvf); + check_index_buffer(mesh, framed_index_buffer, ARRAY_SIZE(framed_index_buffer), sizeof(*framed_index_buffer)); + check_materials(container->pMaterials, container->NumMaterials, NULL, 0); check_generated_effects(container->pMaterials, container->NumMaterials, container->pEffects); check_generated_adjacency(mesh, container->pAdjacency, 0.0f); - hr = D3DXFrameDestroy(frame_hier, &alloc_hier); - ok(hr == D3D_OK, "Expected D3D_OK, got %#lx\n", hr); - frame_hier = NULL; + container = container->pNextMeshContainer; } - - hr = D3DXLoadMeshHierarchyFromXInMemory(framed_xfile, sizeof(framed_xfile) - 1, - D3DXMESH_MANAGED, device, &alloc_hier, NULL, &frame_hier, NULL); + ok(container == NULL, "Expected NULL, got %p\n", container); + hr = D3DXFrameDestroy(frame_hier, &alloc_hier); ok(hr == D3D_OK, "Expected D3D_OK, got %#lx\n", hr); - if (SUCCEEDED(hr)) { - D3DXMESHCONTAINER *container = frame_hier->pMeshContainer; - int i; - - ok(!strcmp(frame_hier->Name, ""), "Expected '', got '%s'\n", frame_hier->Name); - /* last frame transform replaces the first */ - D3DXMatrixIdentity(&transform); - transform.m[3][2] = 3.0; - check_matrix(&frame_hier->TransformationMatrix, &transform); - - for (i = 0; i < 3; i++) { - ok(!strcmp(container->Name, ""), "Expected '', got '%s'\n", container->Name); - ok(container->MeshData.Type == D3DXMESHTYPE_MESH, "Expected %d, got %d\n", - D3DXMESHTYPE_MESH, container->MeshData.Type); - mesh = container->MeshData.pMesh; - check_vertex_buffer(mesh, framed_vertex_buffers[i], ARRAY_SIZE(framed_vertex_buffers[0]), framed_fvf); - check_index_buffer(mesh, framed_index_buffer, ARRAY_SIZE(framed_index_buffer), sizeof(*framed_index_buffer)); - check_materials(container->pMaterials, container->NumMaterials, NULL, 0); - check_generated_effects(container->pMaterials, container->NumMaterials, container->pEffects); - check_generated_adjacency(mesh, container->pAdjacency, 0.0f); - container = container->pNextMeshContainer; - } - ok(container == NULL, "Expected NULL, got %p\n", container); - hr = D3DXFrameDestroy(frame_hier, &alloc_hier); - ok(hr == D3D_OK, "Expected D3D_OK, got %#lx\n", hr); - frame_hier = NULL; - } + frame_hier = NULL;
hr = D3DXLoadMeshFromXInMemory(NULL, 0, D3DXMESH_MANAGED, @@ -2541,8 +2536,7 @@ static void D3DXLoadMeshTest(void) hr = D3DXLoadMeshFromXInMemory(simple_xfile, sizeof(simple_xfile) - 1, D3DXMESH_MANAGED, device, NULL, NULL, NULL, NULL, &mesh); ok(hr == D3D_OK, "Expected D3D_OK, got %#lx\n", hr); - if (SUCCEEDED(hr)) - IUnknown_Release(mesh); + IUnknown_Release(mesh);
test_LoadMeshFromX(device, simple_xfile, simple_vertex_buffer, simple_fvf, simple_index_buffer, default_materials, TRUE); test_LoadMeshFromX(device, box_xfile, box_vertex_buffer, box_fvf, box_index_buffer, box_materials, TRUE);
From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
--- dlls/d3dx9_36/mesh.c | 51 ++++++++++++++++++++++++++++++-------- dlls/d3dx9_36/tests/mesh.c | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 10 deletions(-)
diff --git a/dlls/d3dx9_36/mesh.c b/dlls/d3dx9_36/mesh.c index 7aa70783735..d6c13007126 100644 --- a/dlls/d3dx9_36/mesh.c +++ b/dlls/d3dx9_36/mesh.c @@ -3506,6 +3506,19 @@ HRESULT WINAPI D3DXLoadSkinMeshFromXof(struct ID3DXFileData *filedata, DWORD opt hr = parse_mesh(filedata, &mesh_data, provide_flags); if (FAILED(hr)) goto cleanup;
+ if (!mesh_data.num_vertices) + { + if (adjacency_out) + *adjacency_out = NULL; + if (materials_out) + *materials_out = NULL; + if (effects_out) + *effects_out = NULL; + *mesh_out = NULL; + hr = D3D_OK; + goto cleanup; + } + total_vertices = mesh_data.num_vertices; if (mesh_data.fvf & D3DFVF_NORMAL) { /* duplicate vertices with multiple normals */ @@ -3815,12 +3828,15 @@ static HRESULT load_mesh_container(struct ID3DXFileData *filedata, DWORD options hr = filedata_get_name(filedata, &name); if (FAILED(hr)) goto cleanup;
- hr = alloc_hier->lpVtbl->CreateMeshContainer(alloc_hier, name, &mesh_data, - materials ? ID3DXBuffer_GetBufferPointer(materials) : NULL, - effects ? ID3DXBuffer_GetBufferPointer(effects) : NULL, - num_materials, - adjacency ? ID3DXBuffer_GetBufferPointer(adjacency) : NULL, - skin_info, mesh_container); + if (mesh_data.pMesh) + { + hr = alloc_hier->lpVtbl->CreateMeshContainer(alloc_hier, name, &mesh_data, + materials ? ID3DXBuffer_GetBufferPointer(materials) : NULL, + effects ? ID3DXBuffer_GetBufferPointer(effects) : NULL, + num_materials, + adjacency ? ID3DXBuffer_GetBufferPointer(adjacency) : NULL, + skin_info, mesh_container); + }
cleanup: if (materials) ID3DXBuffer_Release(materials); @@ -4200,13 +4216,21 @@ static HRESULT parse_frame(struct ID3DXFileData *filedata, DWORD options, struct hr = E_OUTOFMEMORY; goto err; } - list_add_tail(container_list, &container->entry); - container->transform = transform;
hr = D3DXLoadSkinMeshFromXof(child, options, device, (provide_flags & PROVIDE_ADJACENCY) ? &container->adjacency : NULL, (provide_flags & PROVIDE_MATERIALS) ? &container->materials : NULL, NULL, &container->num_materials, NULL, &container->mesh); + + if (container->mesh) + { + list_add_tail(container_list, &container->entry); + container->transform = transform; + } + else + { + HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, container); + } } else if (IsEqualGUID(&type, &TID_D3DRMFrameTransformMatrix)) { D3DXMATRIX new_transform; hr = parse_transform_matrix(child, &new_transform); @@ -4294,13 +4318,20 @@ HRESULT WINAPI D3DXLoadMeshFromXInMemory(const void *memory, DWORD memory_size, hr = E_OUTOFMEMORY; goto cleanup; } - list_add_tail(&container_list, &container_ptr->entry); - D3DXMatrixIdentity(&container_ptr->transform);
hr = D3DXLoadSkinMeshFromXof(filedata, options, device, (provide_flags & PROVIDE_ADJACENCY) ? &container_ptr->adjacency : NULL, (provide_flags & PROVIDE_MATERIALS) ? &container_ptr->materials : NULL, NULL, &container_ptr->num_materials, NULL, &container_ptr->mesh); + if (container_ptr->mesh) + { + list_add_tail(&container_list, &container_ptr->entry); + D3DXMatrixIdentity(&container_ptr->transform); + } + else + { + HeapFree(GetProcessHeap(), 0, container_ptr); + } } else if (IsEqualGUID(&guid, &TID_D3DRMFrame)) { hr = parse_frame(filedata, options, device, &identity, &container_list, provide_flags); } diff --git a/dlls/d3dx9_36/tests/mesh.c b/dlls/d3dx9_36/tests/mesh.c index 7b7bb215b09..ce68903572b 100644 --- a/dlls/d3dx9_36/tests/mesh.c +++ b/dlls/d3dx9_36/tests/mesh.c @@ -2068,6 +2068,14 @@ static void D3DXLoadMeshTest(void) "}" "Mesh { 3; 0.0; 0.0; 0.0;, 0.0; 1.0; 0.0;, 3.0; 1.0; 0.0;; 1; 3; 0, 1, 2;; }" "}"; + static const char framed_xfile_empty[] = + "xof 0303txt 0032" + "Frame Box01 {" + " Mesh { 0;; 0;;" + " MeshNormals { 0;; 0;; }" + " }" + "}"; + static const WORD framed_index_buffer[] = { 0, 1, 2 }; static const D3DXVECTOR3 framed_vertex_buffers[3][3] = { {{0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 1.0, 0.0}}, @@ -2508,6 +2516,16 @@ static void D3DXLoadMeshTest(void) ok(hr == D3D_OK, "Expected D3D_OK, got %#lx\n", hr); frame_hier = NULL;
+ hr = D3DXLoadMeshHierarchyFromXInMemory(framed_xfile_empty, sizeof(framed_xfile_empty) - 1, + D3DXMESH_MANAGED, device, &alloc_hier, NULL, &frame_hier, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + container = frame_hier->pMeshContainer; + ok(!strcmp(frame_hier->Name, "Box01"), "Unexpected name %s.\n", debugstr_a(frame_hier->Name)); + ok(!container, "Unexpected container %p.\n", container); + + hr = D3DXFrameDestroy(frame_hier, &alloc_hier); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + frame_hier = NULL;
hr = D3DXLoadMeshFromXInMemory(NULL, 0, D3DXMESH_MANAGED, device, NULL, NULL, NULL, NULL, &mesh); @@ -11317,6 +11335,9 @@ static void test_load_skin_mesh_from_xof(void) "1;" "3; 0, 1, 2;;" "}"; + static const char simple_xfile_empty[] = + "xof 0303txt 0032" + "Mesh { 0;; 0;; }"; static const D3DVERTEXELEMENT9 expected_declaration[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, @@ -11428,6 +11449,28 @@ static void test_load_skin_mesh_from_xof(void) mesh->lpVtbl->Release(mesh); adjacency->lpVtbl->Release(adjacency); file_data->lpVtbl->Release(file_data); + + /* Empty Mesh Test */ + file_data = get_mesh_data(simple_xfile_empty, sizeof(simple_xfile_empty) - 1); + ok(!!file_data, "Failed to load mesh data.\n"); + + adjacency = materials = effects = (void *)0xdeadbeef; + count = 0xdeadbeefu; + skin_info = (void *)0xdeadbeef; + mesh = (void *)0xdeadbeef; + + hr = D3DXLoadSkinMeshFromXof(file_data, 0, device, &adjacency, &materials, &effects, &count, + &skin_info, &mesh); + todo_wine ok(hr == D3DXERR_LOADEDMESHASNODATA, "Unexpected hr %#lx.\n", hr); + ok(!adjacency, "Unexpected adjacency %p.\n", adjacency); + ok(!materials, "Unexpected materials %p.\n", materials); + ok(!effects, "Unexpected effects %p.\n", effects); + ok(count == 0xdeadbeefu, "Unexpected count %lu.\n", count); + ok(skin_info == (void *)0xdeadbeef, "Unexpected skin_info %p.\n", skin_info); + ok(!mesh, "Unexpected mesh %p.\n", mesh); + + file_data->lpVtbl->Release(file_data); + refcount = IDirect3DDevice9_Release(device); ok(!refcount, "Device has %lu references left.\n", refcount); DestroyWindow(hwnd);
This merge request was approved by Matteo Bruni.