Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
0e058183
Commit
0e058183
authored
Jun 06, 2011
by
Dylan Smith
Committed by
Alexandre Julliard
Jun 07, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
d3dx9: Add support for loading materials from X files.
parent
420947c5
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
245 additions
and
4 deletions
+245
-4
mesh.c
dlls/d3dx9_36/mesh.c
+245
-4
No files found.
dlls/d3dx9_36/mesh.c
View file @
0e058183
...
...
@@ -1829,6 +1829,10 @@ struct mesh_data {
DWORD
num_normals
;
D3DXVECTOR3
*
normals
;
DWORD
*
normal_indices
;
DWORD
num_materials
;
D3DXMATERIAL
*
materials
;
DWORD
*
material_indices
;
};
static
HRESULT
get_next_child
(
IDirectXFileData
*
filedata
,
IDirectXFileData
**
child
,
const
GUID
**
type
)
...
...
@@ -1862,6 +1866,192 @@ static HRESULT get_next_child(IDirectXFileData *filedata, IDirectXFileData **chi
return
hr
;
}
static
HRESULT
parse_texture_filename
(
IDirectXFileData
*
filedata
,
LPSTR
*
filename_out
)
{
HRESULT
hr
;
DWORD
data_size
;
BYTE
*
data
;
char
*
filename_in
;
char
*
filename
=
NULL
;
/* template TextureFilename {
* STRING filename;
* }
*/
HeapFree
(
GetProcessHeap
(),
0
,
*
filename_out
);
*
filename_out
=
NULL
;
hr
=
IDirectXFileData_GetData
(
filedata
,
NULL
,
&
data_size
,
(
void
**
)
&
data
);
if
(
FAILED
(
hr
))
return
hr
;
if
(
data_size
<
sizeof
(
LPSTR
))
{
WARN
(
"truncated data (%u bytes)
\n
"
,
data_size
);
return
E_FAIL
;
}
filename_in
=
*
(
LPSTR
*
)
data
;
filename
=
HeapAlloc
(
GetProcessHeap
(),
0
,
strlen
(
filename_in
)
+
1
);
if
(
!
filename
)
return
E_OUTOFMEMORY
;
strcpy
(
filename
,
filename_in
);
*
filename_out
=
filename
;
return
D3D_OK
;
}
static
HRESULT
parse_material
(
IDirectXFileData
*
filedata
,
D3DXMATERIAL
*
material
)
{
HRESULT
hr
;
DWORD
data_size
;
BYTE
*
data
;
const
GUID
*
type
;
IDirectXFileData
*
child
;
material
->
pTextureFilename
=
NULL
;
hr
=
IDirectXFileData_GetData
(
filedata
,
NULL
,
&
data_size
,
(
void
**
)
&
data
);
if
(
FAILED
(
hr
))
return
hr
;
/*
* template ColorRGBA {
* FLOAT red;
* FLOAT green;
* FLOAT blue;
* FLOAT alpha;
* }
* template ColorRGB {
* FLOAT red;
* FLOAT green;
* FLOAT blue;
* }
* template Material {
* ColorRGBA faceColor;
* FLOAT power;
* ColorRGB specularColor;
* ColorRGB emissiveColor;
* [ ... ]
* }
*/
if
(
data_size
!=
sizeof
(
FLOAT
)
*
11
)
{
WARN
(
"incorrect data size (%u bytes)
\n
"
,
data_size
);
return
E_FAIL
;
}
memcpy
(
&
material
->
MatD3D
.
Diffuse
,
data
,
sizeof
(
D3DCOLORVALUE
));
data
+=
sizeof
(
D3DCOLORVALUE
);
material
->
MatD3D
.
Power
=
*
(
FLOAT
*
)
data
;
data
+=
sizeof
(
FLOAT
);
memcpy
(
&
material
->
MatD3D
.
Specular
,
data
,
sizeof
(
FLOAT
)
*
3
);
material
->
MatD3D
.
Specular
.
a
=
1
.
0
f
;
data
+=
3
*
sizeof
(
FLOAT
);
memcpy
(
&
material
->
MatD3D
.
Emissive
,
data
,
sizeof
(
FLOAT
)
*
3
);
material
->
MatD3D
.
Emissive
.
a
=
1
.
0
f
;
material
->
MatD3D
.
Ambient
.
r
=
0
.
0
f
;
material
->
MatD3D
.
Ambient
.
g
=
0
.
0
f
;
material
->
MatD3D
.
Ambient
.
b
=
0
.
0
f
;
material
->
MatD3D
.
Ambient
.
a
=
1
.
0
f
;
while
(
SUCCEEDED
(
hr
=
get_next_child
(
filedata
,
&
child
,
&
type
)))
{
if
(
IsEqualGUID
(
type
,
&
TID_D3DRMTextureFilename
))
{
hr
=
parse_texture_filename
(
child
,
&
material
->
pTextureFilename
);
if
(
FAILED
(
hr
))
break
;
}
}
return
hr
==
DXFILEERR_NOMOREOBJECTS
?
D3D_OK
:
hr
;
}
static
void
destroy_materials
(
struct
mesh_data
*
mesh
)
{
int
i
;
for
(
i
=
0
;
i
<
mesh
->
num_materials
;
i
++
)
HeapFree
(
GetProcessHeap
(),
0
,
mesh
->
materials
[
i
].
pTextureFilename
);
HeapFree
(
GetProcessHeap
(),
0
,
mesh
->
materials
);
HeapFree
(
GetProcessHeap
(),
0
,
mesh
->
material_indices
);
mesh
->
num_materials
=
0
;
mesh
->
materials
=
NULL
;
mesh
->
material_indices
=
NULL
;
}
static
HRESULT
parse_material_list
(
IDirectXFileData
*
filedata
,
struct
mesh_data
*
mesh
)
{
HRESULT
hr
;
DWORD
data_size
;
DWORD
*
data
,
*
in_ptr
;
const
GUID
*
type
;
IDirectXFileData
*
child
;
DWORD
num_materials
;
int
i
;
destroy_materials
(
mesh
);
hr
=
IDirectXFileData_GetData
(
filedata
,
NULL
,
&
data_size
,
(
void
**
)
&
data
);
if
(
FAILED
(
hr
))
return
hr
;
/* template MeshMaterialList {
* DWORD nMaterials;
* DWORD nFaceIndexes;
* array DWORD faceIndexes[nFaceIndexes];
* [ Material ]
* }
*/
in_ptr
=
data
;
if
(
data_size
<
sizeof
(
DWORD
))
goto
truncated_data_error
;
num_materials
=
*
in_ptr
++
;
if
(
!
num_materials
)
return
D3D_OK
;
if
(
data_size
<
2
*
sizeof
(
DWORD
))
goto
truncated_data_error
;
if
(
*
in_ptr
++
!=
mesh
->
num_poly_faces
)
{
WARN
(
"number of material face indices (%u) doesn't match number of faces (%u)
\n
"
,
*
(
in_ptr
-
1
),
mesh
->
num_poly_faces
);
return
E_FAIL
;
}
if
(
data_size
<
2
*
sizeof
(
DWORD
)
+
mesh
->
num_poly_faces
*
sizeof
(
DWORD
))
goto
truncated_data_error
;
for
(
i
=
0
;
i
<
mesh
->
num_poly_faces
;
i
++
)
{
if
(
*
in_ptr
++
>=
num_materials
)
{
WARN
(
"face %u: reference to undefined material %u (only %u materials)
\n
"
,
i
,
*
(
in_ptr
-
1
),
num_materials
);
return
E_FAIL
;
}
}
mesh
->
materials
=
HeapAlloc
(
GetProcessHeap
(),
0
,
num_materials
*
sizeof
(
*
mesh
->
materials
));
mesh
->
material_indices
=
HeapAlloc
(
GetProcessHeap
(),
0
,
mesh
->
num_poly_faces
*
sizeof
(
*
mesh
->
material_indices
));
if
(
!
mesh
->
materials
||
!
mesh
->
material_indices
)
return
E_OUTOFMEMORY
;
memcpy
(
mesh
->
material_indices
,
data
+
2
,
mesh
->
num_poly_faces
*
sizeof
(
DWORD
));
while
(
SUCCEEDED
(
hr
=
get_next_child
(
filedata
,
&
child
,
&
type
)))
{
if
(
IsEqualGUID
(
type
,
&
TID_D3DRMMaterial
))
{
if
(
mesh
->
num_materials
>=
num_materials
)
{
WARN
(
"more materials defined than declared
\n
"
);
return
E_FAIL
;
}
hr
=
parse_material
(
child
,
&
mesh
->
materials
[
mesh
->
num_materials
++
]);
if
(
FAILED
(
hr
))
break
;
}
}
if
(
hr
!=
DXFILEERR_NOMOREOBJECTS
)
return
hr
;
if
(
num_materials
!=
mesh
->
num_materials
)
{
WARN
(
"only %u of %u materials defined
\n
"
,
num_materials
,
mesh
->
num_materials
);
return
E_FAIL
;
}
return
D3D_OK
;
truncated_data_error:
WARN
(
"truncated data (%u bytes)
\n
"
,
data_size
);
return
E_FAIL
;
}
static
HRESULT
parse_normals
(
IDirectXFileData
*
filedata
,
struct
mesh_data
*
mesh
)
{
HRESULT
hr
;
...
...
@@ -2059,8 +2249,7 @@ static HRESULT parse_mesh(IDirectXFileData *filedata, struct mesh_data *mesh_dat
}
else
if
(
IsEqualGUID
(
type
,
&
TID_D3DRMMeshMaterialList
)
&&
(
provide_flags
&
PROVIDE_MATERIALS
))
{
FIXME
(
"Mesh material list loading not implemented.
\n
"
);
hr
=
E_NOTIMPL
;
hr
=
parse_material_list
(
child
,
mesh_data
);
}
else
if
(
provide_flags
&
PROVIDE_SKININFO
)
{
if
(
IsEqualGUID
(
type
,
&
DXFILEOBJ_XSkinMeshHeader
))
{
FIXME
(
"Skin mesh loading not implemented.
\n
"
);
...
...
@@ -2095,6 +2284,7 @@ static HRESULT load_skin_mesh_from_xof(IDirectXFileData *filedata,
DWORD
total_vertices
;
ID3DXMesh
*
d3dxmesh
=
NULL
;
ID3DXBuffer
*
adjacency
=
NULL
;
ID3DXBuffer
*
materials
=
NULL
;
struct
vertex_duplication
{
DWORD
normal_index
;
struct
list
entry
;
...
...
@@ -2226,6 +2416,55 @@ static HRESULT load_skin_mesh_from_xof(IDirectXFileData *filedata,
#undef FILL_INDEX_BUFFER
d3dxmesh
->
lpVtbl
->
UnlockIndexBuffer
(
d3dxmesh
);
if
(
mesh_data
.
material_indices
)
{
DWORD
*
attrib_buffer
=
NULL
;
hr
=
d3dxmesh
->
lpVtbl
->
LockAttributeBuffer
(
d3dxmesh
,
D3DLOCK_DISCARD
,
&
attrib_buffer
);
if
(
FAILED
(
hr
))
goto
cleanup
;
for
(
i
=
0
;
i
<
mesh_data
.
num_poly_faces
;
i
++
)
{
DWORD
count
=
mesh_data
.
num_tri_per_face
[
i
];
while
(
count
--
)
*
attrib_buffer
++
=
mesh_data
.
material_indices
[
i
];
}
d3dxmesh
->
lpVtbl
->
UnlockAttributeBuffer
(
d3dxmesh
);
hr
=
d3dxmesh
->
lpVtbl
->
OptimizeInplace
(
d3dxmesh
,
D3DXMESHOPT_ATTRSORT
|
D3DXMESHOPT_IGNOREVERTS
|
D3DXMESHOPT_DONOTSPLIT
,
NULL
,
NULL
,
NULL
,
NULL
);
if
(
FAILED
(
hr
))
goto
cleanup
;
}
if
(
mesh_data
.
num_materials
&&
materials_out
)
{
DWORD
buffer_size
=
mesh_data
.
num_materials
*
sizeof
(
D3DXMATERIAL
);
char
*
strings_out_ptr
;
D3DXMATERIAL
*
materials_ptr
;
for
(
i
=
0
;
i
<
mesh_data
.
num_materials
;
i
++
)
{
if
(
mesh_data
.
materials
[
i
].
pTextureFilename
)
buffer_size
+=
strlen
(
mesh_data
.
materials
[
i
].
pTextureFilename
)
+
1
;
}
hr
=
D3DXCreateBuffer
(
buffer_size
,
&
materials
);
if
(
FAILED
(
hr
))
goto
cleanup
;
materials_ptr
=
ID3DXBuffer_GetBufferPointer
(
materials
);
memcpy
(
materials_ptr
,
mesh_data
.
materials
,
mesh_data
.
num_materials
*
sizeof
(
D3DXMATERIAL
));
strings_out_ptr
=
(
char
*
)(
materials_ptr
+
mesh_data
.
num_materials
);
for
(
i
=
0
;
i
<
mesh_data
.
num_materials
;
i
++
)
{
if
(
materials_ptr
[
i
].
pTextureFilename
)
{
strcpy
(
strings_out_ptr
,
mesh_data
.
materials
[
i
].
pTextureFilename
);
materials_ptr
[
i
].
pTextureFilename
=
strings_out_ptr
;
strings_out_ptr
+=
strlen
(
mesh_data
.
materials
[
i
].
pTextureFilename
)
+
1
;
}
}
}
if
(
mesh_data
.
num_materials
&&
effects_out
)
{
FIXME
(
"Effect instance generation not supported.
\n
"
);
hr
=
E_NOTIMPL
;
goto
cleanup
;
}
if
(
adjacency_out
)
{
hr
=
D3DXCreateBuffer
(
mesh_data
.
num_tri_faces
*
3
*
sizeof
(
DWORD
),
&
adjacency
);
if
(
FAILED
(
hr
))
goto
cleanup
;
...
...
@@ -2235,8 +2474,8 @@ static HRESULT load_skin_mesh_from_xof(IDirectXFileData *filedata,
*
mesh_out
=
d3dxmesh
;
if
(
adjacency_out
)
*
adjacency_out
=
adjacency
;
if
(
num_materials_out
)
*
num_materials_out
=
0
;
if
(
materials_out
)
*
materials_out
=
NULL
;
if
(
num_materials_out
)
*
num_materials_out
=
mesh_data
.
num_materials
;
if
(
materials_out
)
*
materials_out
=
materials
;
if
(
effects_out
)
*
effects_out
=
NULL
;
if
(
skin_info_out
)
*
skin_info_out
=
NULL
;
...
...
@@ -2245,12 +2484,14 @@ cleanup:
if
(
FAILED
(
hr
))
{
if
(
d3dxmesh
)
IUnknown_Release
(
d3dxmesh
);
if
(
adjacency
)
ID3DXBuffer_Release
(
adjacency
);
if
(
materials
)
ID3DXBuffer_Release
(
materials
);
}
HeapFree
(
GetProcessHeap
(),
0
,
mesh_data
.
vertices
);
HeapFree
(
GetProcessHeap
(),
0
,
mesh_data
.
num_tri_per_face
);
HeapFree
(
GetProcessHeap
(),
0
,
mesh_data
.
indices
);
HeapFree
(
GetProcessHeap
(),
0
,
mesh_data
.
normals
);
HeapFree
(
GetProcessHeap
(),
0
,
mesh_data
.
normal_indices
);
destroy_materials
(
&
mesh_data
);
HeapFree
(
GetProcessHeap
(),
0
,
duplications
);
return
hr
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment