Commit 21e91690 authored by Alistair Leslie-Hughes's avatar Alistair Leslie-Hughes Committed by Alexandre Julliard

d3dx9: Support empty mesh in D3DXLoadMeshHierarchyFromXInMemory().

parent 526909f8
...@@ -3506,6 +3506,19 @@ HRESULT WINAPI D3DXLoadSkinMeshFromXof(struct ID3DXFileData *filedata, DWORD opt ...@@ -3506,6 +3506,19 @@ HRESULT WINAPI D3DXLoadSkinMeshFromXof(struct ID3DXFileData *filedata, DWORD opt
hr = parse_mesh(filedata, &mesh_data, provide_flags); hr = parse_mesh(filedata, &mesh_data, provide_flags);
if (FAILED(hr)) goto cleanup; 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; total_vertices = mesh_data.num_vertices;
if (mesh_data.fvf & D3DFVF_NORMAL) { if (mesh_data.fvf & D3DFVF_NORMAL) {
/* duplicate vertices with multiple normals */ /* duplicate vertices with multiple normals */
...@@ -3815,12 +3828,15 @@ static HRESULT load_mesh_container(struct ID3DXFileData *filedata, DWORD options ...@@ -3815,12 +3828,15 @@ static HRESULT load_mesh_container(struct ID3DXFileData *filedata, DWORD options
hr = filedata_get_name(filedata, &name); hr = filedata_get_name(filedata, &name);
if (FAILED(hr)) goto cleanup; if (FAILED(hr)) goto cleanup;
hr = alloc_hier->lpVtbl->CreateMeshContainer(alloc_hier, name, &mesh_data, if (mesh_data.pMesh)
materials ? ID3DXBuffer_GetBufferPointer(materials) : NULL, {
effects ? ID3DXBuffer_GetBufferPointer(effects) : NULL, hr = alloc_hier->lpVtbl->CreateMeshContainer(alloc_hier, name, &mesh_data,
num_materials, materials ? ID3DXBuffer_GetBufferPointer(materials) : NULL,
adjacency ? ID3DXBuffer_GetBufferPointer(adjacency) : NULL, effects ? ID3DXBuffer_GetBufferPointer(effects) : NULL,
skin_info, mesh_container); num_materials,
adjacency ? ID3DXBuffer_GetBufferPointer(adjacency) : NULL,
skin_info, mesh_container);
}
cleanup: cleanup:
if (materials) ID3DXBuffer_Release(materials); if (materials) ID3DXBuffer_Release(materials);
...@@ -4200,13 +4216,21 @@ static HRESULT parse_frame(struct ID3DXFileData *filedata, DWORD options, struct ...@@ -4200,13 +4216,21 @@ static HRESULT parse_frame(struct ID3DXFileData *filedata, DWORD options, struct
hr = E_OUTOFMEMORY; hr = E_OUTOFMEMORY;
goto err; goto err;
} }
list_add_tail(container_list, &container->entry);
container->transform = transform;
hr = D3DXLoadSkinMeshFromXof(child, options, device, hr = D3DXLoadSkinMeshFromXof(child, options, device,
(provide_flags & PROVIDE_ADJACENCY) ? &container->adjacency : NULL, (provide_flags & PROVIDE_ADJACENCY) ? &container->adjacency : NULL,
(provide_flags & PROVIDE_MATERIALS) ? &container->materials : NULL, (provide_flags & PROVIDE_MATERIALS) ? &container->materials : NULL,
NULL, &container->num_materials, NULL, &container->mesh); 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)) { } else if (IsEqualGUID(&type, &TID_D3DRMFrameTransformMatrix)) {
D3DXMATRIX new_transform; D3DXMATRIX new_transform;
hr = parse_transform_matrix(child, &new_transform); hr = parse_transform_matrix(child, &new_transform);
...@@ -4294,13 +4318,20 @@ HRESULT WINAPI D3DXLoadMeshFromXInMemory(const void *memory, DWORD memory_size, ...@@ -4294,13 +4318,20 @@ HRESULT WINAPI D3DXLoadMeshFromXInMemory(const void *memory, DWORD memory_size,
hr = E_OUTOFMEMORY; hr = E_OUTOFMEMORY;
goto cleanup; goto cleanup;
} }
list_add_tail(&container_list, &container_ptr->entry);
D3DXMatrixIdentity(&container_ptr->transform);
hr = D3DXLoadSkinMeshFromXof(filedata, options, device, hr = D3DXLoadSkinMeshFromXof(filedata, options, device,
(provide_flags & PROVIDE_ADJACENCY) ? &container_ptr->adjacency : NULL, (provide_flags & PROVIDE_ADJACENCY) ? &container_ptr->adjacency : NULL,
(provide_flags & PROVIDE_MATERIALS) ? &container_ptr->materials : NULL, (provide_flags & PROVIDE_MATERIALS) ? &container_ptr->materials : NULL,
NULL, &container_ptr->num_materials, NULL, &container_ptr->mesh); 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)) { } else if (IsEqualGUID(&guid, &TID_D3DRMFrame)) {
hr = parse_frame(filedata, options, device, &identity, &container_list, provide_flags); hr = parse_frame(filedata, options, device, &identity, &container_list, provide_flags);
} }
......
...@@ -2068,6 +2068,14 @@ static void D3DXLoadMeshTest(void) ...@@ -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;; }" "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 WORD framed_index_buffer[] = { 0, 1, 2 };
static const D3DXVECTOR3 framed_vertex_buffers[3][3] = { 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}}, {{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) ...@@ -2508,6 +2516,16 @@ static void D3DXLoadMeshTest(void)
ok(hr == D3D_OK, "Expected D3D_OK, got %#lx\n", hr); ok(hr == D3D_OK, "Expected D3D_OK, got %#lx\n", hr);
frame_hier = NULL; 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, hr = D3DXLoadMeshFromXInMemory(NULL, 0, D3DXMESH_MANAGED,
device, NULL, NULL, NULL, NULL, &mesh); device, NULL, NULL, NULL, NULL, &mesh);
...@@ -11317,6 +11335,9 @@ static void test_load_skin_mesh_from_xof(void) ...@@ -11317,6 +11335,9 @@ static void test_load_skin_mesh_from_xof(void)
"1;" "1;"
"3; 0, 1, 2;;" "3; 0, 1, 2;;"
"}"; "}";
static const char simple_xfile_empty[] =
"xof 0303txt 0032"
"Mesh { 0;; 0;; }";
static const D3DVERTEXELEMENT9 expected_declaration[] = static const D3DVERTEXELEMENT9 expected_declaration[] =
{ {
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
...@@ -11428,6 +11449,28 @@ static void test_load_skin_mesh_from_xof(void) ...@@ -11428,6 +11449,28 @@ static void test_load_skin_mesh_from_xof(void)
mesh->lpVtbl->Release(mesh); mesh->lpVtbl->Release(mesh);
adjacency->lpVtbl->Release(adjacency); adjacency->lpVtbl->Release(adjacency);
file_data->lpVtbl->Release(file_data); 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); refcount = IDirect3DDevice9_Release(device);
ok(!refcount, "Device has %lu references left.\n", refcount); ok(!refcount, "Device has %lu references left.\n", refcount);
DestroyWindow(hwnd); DestroyWindow(hwnd);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment