d3dx9: Support optional parameters for D3DXLoadMeshFromXInMemory.
This commit is contained in:
parent
85307b6b49
commit
fe8615f889
|
@ -2261,6 +2261,7 @@ truncated_data_error:
|
||||||
/* for provide_flags parameters */
|
/* for provide_flags parameters */
|
||||||
#define PROVIDE_MATERIALS 0x1
|
#define PROVIDE_MATERIALS 0x1
|
||||||
#define PROVIDE_SKININFO 0x2
|
#define PROVIDE_SKININFO 0x2
|
||||||
|
#define PROVIDE_ADJACENCY 0x4
|
||||||
|
|
||||||
static HRESULT parse_mesh(IDirectXFileData *filedata, struct mesh_data *mesh_data, DWORD provide_flags)
|
static HRESULT parse_mesh(IDirectXFileData *filedata, struct mesh_data *mesh_data, DWORD provide_flags)
|
||||||
{
|
{
|
||||||
|
@ -3069,6 +3070,9 @@ struct mesh_container
|
||||||
{
|
{
|
||||||
struct list entry;
|
struct list entry;
|
||||||
ID3DXMesh *mesh;
|
ID3DXMesh *mesh;
|
||||||
|
ID3DXBuffer *adjacency;
|
||||||
|
ID3DXBuffer *materials;
|
||||||
|
ID3DXBuffer *effects;
|
||||||
DWORD num_materials;
|
DWORD num_materials;
|
||||||
D3DXMATRIX transform;
|
D3DXMATRIX transform;
|
||||||
};
|
};
|
||||||
|
@ -3077,7 +3081,8 @@ static HRESULT parse_frame(IDirectXFileData *filedata,
|
||||||
DWORD options,
|
DWORD options,
|
||||||
LPDIRECT3DDEVICE9 device,
|
LPDIRECT3DDEVICE9 device,
|
||||||
const D3DXMATRIX *parent_transform,
|
const D3DXMATRIX *parent_transform,
|
||||||
struct list *container_list)
|
struct list *container_list,
|
||||||
|
DWORD provide_flags)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
D3DXMATRIX transform = *parent_transform;
|
D3DXMATRIX transform = *parent_transform;
|
||||||
|
@ -3095,14 +3100,16 @@ static HRESULT parse_frame(IDirectXFileData *filedata,
|
||||||
list_add_tail(container_list, &container->entry);
|
list_add_tail(container_list, &container->entry);
|
||||||
container->transform = transform;
|
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);
|
NULL, &container->num_materials, NULL, &container->mesh);
|
||||||
} 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);
|
||||||
D3DXMatrixMultiply(&transform, &transform, &new_transform);
|
D3DXMatrixMultiply(&transform, &transform, &new_transform);
|
||||||
} else if (IsEqualGUID(type, &TID_D3DRMFrame)) {
|
} 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;
|
if (FAILED(hr)) break;
|
||||||
}
|
}
|
||||||
|
@ -3124,12 +3131,16 @@ HRESULT WINAPI D3DXLoadMeshFromXInMemory(LPCVOID memory,
|
||||||
IDirectXFileEnumObject *enumobj = NULL;
|
IDirectXFileEnumObject *enumobj = NULL;
|
||||||
IDirectXFileData *filedata = NULL;
|
IDirectXFileData *filedata = NULL;
|
||||||
DXFILELOADMEMORY source;
|
DXFILELOADMEMORY source;
|
||||||
|
ID3DXBuffer *materials = NULL;
|
||||||
|
ID3DXBuffer *effects = NULL;
|
||||||
|
ID3DXBuffer *adjacency = NULL;
|
||||||
struct list container_list = LIST_INIT(container_list);
|
struct list container_list = LIST_INIT(container_list);
|
||||||
struct mesh_container *container_ptr, *next_container_ptr;
|
struct mesh_container *container_ptr, *next_container_ptr;
|
||||||
DWORD num_materials;
|
DWORD num_materials;
|
||||||
DWORD num_faces, num_vertices;
|
DWORD num_faces, num_vertices;
|
||||||
D3DXMATRIX identity;
|
D3DXMATRIX identity;
|
||||||
int i;
|
int i;
|
||||||
|
DWORD provide_flags = 0;
|
||||||
DWORD fvf;
|
DWORD fvf;
|
||||||
ID3DXMesh *concat_mesh = NULL;
|
ID3DXMesh *concat_mesh = NULL;
|
||||||
D3DVERTEXELEMENT9 concat_decl[MAX_FVF_DECL_SIZE];
|
D3DVERTEXELEMENT9 concat_decl[MAX_FVF_DECL_SIZE];
|
||||||
|
@ -3143,13 +3154,6 @@ HRESULT WINAPI D3DXLoadMeshFromXInMemory(LPCVOID memory,
|
||||||
|
|
||||||
if (!memory || !memory_size || !device || !mesh_out)
|
if (!memory || !memory_size || !device || !mesh_out)
|
||||||
return D3DERR_INVALIDCALL;
|
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);
|
hr = DirectXFileCreate(&dxfile);
|
||||||
if (FAILED(hr)) goto cleanup;
|
if (FAILED(hr)) goto cleanup;
|
||||||
|
@ -3163,6 +3167,8 @@ HRESULT WINAPI D3DXLoadMeshFromXInMemory(LPCVOID memory,
|
||||||
if (FAILED(hr)) goto cleanup;
|
if (FAILED(hr)) goto cleanup;
|
||||||
|
|
||||||
D3DXMatrixIdentity(&identity);
|
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)))
|
while (SUCCEEDED(hr = IDirectXFileEnumObject_GetNextDataObject(enumobj, &filedata)))
|
||||||
{
|
{
|
||||||
|
@ -3179,10 +3185,12 @@ HRESULT WINAPI D3DXLoadMeshFromXInMemory(LPCVOID memory,
|
||||||
list_add_tail(&container_list, &container_ptr->entry);
|
list_add_tail(&container_list, &container_ptr->entry);
|
||||||
D3DXMatrixIdentity(&container_ptr->transform);
|
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);
|
NULL, &container_ptr->num_materials, NULL, &container_ptr->mesh);
|
||||||
} else if (IsEqualGUID(guid, &TID_D3DRMFrame)) {
|
} 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;
|
if (FAILED(hr)) goto cleanup;
|
||||||
}
|
}
|
||||||
|
@ -3341,11 +3349,103 @@ HRESULT WINAPI D3DXLoadMeshFromXInMemory(LPCVOID memory,
|
||||||
concat_mesh->lpVtbl->UnlockAttributeBuffer(concat_mesh);
|
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)
|
if (!num_materials)
|
||||||
num_materials = 1;
|
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;
|
*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;
|
if (num_materials_out) *num_materials_out = num_materials;
|
||||||
|
|
||||||
hr = D3D_OK;
|
hr = D3D_OK;
|
||||||
|
@ -3357,10 +3457,16 @@ cleanup:
|
||||||
if (dxfile) IDirectXFile_Release(dxfile);
|
if (dxfile) IDirectXFile_Release(dxfile);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
if (concat_mesh) IUnknown_Release(concat_mesh);
|
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)
|
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->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);
|
HeapFree(GetProcessHeap(), 0, container_ptr);
|
||||||
}
|
}
|
||||||
return hr;
|
return hr;
|
||||||
|
|
Loading…
Reference in New Issue