diff --git a/dlls/d3drm/d3drm.c b/dlls/d3drm/d3drm.c index 8ee3d567f40..b4758444c89 100644 --- a/dlls/d3drm/d3drm.c +++ b/dlls/d3drm/d3drm.c @@ -149,6 +149,19 @@ static HRESULT d3drm_create_material_object(void **object, IDirect3DRM *d3drm) return hr; } +static HRESULT d3drm_create_mesh_object(void **object, IDirect3DRM *d3drm) +{ + struct d3drm_mesh *mesh; + HRESULT hr; + + if (FAILED(hr = d3drm_mesh_create(&mesh, d3drm))) + return hr; + + *object = &mesh->IDirect3DRMMesh_iface; + + return hr; +} + struct d3drm { IDirect3DRM IDirect3DRM_iface; @@ -1299,6 +1312,7 @@ static HRESULT WINAPI d3drm3_CreateObject(IDirect3DRM3 *iface, {&CLSID_CDirect3DRMFrame, d3drm_create_frame_object}, {&CLSID_CDirect3DRMLight, d3drm_create_light_object}, {&CLSID_CDirect3DRMMaterial, d3drm_create_material_object}, + {&CLSID_CDirect3DRMMesh, d3drm_create_mesh_object}, }; TRACE("iface %p, clsid %s, outer %p, iid %s, out %p.\n", @@ -1365,9 +1379,18 @@ static HRESULT WINAPI d3drm3_CreateFrame(IDirect3DRM3 *iface, static HRESULT WINAPI d3drm3_CreateMesh(IDirect3DRM3 *iface, IDirect3DRMMesh **mesh) { + struct d3drm *d3drm = impl_from_IDirect3DRM3(iface); + struct d3drm_mesh *object; + HRESULT hr; + TRACE("iface %p, mesh %p.\n", iface, mesh); - return Direct3DRMMesh_create(mesh); + if (FAILED(hr = d3drm_mesh_create(&object, &d3drm->IDirect3DRM_iface))) + return hr; + + *mesh = &object->IDirect3DRMMesh_iface; + + return S_OK; } static HRESULT WINAPI d3drm3_CreateMeshBuilder(IDirect3DRM3 *iface, IDirect3DRMMeshBuilder3 **mesh_builder) diff --git a/dlls/d3drm/d3drm_private.h b/dlls/d3drm/d3drm_private.h index 1b00e1a36de..af79b43292d 100644 --- a/dlls/d3drm/d3drm_private.h +++ b/dlls/d3drm/d3drm_private.h @@ -147,6 +147,30 @@ struct d3drm_mesh_builder DWORD *material_indices; }; +struct mesh_group +{ + unsigned nb_vertices; + D3DRMVERTEX* vertices; + unsigned nb_faces; + unsigned vertex_per_face; + DWORD face_data_size; + unsigned* face_data; + D3DCOLOR color; + IDirect3DRMMaterial2* material; + IDirect3DRMTexture3* texture; +}; + +struct d3drm_mesh +{ + struct d3drm_object obj; + IDirect3DRMMesh IDirect3DRMMesh_iface; + LONG ref; + IDirect3DRM *d3drm; + DWORD groups_capacity; + DWORD nb_groups; + struct mesh_group *groups; +}; + struct d3drm_light { struct d3drm_object obj; @@ -207,7 +231,7 @@ HRESULT d3drm_viewport_create(struct d3drm_viewport **viewport, IDirect3DRM *d3d HRESULT d3drm_mesh_builder_create(struct d3drm_mesh_builder **mesh_builder, IDirect3DRM *d3drm) DECLSPEC_HIDDEN; HRESULT d3drm_light_create(struct d3drm_light **light, IDirect3DRM *d3drm) DECLSPEC_HIDDEN; HRESULT d3drm_material_create(struct d3drm_material **material, IDirect3DRM *d3drm) DECLSPEC_HIDDEN; -HRESULT Direct3DRMMesh_create(IDirect3DRMMesh** obj) DECLSPEC_HIDDEN; +HRESULT d3drm_mesh_create(struct d3drm_mesh **mesh, IDirect3DRM *d3drm) DECLSPEC_HIDDEN; HRESULT load_mesh_data(IDirect3DRMMeshBuilder3 *iface, IDirectXFileData *data, D3DRMLOADTEXTURECALLBACK load_texture_proc, void *arg) DECLSPEC_HIDDEN; diff --git a/dlls/d3drm/meshbuilder.c b/dlls/d3drm/meshbuilder.c index 2afff7ac517..4f6c7602c8c 100644 --- a/dlls/d3drm/meshbuilder.c +++ b/dlls/d3drm/meshbuilder.c @@ -26,29 +26,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3drm); -struct mesh_group -{ - unsigned nb_vertices; - D3DRMVERTEX* vertices; - unsigned nb_faces; - unsigned vertex_per_face; - DWORD face_data_size; - unsigned* face_data; - D3DCOLOR color; - IDirect3DRMMaterial2* material; - IDirect3DRMTexture3* texture; -}; - -struct d3drm_mesh -{ - struct d3drm_object obj; - IDirect3DRMMesh IDirect3DRMMesh_iface; - LONG ref; - DWORD groups_capacity; - DWORD nb_groups; - struct mesh_group *groups; -}; - struct coords_2d { D3DVALUE u; @@ -1977,7 +1954,7 @@ static HRESULT WINAPI d3drm_mesh_builder3_CreateMesh(IDirect3DRMMeshBuilder3 *if if (!mesh) return E_POINTER; - hr = Direct3DRMMesh_create(mesh); + hr = IDirect3DRM_CreateMesh(mesh_builder->d3drm, mesh); if (FAILED(hr)) return hr; @@ -2422,6 +2399,8 @@ static ULONG WINAPI d3drm_mesh_Release(IDirect3DRMMesh *iface) { DWORD i; + d3drm_object_cleanup((IDirect3DRMObject *)iface, &mesh->obj); + IDirect3DRM_Release(mesh->d3drm); for (i = 0; i < mesh->nb_groups; ++i) { HeapFree(GetProcessHeap(), 0, mesh->groups[i].vertices); @@ -2449,17 +2428,21 @@ static HRESULT WINAPI d3drm_mesh_Clone(IDirect3DRMMesh *iface, static HRESULT WINAPI d3drm_mesh_AddDestroyCallback(IDirect3DRMMesh *iface, D3DRMOBJECTCALLBACK cb, void *ctx) { - FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx); + struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); - return E_NOTIMPL; + TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); + + return d3drm_object_add_destroy_callback(&mesh->obj, cb, ctx); } static HRESULT WINAPI d3drm_mesh_DeleteDestroyCallback(IDirect3DRMMesh *iface, D3DRMOBJECTCALLBACK cb, void *ctx) { - FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx); + struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); - return E_NOTIMPL; + TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); + + return d3drm_object_delete_destroy_callback(&mesh->obj, cb, ctx); } static HRESULT WINAPI d3drm_mesh_SetAppData(IDirect3DRMMesh *iface, DWORD data) @@ -2874,22 +2857,24 @@ static const struct IDirect3DRMMeshVtbl d3drm_mesh_vtbl = d3drm_mesh_GetGroupTexture, }; -HRESULT Direct3DRMMesh_create(IDirect3DRMMesh **mesh) +HRESULT d3drm_mesh_create(struct d3drm_mesh **mesh, IDirect3DRM *d3drm) { static const char classname[] = "Mesh"; struct d3drm_mesh *object; - TRACE("mesh %p.\n", mesh); + TRACE("mesh %p, d3drm %p.\n", mesh, d3drm); if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) return E_OUTOFMEMORY; object->IDirect3DRMMesh_iface.lpVtbl = &d3drm_mesh_vtbl; object->ref = 1; + object->d3drm = d3drm; + IDirect3DRM_AddRef(object->d3drm); d3drm_object_init(&object->obj, classname); - *mesh = &object->IDirect3DRMMesh_iface; + *mesh = object; return S_OK; } diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index 82e0166acbb..a432816cb30 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -1487,6 +1487,7 @@ static void test_object(void) { &CLSID_CDirect3DRMLight, &IID_IDirect3DRMLight }, { &CLSID_CDirect3DRMMaterial, &IID_IDirect3DRMMaterial }, { &CLSID_CDirect3DRMMaterial, &IID_IDirect3DRMMaterial2 }, + { &CLSID_CDirect3DRMMesh, &IID_IDirect3DRMMesh }, }; IDirect3DRM *d3drm1; IDirect3DRM2 *d3drm2; @@ -1513,7 +1514,8 @@ static void test_object(void) BOOL takes_ref = IsEqualGUID(tests[i].clsid, &CLSID_CDirect3DRMMeshBuilder) || IsEqualGUID(tests[i].clsid, &CLSID_CDirect3DRMFrame) || IsEqualGUID(tests[i].clsid, &CLSID_CDirect3DRMLight) || - IsEqualGUID(tests[i].clsid, &CLSID_CDirect3DRMMaterial); + IsEqualGUID(tests[i].clsid, &CLSID_CDirect3DRMMaterial) || + IsEqualGUID(tests[i].clsid, &CLSID_CDirect3DRMMesh); unknown = (IUnknown *)0xdeadbeef; hr = IDirect3DRM_CreateObject(d3drm1, NULL, NULL, tests[i].iid, (void **)&unknown);