Skip to content

Commit 21e9169

Browse files
alesliehughesjulliard
authored andcommitted
d3dx9: Support empty mesh in D3DXLoadMeshHierarchyFromXInMemory().
1 parent 526909f commit 21e9169

File tree

2 files changed

+84
-10
lines changed

2 files changed

+84
-10
lines changed

dlls/d3dx9_36/mesh.c

+41-10
Original file line numberDiff line numberDiff line change
@@ -3506,6 +3506,19 @@ HRESULT WINAPI D3DXLoadSkinMeshFromXof(struct ID3DXFileData *filedata, DWORD opt
35063506
hr = parse_mesh(filedata, &mesh_data, provide_flags);
35073507
if (FAILED(hr)) goto cleanup;
35083508

3509+
if (!mesh_data.num_vertices)
3510+
{
3511+
if (adjacency_out)
3512+
*adjacency_out = NULL;
3513+
if (materials_out)
3514+
*materials_out = NULL;
3515+
if (effects_out)
3516+
*effects_out = NULL;
3517+
*mesh_out = NULL;
3518+
hr = D3D_OK;
3519+
goto cleanup;
3520+
}
3521+
35093522
total_vertices = mesh_data.num_vertices;
35103523
if (mesh_data.fvf & D3DFVF_NORMAL) {
35113524
/* duplicate vertices with multiple normals */
@@ -3815,12 +3828,15 @@ static HRESULT load_mesh_container(struct ID3DXFileData *filedata, DWORD options
38153828
hr = filedata_get_name(filedata, &name);
38163829
if (FAILED(hr)) goto cleanup;
38173830

3818-
hr = alloc_hier->lpVtbl->CreateMeshContainer(alloc_hier, name, &mesh_data,
3819-
materials ? ID3DXBuffer_GetBufferPointer(materials) : NULL,
3820-
effects ? ID3DXBuffer_GetBufferPointer(effects) : NULL,
3821-
num_materials,
3822-
adjacency ? ID3DXBuffer_GetBufferPointer(adjacency) : NULL,
3823-
skin_info, mesh_container);
3831+
if (mesh_data.pMesh)
3832+
{
3833+
hr = alloc_hier->lpVtbl->CreateMeshContainer(alloc_hier, name, &mesh_data,
3834+
materials ? ID3DXBuffer_GetBufferPointer(materials) : NULL,
3835+
effects ? ID3DXBuffer_GetBufferPointer(effects) : NULL,
3836+
num_materials,
3837+
adjacency ? ID3DXBuffer_GetBufferPointer(adjacency) : NULL,
3838+
skin_info, mesh_container);
3839+
}
38243840

38253841
cleanup:
38263842
if (materials) ID3DXBuffer_Release(materials);
@@ -4200,13 +4216,21 @@ static HRESULT parse_frame(struct ID3DXFileData *filedata, DWORD options, struct
42004216
hr = E_OUTOFMEMORY;
42014217
goto err;
42024218
}
4203-
list_add_tail(container_list, &container->entry);
4204-
container->transform = transform;
42054219

42064220
hr = D3DXLoadSkinMeshFromXof(child, options, device,
42074221
(provide_flags & PROVIDE_ADJACENCY) ? &container->adjacency : NULL,
42084222
(provide_flags & PROVIDE_MATERIALS) ? &container->materials : NULL,
42094223
NULL, &container->num_materials, NULL, &container->mesh);
4224+
4225+
if (container->mesh)
4226+
{
4227+
list_add_tail(container_list, &container->entry);
4228+
container->transform = transform;
4229+
}
4230+
else
4231+
{
4232+
HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, container);
4233+
}
42104234
} else if (IsEqualGUID(&type, &TID_D3DRMFrameTransformMatrix)) {
42114235
D3DXMATRIX new_transform;
42124236
hr = parse_transform_matrix(child, &new_transform);
@@ -4294,13 +4318,20 @@ HRESULT WINAPI D3DXLoadMeshFromXInMemory(const void *memory, DWORD memory_size,
42944318
hr = E_OUTOFMEMORY;
42954319
goto cleanup;
42964320
}
4297-
list_add_tail(&container_list, &container_ptr->entry);
4298-
D3DXMatrixIdentity(&container_ptr->transform);
42994321

43004322
hr = D3DXLoadSkinMeshFromXof(filedata, options, device,
43014323
(provide_flags & PROVIDE_ADJACENCY) ? &container_ptr->adjacency : NULL,
43024324
(provide_flags & PROVIDE_MATERIALS) ? &container_ptr->materials : NULL,
43034325
NULL, &container_ptr->num_materials, NULL, &container_ptr->mesh);
4326+
if (container_ptr->mesh)
4327+
{
4328+
list_add_tail(&container_list, &container_ptr->entry);
4329+
D3DXMatrixIdentity(&container_ptr->transform);
4330+
}
4331+
else
4332+
{
4333+
HeapFree(GetProcessHeap(), 0, container_ptr);
4334+
}
43044335
} else if (IsEqualGUID(&guid, &TID_D3DRMFrame)) {
43054336
hr = parse_frame(filedata, options, device, &identity, &container_list, provide_flags);
43064337
}

dlls/d3dx9_36/tests/mesh.c

+43
Original file line numberDiff line numberDiff line change
@@ -2068,6 +2068,14 @@ static void D3DXLoadMeshTest(void)
20682068
"}"
20692069
"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;; }"
20702070
"}";
2071+
static const char framed_xfile_empty[] =
2072+
"xof 0303txt 0032"
2073+
"Frame Box01 {"
2074+
" Mesh { 0;; 0;;"
2075+
" MeshNormals { 0;; 0;; }"
2076+
" }"
2077+
"}";
2078+
20712079
static const WORD framed_index_buffer[] = { 0, 1, 2 };
20722080
static const D3DXVECTOR3 framed_vertex_buffers[3][3] = {
20732081
{{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)
25082516
ok(hr == D3D_OK, "Expected D3D_OK, got %#lx\n", hr);
25092517
frame_hier = NULL;
25102518

2519+
hr = D3DXLoadMeshHierarchyFromXInMemory(framed_xfile_empty, sizeof(framed_xfile_empty) - 1,
2520+
D3DXMESH_MANAGED, device, &alloc_hier, NULL, &frame_hier, NULL);
2521+
ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
2522+
container = frame_hier->pMeshContainer;
2523+
ok(!strcmp(frame_hier->Name, "Box01"), "Unexpected name %s.\n", debugstr_a(frame_hier->Name));
2524+
ok(!container, "Unexpected container %p.\n", container);
2525+
2526+
hr = D3DXFrameDestroy(frame_hier, &alloc_hier);
2527+
ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
2528+
frame_hier = NULL;
25112529

25122530
hr = D3DXLoadMeshFromXInMemory(NULL, 0, D3DXMESH_MANAGED,
25132531
device, NULL, NULL, NULL, NULL, &mesh);
@@ -11317,6 +11335,9 @@ static void test_load_skin_mesh_from_xof(void)
1131711335
"1;"
1131811336
"3; 0, 1, 2;;"
1131911337
"}";
11338+
static const char simple_xfile_empty[] =
11339+
"xof 0303txt 0032"
11340+
"Mesh { 0;; 0;; }";
1132011341
static const D3DVERTEXELEMENT9 expected_declaration[] =
1132111342
{
1132211343
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
@@ -11428,6 +11449,28 @@ static void test_load_skin_mesh_from_xof(void)
1142811449
mesh->lpVtbl->Release(mesh);
1142911450
adjacency->lpVtbl->Release(adjacency);
1143011451
file_data->lpVtbl->Release(file_data);
11452+
11453+
/* Empty Mesh Test */
11454+
file_data = get_mesh_data(simple_xfile_empty, sizeof(simple_xfile_empty) - 1);
11455+
ok(!!file_data, "Failed to load mesh data.\n");
11456+
11457+
adjacency = materials = effects = (void *)0xdeadbeef;
11458+
count = 0xdeadbeefu;
11459+
skin_info = (void *)0xdeadbeef;
11460+
mesh = (void *)0xdeadbeef;
11461+
11462+
hr = D3DXLoadSkinMeshFromXof(file_data, 0, device, &adjacency, &materials, &effects, &count,
11463+
&skin_info, &mesh);
11464+
todo_wine ok(hr == D3DXERR_LOADEDMESHASNODATA, "Unexpected hr %#lx.\n", hr);
11465+
ok(!adjacency, "Unexpected adjacency %p.\n", adjacency);
11466+
ok(!materials, "Unexpected materials %p.\n", materials);
11467+
ok(!effects, "Unexpected effects %p.\n", effects);
11468+
ok(count == 0xdeadbeefu, "Unexpected count %lu.\n", count);
11469+
ok(skin_info == (void *)0xdeadbeef, "Unexpected skin_info %p.\n", skin_info);
11470+
ok(!mesh, "Unexpected mesh %p.\n", mesh);
11471+
11472+
file_data->lpVtbl->Release(file_data);
11473+
1143111474
refcount = IDirect3DDevice9_Release(device);
1143211475
ok(!refcount, "Device has %lu references left.\n", refcount);
1143311476
DestroyWindow(hwnd);

0 commit comments

Comments
 (0)