[2/4] d3dx9: Support optional parameters for D3DXLoadMeshFromXInMemory.
Dylan Smith
dylan.ah.smith at gmail.com
Tue Jun 7 18:43:07 CDT 2011
---
dlls/d3dx9_36/mesh.c | 132 +++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 119 insertions(+), 13 deletions(-)
diff --git a/dlls/d3dx9_36/mesh.c b/dlls/d3dx9_36/mesh.c
index 5df451d..58df295 100644
--- a/dlls/d3dx9_36/mesh.c
+++ b/dlls/d3dx9_36/mesh.c
@@ -2261,6 +2261,7 @@ truncated_data_error:
/* for provide_flags parameters */
#define PROVIDE_MATERIALS 0x1
#define PROVIDE_SKININFO 0x2
+#define PROVIDE_ADJACENCY 0x4
static HRESULT parse_mesh(IDirectXFileData *filedata, struct mesh_data *mesh_data, DWORD provide_flags)
{
@@ -3069,6 +3070,9 @@ struct mesh_container
{
struct list entry;
ID3DXMesh *mesh;
+ ID3DXBuffer *adjacency;
+ ID3DXBuffer *materials;
+ ID3DXBuffer *effects;
DWORD num_materials;
D3DXMATRIX transform;
};
@@ -3077,7 +3081,8 @@ static HRESULT parse_frame(IDirectXFileData *filedata,
DWORD options,
LPDIRECT3DDEVICE9 device,
const D3DXMATRIX *parent_transform,
- struct list *container_list)
+ struct list *container_list,
+ DWORD provide_flags)
{
HRESULT hr;
D3DXMATRIX transform = *parent_transform;
@@ -3095,14 +3100,16 @@ static HRESULT parse_frame(IDirectXFileData *filedata,
list_add_tail(container_list, &container->entry);
container->transform = transform;
- hr = load_skin_mesh_from_xof(child, options, device, NULL, NULL,
+ hr = load_skin_mesh_from_xof(child, options, device,
+ (provide_flags & PROVIDE_ADJACENCY) ? &container->adjacency : NULL,
+ (provide_flags & PROVIDE_MATERIALS) ? &container->materials : NULL,
NULL, &container->num_materials, NULL, &container->mesh);
} else if (IsEqualGUID(type, &TID_D3DRMFrameTransformMatrix)) {
D3DXMATRIX new_transform;
hr = parse_transform_matrix(child, &new_transform);
D3DXMatrixMultiply(&transform, &transform, &new_transform);
} else if (IsEqualGUID(type, &TID_D3DRMFrame)) {
- hr = parse_frame(child, options, device, &transform, container_list);
+ hr = parse_frame(child, options, device, &transform, container_list, provide_flags);
}
if (FAILED(hr)) break;
}
@@ -3124,12 +3131,16 @@ HRESULT WINAPI D3DXLoadMeshFromXInMemory(LPCVOID memory,
IDirectXFileEnumObject *enumobj = NULL;
IDirectXFileData *filedata = NULL;
DXFILELOADMEMORY source;
+ ID3DXBuffer *materials = NULL;
+ ID3DXBuffer *effects = NULL;
+ ID3DXBuffer *adjacency = NULL;
struct list container_list = LIST_INIT(container_list);
struct mesh_container *container_ptr, *next_container_ptr;
DWORD num_materials;
DWORD num_faces, num_vertices;
D3DXMATRIX identity;
int i;
+ DWORD provide_flags = 0;
DWORD fvf;
ID3DXMesh *concat_mesh = NULL;
D3DVERTEXELEMENT9 concat_decl[MAX_FVF_DECL_SIZE];
@@ -3143,13 +3154,6 @@ HRESULT WINAPI D3DXLoadMeshFromXInMemory(LPCVOID memory,
if (!memory || !memory_size || !device || !mesh_out)
return D3DERR_INVALIDCALL;
- if (adjacency_out || materials_out || effects_out)
- {
- if (adjacency_out) FIXME("Support for returning adjacency data not implemented\n");
- if (materials_out) FIXME("Support for returning materials not implemented\n");
- if (effects_out) FIXME("Support for returning effects not implemented\n");
- return E_NOTIMPL;
- }
hr = DirectXFileCreate(&dxfile);
if (FAILED(hr)) goto cleanup;
@@ -3163,6 +3167,8 @@ HRESULT WINAPI D3DXLoadMeshFromXInMemory(LPCVOID memory,
if (FAILED(hr)) goto cleanup;
D3DXMatrixIdentity(&identity);
+ if (adjacency_out) provide_flags |= PROVIDE_ADJACENCY;
+ if (materials_out || effects_out) provide_flags |= PROVIDE_MATERIALS;
while (SUCCEEDED(hr = IDirectXFileEnumObject_GetNextDataObject(enumobj, &filedata)))
{
@@ -3179,10 +3185,12 @@ HRESULT WINAPI D3DXLoadMeshFromXInMemory(LPCVOID memory,
list_add_tail(&container_list, &container_ptr->entry);
D3DXMatrixIdentity(&container_ptr->transform);
- hr = load_skin_mesh_from_xof(filedata, options, device, NULL, NULL,
+ hr = load_skin_mesh_from_xof(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);
} else if (IsEqualGUID(guid, &TID_D3DRMFrame)) {
- hr = parse_frame(filedata, options, device, &identity, &container_list);
+ hr = parse_frame(filedata, options, device, &identity, &container_list, provide_flags);
}
if (FAILED(hr)) goto cleanup;
}
@@ -3341,11 +3349,103 @@ HRESULT WINAPI D3DXLoadMeshFromXInMemory(LPCVOID memory,
concat_mesh->lpVtbl->UnlockAttributeBuffer(concat_mesh);
}
- /* generated default material */
+ if (materials_out || effects_out) {
+ D3DXMATERIAL *out_ptr;
+ if (!num_materials) {
+ /* create default material */
+ hr = D3DXCreateBuffer(sizeof(D3DXMATERIAL), &materials);
+ if (FAILED(hr)) goto cleanup;
+
+ out_ptr = ID3DXBuffer_GetBufferPointer(materials);
+ out_ptr->MatD3D.Diffuse.r = 0.5f;
+ out_ptr->MatD3D.Diffuse.g = 0.5f;
+ out_ptr->MatD3D.Diffuse.b = 0.5f;
+ out_ptr->MatD3D.Specular.r = 0.5f;
+ out_ptr->MatD3D.Specular.g = 0.5f;
+ out_ptr->MatD3D.Specular.b = 0.5f;
+ /* D3DXCreateBuffer initializes the rest to zero */
+ } else {
+ DWORD buffer_size = num_materials * sizeof(D3DXMATERIAL);
+ char *strings_out_ptr;
+
+ LIST_FOR_EACH_ENTRY(container_ptr, &container_list, struct mesh_container, entry)
+ {
+ if (container_ptr->materials) {
+ const D3DXMATERIAL *in_ptr = ID3DXBuffer_GetBufferPointer(container_ptr->materials);
+ for (i = 0; i < container_ptr->num_materials; i++)
+ {
+ if (in_ptr->pTextureFilename)
+ buffer_size += strlen(in_ptr->pTextureFilename) + 1;
+ in_ptr++;
+ }
+ }
+ }
+
+ hr = D3DXCreateBuffer(buffer_size, &materials);
+ if (FAILED(hr)) goto cleanup;
+ out_ptr = ID3DXBuffer_GetBufferPointer(materials);
+ strings_out_ptr = (char*)(out_ptr + num_materials);
+
+ LIST_FOR_EACH_ENTRY(container_ptr, &container_list, struct mesh_container, entry)
+ {
+ if (container_ptr->materials) {
+ const D3DXMATERIAL *in_ptr = ID3DXBuffer_GetBufferPointer(container_ptr->materials);
+ for (i = 0; i < container_ptr->num_materials; i++)
+ {
+ out_ptr->MatD3D = in_ptr->MatD3D;
+ if (in_ptr->pTextureFilename) {
+ out_ptr->pTextureFilename = strings_out_ptr;
+ strcpy(out_ptr->pTextureFilename, in_ptr->pTextureFilename);
+ strings_out_ptr += strlen(in_ptr->pTextureFilename) + 1;
+ }
+ in_ptr++;
+ out_ptr++;
+ }
+ }
+ }
+ }
+ }
if (!num_materials)
num_materials = 1;
+ if (effects_out) {
+ generate_effects(materials, num_materials, &effects);
+ if (!materials_out) {
+ ID3DXBuffer_Release(materials);
+ materials = NULL;
+ }
+ }
+
+ if (adjacency_out) {
+ if (!list_next(&container_list, list_head(&container_list))) {
+ container_ptr = LIST_ENTRY(list_head(&container_list), struct mesh_container, entry);
+ adjacency = container_ptr->adjacency;
+ container_ptr->adjacency = NULL;
+ } else {
+ DWORD offset = 0;
+ DWORD *out_ptr;
+
+ hr = D3DXCreateBuffer(num_faces * 3 * sizeof(DWORD), &adjacency);
+ if (FAILED(hr)) goto cleanup;
+
+ out_ptr = ID3DXBuffer_GetBufferPointer(adjacency);
+ LIST_FOR_EACH_ENTRY(container_ptr, &container_list, struct mesh_container, entry)
+ {
+ DWORD *in_ptr = ID3DXBuffer_GetBufferPointer(container_ptr->adjacency);
+ int count = 3 * container_ptr->mesh->lpVtbl->GetNumFaces(container_ptr->mesh);
+
+ for (i = 0; i < count; i++)
+ *out_ptr++ = offset + *in_ptr++;
+
+ offset += count;
+ }
+ }
+ }
+
*mesh_out = concat_mesh;
+ if (adjacency_out) *adjacency_out = adjacency;
+ if (materials_out) *materials_out = materials;
+ if (effects_out) *effects_out = effects;
if (num_materials_out) *num_materials_out = num_materials;
hr = D3D_OK;
@@ -3357,10 +3457,16 @@ cleanup:
if (dxfile) IDirectXFile_Release(dxfile);
if (FAILED(hr)) {
if (concat_mesh) IUnknown_Release(concat_mesh);
+ if (materials) ID3DXBuffer_Release(materials);
+ if (effects) ID3DXBuffer_Release(effects);
+ if (adjacency) ID3DXBuffer_Release(adjacency);
}
LIST_FOR_EACH_ENTRY_SAFE(container_ptr, next_container_ptr, &container_list, struct mesh_container, entry)
{
if (container_ptr->mesh) IUnknown_Release(container_ptr->mesh);
+ if (container_ptr->adjacency) ID3DXBuffer_Release(container_ptr->adjacency);
+ if (container_ptr->materials) ID3DXBuffer_Release(container_ptr->materials);
+ if (container_ptr->effects) ID3DXBuffer_Release(container_ptr->effects);
HeapFree(GetProcessHeap(), 0, container_ptr);
}
return hr;
--
1.7.4.1
More information about the wine-patches
mailing list