ReactOS 0.4.17-dev-966-gf06eace
mesh.c File Reference
#include <assert.h>
#include <float.h>
#include "d3dx9_private.h"
#include "dxfile.h"
#include "rmxfguid.h"
#include "rmxftmpl.h"
#include "wine/list.h"
Include dependency graph for mesh.c:

Go to the source code of this file.

Classes

struct  d3dx9_mesh
 
struct  edge_face
 
struct  edge_face_map
 
struct  vertex_metadata
 
struct  mesh_data
 
struct  mesh_container
 
struct  vertex
 
struct  sincos_table
 
struct  point2d
 
struct  dynamic_array
 
struct  outline
 
struct  outline_array
 
struct  face_array
 
struct  point2d_index
 
struct  point2d_index_array
 
struct  glyphinfo
 
struct  word_array
 
struct  triangulation
 
struct  triangulation_array
 
struct  cos_table
 
struct  udec3
 
struct  dec3n
 
struct  frame_node
 

Macros

#define PROVIDE_MATERIALS   0x1
 
#define PROVIDE_SKININFO   0x2
 
#define PROVIDE_ADJACENCY   0x4
 
#define EFFECT_TABLE_ENTRY(str, field)    {str, sizeof(str), sizeof(material_ptr->MatD3D.field), offsetof(D3DXMATERIAL, MatD3D.field)}
 
#define FILL_INDEX_BUFFER(indices_var)
 
#define NUM_ELEM   2
 
#define NUM_ELEM   4
 

Typedefs

typedef HRESULT(* mesh_parse_func) (ID3DXFileData *, struct mesh_data *, DWORD)
 
typedef WORD face[3]
 

Enumerations

enum  pointtype {
  POINTTYPE_CURVE = 0 , POINTTYPE_CORNER , POINTTYPE_CURVE_START , POINTTYPE_CURVE_END ,
  POINTTYPE_CURVE_MIDDLE , POINTTYPE_CURVE = 0 , POINTTYPE_CORNER , POINTTYPE_CURVE_START ,
  POINTTYPE_CURVE_END , POINTTYPE_CURVE_MIDDLE
}
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (d3dx)
 
static struct d3dx9_mesh * impl_from_ID3DXMesh (ID3DXMesh *iface)
 
static HRESULT WINAPI d3dx9_mesh_QueryInterface (ID3DXMesh *iface, REFIID riid, void **out)
 
static ULONG WINAPI d3dx9_mesh_AddRef (ID3DXMesh *iface)
 
static ULONG WINAPI d3dx9_mesh_Release (ID3DXMesh *iface)
 
static HRESULT WINAPI d3dx9_mesh_DrawSubset (ID3DXMesh *iface, DWORD attrib_id)
 
static DWORD WINAPI d3dx9_mesh_GetNumFaces (ID3DXMesh *iface)
 
static DWORD WINAPI d3dx9_mesh_GetNumVertices (ID3DXMesh *iface)
 
static DWORD WINAPI d3dx9_mesh_GetFVF (ID3DXMesh *iface)
 
static void copy_declaration (D3DVERTEXELEMENT9 *dst, const D3DVERTEXELEMENT9 *src, UINT num_elem)
 
static HRESULT WINAPI d3dx9_mesh_GetDeclaration (ID3DXMesh *iface, D3DVERTEXELEMENT9 declaration[MAX_FVF_DECL_SIZE])
 
static DWORD WINAPI d3dx9_mesh_GetNumBytesPerVertex (ID3DXMesh *iface)
 
static DWORD WINAPI d3dx9_mesh_GetOptions (ID3DXMesh *iface)
 
static HRESULT WINAPI d3dx9_mesh_GetDevice (struct ID3DXMesh *iface, struct IDirect3DDevice9 **device)
 
static HRESULT WINAPI d3dx9_mesh_CloneMeshFVF (struct ID3DXMesh *iface, DWORD options, DWORD fvf, struct IDirect3DDevice9 *device, struct ID3DXMesh **clone_mesh)
 
static FLOAT scale_clamp_ubyten (FLOAT value)
 
static FLOAT scale_clamp_shortn (FLOAT value)
 
static FLOAT scale_clamp_ushortn (FLOAT value)
 
static INT simple_round (FLOAT value)
 
static void convert_float4 (BYTE *dst, const D3DXVECTOR4 *src, D3DDECLTYPE type_dst)
 
static void convert_component (BYTE *dst, BYTE *src, D3DDECLTYPE type_dst, D3DDECLTYPE type_src)
 
static INT get_equivalent_declaration_index (D3DVERTEXELEMENT9 orig_declaration, D3DVERTEXELEMENT9 *declaration)
 
static HRESULT convert_vertex_buffer (ID3DXMesh *mesh_dst, ID3DXMesh *mesh_src)
 
static BOOL declaration_equals (const D3DVERTEXELEMENT9 *declaration1, const D3DVERTEXELEMENT9 *declaration2)
 
static HRESULT WINAPI d3dx9_mesh_CloneMesh (struct ID3DXMesh *iface, DWORD options, const D3DVERTEXELEMENT9 *declaration, struct IDirect3DDevice9 *device, struct ID3DXMesh **clone_mesh_out)
 
static HRESULT WINAPI d3dx9_mesh_GetVertexBuffer (struct ID3DXMesh *iface, struct IDirect3DVertexBuffer9 **vertex_buffer)
 
static HRESULT WINAPI d3dx9_mesh_GetIndexBuffer (struct ID3DXMesh *iface, struct IDirect3DIndexBuffer9 **index_buffer)
 
static HRESULT WINAPI d3dx9_mesh_LockVertexBuffer (ID3DXMesh *iface, DWORD flags, void **data)
 
static HRESULT WINAPI d3dx9_mesh_UnlockVertexBuffer (ID3DXMesh *iface)
 
static HRESULT WINAPI d3dx9_mesh_LockIndexBuffer (ID3DXMesh *iface, DWORD flags, void **data)
 
static HRESULT WINAPI d3dx9_mesh_UnlockIndexBuffer (ID3DXMesh *iface)
 
static HRESULT WINAPI d3dx9_mesh_GetAttributeTable (ID3DXMesh *iface, D3DXATTRIBUTERANGE *attrib_table, DWORD *attrib_table_size)
 
static HRESULT init_edge_face_map (struct edge_face_map *edge_face_map, const DWORD *index_buffer, const DWORD *point_reps, DWORD num_faces)
 
static DWORD find_adjacent_face (struct edge_face_map *edge_face_map, DWORD vertex1, DWORD vertex2, DWORD num_faces)
 
static DWORD * generate_identity_point_reps (DWORD num_vertices)
 
static HRESULT WINAPI d3dx9_mesh_ConvertPointRepsToAdjacency (ID3DXMesh *iface, const DWORD *point_reps, DWORD *adjacency)
 
static HRESULT propagate_face_vertices (const DWORD *adjacency, DWORD *point_reps, const uint32_t *indices, uint32_t *new_indices, unsigned int face_idx, unsigned int face_count)
 
static HRESULT WINAPI d3dx9_mesh_ConvertAdjacencyToPointReps (ID3DXMesh *iface, const DWORD *adjacency, DWORD *point_reps)
 
static int __cdecl compare_vertex_keys (const void *a, const void *b)
 
static HRESULT WINAPI d3dx9_mesh_GenerateAdjacency (ID3DXMesh *iface, float epsilon, DWORD *adjacency)
 
static HRESULT WINAPI d3dx9_mesh_UpdateSemantics (ID3DXMesh *iface, D3DVERTEXELEMENT9 declaration[MAX_FVF_DECL_SIZE])
 
static HRESULT WINAPI d3dx9_mesh_LockAttributeBuffer (ID3DXMesh *iface, DWORD flags, DWORD **data)
 
static HRESULT WINAPI d3dx9_mesh_UnlockAttributeBuffer (ID3DXMesh *iface)
 
static HRESULT WINAPI d3dx9_mesh_Optimize (ID3DXMesh *iface, DWORD flags, const DWORD *adjacency_in, DWORD *adjacency_out, DWORD *face_remap, ID3DXBuffer **vertex_remap, ID3DXMesh **opt_mesh)
 
static HRESULT compact_mesh (struct d3dx9_mesh *This, DWORD *indices, DWORD *new_num_vertices, ID3DXBuffer **vertex_remap)
 
static DWORD count_attributes (const DWORD *attrib_buffer, DWORD numfaces)
 
static void fill_attribute_table (DWORD *attrib_buffer, DWORD numfaces, void *indices, BOOL is_32bit_indices, D3DXATTRIBUTERANGE *attrib_table)
 
static int __cdecl attrib_entry_compare (const void *a, const void *b)
 
static HRESULT remap_faces_for_attrsort (struct d3dx9_mesh *This, const DWORD *indices, DWORD *attrib_buffer, DWORD **sorted_attrib_buffer, DWORD **face_remap)
 
static DWORD adjacency_remap (DWORD *face_remap, DWORD index)
 
static HRESULT WINAPI d3dx9_mesh_OptimizeInplace (ID3DXMesh *iface, DWORD flags, const DWORD *adjacency_in, DWORD *adjacency_out, DWORD *face_remap_out, ID3DXBuffer **vertex_remap_out)
 
static HRESULT WINAPI d3dx9_mesh_SetAttributeTable (ID3DXMesh *iface, const D3DXATTRIBUTERANGE *attrib_table, DWORD attrib_table_size)
 
BOOL WINAPI D3DXBoxBoundProbe (const D3DXVECTOR3 *pmin, const D3DXVECTOR3 *pmax, const D3DXVECTOR3 *prayposition, const D3DXVECTOR3 *praydirection)
 
HRESULT WINAPI D3DXComputeBoundingBox (const D3DXVECTOR3 *pfirstposition, DWORD numvertices, DWORD dwstride, D3DXVECTOR3 *pmin, D3DXVECTOR3 *pmax)
 
HRESULT WINAPI D3DXComputeBoundingSphere (const D3DXVECTOR3 *pfirstposition, DWORD numvertices, DWORD dwstride, D3DXVECTOR3 *pcenter, float *pradius)
 
static void append_decl_element (D3DVERTEXELEMENT9 *declaration, UINT *idx, UINT *offset, D3DDECLTYPE type, D3DDECLUSAGE usage, UINT usage_idx)
 
HRESULT WINAPI D3DXDeclaratorFromFVF (DWORD fvf, D3DVERTEXELEMENT9 declaration[MAX_FVF_DECL_SIZE])
 
HRESULT WINAPI D3DXFVFFromDeclarator (const D3DVERTEXELEMENT9 *declaration, DWORD *fvf)
 
static UINT Get_TexCoord_Size_From_FVF (DWORD FVF, int tex_num)
 
UINT WINAPI D3DXGetFVFVertexSize (DWORD FVF)
 
UINT WINAPI D3DXGetDeclVertexSize (const D3DVERTEXELEMENT9 *decl, DWORD stream_idx)
 
UINT WINAPI D3DXGetDeclLength (const D3DVERTEXELEMENT9 *decl)
 
BOOL WINAPI D3DXIntersectTri (const D3DXVECTOR3 *p0, const D3DXVECTOR3 *p1, const D3DXVECTOR3 *p2, const D3DXVECTOR3 *praypos, const D3DXVECTOR3 *praydir, float *pu, float *pv, float *pdist)
 
BOOL WINAPI D3DXSphereBoundProbe (const D3DXVECTOR3 *center, float radius, const D3DXVECTOR3 *ray_position, const D3DXVECTOR3 *ray_direction)
 
HRESULT WINAPI D3DXCreateMesh (DWORD numfaces, DWORD numvertices, DWORD options, const D3DVERTEXELEMENT9 *declaration, struct IDirect3DDevice9 *device, struct ID3DXMesh **mesh)
 
HRESULT WINAPI D3DXCreateMeshFVF (DWORD face_count, DWORD vertex_count, DWORD options, DWORD fvf, struct IDirect3DDevice9 *device, struct ID3DXMesh **mesh)
 
static HRESULT parse_texture_filename (ID3DXFileData *filedata, char **filename_out)
 
static HRESULT parse_material (ID3DXFileData *filedata, D3DXMATERIAL *material)
 
static void destroy_materials (struct mesh_data *mesh)
 
static HRESULT parse_material_list (ID3DXFileData *filedata, struct mesh_data *mesh, DWORD flags)
 
static HRESULT parse_texture_coords (ID3DXFileData *filedata, struct mesh_data *mesh, DWORD flags)
 
static HRESULT parse_vertex_colors (ID3DXFileData *filedata, struct mesh_data *mesh, DWORD flags)
 
static HRESULT parse_normals (ID3DXFileData *filedata, struct mesh_data *mesh, DWORD flags)
 
static HRESULT parse_skin_mesh_header (ID3DXFileData *filedata, struct mesh_data *mesh_data, DWORD flags)
 
static HRESULT parse_skin_weights_info (ID3DXFileData *filedata, struct mesh_data *mesh_data, DWORD flags)
 
static mesh_parse_func mesh_get_parse_func (const GUID *type)
 
static HRESULT parse_mesh (ID3DXFileData *filedata, struct mesh_data *mesh_data, DWORD provide_flags)
 
static HRESULT generate_effects (ID3DXBuffer *materials, DWORD num_materials, ID3DXBuffer **effects)
 
HRESULT WINAPI D3DXLoadSkinMeshFromXof (struct ID3DXFileData *filedata, DWORD options, struct IDirect3DDevice9 *device, struct ID3DXBuffer **adjacency_out, struct ID3DXBuffer **materials_out, struct ID3DXBuffer **effects_out, DWORD *num_materials_out, struct ID3DXSkinInfo **skin_info_out, struct ID3DXMesh **mesh_out)
 
HRESULT WINAPI D3DXLoadMeshHierarchyFromXA (const char *filename, DWORD options, struct IDirect3DDevice9 *device, struct ID3DXAllocateHierarchy *alloc_hier, struct ID3DXLoadUserData *load_user_data, D3DXFRAME **frame_hierarchy, struct ID3DXAnimationController **anim_controller)
 
HRESULT WINAPI D3DXLoadMeshHierarchyFromXW (const WCHAR *filename, DWORD options, struct IDirect3DDevice9 *device, struct ID3DXAllocateHierarchy *alloc_hier, struct ID3DXLoadUserData *load_user_data, D3DXFRAME **frame_hierarchy, struct ID3DXAnimationController **anim_controller)
 
static HRESULT filedata_get_name (ID3DXFileData *filedata, char **name)
 
static HRESULT load_mesh_container (struct ID3DXFileData *filedata, DWORD options, struct IDirect3DDevice9 *device, struct ID3DXAllocateHierarchy *alloc_hier, D3DXMESHCONTAINER **mesh_container, struct ID3DXLoadUserData *load_user_data)
 
static HRESULT parse_transform_matrix (ID3DXFileData *filedata, D3DXMATRIX *transform)
 
static HRESULT load_frame (struct ID3DXFileData *filedata, DWORD options, struct IDirect3DDevice9 *device, struct ID3DXAllocateHierarchy *alloc_hier, D3DXFRAME **frame_out, struct ID3DXLoadUserData *load_user_data)
 
HRESULT WINAPI D3DXLoadMeshHierarchyFromXInMemory (const void *memory, DWORD memory_size, DWORD options, struct IDirect3DDevice9 *device, struct ID3DXAllocateHierarchy *alloc_hier, struct ID3DXLoadUserData *load_user_data, D3DXFRAME **frame_hierarchy, struct ID3DXAnimationController **anim_controller)
 
HRESULT WINAPI D3DXCleanMesh (D3DXCLEANTYPE clean_type, ID3DXMesh *mesh_in, const DWORD *adjacency_in, ID3DXMesh **mesh_out, DWORD *adjacency_out, ID3DXBuffer **errors_and_warnings)
 
HRESULT WINAPI D3DXFrameDestroy (D3DXFRAME *frame, ID3DXAllocateHierarchy *alloc_hier)
 
HRESULT WINAPI D3DXLoadMeshFromXA (const char *filename, DWORD options, struct IDirect3DDevice9 *device, struct ID3DXBuffer **adjacency, struct ID3DXBuffer **materials, struct ID3DXBuffer **effect_instances, DWORD *num_materials, struct ID3DXMesh **mesh)
 
HRESULT WINAPI D3DXLoadMeshFromXW (const WCHAR *filename, DWORD options, struct IDirect3DDevice9 *device, struct ID3DXBuffer **adjacency, struct ID3DXBuffer **materials, struct ID3DXBuffer **effect_instances, DWORD *num_materials, struct ID3DXMesh **mesh)
 
HRESULT WINAPI D3DXLoadMeshFromXResource (HMODULE module, const char *name, const char *type, DWORD options, struct IDirect3DDevice9 *device, struct ID3DXBuffer **adjacency, struct ID3DXBuffer **materials, struct ID3DXBuffer **effect_instances, DWORD *num_materials, struct ID3DXMesh **mesh)
 
static HRESULT parse_frame (struct ID3DXFileData *filedata, DWORD options, struct IDirect3DDevice9 *device, const D3DXMATRIX *parent_transform, struct list *container_list, DWORD provide_flags)
 
HRESULT WINAPI D3DXLoadMeshFromXInMemory (const void *memory, DWORD memory_size, DWORD options, struct IDirect3DDevice9 *device, struct ID3DXBuffer **adjacency_out, struct ID3DXBuffer **materials_out, struct ID3DXBuffer **effects_out, DWORD *num_materials_out, struct ID3DXMesh **mesh_out)
 
HRESULT WINAPI D3DXCreatePolygon (struct IDirect3DDevice9 *device, float length, UINT sides, struct ID3DXMesh **mesh, struct ID3DXBuffer **adjacency)
 
HRESULT WINAPI D3DXCreateBox (struct IDirect3DDevice9 *device, float width, float height, float depth, struct ID3DXMesh **mesh, struct ID3DXBuffer **adjacency)
 
static void free_sincos_table (struct sincos_table *sincos_table)
 
static BOOL compute_sincos_table (struct sincos_table *sincos_table, float angle_start, float angle_step, int n)
 
static WORD vertex_index (UINT slices, int slice, int stack)
 
HRESULT WINAPI D3DXCreateSphere (struct IDirect3DDevice9 *device, float radius, UINT slices, UINT stacks, struct ID3DXMesh **mesh, struct ID3DXBuffer **adjacency)
 
HRESULT WINAPI D3DXCreateCylinder (struct IDirect3DDevice9 *device, float radius1, float radius2, float length, UINT slices, UINT stacks, struct ID3DXMesh **mesh, struct ID3DXBuffer **adjacency)
 
HRESULT WINAPI D3DXCreateTeapot (struct IDirect3DDevice9 *device, struct ID3DXMesh **mesh, struct ID3DXBuffer **adjacency)
 
HRESULT WINAPI D3DXCreateTextA (struct IDirect3DDevice9 *device, HDC hdc, const char *text, float deviation, float extrusion, struct ID3DXMesh **mesh, struct ID3DXBuffer **adjacency, GLYPHMETRICSFLOAT *glyphmetrics)
 
HRESULT WINAPI D3DXCreateTorus (struct IDirect3DDevice9 *device, float innerradius, float outerradius, UINT sides, UINT rings, struct ID3DXMesh **mesh, ID3DXBuffer **adjacency)
 
static BOOL reserve (struct dynamic_array *array, int count, int itemsize)
 
static struct point2d * add_points (struct outline *array, int num)
 
static struct outline * add_outline (struct outline_array *array)
 
static face * add_face (struct face_array *array)
 
static struct triangulation * add_triangulation (struct triangulation_array *array)
 
static HRESULT add_vertex_index (struct word_array *array, WORD vertex_index)
 
 C_ASSERT (sizeof(FIXED)==sizeof(float))
 
 C_ASSERT (sizeof(POINTFX)==sizeof(D3DXVECTOR2))
 
static D3DXVECTOR2 * convert_fixed_to_float (POINTFX *pt, int count, unsigned int emsquare)
 
static HRESULT add_bezier_points (struct outline *outline, const D3DXVECTOR2 *p1, const D3DXVECTOR2 *p2, const D3DXVECTOR2 *p3, float max_deviation_sq)
 
static BOOL is_direction_similar (D3DXVECTOR2 *dir1, D3DXVECTOR2 *dir2, float cos_theta)
 
static D3DXVECTOR2 * unit_vec2 (D3DXVECTOR2 *dir, const D3DXVECTOR2 *pt1, const D3DXVECTOR2 *pt2)
 
static BOOL attempt_line_merge (struct outline *outline, int pt_index, const D3DXVECTOR2 *nextpt, BOOL to_curve, const struct cos_table *table)
 
static HRESULT create_outline (struct glyphinfo *glyph, void *raw_outline, int datasize, float max_deviation_sq, unsigned int emsquare, const struct cos_table *cos_table)
 
static float get_line_to_point_y_distance (D3DXVECTOR2 *line_pt1, D3DXVECTOR2 *line_pt2, D3DXVECTOR2 *point)
 
static D3DXVECTOR2 * get_indexed_point (struct point2d_index *pt_idx)
 
static D3DXVECTOR2 * get_ordered_vertex (struct glyphinfo *glyph, WORD index)
 
static void remove_triangulation (struct triangulation_array *array, struct triangulation *item)
 
static HRESULT triangulation_add_point (struct triangulation **t_ptr, struct triangulation_array *triangulations, WORD vtx_idx, BOOL to_top)
 
static D3DXVECTOR2 * triangulation_get_next_point (struct triangulation *t, struct glyphinfo *glyph, BOOL on_top)
 
static int __cdecl compare_vertex_indices (const void *a, const void *b)
 
static HRESULT triangulate (struct triangulation_array *triangulations)
 
HRESULT WINAPI D3DXCreateTextW (struct IDirect3DDevice9 *device, HDC hdc, const WCHAR *text, float deviation, float extrusion, struct ID3DXMesh **mesh_ptr, struct ID3DXBuffer **adjacency, GLYPHMETRICSFLOAT *glyphmetrics)
 
HRESULT WINAPI D3DXValidMesh (ID3DXMesh *mesh, const DWORD *adjacency, ID3DXBuffer **errors_and_warnings)
 
static BOOL weld_float1 (void *to, void *from, FLOAT epsilon)
 
static BOOL weld_float2 (void *to, void *from, FLOAT epsilon)
 
static BOOL weld_float3 (void *to, void *from, FLOAT epsilon)
 
static BOOL weld_float4 (void *to, void *from, FLOAT epsilon)
 
static BOOL weld_ubyte4 (void *to, void *from, FLOAT epsilon)
 
static BOOL weld_ubyte4n (void *to, void *from, FLOAT epsilon)
 
static BOOL weld_d3dcolor (void *to, void *from, FLOAT epsilon)
 
static BOOL weld_short2 (void *to, void *from, FLOAT epsilon)
 
static BOOL weld_short2n (void *to, void *from, FLOAT epsilon)
 
static BOOL weld_short4 (void *to, void *from, FLOAT epsilon)
 
static BOOL weld_short4n (void *to, void *from, FLOAT epsilon)
 
static BOOL weld_ushort2n (void *to, void *from, FLOAT epsilon)
 
static BOOL weld_ushort4n (void *to, void *from, FLOAT epsilon)
 
static struct udec3 dword_to_udec3 (DWORD d)
 
static BOOL weld_udec3 (void *to, void *from, FLOAT epsilon)
 
static struct dec3n dword_to_dec3n (DWORD d)
 
static BOOL weld_dec3n (void *to, void *from, FLOAT epsilon)
 
static BOOL weld_float16_2 (void *to, void *from, FLOAT epsilon)
 
static BOOL weld_float16_4 (void *to, void *from, FLOAT epsilon)
 
static BOOL weld_component (void *to, void *from, D3DDECLTYPE type, FLOAT epsilon)
 
static FLOAT get_component_epsilon (const D3DVERTEXELEMENT9 *decl_ptr, const D3DXWELDEPSILONS *epsilons)
 
static DWORD read_ib (void *index_buffer, BOOL indices_are_32bit, DWORD index)
 
static void write_ib (void *index_buffer, BOOL indices_are_32bit, DWORD index, DWORD value)
 
HRESULT WINAPI D3DXWeldVertices (ID3DXMesh *mesh, DWORD flags, const D3DXWELDEPSILONS *epsilons, const DWORD *adjacency, DWORD *adjacency_out, DWORD *face_remap_out, ID3DXBuffer **vertex_remap_out)
 
HRESULT WINAPI D3DXOptimizeFaces (const void *indices, UINT num_faces, UINT num_vertices, BOOL indices_are_32bit, DWORD *face_remap)
 
HRESULT WINAPI D3DXOptimizeVertices (const void *indices, UINT face_count, UINT vertex_count, BOOL indices_are_32bit, DWORD *vertex_remap)
 
static D3DXVECTOR3 * vertex_element_vec3 (BYTE *vertices, const D3DVERTEXELEMENT9 *declaration, DWORD vertex_stride, DWORD index)
 
static D3DXVECTOR3 read_vec3 (BYTE *vertices, const D3DVERTEXELEMENT9 *declaration, DWORD vertex_stride, DWORD index)
 
HRESULT WINAPI D3DXComputeTangentFrameEx (ID3DXMesh *mesh, DWORD texture_in_semantic, DWORD texture_in_index, DWORD u_partial_out_semantic, DWORD u_partial_out_index, DWORD v_partial_out_semantic, DWORD v_partial_out_index, DWORD normal_out_semantic, DWORD normal_out_index, DWORD options, const DWORD *adjacency, float partial_edge_threshold, float singular_point_threshold, float normal_edge_threshold, ID3DXMesh **mesh_out, ID3DXBuffer **vertex_mapping)
 
HRESULT WINAPI D3DXComputeNormals (struct ID3DXBaseMesh *mesh, const DWORD *adjacency)
 
HRESULT WINAPI D3DXIntersect (ID3DXBaseMesh *mesh, const D3DXVECTOR3 *ray_pos, const D3DXVECTOR3 *ray_dir, BOOL *hit, DWORD *face_index, float *u, float *v, float *distance, ID3DXBuffer **all_hits, DWORD *count_of_hits)
 
HRESULT WINAPI D3DXTessellateNPatches (ID3DXMesh *mesh, const DWORD *adjacency_in, float num_segs, BOOL quadratic_normals, ID3DXMesh **mesh_out, ID3DXBuffer **adjacency_out)
 
HRESULT WINAPI D3DXConvertMeshSubsetToSingleStrip (struct ID3DXBaseMesh *mesh_in, DWORD attribute_id, DWORD ib_flags, struct IDirect3DIndexBuffer9 **index_buffer, DWORD *index_count)
 
static BOOL queue_frame_node (struct list *queue, D3DXFRAME *frame)
 
static void empty_frame_queue (struct list *queue)
 
D3DXFRAME *WINAPI D3DXFrameFind (const D3DXFRAME *root, const char *name)
 

Variables

static const UINT d3dx_decltype_size []
 
static const struct ID3DXMeshVtbl D3DXMesh_Vtbl
 

Macro Definition Documentation

◆ EFFECT_TABLE_ENTRY

#define EFFECT_TABLE_ENTRY (   str,
  field 
)     {str, sizeof(str), sizeof(material_ptr->MatD3D.field), offsetof(D3DXMATERIAL, MatD3D.field)}

◆ FILL_INDEX_BUFFER

#define FILL_INDEX_BUFFER (   indices_var)
Value:
for (i = 0; i < mesh_data.num_poly_faces; i++) \
{ \
WORD first_index = *index_in_ptr++; \
while (count--) { \
*indices_var++ = first_index; \
*indices_var++ = *index_in_ptr; \
index_in_ptr++; \
*indices_var++ = *index_in_ptr; \
} \
index_in_ptr++; \
}
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int num_poly_faces
Definition: mesh.c:2595
unsigned int * num_tri_per_face
Definition: mesh.c:2598

◆ NUM_ELEM [1/2]

#define NUM_ELEM   2

◆ NUM_ELEM [2/2]

#define NUM_ELEM   4

◆ PROVIDE_ADJACENCY

#define PROVIDE_ADJACENCY   0x4

Definition at line 43 of file mesh.c.

◆ PROVIDE_MATERIALS

#define PROVIDE_MATERIALS   0x1

Definition at line 41 of file mesh.c.

◆ PROVIDE_SKININFO

#define PROVIDE_SKININFO   0x2

Definition at line 42 of file mesh.c.

Typedef Documentation

◆ face

Definition at line 4854 of file mesh.c.

◆ mesh_parse_func

typedef HRESULT(* mesh_parse_func) (ID3DXFileData *, struct mesh_data *, DWORD)

Definition at line 3204 of file mesh.c.

Enumeration Type Documentation

◆ pointtype

Enumerator
POINTTYPE_CURVE 
POINTTYPE_CORNER 
POINTTYPE_CURVE_START 
POINTTYPE_CURVE_END 
POINTTYPE_CURVE_MIDDLE 
POINTTYPE_CURVE 
POINTTYPE_CORNER 
POINTTYPE_CURVE_START 
POINTTYPE_CURVE_END 
POINTTYPE_CURVE_MIDDLE 

Definition at line 5415 of file mesh.c.

5415 {
5416 POINTTYPE_CURVE = 0,
5421};
@ POINTTYPE_CURVE_MIDDLE
Definition: mesh.c:5420
@ POINTTYPE_CORNER
Definition: mesh.c:5417
@ POINTTYPE_CURVE_END
Definition: mesh.c:5419
@ POINTTYPE_CURVE_START
Definition: mesh.c:5418
@ POINTTYPE_CURVE
Definition: mesh.c:5416

Function Documentation

◆ add_bezier_points()

static HRESULT add_bezier_points ( struct outline *  outline,
const D3DXVECTOR2 *  p1,
const D3DXVECTOR2 *  p2,
const D3DXVECTOR2 *  p3,
float  max_deviation_sq 
)
static

Definition at line 5579 of file mesh.c.

5582{
5583 D3DXVECTOR2 split1 = {0, 0}, split2 = {0, 0}, middle, vec;
5584 float deviation_sq;
5585
5586 D3DXVec2Scale(&split1, D3DXVec2Add(&split1, p1, p2), 0.5f);
5587 D3DXVec2Scale(&split2, D3DXVec2Add(&split2, p2, p3), 0.5f);
5588 D3DXVec2Scale(&middle, D3DXVec2Add(&middle, &split1, &split2), 0.5f);
5589
5590 deviation_sq = D3DXVec2LengthSq(D3DXVec2Subtract(&vec, &middle, p2));
5591 if (deviation_sq < max_deviation_sq) {
5592 struct point2d *pt = add_points(outline, 1);
5593 if (!pt) return E_OUTOFMEMORY;
5594 pt->pos = *p2;
5595 pt->corner = POINTTYPE_CURVE;
5596 /* the end point is omitted because the end line merges into the next segment of
5597 * the split bezier curve, and the end of the split bezier curve is added outside
5598 * this recursive function. */
5599 } else {
5600 HRESULT hr = add_bezier_points(outline, p1, &split1, &middle, max_deviation_sq);
5601 if (hr != S_OK) return hr;
5602 hr = add_bezier_points(outline, &middle, &split2, p3, max_deviation_sq);
5603 if (hr != S_OK) return hr;
5604 }
5605
5606 return S_OK;
5607}
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
HRESULT hr
Definition: delayimp.cpp:582
static struct point2d * add_points(struct outline *array, int num)
Definition: mesh.c:5513
static HRESULT add_bezier_points(struct outline *outline, const D3DXVECTOR2 *p1, const D3DXVECTOR2 *p2, const D3DXVECTOR2 *p3, float max_deviation_sq)
Definition: mesh.c:5579
#define pt(x, y)
Definition: drawing.c:79
FT_Vector * vec
Definition: ftbbox.c:469
#define S_OK
Definition: intsafe.h:52
Definition: mesh.c:5437
Definition: mesh.c:5424

Referenced by add_bezier_points(), and create_outline().

◆ add_face()

static face * add_face ( struct face_array *  array)
inlinestatic

Definition at line 5537 of file mesh.c.

5538{
5539 return &array->items[array->count++];
5540}
Definition: undname.c:54

Referenced by triangulation_add_point().

◆ add_outline()

static struct outline * add_outline ( struct outline_array *  array)
static

Definition at line 5525 of file mesh.c.

5526{
5527 struct outline *item;
5528
5529 if (!reserve((struct dynamic_array *)array, array->count + 1, sizeof(array->items[0])))
5530 return NULL;
5531
5532 item = &array->items[array->count++];
5533 ZeroMemory(item, sizeof(*item));
5534 return item;
5535}
#define NULL
Definition: types.h:112
static BOOL reserve(struct dynamic_array *array, int count, int itemsize)
Definition: mesh.c:5499
#define ZeroMemory
Definition: minwinbase.h:31

Referenced by create_outline().

◆ add_points()

static struct point2d * add_points ( struct outline *  array,
int  num 
)
static

Definition at line 5513 of file mesh.c.

5514{
5515 struct point2d *item;
5516
5517 if (!reserve((struct dynamic_array *)array, array->count + num, sizeof(array->items[0])))
5518 return NULL;
5519
5520 item = &array->items[array->count];
5521 array->count += num;
5522 return item;
5523}
GLuint GLuint num
Definition: glext.h:9618

Referenced by add_bezier_points(), and create_outline().

◆ add_triangulation()

static struct triangulation * add_triangulation ( struct triangulation_array *  array)
static

Definition at line 5542 of file mesh.c.

5543{
5544 struct triangulation *item;
5545
5546 if (!reserve((struct dynamic_array *)array, array->count + 1, sizeof(array->items[0])))
5547 return NULL;
5548
5549 item = &array->items[array->count++];
5550 ZeroMemory(item, sizeof(*item));
5551 return item;
5552}

Referenced by triangulate().

◆ add_vertex_index()

static HRESULT add_vertex_index ( struct word_array *  array,
WORD  vertex_index 
)
static

Definition at line 5554 of file mesh.c.

5555{
5556 if (!reserve((struct dynamic_array *)array, array->count + 1, sizeof(array->items[0])))
5557 return E_OUTOFMEMORY;
5558
5559 array->items[array->count++] = vertex_index;
5560 return S_OK;
5561}
static WORD vertex_index(UINT slices, int slice, int stack)
Definition: mesh.c:4897

Referenced by triangulate(), and triangulation_add_point().

◆ adjacency_remap()

static DWORD adjacency_remap ( DWORD *  face_remap,
DWORD  index 
)
static

Definition at line 1632 of file mesh.c.

1633{
1634 if (index == 0xffffffff)
1635 return index;
1636 return face_remap[index];
1637}
#define index(s, c)
Definition: various.h:29
GLuint index
Definition: glext.h:6031

Referenced by d3dx9_mesh_OptimizeInplace().

◆ append_decl_element()

static void append_decl_element ( D3DVERTEXELEMENT9 *  declaration,
UINT *  idx,
UINT *  offset,
D3DDECLTYPE  type,
D3DDECLUSAGE  usage,
UINT  usage_idx 
)
static

Definition at line 2017 of file mesh.c.

2019{
2020 declaration[*idx].Stream = 0;
2021 declaration[*idx].Offset = *offset;
2022 declaration[*idx].Type = type;
2024 declaration[*idx].Usage = usage;
2025 declaration[*idx].UsageIndex = usage_idx;
2026
2028 ++(*idx);
2029}
BYTE usage_idx
@ D3DDECLMETHOD_DEFAULT
Definition: d3d9types.h:258
static const UINT d3dx_decltype_size[]
Definition: mesh.c:67
unsigned int idx
Definition: utils.c:40
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLintptr offset
Definition: glext.h:5920
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919

Referenced by D3DXDeclaratorFromFVF().

◆ attempt_line_merge()

static BOOL attempt_line_merge ( struct outline *  outline,
int  pt_index,
const D3DXVECTOR2 *  nextpt,
BOOL  to_curve,
const struct cos_table *  table 
)
static

Definition at line 5627 of file mesh.c.

5632{
5633 D3DXVECTOR2 curdir, lastdir;
5634 struct point2d *prevpt, *pt;
5635 BOOL ret = FALSE;
5636
5637 pt = &outline->items[pt_index];
5638 pt_index = (pt_index - 1 + outline->count) % outline->count;
5639 prevpt = &outline->items[pt_index];
5640
5641 if (to_curve)
5643
5644 if (outline->count < 2)
5645 return FALSE;
5646
5647 /* remove last point if the next line continues the last line */
5648 unit_vec2(&lastdir, &prevpt->pos, &pt->pos);
5649 unit_vec2(&curdir, &pt->pos, nextpt);
5650 if (is_direction_similar(&lastdir, &curdir, table->cos_half))
5651 {
5652 outline->count--;
5653 if (pt->corner == POINTTYPE_CURVE_END)
5654 prevpt->corner = pt->corner;
5655 if (prevpt->corner == POINTTYPE_CURVE_END && to_curve)
5657 pt = prevpt;
5658
5659 ret = TRUE;
5660 if (outline->count < 2)
5661 return ret;
5662
5663 pt_index = (pt_index - 1 + outline->count) % outline->count;
5664 prevpt = &outline->items[pt_index];
5665 unit_vec2(&lastdir, &prevpt->pos, &pt->pos);
5666 unit_vec2(&curdir, &pt->pos, nextpt);
5667 }
5668 return ret;
5669}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static BOOL is_direction_similar(D3DXVECTOR2 *dir1, D3DXVECTOR2 *dir2, float cos_theta)
Definition: mesh.c:5609
static D3DXVECTOR2 * unit_vec2(D3DXVECTOR2 *dir, const D3DXVECTOR2 *pt1, const D3DXVECTOR2 *pt2)
Definition: mesh.c:5615
return ret
Definition: mutex.c:147
unsigned int BOOL
Definition: ntddk_ex.h:94
if(dx< 0)
Definition: linetemp.h:194
struct point2d * items
Definition: mesh.c:5439
int count
Definition: mesh.c:5438
D3DXVECTOR2 pos
Definition: mesh.c:5425
enum pointtype corner
Definition: mesh.c:5426

Referenced by create_outline().

◆ attrib_entry_compare()

static int __cdecl attrib_entry_compare ( const void *  a,
const void *  b 
)
static

Definition at line 1583 of file mesh.c.

1584{
1585 const DWORD *ptr_a = *(const DWORD **)a;
1586 const DWORD *ptr_b = *(const DWORD **)b;
1587 int delta = *ptr_a - *ptr_b;
1588
1589 if (delta)
1590 return delta;
1591
1592 delta = ptr_a - ptr_b; /* for stable sort */
1593 return delta;
1594}
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204

Referenced by remap_faces_for_attrsort().

◆ C_ASSERT() [1/2]

C_ASSERT ( sizeof(FIXED)  = =sizeof(float))

◆ C_ASSERT() [2/2]

C_ASSERT ( sizeof(POINTFX)  = =sizeof(D3DXVECTOR2))

◆ compact_mesh()

static HRESULT compact_mesh ( struct d3dx9_mesh *  This,
DWORD *  indices,
DWORD *  new_num_vertices,
ID3DXBuffer **  vertex_remap 
)
static

Definition at line 1487 of file mesh.c.

1489{
1490 HRESULT hr;
1491 DWORD *vertex_remap_ptr;
1492 DWORD num_used_vertices;
1493 DWORD i;
1494
1495 hr = D3DXCreateBuffer(This->numvertices * sizeof(DWORD), vertex_remap);
1496 if (FAILED(hr)) return hr;
1497 vertex_remap_ptr = ID3DXBuffer_GetBufferPointer(*vertex_remap);
1498
1499 for (i = 0; i < This->numfaces * 3; i++)
1500 vertex_remap_ptr[indices[i]] = 1;
1501
1502 /* create old->new vertex mapping */
1503 num_used_vertices = 0;
1504 for (i = 0; i < This->numvertices; i++) {
1505 if (vertex_remap_ptr[i])
1506 vertex_remap_ptr[i] = num_used_vertices++;
1507 else
1508 vertex_remap_ptr[i] = -1;
1509 }
1510 /* convert indices */
1511 for (i = 0; i < This->numfaces * 3; i++)
1512 indices[i] = vertex_remap_ptr[indices[i]];
1513
1514 /* create new->old vertex mapping */
1515 num_used_vertices = 0;
1516 for (i = 0; i < This->numvertices; i++) {
1517 if (vertex_remap_ptr[i] != -1)
1518 vertex_remap_ptr[num_used_vertices++] = i;
1519 }
1520 for (i = num_used_vertices; i < This->numvertices; i++)
1521 vertex_remap_ptr[i] = -1;
1522
1523 *new_num_vertices = num_used_vertices;
1524
1525 return D3D_OK;
1526}
#define D3D_OK
Definition: d3d.h:106
HRESULT WINAPI D3DXCreateBuffer(DWORD size, ID3DXBuffer **buffer)
Definition: core.c:127
#define ID3DXBuffer_GetBufferPointer(p)
Definition: d3dx9core.h:85
GLuint GLuint GLsizei GLenum const GLvoid * indices
Definition: gl.h:1545
#define FAILED(hr)
Definition: intsafe.h:51

Referenced by d3dx9_mesh_OptimizeInplace().

◆ compare_vertex_indices()

static int __cdecl compare_vertex_indices ( const void *  a,
const void *  b 
)
static

Definition at line 5946 of file mesh.c.

5947{
5948 const struct point2d_index *idx1 = a, *idx2 = b;
5949 const D3DXVECTOR2 *p1 = &idx1->outline->items[idx1->vertex].pos;
5950 const D3DXVECTOR2 *p2 = &idx2->outline->items[idx2->vertex].pos;
5951 float diff = p1->x - p2->x;
5952
5953 if (diff == 0.0f)
5954 diff = p1->y - p2->y;
5955
5956 return diff == 0.0f ? 0 : (diff > 0.0f ? -1 : 1);
5957}
#define a
Definition: ke_i.h:78
#define b
Definition: ke_i.h:79
FLOAT x
Definition: d3dx9math.h:64
FLOAT y
Definition: d3dx9math.h:64
struct outline * outline
Definition: mesh.c:5457
int vertex
Definition: mesh.c:5458

Referenced by triangulate().

◆ compare_vertex_keys()

static int __cdecl compare_vertex_keys ( const void *  a,
const void *  b 
)
static

Definition at line 1205 of file mesh.c.

1206{
1207 const struct vertex_metadata *left = a;
1208 const struct vertex_metadata *right = b;
1209 if (left->key == right->key)
1210 return 0;
1211 return left->key < right->key ? -1 : 1;
1212}
GLdouble GLdouble right
Definition: glext.h:10859
GLint left
Definition: glext.h:7726

Referenced by d3dx9_mesh_GenerateAdjacency().

◆ compute_sincos_table()

static BOOL compute_sincos_table ( struct sincos_table *  sincos_table,
float  angle_start,
float  angle_step,
int  n 
)
static

Definition at line 4869 of file mesh.c.

4870{
4871 float angle;
4872 int i;
4873
4874 sincos_table->sin = malloc(n * sizeof(*sincos_table->sin));
4875 if (!sincos_table->sin)
4876 {
4877 return FALSE;
4878 }
4879 sincos_table->cos = malloc(n * sizeof(*sincos_table->cos));
4880 if (!sincos_table->cos)
4881 {
4883 return FALSE;
4884 }
4885
4886 angle = angle_start;
4887 for (i = 0; i < n; i++)
4888 {
4891 angle += angle_step;
4892 }
4893
4894 return TRUE;
4895}
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
_ACRTIMP float __cdecl cosf(float)
Definition: cosf.c:13
_ACRTIMP float __cdecl sinf(float)
Definition: sinf.c:13
GLdouble n
Definition: glext.h:7729
GLfloat angle
Definition: glext.h:10853
float * sin
Definition: mesh.c:4858
float * cos
Definition: mesh.c:4859

Referenced by compute_cylinder(), compute_sphere(), D3DXCreateCylinder(), and D3DXCreateSphere().

◆ convert_component()

static void convert_component ( BYTE *  dst,
BYTE *  src,
D3DDECLTYPE  type_dst,
D3DDECLTYPE  type_src 
)
static

Definition at line 469 of file mesh.c.

470{
471 BOOL fixme_once = FALSE;
472
473 switch (type_src)
474 {
476 {
477 FLOAT *src_ptr = (FLOAT*)src;
478 D3DXVECTOR4 src_float4 = {*src_ptr, 0.0f, 0.0f, 1.0f};
479 convert_float4(dst, &src_float4, type_dst);
480 break;
481 }
483 {
484 D3DXVECTOR2 *src_ptr = (D3DXVECTOR2*)src;
485 D3DXVECTOR4 src_float4 = {src_ptr->x, src_ptr->y, 0.0f, 1.0f};
486 convert_float4(dst, &src_float4, type_dst);
487 break;
488 }
490 {
491 D3DXVECTOR3 *src_ptr = (D3DXVECTOR3*)src;
492 D3DXVECTOR4 src_float4 = {src_ptr->x, src_ptr->y, src_ptr->z, 1.0f};
493 convert_float4(dst, &src_float4, type_dst);
494 break;
495 }
497 {
498 D3DXVECTOR4 *src_ptr = (D3DXVECTOR4*)src;
499 D3DXVECTOR4 src_float4 = {src_ptr->x, src_ptr->y, src_ptr->z, src_ptr->w};
500 convert_float4(dst, &src_float4, type_dst);
501 break;
502 }
504 {
505 D3DXVECTOR4 src_float4 =
506 {
507 (FLOAT)src[2]/UCHAR_MAX,
508 (FLOAT)src[1]/UCHAR_MAX,
509 (FLOAT)src[0]/UCHAR_MAX,
511 };
512 convert_float4(dst, &src_float4, type_dst);
513 break;
514 }
516 {
517 D3DXVECTOR4 src_float4 = {src[0], src[1], src[2], src[3]};
518 convert_float4(dst, &src_float4, type_dst);
519 break;
520 }
522 {
523 SHORT *src_ptr = (SHORT*)src;
524 D3DXVECTOR4 src_float4 = {src_ptr[0], src_ptr[1], 0.0f, 1.0f};
525 convert_float4(dst, &src_float4, type_dst);
526 break;
527 }
529 {
530 SHORT *src_ptr = (SHORT*)src;
531 D3DXVECTOR4 src_float4 = {src_ptr[0], src_ptr[1], src_ptr[2], src_ptr[3]};
532 convert_float4(dst, &src_float4, type_dst);
533 break;
534 }
536 {
537 D3DXVECTOR4 src_float4 =
538 {
539 (FLOAT)src[0]/UCHAR_MAX,
540 (FLOAT)src[1]/UCHAR_MAX,
541 (FLOAT)src[2]/UCHAR_MAX,
543 };
544 convert_float4(dst, &src_float4, type_dst);
545 break;
546 }
548 {
549 SHORT *src_ptr = (SHORT*)src;
550 D3DXVECTOR4 src_float4 = {(FLOAT)src_ptr[0]/SHRT_MAX, (FLOAT)src_ptr[1]/SHRT_MAX, 0.0f, 1.0f};
551 convert_float4(dst, &src_float4, type_dst);
552 break;
553 }
555 {
556 SHORT *src_ptr = (SHORT*)src;
557 D3DXVECTOR4 src_float4 =
558 {
559 (FLOAT)src_ptr[0]/SHRT_MAX,
560 (FLOAT)src_ptr[1]/SHRT_MAX,
561 (FLOAT)src_ptr[2]/SHRT_MAX,
562 (FLOAT)src_ptr[3]/SHRT_MAX
563 };
564 convert_float4(dst, &src_float4, type_dst);
565 break;
566 }
568 {
569 D3DXVECTOR4 src_float4 = {0.0f, 0.0f, 0.0f, 1.0f};
570 D3DXFloat16To32Array((FLOAT*)&src_float4, (D3DXFLOAT16*)src, 2);
571 convert_float4(dst, &src_float4, type_dst);
572 break;
573 }
575 {
576 D3DXVECTOR4 src_float4;
577 D3DXFloat16To32Array((FLOAT*)&src_float4, (D3DXFLOAT16*)src, 4);
578 convert_float4(dst, &src_float4, type_dst);
579 break;
580 }
581 default:
582 if (!fixme_once++)
583 FIXME("Conversion of D3DDECLTYPE %d to %d not implemented.\n", type_src, type_dst);
584 break;
585 }
586}
#define FIXME(fmt,...)
Definition: precomp.h:53
@ D3DDECLTYPE_UBYTE4
Definition: d3d9types.h:276
@ D3DDECLTYPE_SHORT2
Definition: d3d9types.h:277
@ D3DDECLTYPE_FLOAT3
Definition: d3d9types.h:273
@ D3DDECLTYPE_FLOAT1
Definition: d3d9types.h:271
@ D3DDECLTYPE_SHORT2N
Definition: d3d9types.h:281
@ D3DDECLTYPE_FLOAT16_4
Definition: d3d9types.h:288
@ D3DDECLTYPE_FLOAT16_2
Definition: d3d9types.h:287
@ D3DDECLTYPE_D3DCOLOR
Definition: d3d9types.h:275
@ D3DDECLTYPE_SHORT4
Definition: d3d9types.h:278
@ D3DDECLTYPE_UBYTE4N
Definition: d3d9types.h:280
@ D3DDECLTYPE_SHORT4N
Definition: d3d9types.h:282
@ D3DDECLTYPE_FLOAT2
Definition: d3d9types.h:272
@ D3DDECLTYPE_FLOAT4
Definition: d3d9types.h:274
FLOAT *WINAPI D3DXFloat16To32Array(FLOAT *pout, const D3DXFLOAT16 *pin, UINT n)
Definition: math.c:2221
static void convert_float4(BYTE *dst, const D3DXVECTOR4 *src, D3DDECLTYPE type_dst)
Definition: mesh.c:344
#define SHRT_MAX
Definition: limits.h:22
#define UCHAR_MAX
Definition: limits.h:11
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
#define FLOAT
Definition: i386-dis.c:525
short SHORT
Definition: pedump.c:59
float FLOAT
Definition: typedefs.h:69

Referenced by convert_vertex_buffer().

◆ convert_fixed_to_float()

static D3DXVECTOR2 * convert_fixed_to_float ( POINTFX *  pt,
int  count,
unsigned int  emsquare 
)
inlinestatic

Definition at line 5567 of file mesh.c.

5568{
5570 while (count--) {
5571 D3DXVECTOR2 *pt_flt = (D3DXVECTOR2*)pt;
5572 pt_flt->x = (pt->x.value + pt->x.fract / (float)0x10000) / emsquare;
5573 pt_flt->y = (pt->y.value + pt->y.fract / (float)0x10000) / emsquare;
5574 pt++;
5575 }
5576 return ret;
5577}
static float(__cdecl *square_half_float)(float x
char * value
Definition: wpp.c:53

Referenced by create_outline().

◆ convert_float4()

static void convert_float4 ( BYTE *  dst,
const D3DXVECTOR4 *  src,
D3DDECLTYPE  type_dst 
)
static

Definition at line 344 of file mesh.c.

345{
346 BOOL fixme_once = FALSE;
347
348 switch (type_dst)
349 {
351 {
352 FLOAT *dst_ptr = (FLOAT*)dst;
353 *dst_ptr = src->x;
354 break;
355 }
357 {
358 D3DXVECTOR2 *dst_ptr = (D3DXVECTOR2*)dst;
359 dst_ptr->x = src->x;
360 dst_ptr->y = src->y;
361 break;
362 }
364 {
365 D3DXVECTOR3 *dst_ptr = (D3DXVECTOR3*)dst;
366 dst_ptr->x = src->x;
367 dst_ptr->y = src->y;
368 dst_ptr->z = src->z;
369 break;
370 }
372 {
373 D3DXVECTOR4 *dst_ptr = (D3DXVECTOR4*)dst;
374 dst_ptr->x = src->x;
375 dst_ptr->y = src->y;
376 dst_ptr->z = src->z;
377 dst_ptr->w = src->w;
378 break;
379 }
381 {
386 break;
387 }
389 {
390 dst[0] = src->x < 0.0f ? 0 : (BYTE)simple_round(src->x);
391 dst[1] = src->y < 0.0f ? 0 : (BYTE)simple_round(src->y);
392 dst[2] = src->z < 0.0f ? 0 : (BYTE)simple_round(src->z);
393 dst[3] = src->w < 0.0f ? 0 : (BYTE)simple_round(src->w);
394 break;
395 }
397 {
398 SHORT *dst_ptr = (SHORT*)dst;
399 dst_ptr[0] = (SHORT)simple_round(src->x);
400 dst_ptr[1] = (SHORT)simple_round(src->y);
401 break;
402 }
404 {
405 SHORT *dst_ptr = (SHORT*)dst;
406 dst_ptr[0] = (SHORT)simple_round(src->x);
407 dst_ptr[1] = (SHORT)simple_round(src->y);
408 dst_ptr[2] = (SHORT)simple_round(src->z);
409 dst_ptr[3] = (SHORT)simple_round(src->w);
410 break;
411 }
413 {
418 break;
419 }
421 {
422 SHORT *dst_ptr = (SHORT*)dst;
423 dst_ptr[0] = (SHORT)simple_round(scale_clamp_shortn(src->x));
424 dst_ptr[1] = (SHORT)simple_round(scale_clamp_shortn(src->y));
425 break;
426 }
428 {
429 SHORT *dst_ptr = (SHORT*)dst;
430 dst_ptr[0] = (SHORT)simple_round(scale_clamp_shortn(src->x));
431 dst_ptr[1] = (SHORT)simple_round(scale_clamp_shortn(src->y));
432 dst_ptr[2] = (SHORT)simple_round(scale_clamp_shortn(src->z));
433 dst_ptr[3] = (SHORT)simple_round(scale_clamp_shortn(src->w));
434 break;
435 }
437 {
438 USHORT *dst_ptr = (USHORT*)dst;
439 dst_ptr[0] = (USHORT)simple_round(scale_clamp_ushortn(src->x));
440 dst_ptr[1] = (USHORT)simple_round(scale_clamp_ushortn(src->y));
441 break;
442 }
444 {
445 USHORT *dst_ptr = (USHORT*)dst;
446 dst_ptr[0] = (USHORT)simple_round(scale_clamp_ushortn(src->x));
447 dst_ptr[1] = (USHORT)simple_round(scale_clamp_ushortn(src->y));
448 dst_ptr[2] = (USHORT)simple_round(scale_clamp_ushortn(src->z));
449 dst_ptr[3] = (USHORT)simple_round(scale_clamp_ushortn(src->w));
450 break;
451 }
453 {
455 break;
456 }
458 {
460 break;
461 }
462 default:
463 if (!fixme_once++)
464 FIXME("Conversion from D3DDECLTYPE_FLOAT4 to %d not implemented.\n", type_dst);
465 break;
466 }
467}
@ D3DDECLTYPE_USHORT4N
Definition: d3d9types.h:284
@ D3DDECLTYPE_USHORT2N
Definition: d3d9types.h:283
D3DXFLOAT16 *WINAPI D3DXFloat32To16Array(D3DXFLOAT16 *pout, const FLOAT *pin, UINT n)
Definition: math.c:2187
static FLOAT scale_clamp_ushortn(FLOAT value)
Definition: mesh.c:320
static FLOAT scale_clamp_shortn(FLOAT value)
Definition: mesh.c:301
static FLOAT scale_clamp_ubyten(FLOAT value)
Definition: mesh.c:284
static INT simple_round(FLOAT value)
Definition: mesh.c:337
unsigned short USHORT
Definition: pedump.c:61
unsigned char BYTE
Definition: xxhash.c:193

Referenced by convert_component().

◆ convert_vertex_buffer()

static HRESULT convert_vertex_buffer ( ID3DXMesh *  mesh_dst,
ID3DXMesh *  mesh_src 
)
static

Definition at line 604 of file mesh.c.

605{
606 HRESULT hr;
607 D3DVERTEXELEMENT9 orig_declaration[MAX_FVF_DECL_SIZE] = {D3DDECL_END()};
609 BYTE *vb_dst = NULL;
610 BYTE *vb_src = NULL;
611 UINT i;
612 UINT num_vertices = mesh_src->lpVtbl->GetNumVertices(mesh_src);
613 UINT dst_vertex_size = mesh_dst->lpVtbl->GetNumBytesPerVertex(mesh_dst);
614 UINT src_vertex_size = mesh_src->lpVtbl->GetNumBytesPerVertex(mesh_src);
615
616 hr = mesh_src->lpVtbl->GetDeclaration(mesh_src, orig_declaration);
617 if (FAILED(hr)) return hr;
618 hr = mesh_dst->lpVtbl->GetDeclaration(mesh_dst, declaration);
619 if (FAILED(hr)) return hr;
620
621 hr = mesh_src->lpVtbl->LockVertexBuffer(mesh_src, D3DLOCK_READONLY, (void**)&vb_src);
622 if (FAILED(hr)) goto cleanup;
623 hr = mesh_dst->lpVtbl->LockVertexBuffer(mesh_dst, 0, (void**)&vb_dst);
624 if (FAILED(hr)) goto cleanup;
625
626 /* Clear all new fields by clearing the entire vertex buffer. */
627 memset(vb_dst, 0, num_vertices * dst_vertex_size);
628
629 for (i = 0; orig_declaration[i].Stream != 0xff; i++)
630 {
631 INT eq_idx = get_equivalent_declaration_index(orig_declaration[i], declaration);
632
633 if (eq_idx >= 0)
634 {
635 UINT j;
636 for (j = 0; j < num_vertices; j++)
637 {
638 UINT idx_dst = dst_vertex_size * j + declaration[eq_idx].Offset;
639 UINT idx_src = src_vertex_size * j + orig_declaration[i].Offset;
640 UINT type_size = d3dx_decltype_size[orig_declaration[i].Type];
641
642 if (orig_declaration[i].Type == declaration[eq_idx].Type)
643 memcpy(&vb_dst[idx_dst], &vb_src[idx_src], type_size);
644 else
645 convert_component(&vb_dst[idx_dst], &vb_src[idx_src], declaration[eq_idx].Type, orig_declaration[i].Type);
646 }
647 }
648 }
649
650 hr = D3D_OK;
651cleanup:
652 if (vb_dst) mesh_dst->lpVtbl->UnlockVertexBuffer(mesh_dst);
653 if (vb_src) mesh_src->lpVtbl->UnlockVertexBuffer(mesh_src);
654
655 return hr;
656}
Type
Definition: Type.h:7
#define D3DLOCK_READONLY
Definition: d3d8types.h:69
#define D3DDECL_END()
Definition: d3d9types.h:329
static void convert_component(BYTE *dst, BYTE *src, D3DDECLTYPE type_dst, D3DDECLTYPE type_src)
Definition: mesh.c:469
static INT get_equivalent_declaration_index(D3DVERTEXELEMENT9 orig_declaration, D3DVERTEXELEMENT9 *declaration)
Definition: mesh.c:588
static void cleanup(void)
Definition: main.c:1335
@ MAX_FVF_DECL_SIZE
Definition: d3dx9mesh.h:41
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
unsigned int UINT
Definition: sysinfo.c:13
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memset(x, y, z)
Definition: compat.h:39
int32_t INT
Definition: typedefs.h:58

Referenced by d3dx9_mesh_CloneMesh().

◆ copy_declaration()

static void copy_declaration ( D3DVERTEXELEMENT9 *  dst,
const D3DVERTEXELEMENT9 *  src,
UINT  num_elem 
)
static

Definition at line 218 of file mesh.c.

219{
220 memcpy(dst, src, num_elem * sizeof(*src));
221}

Referenced by d3dx9_mesh_GetDeclaration(), d3dx9_mesh_UpdateSemantics(), and D3DXCreateMesh().

◆ count_attributes()

static DWORD count_attributes ( const DWORD *  attrib_buffer,
DWORD  numfaces 
)
static

Definition at line 1529 of file mesh.c.

1530{
1531 DWORD last_attribute = attrib_buffer[0];
1532 DWORD attrib_table_size = 1;
1533 DWORD i;
1534 for (i = 1; i < numfaces; i++) {
1535 if (attrib_buffer[i] != last_attribute) {
1536 last_attribute = attrib_buffer[i];
1537 attrib_table_size++;
1538 }
1539 }
1540 return attrib_table_size;
1541}

Referenced by d3dx9_mesh_OptimizeInplace().

◆ create_outline()

static HRESULT create_outline ( struct glyphinfo *  glyph,
void *  raw_outline,
int  datasize,
float  max_deviation_sq,
unsigned int  emsquare,
const struct cos_table *  cos_table 
)
static

Definition at line 5671 of file mesh.c.

5674{
5675 TTPOLYGONHEADER *header = (TTPOLYGONHEADER *)raw_outline;
5676
5677 while ((char *)header < (char *)raw_outline + datasize)
5678 {
5679 TTPOLYCURVE *curve = (TTPOLYCURVE *)(header + 1);
5680 struct point2d *lastpt, *pt;
5681 D3DXVECTOR2 lastdir;
5682 D3DXVECTOR2 *pt_flt;
5683 int j;
5684 struct outline *outline = add_outline(&glyph->outlines);
5685
5686 if (!outline)
5687 return E_OUTOFMEMORY;
5688
5689 pt = add_points(outline, 1);
5690 if (!pt)
5691 return E_OUTOFMEMORY;
5692 pt_flt = convert_fixed_to_float(&header->pfxStart, 1, emsquare);
5693 pt->pos = *pt_flt;
5694 pt->corner = POINTTYPE_CORNER;
5695
5696 if (header->dwType != TT_POLYGON_TYPE)
5697 FIXME("Unknown header type %lu.\n", header->dwType);
5698
5699 while ((char *)curve < (char *)header + header->cb)
5700 {
5701 D3DXVECTOR2 bezier_start = outline->items[outline->count - 1].pos;
5702 BOOL to_curve = curve->wType != TT_PRIM_LINE && curve->cpfx > 1;
5703 unsigned int j2 = 0;
5704
5705 if (!curve->cpfx) {
5706 curve = (TTPOLYCURVE *)&curve->apfx[curve->cpfx];
5707 continue;
5708 }
5709
5710 pt_flt = convert_fixed_to_float(curve->apfx, curve->cpfx, emsquare);
5711
5712 attempt_line_merge(outline, outline->count - 1, &pt_flt[0], to_curve, cos_table);
5713
5714 if (to_curve)
5715 {
5716 HRESULT hr;
5717 int count = curve->cpfx;
5718
5719 while (count > 2)
5720 {
5721 D3DXVECTOR2 bezier_end;
5722
5723 D3DXVec2Scale(&bezier_end, D3DXVec2Add(&bezier_end, &pt_flt[j2], &pt_flt[j2+1]), 0.5f);
5724 hr = add_bezier_points(outline, &bezier_start, &pt_flt[j2], &bezier_end, max_deviation_sq);
5725 if (hr != S_OK)
5726 return hr;
5727 bezier_start = bezier_end;
5728 count--;
5729 j2++;
5730 }
5731 hr = add_bezier_points(outline, &bezier_start, &pt_flt[j2], &pt_flt[j2+1], max_deviation_sq);
5732 if (hr != S_OK)
5733 return hr;
5734
5735 pt = add_points(outline, 1);
5736 if (!pt)
5737 return E_OUTOFMEMORY;
5738 j2++;
5739 pt->pos = pt_flt[j2];
5740 pt->corner = POINTTYPE_CURVE_END;
5741 } else {
5742 pt = add_points(outline, curve->cpfx);
5743 if (!pt)
5744 return E_OUTOFMEMORY;
5745 for (j2 = 0; j2 < curve->cpfx; j2++)
5746 {
5747 pt->pos = pt_flt[j2];
5748 pt->corner = POINTTYPE_CORNER;
5749 pt++;
5750 }
5751 }
5752
5753 curve = (TTPOLYCURVE *)&curve->apfx[curve->cpfx];
5754 }
5755
5756 /* remove last point if the next line continues the last line */
5757 if (outline->count >= 3) {
5758 BOOL to_curve;
5759
5760 lastpt = &outline->items[outline->count - 1];
5761 pt = &outline->items[0];
5762 if (pt->pos.x == lastpt->pos.x && pt->pos.y == lastpt->pos.y) {
5763 if (lastpt->corner == POINTTYPE_CURVE_END)
5764 {
5765 if (pt->corner == POINTTYPE_CURVE_START)
5766 pt->corner = POINTTYPE_CURVE_MIDDLE;
5767 else
5768 pt->corner = POINTTYPE_CURVE_END;
5769 }
5770 outline->count--;
5771 } else {
5772 /* outline closed with a line from end to start point */
5774 }
5775 lastpt = &outline->items[0];
5776 to_curve = lastpt->corner != POINTTYPE_CORNER && lastpt->corner != POINTTYPE_CURVE_END;
5777 if (lastpt->corner == POINTTYPE_CURVE_START)
5778 lastpt->corner = POINTTYPE_CORNER;
5779 pt = &outline->items[1];
5780 if (attempt_line_merge(outline, 0, &pt->pos, to_curve, cos_table))
5781 *lastpt = outline->items[outline->count];
5782 }
5783
5784 lastpt = &outline->items[outline->count - 1];
5785 pt = &outline->items[0];
5786 unit_vec2(&lastdir, &lastpt->pos, &pt->pos);
5787 for (j = 0; j < outline->count; j++)
5788 {
5789 D3DXVECTOR2 curdir;
5790
5791 lastpt = pt;
5792 pt = &outline->items[(j + 1) % outline->count];
5793 unit_vec2(&curdir, &lastpt->pos, &pt->pos);
5794
5795 switch (lastpt->corner)
5796 {
5799 if (!is_direction_similar(&lastdir, &curdir, cos_table->cos_45))
5800 lastpt->corner = POINTTYPE_CORNER;
5801 break;
5803 if (!is_direction_similar(&lastdir, &curdir, cos_table->cos_90))
5804 lastpt->corner = POINTTYPE_CORNER;
5805 else
5806 lastpt->corner = POINTTYPE_CURVE;
5807 break;
5808 default:
5809 break;
5810 }
5811 lastdir = curdir;
5812 }
5813
5814 header = (TTPOLYGONHEADER *)((char *)header + header->cb);
5815 }
5816 return S_OK;
5817}
static SIZE_T datasize
Definition: asm.c:30
static D3DXVECTOR2 * convert_fixed_to_float(POINTFX *pt, int count, unsigned int emsquare)
Definition: mesh.c:5567
static struct outline * add_outline(struct outline_array *array)
Definition: mesh.c:5525
static BOOL attempt_line_merge(struct outline *outline, int pt_index, const D3DXVECTOR2 *nextpt, BOOL to_curve, const struct cos_table *table)
Definition: mesh.c:5627
float cos_90
Definition: mesh.c:5624
float cos_45
Definition: mesh.c:5623
struct outline_array outlines
Definition: mesh.c:5469
POINTFX apfx[1]
Definition: wingdi.h:3160
#define TT_POLYGON_TYPE
Definition: wingdi.h:1318
#define TT_PRIM_LINE
Definition: wingdi.h:1319

Referenced by D3DXCreateTextW(), and test_createtext().

◆ d3dx9_mesh_AddRef()

static ULONG WINAPI d3dx9_mesh_AddRef ( ID3DXMesh *  iface)
static

Definition at line 111 of file mesh.c.

112{
113 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
114 ULONG refcount = InterlockedIncrement(&mesh->ref);
115
116 TRACE("%p increasing refcount to %lu.\n", mesh, refcount);
117
118 return refcount;
119}
#define InterlockedIncrement
Definition: armddk.h:53
static struct d3dx9_mesh * impl_from_ID3DXMesh(ID3DXMesh *iface)
Definition: mesh.c:88
#define TRACE(s)
Definition: solgame.cpp:4
Definition: mesh.c:189
uint32_t ULONG
Definition: typedefs.h:59

◆ d3dx9_mesh_CloneMesh()

static HRESULT WINAPI d3dx9_mesh_CloneMesh ( struct ID3DXMesh *  iface,
DWORD  options,
const D3DVERTEXELEMENT9 *  declaration,
struct IDirect3DDevice9 *  device,
struct ID3DXMesh **  clone_mesh_out 
)
static

Definition at line 677 of file mesh.c.

679{
680 struct d3dx9_mesh *This = impl_from_ID3DXMesh(iface);
681 struct d3dx9_mesh *cloned_this;
682 ID3DXMesh *clone_mesh;
683 D3DVERTEXELEMENT9 orig_declaration[MAX_FVF_DECL_SIZE] = { D3DDECL_END() };
684 void *data_in, *data_out;
685 DWORD vertex_size;
686 HRESULT hr;
687 BOOL same_declaration;
688
689 TRACE("iface %p, options %#lx, declaration %p, device %p, clone_mesh_out %p.\n",
690 iface, options, declaration, device, clone_mesh_out);
691
692 if (!clone_mesh_out)
693 return D3DERR_INVALIDCALL;
694
695 hr = iface->lpVtbl->GetDeclaration(iface, orig_declaration);
696 if (FAILED(hr)) return hr;
697
698 hr = D3DXCreateMesh(This->numfaces, This->numvertices, options & ~D3DXMESH_VB_SHARE,
699 declaration, device, &clone_mesh);
700 if (FAILED(hr)) return hr;
701
702 cloned_this = impl_from_ID3DXMesh(clone_mesh);
703 vertex_size = clone_mesh->lpVtbl->GetNumBytesPerVertex(clone_mesh);
704 same_declaration = declaration_equals(declaration, orig_declaration);
705
707 if (!same_declaration) {
709 goto error;
710 }
711 IDirect3DVertexBuffer9_AddRef(This->vertex_buffer);
712 /* FIXME: refactor to avoid creating a new vertex buffer */
714 cloned_this->vertex_buffer = This->vertex_buffer;
715 } else if (same_declaration) {
716 hr = iface->lpVtbl->LockVertexBuffer(iface, D3DLOCK_READONLY, &data_in);
717 if (FAILED(hr)) goto error;
718 hr = clone_mesh->lpVtbl->LockVertexBuffer(clone_mesh, 0, &data_out);
719 if (FAILED(hr)) {
720 iface->lpVtbl->UnlockVertexBuffer(iface);
721 goto error;
722 }
723 memcpy(data_out, data_in, This->numvertices * vertex_size);
724 clone_mesh->lpVtbl->UnlockVertexBuffer(clone_mesh);
725 iface->lpVtbl->UnlockVertexBuffer(iface);
726 } else {
727 hr = convert_vertex_buffer(clone_mesh, iface);
728 if (FAILED(hr)) goto error;
729 }
730
731 hr = iface->lpVtbl->LockIndexBuffer(iface, D3DLOCK_READONLY, &data_in);
732 if (FAILED(hr)) goto error;
733 hr = clone_mesh->lpVtbl->LockIndexBuffer(clone_mesh, 0, &data_out);
734 if (FAILED(hr)) {
735 iface->lpVtbl->UnlockIndexBuffer(iface);
736 goto error;
737 }
738 if ((options ^ This->options) & D3DXMESH_32BIT) {
739 DWORD i;
740 if (options & D3DXMESH_32BIT) {
741 for (i = 0; i < This->numfaces * 3; i++)
742 ((DWORD*)data_out)[i] = ((WORD*)data_in)[i];
743 } else {
744 for (i = 0; i < This->numfaces * 3; i++)
745 ((WORD*)data_out)[i] = ((DWORD*)data_in)[i];
746 }
747 } else {
748 memcpy(data_out, data_in, This->numfaces * 3 * (options & D3DXMESH_32BIT ? 4 : 2));
749 }
750 clone_mesh->lpVtbl->UnlockIndexBuffer(clone_mesh);
751 iface->lpVtbl->UnlockIndexBuffer(iface);
752
753 memcpy(cloned_this->attrib_buffer, This->attrib_buffer, This->numfaces * sizeof(*This->attrib_buffer));
754
755 if (This->attrib_table_size)
756 {
757 cloned_this->attrib_table_size = This->attrib_table_size;
758 cloned_this->attrib_table = malloc(This->attrib_table_size * sizeof(*This->attrib_table));
759 if (!cloned_this->attrib_table) {
761 goto error;
762 }
763 memcpy(cloned_this->attrib_table, This->attrib_table, This->attrib_table_size * sizeof(*This->attrib_table));
764 }
765
766 *clone_mesh_out = clone_mesh;
767
768 return D3D_OK;
769error:
770 IUnknown_Release(clone_mesh);
771 return hr;
772}
#define D3DERR_INVALIDCALL
Definition: d3d10_private.h:42
#define IDirect3DVertexBuffer9_Release(p)
Definition: d3d9.h:524
#define IDirect3DVertexBuffer9_AddRef(p)
Definition: d3d9.h:523
static HRESULT convert_vertex_buffer(ID3DXMesh *mesh_dst, ID3DXMesh *mesh_src)
Definition: mesh.c:604
HRESULT WINAPI D3DXCreateMesh(DWORD numfaces, DWORD numvertices, DWORD options, const D3DVERTEXELEMENT9 *declaration, struct IDirect3DDevice9 *device, struct ID3DXMesh **mesh)
Definition: mesh.c:2431
static BOOL declaration_equals(const D3DVERTEXELEMENT9 *declaration1, const D3DVERTEXELEMENT9 *declaration2)
Definition: mesh.c:658
@ D3DXMESH_32BIT
Definition: d3dx9mesh.h:46
@ D3DXMESH_VB_SHARE
Definition: d3dx9mesh.h:61
#define error(str)
Definition: mkdosfs.c:1605
D3DXATTRIBUTERANGE * attrib_table
Definition: mesh.c:64
IDirect3DVertexBuffer9 * vertex_buffer
Definition: mesh.c:59
DWORD * attrib_buffer
Definition: mesh.c:61
DWORD attrib_table_size
Definition: mesh.c:63
Definition: devices.h:37

◆ d3dx9_mesh_CloneMeshFVF()

static HRESULT WINAPI d3dx9_mesh_CloneMeshFVF ( struct ID3DXMesh *  iface,
DWORD  options,
DWORD  fvf,
struct IDirect3DDevice9 *  device,
struct ID3DXMesh **  clone_mesh 
)
static

Definition at line 269 of file mesh.c.

271{
272 HRESULT hr;
274
275 TRACE("iface %p, options %#lx, fvf %#lx, device %p, clone_mesh %p.\n",
276 iface, options, fvf, device, clone_mesh);
277
279 return hr;
280
281 return iface->lpVtbl->CloneMesh(iface, options, declaration, device, clone_mesh);
282}
HRESULT WINAPI D3DXDeclaratorFromFVF(DWORD fvf, D3DVERTEXELEMENT9 declaration[MAX_FVF_DECL_SIZE])
Definition: mesh.c:2034

◆ d3dx9_mesh_ConvertAdjacencyToPointReps()

static HRESULT WINAPI d3dx9_mesh_ConvertAdjacencyToPointReps ( ID3DXMesh *  iface,
const DWORD *  adjacency,
DWORD *  point_reps 
)
static

Definition at line 1103 of file mesh.c.

1105{
1106 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
1107 uint16_t *indices_16bit = NULL;
1108 uint32_t *new_indices = NULL;
1110 unsigned int face, i;
1111 HRESULT hr;
1112
1113 TRACE("iface %p, adjacency %p, point_reps %p.\n", iface, adjacency, point_reps);
1114
1115 if (!adjacency)
1116 {
1117 WARN("NULL adjacency.\n");
1118 return D3DERR_INVALIDCALL;
1119 }
1120
1121 if (!point_reps)
1122 {
1123 WARN("NULL point_reps.\n");
1124 return D3DERR_INVALIDCALL;
1125 }
1126
1127 /* Should never happen as CreateMesh does not allow meshes with 0 faces. */
1128 if (!mesh->numfaces)
1129 {
1130 ERR("Number of faces was zero.\n");
1131 return D3DERR_INVALIDCALL;
1132 }
1133
1134 if (!(new_indices = malloc(3 * mesh->numfaces * sizeof(*indices))))
1135 return E_OUTOFMEMORY;
1136
1137 if (mesh->options & D3DXMESH_32BIT)
1138 {
1139 if (FAILED(hr = iface->lpVtbl->LockIndexBuffer(iface, D3DLOCK_READONLY, (void **)&indices)))
1140 goto cleanup;
1141 memcpy(new_indices, indices, 3 * mesh->numfaces * sizeof(*indices));
1142 }
1143 else
1144 {
1145 /* Make a widening copy of indices_16bit into indices and new_indices
1146 * in order to re-use the helper function. */
1147 if (FAILED(hr = iface->lpVtbl->LockIndexBuffer(iface, D3DLOCK_READONLY, (void **)&indices_16bit)))
1148 goto cleanup;
1149
1150 if (!(indices = malloc(3 * mesh->numfaces * sizeof(*indices))))
1151 {
1152 hr = E_OUTOFMEMORY;
1153 goto cleanup;
1154 }
1155 for (i = 0; i < 3 * mesh->numfaces; ++i)
1156 {
1157 new_indices[i] = indices_16bit[i];
1158 indices[i] = indices_16bit[i];
1159 }
1160 }
1161
1162 /* Vertices are ordered sequentially in the point representation. */
1163 for (i = 0; i < mesh->numvertices; ++i)
1164 point_reps[i] = i;
1165
1166 /* Propagate vertices with low indices so as few vertices as possible are
1167 * used in the mesh. */
1168 for (face = 0; face < mesh->numfaces; ++face)
1169 {
1170 if (FAILED(hr = propagate_face_vertices(adjacency, point_reps, indices, new_indices, face, mesh->numfaces)))
1171 goto cleanup;
1172 }
1173 /* Go in opposite direction to catch all face orderings. */
1174 for (face = 0; face < mesh->numfaces; ++face)
1175 {
1176 if (FAILED(hr = propagate_face_vertices(adjacency, point_reps, indices, new_indices,
1177 (mesh->numfaces - 1) - face, mesh->numfaces)))
1178 goto cleanup;
1179 }
1180
1181 hr = D3D_OK;
1182
1183 cleanup:
1184 if (mesh->options & D3DXMESH_32BIT)
1185 {
1186 if (indices)
1187 iface->lpVtbl->UnlockIndexBuffer(iface);
1188 }
1189 else
1190 {
1191 if (indices_16bit)
1192 iface->lpVtbl->UnlockIndexBuffer(iface);
1193 free(indices);
1194 }
1195 free(new_indices);
1196 return hr;
1197}
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
UINT32 uint32_t
Definition: types.h:75
static HRESULT propagate_face_vertices(const DWORD *adjacency, DWORD *point_reps, const uint32_t *indices, uint32_t *new_indices, unsigned int face_idx, unsigned int face_count)
Definition: mesh.c:1054
WORD face[3]
Definition: mesh.c:4854
unsigned short uint16_t
Definition: stdint.h:35
GLenum GLuint GLint GLenum face
Definition: glext.h:7025

◆ d3dx9_mesh_ConvertPointRepsToAdjacency()

static HRESULT WINAPI d3dx9_mesh_ConvertPointRepsToAdjacency ( ID3DXMesh *  iface,
const DWORD *  point_reps,
DWORD *  adjacency 
)
static

Definition at line 953 of file mesh.c.

955{
956 HRESULT hr;
957 DWORD num_faces = iface->lpVtbl->GetNumFaces(iface);
958 DWORD num_vertices = iface->lpVtbl->GetNumVertices(iface);
959 DWORD options = iface->lpVtbl->GetOptions(iface);
960 BOOL indices_are_16_bit = !(options & D3DXMESH_32BIT);
961 DWORD *ib = NULL;
962 void *ib_ptr = NULL;
963 DWORD face;
964 DWORD edge;
965 struct edge_face_map edge_face_map = {0};
966 const DWORD *point_reps_ptr = NULL;
967 DWORD *id_point_reps = NULL;
968
969 TRACE("iface %p, point_reps %p, adjacency %p.\n", iface, point_reps, adjacency);
970
971 if (!adjacency) return D3DERR_INVALIDCALL;
972
973 if (!point_reps) /* Identity point reps */
974 {
975 id_point_reps = generate_identity_point_reps(num_vertices);
976 if (!id_point_reps)
977 {
979 goto cleanup;
980 }
981
982 point_reps_ptr = id_point_reps;
983 }
984 else
985 {
986 point_reps_ptr = point_reps;
987 }
988
989 hr = iface->lpVtbl->LockIndexBuffer(iface, D3DLOCK_READONLY, &ib_ptr);
990 if (FAILED(hr)) goto cleanup;
991
992 if (indices_are_16_bit)
993 {
994 /* Widen 16 bit to 32 bit */
995 DWORD i;
996 WORD *ib_16bit = ib_ptr;
997 ib = malloc(3 * num_faces * sizeof(DWORD));
998 if (!ib)
999 {
1000 hr = E_OUTOFMEMORY;
1001 goto cleanup;
1002 }
1003 for (i = 0; i < 3 * num_faces; i++)
1004 {
1005 ib[i] = ib_16bit[i];
1006 }
1007 }
1008 else
1009 {
1010 ib = ib_ptr;
1011 }
1012
1013 hr = init_edge_face_map(&edge_face_map, ib, point_reps_ptr, num_faces);
1014 if (FAILED(hr)) goto cleanup;
1015
1016 /* Create adjacency */
1017 for (face = 0; face < num_faces; face++)
1018 {
1019 for (edge = 0; edge < 3; edge++)
1020 {
1021 DWORD v1 = ib[3*face + edge];
1022 DWORD v2 = ib[3*face + (edge+1)%3];
1023 DWORD new_v1 = point_reps_ptr[v1];
1024 DWORD new_v2 = point_reps_ptr[v2];
1025 DWORD adj_face;
1026
1027 adj_face = find_adjacent_face(&edge_face_map, new_v1, new_v2, num_faces);
1028 adjacency[3*face + edge] = adj_face;
1029 }
1030 }
1031
1032 hr = D3D_OK;
1033cleanup:
1034 free(id_point_reps);
1035 if (indices_are_16_bit) free(ib);
1038 if(ib_ptr) iface->lpVtbl->UnlockIndexBuffer(iface);
1039 return hr;
1040}
static DWORD find_adjacent_face(struct edge_face_map *edge_face_map, DWORD vertex1, DWORD vertex2, DWORD num_faces)
Definition: mesh.c:923
static HRESULT init_edge_face_map(struct edge_face_map *edge_face_map, const DWORD *index_buffer, const DWORD *point_reps, DWORD num_faces)
Definition: mesh.c:882
static DWORD * generate_identity_point_reps(DWORD num_vertices)
Definition: mesh.c:936
GLfloat GLfloat v1
Definition: glext.h:6062
GLfloat GLfloat GLfloat v2
Definition: glext.h:6063
struct edge_face * entries
Definition: mesh.c:869
struct list * lists
Definition: mesh.c:868

◆ d3dx9_mesh_DrawSubset()

static HRESULT WINAPI d3dx9_mesh_DrawSubset ( ID3DXMesh *  iface,
DWORD  attrib_id 
)
static

Definition at line 143 of file mesh.c.

144{
145 struct d3dx9_mesh *This = impl_from_ID3DXMesh(iface);
146 HRESULT hr;
147 DWORD face_start;
148 DWORD face_end = 0;
149 DWORD vertex_size;
150
151 TRACE("iface %p, attrib_id %lu.\n", iface, attrib_id);
152
153 if (!This->vertex_declaration)
154 {
155 WARN("Can't draw a mesh with an invalid vertex declaration.\n");
156 return E_FAIL;
157 }
158
159 vertex_size = iface->lpVtbl->GetNumBytesPerVertex(iface);
160
161 hr = IDirect3DDevice9_SetVertexDeclaration(This->device, This->vertex_declaration);
162 if (FAILED(hr)) return hr;
163 hr = IDirect3DDevice9_SetStreamSource(This->device, 0, This->vertex_buffer, 0, vertex_size);
164 if (FAILED(hr)) return hr;
165 hr = IDirect3DDevice9_SetIndices(This->device, This->index_buffer);
166 if (FAILED(hr)) return hr;
167
168 while (face_end < This->numfaces)
169 {
170 for (face_start = face_end; face_start < This->numfaces; face_start++)
171 {
172 if (This->attrib_buffer[face_start] == attrib_id)
173 break;
174 }
175 if (face_start >= This->numfaces)
176 break;
177 for (face_end = face_start + 1; face_end < This->numfaces; face_end++)
178 {
179 if (This->attrib_buffer[face_end] != attrib_id)
180 break;
181 }
182
184 0, 0, This->numvertices, face_start * 3, face_end - face_start);
185 if (FAILED(hr)) return hr;
186 }
187
188 return D3D_OK;
189}
@ D3DPT_TRIANGLELIST
Definition: d3d8types.h:721
#define IDirect3DDevice9_SetIndices(p, a)
Definition: d3d9.h:1439
#define IDirect3DDevice9_DrawIndexedPrimitive(p, a, b, c, d, e, f)
Definition: d3d9.h:1417
#define IDirect3DDevice9_SetStreamSource(p, a, b, c, d)
Definition: d3d9.h:1435
#define IDirect3DDevice9_SetVertexDeclaration(p, a)
Definition: d3d9.h:1422
#define E_FAIL
Definition: ddrawi.h:102
DWORD numfaces
Definition: mesh.c:50

◆ d3dx9_mesh_GenerateAdjacency()

static HRESULT WINAPI d3dx9_mesh_GenerateAdjacency ( ID3DXMesh *  iface,
float  epsilon,
DWORD *  adjacency 
)
static

Definition at line 1214 of file mesh.c.

1215{
1216 struct d3dx9_mesh *This = impl_from_ID3DXMesh(iface);
1217 HRESULT hr;
1218 BYTE *vertices = NULL;
1219 const DWORD *indices = NULL;
1220 DWORD vertex_size;
1222 /* sort the vertices by (x + y + z) to quickly find coincident vertices */
1223 struct vertex_metadata *sorted_vertices;
1224 /* shared_indices links together identical indices in the index buffer so
1225 * that adjacency checks can be limited to faces sharing a vertex */
1226 DWORD *shared_indices = NULL;
1227 const FLOAT epsilon_sq = epsilon * epsilon;
1228 DWORD i;
1229
1230 TRACE("iface %p, epsilon %.8e, adjacency %p.\n", iface, epsilon, adjacency);
1231
1232 if (!adjacency)
1233 return D3DERR_INVALIDCALL;
1234
1235 buffer_size = This->numfaces * 3 * sizeof(*shared_indices) + This->numvertices * sizeof(*sorted_vertices);
1236 if (!(This->options & D3DXMESH_32BIT))
1237 buffer_size += This->numfaces * 3 * sizeof(*indices);
1238 shared_indices = malloc(buffer_size);
1239 if (!shared_indices)
1240 return E_OUTOFMEMORY;
1241 sorted_vertices = (struct vertex_metadata*)(shared_indices + This->numfaces * 3);
1242
1243 hr = iface->lpVtbl->LockVertexBuffer(iface, D3DLOCK_READONLY, (void**)&vertices);
1244 if (FAILED(hr)) goto cleanup;
1245 hr = iface->lpVtbl->LockIndexBuffer(iface, D3DLOCK_READONLY, (void**)&indices);
1246 if (FAILED(hr)) goto cleanup;
1247
1248 if (!(This->options & D3DXMESH_32BIT)) {
1249 const WORD *word_indices = (const WORD*)indices;
1250 DWORD *dword_indices = (DWORD*)(sorted_vertices + This->numvertices);
1251 indices = dword_indices;
1252 for (i = 0; i < This->numfaces * 3; i++)
1253 *dword_indices++ = *word_indices++;
1254 }
1255
1256 vertex_size = iface->lpVtbl->GetNumBytesPerVertex(iface);
1257 for (i = 0; i < This->numvertices; i++) {
1258 D3DXVECTOR3 *vertex = (D3DXVECTOR3*)(vertices + vertex_size * i);
1259 sorted_vertices[i].first_shared_index = -1;
1260 sorted_vertices[i].key = vertex->x + vertex->y + vertex->z;
1261 sorted_vertices[i].vertex_index = i;
1262 }
1263 for (i = 0; i < This->numfaces * 3; i++) {
1264 DWORD *first_shared_index = &sorted_vertices[indices[i]].first_shared_index;
1265 shared_indices[i] = *first_shared_index;
1267 adjacency[i] = -1;
1268 }
1269 qsort(sorted_vertices, This->numvertices, sizeof(*sorted_vertices), compare_vertex_keys);
1270
1271 for (i = 0; i < This->numvertices; i++) {
1272 struct vertex_metadata *sorted_vertex_a = &sorted_vertices[i];
1273 D3DXVECTOR3 *vertex_a = (D3DXVECTOR3*)(vertices + sorted_vertex_a->vertex_index * vertex_size);
1274 DWORD shared_index_a = sorted_vertex_a->first_shared_index;
1275
1276 while (shared_index_a != -1) {
1277 DWORD j = i;
1278 DWORD shared_index_b = shared_indices[shared_index_a];
1279 struct vertex_metadata *sorted_vertex_b = sorted_vertex_a;
1280
1281 while (TRUE) {
1282 while (shared_index_b != -1) {
1283 /* faces are adjacent if they have another coincident vertex */
1284 DWORD base_a = (shared_index_a / 3) * 3;
1285 DWORD base_b = (shared_index_b / 3) * 3;
1286 BOOL adjacent = FALSE;
1287 int k;
1288
1289 for (k = 0; k < 3; k++) {
1290 if (adjacency[base_b + k] == shared_index_a / 3) {
1291 adjacent = TRUE;
1292 break;
1293 }
1294 }
1295 if (!adjacent) {
1296 for (k = 1; k <= 2; k++) {
1297 DWORD vertex_index_a = base_a + (shared_index_a + k) % 3;
1298 DWORD vertex_index_b = base_b + (shared_index_b + (3 - k)) % 3;
1299 adjacent = indices[vertex_index_a] == indices[vertex_index_b];
1300 if (!adjacent && epsilon >= 0.0f) {
1301 D3DXVECTOR3 delta = {0.0f, 0.0f, 0.0f};
1302 FLOAT length_sq;
1303
1304 D3DXVec3Subtract(&delta,
1305 (D3DXVECTOR3*)(vertices + indices[vertex_index_a] * vertex_size),
1306 (D3DXVECTOR3*)(vertices + indices[vertex_index_b] * vertex_size));
1307 length_sq = D3DXVec3LengthSq(&delta);
1308 adjacent = epsilon == 0.0f ? length_sq == 0.0f : length_sq < epsilon_sq;
1309 }
1310 if (adjacent) {
1311 DWORD adj_a = base_a + 2 - (vertex_index_a + shared_index_a + 1) % 3;
1312 DWORD adj_b = base_b + 2 - (vertex_index_b + shared_index_b + 1) % 3;
1313 if (adjacency[adj_a] == -1 && adjacency[adj_b] == -1) {
1314 adjacency[adj_a] = base_b / 3;
1315 adjacency[adj_b] = base_a / 3;
1316 break;
1317 }
1318 }
1319 }
1320 }
1321
1322 shared_index_b = shared_indices[shared_index_b];
1323 }
1324 while (++j < This->numvertices) {
1325 D3DXVECTOR3 *vertex_b;
1326
1327 sorted_vertex_b++;
1328 if (sorted_vertex_b->key - sorted_vertex_a->key > epsilon * 3.0f) {
1329 /* no more coincident vertices to try */
1330 j = This->numvertices;
1331 break;
1332 }
1333 /* check for coincidence */
1334 vertex_b = (D3DXVECTOR3*)(vertices + sorted_vertex_b->vertex_index * vertex_size);
1335 if (fabsf(vertex_a->x - vertex_b->x) <= epsilon &&
1336 fabsf(vertex_a->y - vertex_b->y) <= epsilon &&
1337 fabsf(vertex_a->z - vertex_b->z) <= epsilon)
1338 {
1339 break;
1340 }
1341 }
1342 if (j >= This->numvertices)
1343 break;
1344 shared_index_b = sorted_vertex_b->first_shared_index;
1345 }
1346
1347 sorted_vertex_a->first_shared_index = shared_indices[sorted_vertex_a->first_shared_index];
1348 shared_index_a = sorted_vertex_a->first_shared_index;
1349 }
1350 }
1351
1352 hr = D3D_OK;
1353cleanup:
1354 if (indices) iface->lpVtbl->UnlockIndexBuffer(iface);
1355 if (vertices) iface->lpVtbl->UnlockVertexBuffer(iface);
1356 free(shared_indices);
1357 return hr;
1358}
static int __cdecl compare_vertex_keys(const void *a, const void *b)
Definition: mesh.c:1205
_ACRTIMP float __cdecl fabsf(float)
_ACRTIMP void __cdecl qsort(void *, size_t, size_t, int(__cdecl *)(const void *, const void *))
int k
Definition: mpi.c:3369
wchar_t const *const size_t const buffer_size
Definition: stat.cpp:95
DWORD first_shared_index
Definition: mesh.c:1202
float key
Definition: mesh.c:1200
DWORD vertex_index
Definition: mesh.c:1201
Definition: mesh.c:4665

◆ d3dx9_mesh_GetAttributeTable()

static HRESULT WINAPI d3dx9_mesh_GetAttributeTable ( ID3DXMesh *  iface,
D3DXATTRIBUTERANGE *  attrib_table,
DWORD *  attrib_table_size 
)
static

Definition at line 842 of file mesh.c.

844{
845 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
846
847 TRACE("iface %p, attrib_table %p, attrib_table_size %p.\n",
849
851 *attrib_table_size = mesh->attrib_table_size;
852
853 if (attrib_table)
854 memcpy(attrib_table, mesh->attrib_table, mesh->attrib_table_size * sizeof(*attrib_table));
855
856 return D3D_OK;
857}

◆ d3dx9_mesh_GetDeclaration()

static HRESULT WINAPI d3dx9_mesh_GetDeclaration ( ID3DXMesh *  iface,
D3DVERTEXELEMENT9  declaration[MAX_FVF_DECL_SIZE] 
)
static

Definition at line 223 of file mesh.c.

224{
225 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
226
227 TRACE("iface %p, declaration %p.\n", iface, declaration);
228
229 if (!declaration)
230 return D3DERR_INVALIDCALL;
231
232 copy_declaration(declaration, mesh->cached_declaration, mesh->num_elem);
233
234 return D3D_OK;
235}
static void copy_declaration(D3DVERTEXELEMENT9 *dst, const D3DVERTEXELEMENT9 *src, UINT num_elem)
Definition: mesh.c:218

◆ d3dx9_mesh_GetDevice()

static HRESULT WINAPI d3dx9_mesh_GetDevice ( struct ID3DXMesh *  iface,
struct IDirect3DDevice9 **  device 
)
static

Definition at line 255 of file mesh.c.

256{
257 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
258
259 TRACE("iface %p, device %p.\n", iface, device);
260
261 if (!device)
262 return D3DERR_INVALIDCALL;
263 *device = mesh->device;
265
266 return D3D_OK;
267}
#define IDirect3DDevice9_AddRef(p)
Definition: d3d9.h:1335

◆ d3dx9_mesh_GetFVF()

static DWORD WINAPI d3dx9_mesh_GetFVF ( ID3DXMesh *  iface)
static

Definition at line 209 of file mesh.c.

210{
211 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
212
213 TRACE("iface %p.\n", iface);
214
215 return mesh->fvf;
216}
DWORD fvf
Definition: mesh.c:196

◆ d3dx9_mesh_GetIndexBuffer()

static HRESULT WINAPI d3dx9_mesh_GetIndexBuffer ( struct ID3DXMesh *  iface,
struct IDirect3DIndexBuffer9 **  index_buffer 
)
static

Definition at line 789 of file mesh.c.

791{
792 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
793
794 TRACE("iface %p, index_buffer %p.\n", iface, index_buffer);
795
796 if (!index_buffer)
797 return D3DERR_INVALIDCALL;
798 *index_buffer = mesh->index_buffer;
799 IDirect3DIndexBuffer9_AddRef(mesh->index_buffer);
800
801 return D3D_OK;
802}
#define IDirect3DIndexBuffer9_AddRef(p)
Definition: d3d9.h:591
IDirect3DIndexBuffer9 * index_buffer
Definition: mesh.c:60

◆ d3dx9_mesh_GetNumBytesPerVertex()

static DWORD WINAPI d3dx9_mesh_GetNumBytesPerVertex ( ID3DXMesh *  iface)
static

Definition at line 237 of file mesh.c.

238{
239 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
240
241 TRACE("iface %p.\n", iface);
242
243 return mesh->vertex_declaration_size;
244}

◆ d3dx9_mesh_GetNumFaces()

static DWORD WINAPI d3dx9_mesh_GetNumFaces ( ID3DXMesh *  iface)
static

Definition at line 191 of file mesh.c.

192{
193 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
194
195 TRACE("iface %p.\n", iface);
196
197 return mesh->numfaces;
198}

◆ d3dx9_mesh_GetNumVertices()

static DWORD WINAPI d3dx9_mesh_GetNumVertices ( ID3DXMesh *  iface)
static

Definition at line 200 of file mesh.c.

201{
202 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
203
204 TRACE("iface %p.\n", iface);
205
206 return mesh->numvertices;
207}

◆ d3dx9_mesh_GetOptions()

static DWORD WINAPI d3dx9_mesh_GetOptions ( ID3DXMesh *  iface)
static

Definition at line 246 of file mesh.c.

247{
248 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
249
250 TRACE("iface %p.\n", iface);
251
252 return mesh->options;
253}

◆ d3dx9_mesh_GetVertexBuffer()

static HRESULT WINAPI d3dx9_mesh_GetVertexBuffer ( struct ID3DXMesh *  iface,
struct IDirect3DVertexBuffer9 **  vertex_buffer 
)
static

Definition at line 774 of file mesh.c.

776{
777 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
778
779 TRACE("iface %p, vertex_buffer %p.\n", iface, vertex_buffer);
780
781 if (!vertex_buffer)
782 return D3DERR_INVALIDCALL;
783 *vertex_buffer = mesh->vertex_buffer;
784 IDirect3DVertexBuffer9_AddRef(mesh->vertex_buffer);
785
786 return D3D_OK;
787}

◆ d3dx9_mesh_LockAttributeBuffer()

static HRESULT WINAPI d3dx9_mesh_LockAttributeBuffer ( ID3DXMesh *  iface,
DWORD  flags,
DWORD **  data 
)
static

Definition at line 1419 of file mesh.c.

1420{
1421 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
1422
1423 TRACE("iface %p, flags %#lx, data %p.\n", iface, flags, data);
1424
1425 InterlockedIncrement(&mesh->attrib_buffer_lock_count);
1426
1427 if (!(flags & D3DLOCK_READONLY))
1428 {
1429 D3DXATTRIBUTERANGE *attrib_table = mesh->attrib_table;
1430 mesh->attrib_table_size = 0;
1431 mesh->attrib_table = NULL;
1433 }
1434
1435 *data = mesh->attrib_buffer;
1436
1437 return D3D_OK;
1438}
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLbitfield flags
Definition: glext.h:7161

◆ d3dx9_mesh_LockIndexBuffer()

static HRESULT WINAPI d3dx9_mesh_LockIndexBuffer ( ID3DXMesh *  iface,
DWORD  flags,
void **  data 
)
static

Definition at line 822 of file mesh.c.

823{
824 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
825
826 TRACE("iface %p, flags %#lx, data %p.\n", iface, flags, data);
827
828 return IDirect3DIndexBuffer9_Lock(mesh->index_buffer, 0, 0, data, flags);
829}
#define IDirect3DIndexBuffer9_Lock(p, a, b, c, d)
Definition: d3d9.h:603

◆ d3dx9_mesh_LockVertexBuffer()

static HRESULT WINAPI d3dx9_mesh_LockVertexBuffer ( ID3DXMesh *  iface,
DWORD  flags,
void **  data 
)
static

Definition at line 804 of file mesh.c.

805{
806 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
807
808 TRACE("iface %p, flags %#lx, data %p.\n", iface, flags, data);
809
810 return IDirect3DVertexBuffer9_Lock(mesh->vertex_buffer, 0, 0, data, flags);
811}
#define IDirect3DVertexBuffer9_Lock(p, a, b, c, d)
Definition: d3d9.h:535

◆ d3dx9_mesh_Optimize()

static HRESULT WINAPI d3dx9_mesh_Optimize ( ID3DXMesh *  iface,
DWORD  flags,
const DWORD *  adjacency_in,
DWORD *  adjacency_out,
DWORD *  face_remap,
ID3DXBuffer **  vertex_remap,
ID3DXMesh **  opt_mesh 
)
static

Definition at line 1457 of file mesh.c.

1459{
1460 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
1461 HRESULT hr;
1463 ID3DXMesh *optimized_mesh;
1464
1465 TRACE("iface %p, flags %#lx, adjacency_in %p, adjacency_out %p, face_remap %p, vertex_remap %p, opt_mesh %p.\n",
1466 iface, flags, adjacency_in, adjacency_out, face_remap, vertex_remap, opt_mesh);
1467
1468 if (!opt_mesh)
1469 return D3DERR_INVALIDCALL;
1470
1471 hr = iface->lpVtbl->GetDeclaration(iface, declaration);
1472 if (FAILED(hr)) return hr;
1473
1474 if (FAILED(hr = iface->lpVtbl->CloneMesh(iface, mesh->options, declaration, mesh->device, &optimized_mesh)))
1475 return hr;
1476
1477 hr = optimized_mesh->lpVtbl->OptimizeInplace(optimized_mesh, flags, adjacency_in, adjacency_out, face_remap, vertex_remap);
1478 if (SUCCEEDED(hr))
1479 *opt_mesh = optimized_mesh;
1480 else
1481 IUnknown_Release(optimized_mesh);
1482 return hr;
1483}
#define SUCCEEDED(hr)
Definition: intsafe.h:50

◆ d3dx9_mesh_OptimizeInplace()

static HRESULT WINAPI d3dx9_mesh_OptimizeInplace ( ID3DXMesh *  iface,
DWORD  flags,
const DWORD *  adjacency_in,
DWORD *  adjacency_out,
DWORD *  face_remap_out,
ID3DXBuffer **  vertex_remap_out 
)
static

Definition at line 1639 of file mesh.c.

1641{
1642 struct d3dx9_mesh *This = impl_from_ID3DXMesh(iface);
1643 void *indices = NULL;
1645 HRESULT hr;
1646 ID3DXBuffer *vertex_remap = NULL;
1647 DWORD *face_remap = NULL; /* old -> new mapping */
1648 DWORD *dword_indices = NULL;
1649 DWORD new_num_vertices = 0;
1650 DWORD new_num_alloc_vertices = 0;
1651 IDirect3DVertexBuffer9 *vertex_buffer = NULL;
1652 DWORD *sorted_attrib_buffer = NULL;
1653 DWORD i;
1654
1655 TRACE("iface %p, flags %#lx, adjacency_in %p, adjacency_out %p, face_remap_out %p, vertex_remap_out %p.\n",
1656 iface, flags, adjacency_in, adjacency_out, face_remap_out, vertex_remap_out);
1657
1658 if (!flags)
1659 return D3DERR_INVALIDCALL;
1660 if (!adjacency_in && (flags & (D3DXMESHOPT_VERTEXCACHE | D3DXMESHOPT_STRIPREORDER)))
1661 return D3DERR_INVALIDCALL;
1663 return D3DERR_INVALIDCALL;
1664
1666 {
1668 FIXME("D3DXMESHOPT_VERTEXCACHE not implemented.\n");
1670 FIXME("D3DXMESHOPT_STRIPREORDER not implemented.\n");
1671 return E_NOTIMPL;
1672 }
1673
1674 hr = iface->lpVtbl->LockIndexBuffer(iface, 0, &indices);
1675 if (FAILED(hr)) goto cleanup;
1676
1677 dword_indices = malloc(This->numfaces * 3 * sizeof(DWORD));
1678 if (!dword_indices) return E_OUTOFMEMORY;
1679 if (This->options & D3DXMESH_32BIT) {
1680 memcpy(dword_indices, indices, This->numfaces * 3 * sizeof(DWORD));
1681 } else {
1682 WORD *word_indices = indices;
1683 for (i = 0; i < This->numfaces * 3; i++)
1684 dword_indices[i] = *word_indices++;
1685 }
1686
1688 {
1689 new_num_alloc_vertices = This->numvertices;
1690 hr = compact_mesh(This, dword_indices, &new_num_vertices, &vertex_remap);
1691 if (FAILED(hr)) goto cleanup;
1692 } else if (flags & D3DXMESHOPT_ATTRSORT) {
1694 FIXME("D3DXMESHOPT_ATTRSORT vertex reordering not implemented.\n");
1695
1696 hr = iface->lpVtbl->LockAttributeBuffer(iface, 0, &attrib_buffer);
1697 if (FAILED(hr)) goto cleanup;
1698
1699 hr = remap_faces_for_attrsort(This, dword_indices, attrib_buffer, &sorted_attrib_buffer, &face_remap);
1700 if (FAILED(hr)) goto cleanup;
1701 }
1702
1703 if (vertex_remap)
1704 {
1705 /* reorder the vertices using vertex_remap */
1706 D3DVERTEXBUFFER_DESC vertex_desc;
1707 DWORD *vertex_remap_ptr = ID3DXBuffer_GetBufferPointer(vertex_remap);
1708 DWORD vertex_size = iface->lpVtbl->GetNumBytesPerVertex(iface);
1709 BYTE *orig_vertices;
1710 BYTE *new_vertices;
1711
1712 hr = IDirect3DVertexBuffer9_GetDesc(This->vertex_buffer, &vertex_desc);
1713 if (FAILED(hr)) goto cleanup;
1714
1715 hr = IDirect3DDevice9_CreateVertexBuffer(This->device, new_num_alloc_vertices * vertex_size,
1716 vertex_desc.Usage, This->fvf, vertex_desc.Pool, &vertex_buffer, NULL);
1717 if (FAILED(hr)) goto cleanup;
1718
1719 hr = IDirect3DVertexBuffer9_Lock(This->vertex_buffer, 0, 0, (void**)&orig_vertices, D3DLOCK_READONLY);
1720 if (FAILED(hr)) goto cleanup;
1721
1722 hr = IDirect3DVertexBuffer9_Lock(vertex_buffer, 0, 0, (void**)&new_vertices, 0);
1723 if (FAILED(hr)) {
1724 IDirect3DVertexBuffer9_Unlock(This->vertex_buffer);
1725 goto cleanup;
1726 }
1727
1728 for (i = 0; i < new_num_vertices; i++)
1729 memcpy(new_vertices + i * vertex_size, orig_vertices + vertex_remap_ptr[i] * vertex_size, vertex_size);
1730
1731 IDirect3DVertexBuffer9_Unlock(This->vertex_buffer);
1733 } else if (vertex_remap_out) {
1734 DWORD *vertex_remap_ptr;
1735
1736 hr = D3DXCreateBuffer(This->numvertices * sizeof(DWORD), &vertex_remap);
1737 if (FAILED(hr)) goto cleanup;
1738 vertex_remap_ptr = ID3DXBuffer_GetBufferPointer(vertex_remap);
1739 for (i = 0; i < This->numvertices; i++)
1740 *vertex_remap_ptr++ = i;
1741 }
1742
1744 {
1747
1748 attrib_table_size = count_attributes(sorted_attrib_buffer, This->numfaces);
1750 if (!attrib_table) {
1751 hr = E_OUTOFMEMORY;
1752 goto cleanup;
1753 }
1754
1755 memcpy(attrib_buffer, sorted_attrib_buffer, This->numfaces * sizeof(*attrib_buffer));
1756
1757 /* reorder the indices using face_remap */
1758 if (This->options & D3DXMESH_32BIT) {
1759 for (i = 0; i < This->numfaces; i++)
1760 memcpy((DWORD*)indices + face_remap[i] * 3, dword_indices + i * 3, 3 * sizeof(DWORD));
1761 } else {
1762 WORD *word_indices = indices;
1763 for (i = 0; i < This->numfaces; i++) {
1764 DWORD new_pos = face_remap[i] * 3;
1765 DWORD old_pos = i * 3;
1766 word_indices[new_pos++] = dword_indices[old_pos++];
1767 word_indices[new_pos++] = dword_indices[old_pos++];
1768 word_indices[new_pos] = dword_indices[old_pos];
1769 }
1770 }
1771
1773 This->options & D3DXMESH_32BIT, attrib_table);
1774
1775 free(This->attrib_table);
1776 This->attrib_table = attrib_table;
1777 This->attrib_table_size = attrib_table_size;
1778 } else {
1779 if (This->options & D3DXMESH_32BIT) {
1780 memcpy(indices, dword_indices, This->numfaces * 3 * sizeof(DWORD));
1781 } else {
1782 WORD *word_indices = indices;
1783 for (i = 0; i < This->numfaces * 3; i++)
1784 *word_indices++ = dword_indices[i];
1785 }
1786 }
1787
1788 if (adjacency_out) {
1789 if (face_remap) {
1790 for (i = 0; i < This->numfaces; i++) {
1791 DWORD old_pos = i * 3;
1792 DWORD new_pos = face_remap[i] * 3;
1793
1794 adjacency_out[new_pos++] = adjacency_remap(face_remap, adjacency_in[old_pos++]);
1795 adjacency_out[new_pos++] = adjacency_remap(face_remap, adjacency_in[old_pos++]);
1796 adjacency_out[new_pos] = adjacency_remap(face_remap, adjacency_in[old_pos]);
1797 }
1798 } else {
1799 memcpy(adjacency_out, adjacency_in, This->numfaces * 3 * sizeof(*adjacency_out));
1800 }
1801 }
1802 if (face_remap_out) {
1803 if (face_remap) {
1804 for (i = 0; i < This->numfaces; i++)
1805 face_remap_out[face_remap[i]] = i;
1806 } else {
1807 for (i = 0; i < This->numfaces; i++)
1808 face_remap_out[i] = i;
1809 }
1810 }
1811 if (vertex_remap_out)
1812 *vertex_remap_out = vertex_remap;
1813 vertex_remap = NULL;
1814
1815 if (vertex_buffer) {
1816 IDirect3DVertexBuffer9_Release(This->vertex_buffer);
1817 This->vertex_buffer = vertex_buffer;
1819 This->numvertices = new_num_vertices;
1820 }
1821
1822 hr = D3D_OK;
1823cleanup:
1824 free(sorted_attrib_buffer);
1825 free(face_remap);
1826 free(dword_indices);
1827 if (vertex_remap) ID3DXBuffer_Release(vertex_remap);
1829 if (attrib_buffer) iface->lpVtbl->UnlockAttributeBuffer(iface);
1830 if (indices) iface->lpVtbl->UnlockIndexBuffer(iface);
1831 return hr;
1832}
#define IDirect3DVertexBuffer9_Unlock(p)
Definition: d3d9.h:536
#define IDirect3DVertexBuffer9_GetDesc(p, a)
Definition: d3d9.h:537
#define IDirect3DDevice9_CreateVertexBuffer(p, a, b, c, d, e, f)
Definition: d3d9.h:1361
struct ID3DXBuffer ID3DXBuffer
Definition: d3dx8core.h:51
#define E_NOTIMPL
Definition: ddrawi.h:99
static DWORD adjacency_remap(DWORD *face_remap, DWORD index)
Definition: mesh.c:1632
static void fill_attribute_table(DWORD *attrib_buffer, DWORD numfaces, void *indices, BOOL is_32bit_indices, D3DXATTRIBUTERANGE *attrib_table)
Definition: mesh.c:1543
static HRESULT compact_mesh(struct d3dx9_mesh *This, DWORD *indices, DWORD *new_num_vertices, ID3DXBuffer **vertex_remap)
Definition: mesh.c:1487
static HRESULT remap_faces_for_attrsort(struct d3dx9_mesh *This, const DWORD *indices, DWORD *attrib_buffer, DWORD **sorted_attrib_buffer, DWORD **face_remap)
Definition: mesh.c:1597
static DWORD count_attributes(const DWORD *attrib_buffer, DWORD numfaces)
Definition: mesh.c:1529
#define ID3DXBuffer_Release(p)
Definition: d3dx9core.h:83
@ D3DXMESHOPT_STRIPREORDER
Definition: d3dx9mesh.h:76
@ D3DXMESHOPT_IGNOREVERTS
Definition: d3dx9mesh.h:77
@ D3DXMESHOPT_ATTRSORT
Definition: d3dx9mesh.h:74
@ D3DXMESHOPT_VERTEXCACHE
Definition: d3dx9mesh.h:75
@ D3DXMESHOPT_COMPACT
Definition: d3dx9mesh.h:73

◆ d3dx9_mesh_QueryInterface()

static HRESULT WINAPI d3dx9_mesh_QueryInterface ( ID3DXMesh *  iface,
REFIID  riid,
void **  out 
)
static

Definition at line 93 of file mesh.c.

94{
95 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
96
98 IsEqualGUID(riid, &IID_ID3DXBaseMesh) ||
99 IsEqualGUID(riid, &IID_ID3DXMesh))
100 {
101 iface->lpVtbl->AddRef(iface);
102 *out = iface;
103 return S_OK;
104 }
105
106 WARN("Interface %s not found.\n", debugstr_guid(riid));
107
108 return E_NOINTERFACE;
109}
const GUID IID_IUnknown
REFIID riid
Definition: atlbase.h:39
#define debugstr_guid
Definition: kernel32.h:35
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
#define E_NOINTERFACE
Definition: winerror.h:3479

◆ d3dx9_mesh_Release()

static ULONG WINAPI d3dx9_mesh_Release ( ID3DXMesh *  iface)
static

Definition at line 121 of file mesh.c.

122{
123 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
124 ULONG refcount = InterlockedDecrement(&mesh->ref);
125
126 TRACE("%p decreasing refcount to %lu.\n", mesh, refcount);
127
128 if (!refcount)
129 {
130 IDirect3DIndexBuffer9_Release(mesh->index_buffer);
131 IDirect3DVertexBuffer9_Release(mesh->vertex_buffer);
132 if (mesh->vertex_declaration)
133 IDirect3DVertexDeclaration9_Release(mesh->vertex_declaration);
135 free(mesh->attrib_buffer);
136 free(mesh->attrib_table);
137 free(mesh);
138 }
139
140 return refcount;
141}
#define InterlockedDecrement
Definition: armddk.h:52
#define IDirect3DVertexDeclaration9_Release(p)
Definition: d3d9.h:1013
#define IDirect3DDevice9_Release(p)
Definition: d3d9.h:1336
#define IDirect3DIndexBuffer9_Release(p)
Definition: d3d9.h:592

◆ d3dx9_mesh_SetAttributeTable()

static HRESULT WINAPI d3dx9_mesh_SetAttributeTable ( ID3DXMesh *  iface,
const D3DXATTRIBUTERANGE *  attrib_table,
DWORD  attrib_table_size 
)
static

Definition at line 1834 of file mesh.c.

1836{
1837 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
1838 D3DXATTRIBUTERANGE *new_table = NULL;
1839
1840 TRACE("iface %p, attrib_table %p, attrib_table_size %lu.\n", iface, attrib_table, attrib_table_size);
1841
1842 if (attrib_table_size) {
1843 size_t size = attrib_table_size * sizeof(*attrib_table);
1844
1845 new_table = malloc(size);
1846 if (!new_table)
1847 return E_OUTOFMEMORY;
1848
1849 CopyMemory(new_table, attrib_table, size);
1850 } else if (attrib_table) {
1851 return D3DERR_INVALIDCALL;
1852 }
1853 free(mesh->attrib_table);
1854 mesh->attrib_table = new_table;
1855 mesh->attrib_table_size = attrib_table_size;
1856
1857 return D3D_OK;
1858}
GLsizeiptr size
Definition: glext.h:5919
#define CopyMemory
Definition: minwinbase.h:29

◆ d3dx9_mesh_UnlockAttributeBuffer()

static HRESULT WINAPI d3dx9_mesh_UnlockAttributeBuffer ( ID3DXMesh *  iface)
static

Definition at line 1440 of file mesh.c.

1441{
1442 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
1443 int lock_count;
1444
1445 TRACE("iface %p.\n", iface);
1446
1447 lock_count = InterlockedDecrement(&mesh->attrib_buffer_lock_count);
1448 if (lock_count < 0)
1449 {
1450 InterlockedIncrement(&mesh->attrib_buffer_lock_count);
1451 return D3DERR_INVALIDCALL;
1452 }
1453
1454 return D3D_OK;
1455}

◆ d3dx9_mesh_UnlockIndexBuffer()

static HRESULT WINAPI d3dx9_mesh_UnlockIndexBuffer ( ID3DXMesh *  iface)
static

Definition at line 831 of file mesh.c.

832{
833 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
834
835 TRACE("iface %p.\n", iface);
836
837 return IDirect3DIndexBuffer9_Unlock(mesh->index_buffer);
838}
#define IDirect3DIndexBuffer9_Unlock(p)
Definition: d3d9.h:604

◆ d3dx9_mesh_UnlockVertexBuffer()

static HRESULT WINAPI d3dx9_mesh_UnlockVertexBuffer ( ID3DXMesh *  iface)
static

Definition at line 813 of file mesh.c.

814{
815 struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface);
816
817 TRACE("iface %p.\n", iface);
818
819 return IDirect3DVertexBuffer9_Unlock(mesh->vertex_buffer);
820}

◆ d3dx9_mesh_UpdateSemantics()

static HRESULT WINAPI d3dx9_mesh_UpdateSemantics ( ID3DXMesh *  iface,
D3DVERTEXELEMENT9  declaration[MAX_FVF_DECL_SIZE] 
)
static

Definition at line 1360 of file mesh.c.

1361{
1362 struct d3dx9_mesh *This = impl_from_ID3DXMesh(iface);
1363 HRESULT hr;
1365 int i;
1366
1367 TRACE("iface %p, declaration %p.\n", iface, declaration);
1368
1369 if (!declaration)
1370 {
1371 WARN("Invalid declaration. Can't use NULL declaration.\n");
1372 return D3DERR_INVALIDCALL;
1373 }
1374
1375 /* New declaration must be same size as original */
1377 if (vertex_declaration_size != This->vertex_declaration_size)
1378 {
1379 WARN("Invalid declaration. New vertex size does not match the original vertex size.\n");
1380 return D3DERR_INVALIDCALL;
1381 }
1382
1383 /* New declaration must not contain non-zero Stream value */
1384 for (i = 0; declaration[i].Stream != 0xff; i++)
1385 {
1386 if (declaration[i].Stream != 0)
1387 {
1388 WARN("Invalid declaration. New declaration contains non-zero Stream value.\n");
1389 return D3DERR_INVALIDCALL;
1390 }
1391 }
1392
1393 This->num_elem = i + 1;
1394 copy_declaration(This->cached_declaration, declaration, This->num_elem);
1395
1396 if (This->vertex_declaration)
1397 IDirect3DVertexDeclaration9_Release(This->vertex_declaration);
1398
1399 /* An application can pass an invalid declaration to UpdateSemantics and
1400 * still expect D3D_OK (see tests). If the declaration is invalid, then
1401 * subsequent calls to DrawSubset will fail. This is handled by setting the
1402 * vertex declaration to NULL.
1403 * GetDeclaration, GetNumBytesPerVertex must, however, use the new
1404 * invalid declaration. This is handled by them using the cached vertex
1405 * declaration instead of the actual vertex declaration.
1406 */
1409 &This->vertex_declaration);
1410 if (FAILED(hr))
1411 {
1412 WARN("Using invalid declaration. Calls to DrawSubset will fail.\n");
1413 This->vertex_declaration = NULL;
1414 }
1415
1416 return D3D_OK;
1417}
#define IDirect3DDevice9_CreateVertexDeclaration(p, a, b)
Definition: d3d9.h:1421
UINT WINAPI D3DXGetDeclVertexSize(const D3DVERTEXELEMENT9 *decl, DWORD stream_idx)
Definition: mesh.c:2321
static IStream Stream
Definition: htmldoc.c:1115
UINT vertex_declaration_size
Definition: mesh.c:57

◆ D3DXBoxBoundProbe()

BOOL WINAPI D3DXBoxBoundProbe ( const D3DXVECTOR3 *  pmin,
const D3DXVECTOR3 *  pmax,
const D3DXVECTOR3 *  prayposition,
const D3DXVECTOR3 *  praydirection 
)

Definition at line 1909 of file mesh.c.

1911{
1912 FLOAT div, tmin, tmax, tymin, tymax, tzmin, tzmax;
1913
1914 div = 1.0f / praydirection->x;
1915 if ( div >= 0.0f )
1916 {
1917 tmin = ( pmin->x - prayposition->x ) * div;
1918 tmax = ( pmax->x - prayposition->x ) * div;
1919 }
1920 else
1921 {
1922 tmin = ( pmax->x - prayposition->x ) * div;
1923 tmax = ( pmin->x - prayposition->x ) * div;
1924 }
1925
1926 if ( tmax < 0.0f ) return FALSE;
1927
1928 div = 1.0f / praydirection->y;
1929 if ( div >= 0.0f )
1930 {
1931 tymin = ( pmin->y - prayposition->y ) * div;
1932 tymax = ( pmax->y - prayposition->y ) * div;
1933 }
1934 else
1935 {
1936 tymin = ( pmax->y - prayposition->y ) * div;
1937 tymax = ( pmin->y - prayposition->y ) * div;
1938 }
1939
1940 if ( ( tymax < 0.0f ) || ( tmin > tymax ) || ( tymin > tmax ) ) return FALSE;
1941
1942 if ( tymin > tmin ) tmin = tymin;
1943 if ( tymax < tmax ) tmax = tymax;
1944
1945 div = 1.0f / praydirection->z;
1946 if ( div >= 0.0f )
1947 {
1948 tzmin = ( pmin->z - prayposition->z ) * div;
1949 tzmax = ( pmax->z - prayposition->z ) * div;
1950 }
1951 else
1952 {
1953 tzmin = ( pmax->z - prayposition->z ) * div;
1954 tzmax = ( pmin->z - prayposition->z ) * div;
1955 }
1956
1957 if ( (tzmax < 0.0f ) || ( tmin > tzmax ) || ( tzmin > tmax ) ) return FALSE;
1958
1959 return TRUE;
1960}
_ACRTIMP div_t __cdecl div(int, int)
Definition: math.c:2081

Referenced by D3DXBoundProbeTest().

◆ D3DXCleanMesh()

HRESULT WINAPI D3DXCleanMesh ( D3DXCLEANTYPE  clean_type,
ID3DXMesh *  mesh_in,
const DWORD *  adjacency_in,
ID3DXMesh **  mesh_out,
DWORD *  adjacency_out,
ID3DXBuffer **  errors_and_warnings 
)

Definition at line 4093 of file mesh.c.

4095{
4096 FIXME("(%u, %p, %p, %p, %p, %p)\n", clean_type, mesh_in, adjacency_in, mesh_out, adjacency_out, errors_and_warnings);
4097
4098 return E_NOTIMPL;
4099}

◆ D3DXComputeBoundingBox()

HRESULT WINAPI D3DXComputeBoundingBox ( const D3DXVECTOR3 *  pfirstposition,
DWORD  numvertices,
DWORD  dwstride,
D3DXVECTOR3 *  pmin,
D3DXVECTOR3 *  pmax 
)

Definition at line 1962 of file mesh.c.

1964{
1966 unsigned int i;
1967
1968 if( !pfirstposition || !pmin || !pmax ) return D3DERR_INVALIDCALL;
1969
1970 *pmin = *pfirstposition;
1971 *pmax = *pmin;
1972
1973 for(i=0; i<numvertices; i++)
1974 {
1975 vec = *( (const D3DXVECTOR3*)((const char*)pfirstposition + dwstride * i) );
1976
1977 if ( vec.x < pmin->x ) pmin->x = vec.x;
1978 if ( vec.x > pmax->x ) pmax->x = vec.x;
1979
1980 if ( vec.y < pmin->y ) pmin->y = vec.y;
1981 if ( vec.y > pmax->y ) pmax->y = vec.y;
1982
1983 if ( vec.z < pmin->z ) pmin->z = vec.z;
1984 if ( vec.z > pmax->z ) pmax->z = vec.z;
1985 }
1986
1987 return D3D_OK;
1988}
FT_Pos x
Definition: ftimage.h:77
FT_Pos y
Definition: ftimage.h:78

Referenced by D3DXComputeBoundingBoxTest().

◆ D3DXComputeBoundingSphere()

HRESULT WINAPI D3DXComputeBoundingSphere ( const D3DXVECTOR3 *  pfirstposition,
DWORD  numvertices,
DWORD  dwstride,
D3DXVECTOR3 *  pcenter,
float *  pradius 
)

Definition at line 1990 of file mesh.c.

1992{
1994 FLOAT d;
1995 unsigned int i;
1996
1997 if( !pfirstposition || !pcenter || !pradius ) return D3DERR_INVALIDCALL;
1998
1999 temp.x = 0.0f;
2000 temp.y = 0.0f;
2001 temp.z = 0.0f;
2002 *pradius = 0.0f;
2003
2004 for(i=0; i<numvertices; i++)
2005 D3DXVec3Add(&temp, &temp, (const D3DXVECTOR3*)((const char*)pfirstposition + dwstride * i));
2006
2007 D3DXVec3Scale(pcenter, &temp, 1.0f / numvertices);
2008
2009 for(i=0; i<numvertices; i++)
2010 {
2011 d = D3DXVec3Length(D3DXVec3Subtract(&temp, (const D3DXVECTOR3*)((const char*)pfirstposition + dwstride * i), pcenter));
2012 if ( d > *pradius ) *pradius = d;
2013 }
2014 return D3D_OK;
2015}
#define d
Definition: ke_i.h:81
static calc_node_t temp
Definition: rpn_ieee.c:38

Referenced by D3DXComputeBoundingSphereTest().

◆ D3DXComputeNormals()

HRESULT WINAPI D3DXComputeNormals ( struct ID3DXBaseMesh *  mesh,
const DWORD *  adjacency 
)

Definition at line 7637 of file mesh.c.

7638{
7639 TRACE("mesh %p, adjacency %p\n", mesh, adjacency);
7640
7641 if (mesh && (ID3DXMeshVtbl *)mesh->lpVtbl != &D3DXMesh_Vtbl)
7642 {
7643 ERR("Invalid virtual table\n");
7644 return D3DERR_INVALIDCALL;
7645 }
7646
7647 return D3DXComputeTangentFrameEx((ID3DXMesh *)mesh, D3DX_DEFAULT, 0,
7650 adjacency, -1.01f, -0.01f, -1.01f, NULL, NULL);
7651}
@ D3DDECLUSAGE_NORMAL
Definition: d3d9types.h:239
HRESULT WINAPI D3DXComputeTangentFrameEx(ID3DXMesh *mesh, DWORD texture_in_semantic, DWORD texture_in_index, DWORD u_partial_out_semantic, DWORD u_partial_out_index, DWORD v_partial_out_semantic, DWORD v_partial_out_index, DWORD normal_out_semantic, DWORD normal_out_index, DWORD options, const DWORD *adjacency, float partial_edge_threshold, float singular_point_threshold, float normal_edge_threshold, ID3DXMesh **mesh_out, ID3DXBuffer **vertex_mapping)
Definition: mesh.c:7409
static const struct ID3DXMeshVtbl D3DXMesh_Vtbl
Definition: mesh.c:1860
#define D3DX_DEFAULT
Definition: d3dx9.h:24
@ D3DXTANGENT_CALCULATE_NORMALS
Definition: d3dx9mesh.h:121
@ D3DXTANGENT_GENERATE_IN_PLACE
Definition: d3dx9mesh.h:122

Referenced by compute_normals_D3DXComputeNormals().

◆ D3DXComputeTangentFrameEx()

HRESULT WINAPI D3DXComputeTangentFrameEx ( ID3DXMesh *  mesh,
DWORD  texture_in_semantic,
DWORD  texture_in_index,
DWORD  u_partial_out_semantic,
DWORD  u_partial_out_index,
DWORD  v_partial_out_semantic,
DWORD  v_partial_out_index,
DWORD  normal_out_semantic,
DWORD  normal_out_index,
DWORD  options,
const DWORD *  adjacency,
float  partial_edge_threshold,
float  singular_point_threshold,
float  normal_edge_threshold,
ID3DXMesh **  mesh_out,
ID3DXBuffer **  vertex_mapping 
)

Definition at line 7409 of file mesh.c.

7414{
7415 HRESULT hr;
7416 void *indices = NULL;
7417 BYTE *vertices = NULL;
7418 DWORD *point_reps = NULL;
7419 size_t normal_size;
7420 BOOL indices_are_32bit;
7421 DWORD i, j, num_faces, num_vertices, vertex_stride;
7423 D3DVERTEXELEMENT9 *position_declaration = NULL, *normal_declaration = NULL;
7425
7426 TRACE("mesh %p, texture_in_semantic %lu, texture_in_index %lu, u_partial_out_semantic %lu, "
7427 "u_partial_out_index %lu, v_partial_out_semantic %lu, v_partial_out_index %lu, "
7428 "normal_out_semantic %lu, normal_out_index %lu, options %#lx, adjacency %p, "
7429 "partial_edge_threshold %.8e, singular_point_threshold %.8e, normal_edge_threshold %.8e, "
7430 "mesh_out %p, vertex_mapping %p.\n",
7431 mesh, texture_in_semantic, texture_in_index, u_partial_out_semantic, u_partial_out_index,
7432 v_partial_out_semantic, v_partial_out_index, normal_out_semantic, normal_out_index,
7433 options, adjacency, partial_edge_threshold, singular_point_threshold,
7434 normal_edge_threshold, mesh_out, vertex_mapping);
7435
7436 if (!mesh)
7437 {
7438 WARN("mesh is NULL\n");
7439 return D3DERR_INVALIDCALL;
7440 }
7441
7442 if (weighting_method == (D3DXTANGENT_WEIGHT_EQUAL | D3DXTANGENT_WEIGHT_BY_AREA))
7443 {
7444 WARN("D3DXTANGENT_WEIGHT_BY_AREA and D3DXTANGENT_WEIGHT_EQUAL are mutally exclusive\n");
7445 return D3DERR_INVALIDCALL;
7446 }
7447
7448 if (u_partial_out_semantic != D3DX_DEFAULT)
7449 {
7450 FIXME("tangent vectors computation is not supported\n");
7451 return E_NOTIMPL;
7452 }
7453
7454 if (v_partial_out_semantic != D3DX_DEFAULT)
7455 {
7456 FIXME("binormal vectors computation is not supported\n");
7457 return E_NOTIMPL;
7458 }
7459
7462 {
7463 FIXME("Unsupported options %#lx.\n", options);
7464 return E_NOTIMPL;
7465 }
7466
7468 {
7469 FIXME("only normals computation is supported\n");
7470 return E_NOTIMPL;
7471 }
7472
7473 if (!(options & D3DXTANGENT_GENERATE_IN_PLACE) || mesh_out || vertex_mapping)
7474 {
7475 FIXME("only D3DXTANGENT_GENERATE_IN_PLACE is supported\n");
7476 return E_NOTIMPL;
7477 }
7478
7479 if (FAILED(hr = mesh->lpVtbl->GetDeclaration(mesh, declaration)))
7480 return hr;
7481
7482 for (i = 0; declaration[i].Stream != 0xff; i++)
7483 {
7484 if (declaration[i].Usage == D3DDECLUSAGE_POSITION && !declaration[i].UsageIndex)
7485 position_declaration = &declaration[i];
7486 if (declaration[i].Usage == normal_out_semantic && declaration[i].UsageIndex == normal_out_index)
7487 normal_declaration = &declaration[i];
7488 }
7489
7490 if (!position_declaration || !normal_declaration)
7491 return D3DERR_INVALIDCALL;
7492
7493 if (normal_declaration->Type == D3DDECLTYPE_FLOAT3)
7494 {
7495 normal_size = sizeof(D3DXVECTOR3);
7496 }
7497 else if (normal_declaration->Type == D3DDECLTYPE_FLOAT4)
7498 {
7499 normal_size = sizeof(D3DXVECTOR4);
7500 }
7501 else
7502 {
7503 WARN("unsupported normals type %u\n", normal_declaration->Type);
7504 return D3DERR_INVALIDCALL;
7505 }
7506
7507 num_faces = mesh->lpVtbl->GetNumFaces(mesh);
7508 num_vertices = mesh->lpVtbl->GetNumVertices(mesh);
7509 vertex_stride = mesh->lpVtbl->GetNumBytesPerVertex(mesh);
7510 indices_are_32bit = mesh->lpVtbl->GetOptions(mesh) & D3DXMESH_32BIT;
7511
7512 point_reps = malloc(num_vertices * sizeof(*point_reps));
7513 if (!point_reps)
7514 {
7515 hr = E_OUTOFMEMORY;
7516 goto done;
7517 }
7518
7519 if (adjacency)
7520 {
7521 if (FAILED(hr = mesh->lpVtbl->ConvertAdjacencyToPointReps(mesh, adjacency, point_reps)))
7522 goto done;
7523 }
7524 else
7525 {
7526 for (i = 0; i < num_vertices; i++)
7527 point_reps[i] = i;
7528 }
7529
7530 if (FAILED(hr = mesh->lpVtbl->LockIndexBuffer(mesh, 0, &indices)))
7531 goto done;
7532
7533 if (FAILED(hr = mesh->lpVtbl->LockVertexBuffer(mesh, 0, (void **)&vertices)))
7534 goto done;
7535
7536 for (i = 0; i < num_vertices; i++)
7537 {
7538 static const D3DXVECTOR4 default_vector = {0.0f, 0.0f, 0.0f, 1.0f};
7539 void *normal = vertices + normal_declaration->Offset + i * vertex_stride;
7540
7541 memcpy(normal, &default_vector, normal_size);
7542 }
7543
7544 for (i = 0; i < num_faces; i++)
7545 {
7546 float denominator, weights[3];
7547 D3DXVECTOR3 a, b, cross, face_normal;
7548 const DWORD face_indices[3] =
7549 {
7550 read_ib(indices, indices_are_32bit, 3 * i + 0),
7551 read_ib(indices, indices_are_32bit, 3 * i + 1),
7552 read_ib(indices, indices_are_32bit, 3 * i + 2)
7553 };
7554 const D3DXVECTOR3 v0 = read_vec3(vertices, position_declaration, vertex_stride, face_indices[0]);
7555 const D3DXVECTOR3 v1 = read_vec3(vertices, position_declaration, vertex_stride, face_indices[1]);
7556 const D3DXVECTOR3 v2 = read_vec3(vertices, position_declaration, vertex_stride, face_indices[2]);
7557
7558 D3DXVec3Cross(&cross, D3DXVec3Subtract(&a, &v0, &v1), D3DXVec3Subtract(&b, &v0, &v2));
7559
7560 switch (weighting_method)
7561 {
7563 weights[0] = weights[1] = weights[2] = 1.0f;
7564 break;
7566 weights[0] = weights[1] = weights[2] = D3DXVec3Length(&cross);
7567 break;
7568 default:
7569 /* weight by angle */
7570 denominator = D3DXVec3Length(&a) * D3DXVec3Length(&b);
7571 if (!denominator)
7572 weights[0] = 0.0f;
7573 else
7574 weights[0] = acosf(D3DXVec3Dot(&a, &b) / denominator);
7575
7576 D3DXVec3Subtract(&a, &v1, &v0);
7577 D3DXVec3Subtract(&b, &v1, &v2);
7578 denominator = D3DXVec3Length(&a) * D3DXVec3Length(&b);
7579 if (!denominator)
7580 weights[1] = 0.0f;
7581 else
7582 weights[1] = acosf(D3DXVec3Dot(&a, &b) / denominator);
7583
7584 D3DXVec3Subtract(&a, &v2, &v0);
7585 D3DXVec3Subtract(&b, &v2, &v1);
7586 denominator = D3DXVec3Length(&a) * D3DXVec3Length(&b);
7587 if (!denominator)
7588 weights[2] = 0.0f;
7589 else
7590 weights[2] = acosf(D3DXVec3Dot(&a, &b) / denominator);
7591
7592 break;
7593 }
7594
7595 D3DXVec3Normalize(&face_normal, &cross);
7596
7597 for (j = 0; j < 3; j++)
7598 {
7600 DWORD rep_index = point_reps[face_indices[j]];
7601 D3DXVECTOR3 *rep_normal = vertex_element_vec3(vertices, normal_declaration, vertex_stride, rep_index);
7602
7603 D3DXVec3Scale(&normal, &face_normal, weights[j]);
7604 D3DXVec3Add(rep_normal, rep_normal, &normal);
7605 }
7606 }
7607
7608 for (i = 0; i < num_vertices; i++)
7609 {
7610 DWORD rep_index = point_reps[i];
7611 D3DXVECTOR3 *normal = vertex_element_vec3(vertices, normal_declaration, vertex_stride, i);
7612 D3DXVECTOR3 *rep_normal = vertex_element_vec3(vertices, normal_declaration, vertex_stride, rep_index);
7613
7614 if (i == rep_index)
7615 D3DXVec3Normalize(rep_normal, rep_normal);
7616 else
7617 *normal = *rep_normal;
7618 }
7619
7620 hr = D3D_OK;
7621
7622done:
7623 if (vertices)
7624 mesh->lpVtbl->UnlockVertexBuffer(mesh);
7625
7626 if (indices)
7627 mesh->lpVtbl->UnlockIndexBuffer(mesh);
7628
7629 free(point_reps);
7630
7631 return hr;
7632}
@ D3DDECLUSAGE_POSITION
Definition: d3d9types.h:236
D3DXVECTOR3 *WINAPI D3DXVec3Normalize(D3DXVECTOR3 *pout, const D3DXVECTOR3 *pv)
Definition: math.c:1805
static D3DXVECTOR3 read_vec3(BYTE *vertices, const D3DVERTEXELEMENT9 *declaration, DWORD vertex_stride, DWORD index)
Definition: mesh.c:7379
static DWORD read_ib(void *index_buffer, BOOL indices_are_32bit, DWORD index)
Definition: mesh.c:7049
static D3DXVECTOR3 * vertex_element_vec3(BYTE *vertices, const D3DVERTEXELEMENT9 *declaration, DWORD vertex_stride, DWORD index)
Definition: mesh.c:7373
_ACRTIMP float __cdecl acosf(float)
Definition: acosf.c:47
struct _D3DVECTOR D3DXVECTOR3
Definition: d3dx9math.h:97
@ D3DXTANGENT_WEIGHT_BY_AREA
Definition: d3dx9mesh.h:118
@ D3DXTANGENT_WEIGHT_EQUAL
Definition: d3dx9mesh.h:119
GLfloat v0
Definition: glext.h:6061
const GLbyte * weights
Definition: glext.h:6523
_Must_inspect_result_ _In_ USAGE _In_ USHORT _In_ USAGE Usage
Definition: hidpi.h:384
@ normal
Definition: optimize.h:166
static void cross(float v1[3], float v2[3], float result[3])
Definition: project.c:100

Referenced by compute_normals_D3DXComputeTangentFrameEx(), D3DXComputeNormals(), and test_compute_normals().

◆ D3DXConvertMeshSubsetToSingleStrip()

HRESULT WINAPI D3DXConvertMeshSubsetToSingleStrip ( struct ID3DXBaseMesh *  mesh_in,
DWORD  attribute_id,
DWORD  ib_flags,
struct IDirect3DIndexBuffer9 **  index_buffer,
DWORD *  index_count 
)

Definition at line 7674 of file mesh.c.

7676{
7677 FIXME("mesh_in %p, attribute_id %lu, ib_flags %#lx, index_buffer %p, index_count %p stub.\n",
7678 mesh_in, attribute_id, ib_flags, index_buffer, index_count);
7679
7680 return E_NOTIMPL;
7681}

◆ D3DXCreateBox()

HRESULT WINAPI D3DXCreateBox ( struct IDirect3DDevice9 *  device,
float  width,
float  height,
float  depth,
struct ID3DXMesh **  mesh,
struct ID3DXBuffer **  adjacency 
)

Definition at line 4760 of file mesh.c.

4762{
4763 HRESULT hr;
4764 ID3DXMesh *box;
4765 struct vertex *vertices;
4766 WORD (*faces)[3];
4767 DWORD *adjacency_buf;
4768 unsigned int i, face;
4769 static const D3DXVECTOR3 unit_box[] =
4770 {
4771 {-0.5f, -0.5f, -0.5f}, {-0.5f, -0.5f, 0.5f}, {-0.5f, 0.5f, 0.5f}, {-0.5f, 0.5f, -0.5f},
4772 {-0.5f, 0.5f, -0.5f}, {-0.5f, 0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f}, { 0.5f, 0.5f, -0.5f},
4773 { 0.5f, 0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f}, { 0.5f, -0.5f, 0.5f}, { 0.5f, -0.5f, -0.5f},
4774 {-0.5f, -0.5f, 0.5f}, {-0.5f, -0.5f, -0.5f}, { 0.5f, -0.5f, -0.5f}, { 0.5f, -0.5f, 0.5f},
4775 {-0.5f, -0.5f, 0.5f}, { 0.5f, -0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f}, {-0.5f, 0.5f, 0.5f},
4776 {-0.5f, -0.5f, -0.5f}, {-0.5f, 0.5f, -0.5f}, { 0.5f, 0.5f, -0.5f}, { 0.5f, -0.5f, -0.5f}
4777 };
4778 static const D3DXVECTOR3 normals[] =
4779 {
4780 {-1.0f, 0.0f, 0.0f}, { 0.0f, 1.0f, 0.0f}, { 1.0f, 0.0f, 0.0f},
4781 { 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}, { 0.0f, 0.0f, -1.0f}
4782 };
4783 static const DWORD adjacency_table[] =
4784 {
4785 6, 9, 1, 2, 10, 0, 1, 9, 3, 4, 10, 2,
4786 3, 8, 5, 7, 11, 4, 0, 11, 7, 5, 8, 6,
4787 7, 4, 9, 2, 0, 8, 1, 3, 11, 5, 6, 10
4788 };
4789
4790 TRACE("device %p, width %f, height %f, depth %f, mesh %p, adjacency %p\n",
4791 device, width, height, depth, mesh, adjacency);
4792
4793 if (!device || width < 0.0f || height < 0.0f || depth < 0.0f || !mesh)
4794 {
4795 return D3DERR_INVALIDCALL;
4796 }
4797
4799 {
4800 return hr;
4801 }
4802
4803 if (FAILED(hr = box->lpVtbl->LockVertexBuffer(box, 0, (void **)&vertices)))
4804 {
4805 box->lpVtbl->Release(box);
4806 return hr;
4807 }
4808
4809 if (FAILED(hr = box->lpVtbl->LockIndexBuffer(box, 0, (void **)&faces)))
4810 {
4811 box->lpVtbl->UnlockVertexBuffer(box);
4812 box->lpVtbl->Release(box);
4813 return hr;
4814 }
4815
4816 for (i = 0; i < 24; i++)
4817 {
4818 vertices[i].position.x = width * unit_box[i].x;
4819 vertices[i].position.y = height * unit_box[i].y;
4820 vertices[i].position.z = depth * unit_box[i].z;
4821 vertices[i].normal.x = normals[i / 4].x;
4822 vertices[i].normal.y = normals[i / 4].y;
4823 vertices[i].normal.z = normals[i / 4].z;
4824 }
4825
4826 face = 0;
4827 for (i = 0; i < 12; i++)
4828 {
4829 faces[i][0] = face++;
4830 faces[i][1] = face++;
4831 faces[i][2] = (i % 2) ? face - 4 : face;
4832 }
4833
4834 box->lpVtbl->UnlockIndexBuffer(box);
4835 box->lpVtbl->UnlockVertexBuffer(box);
4836
4837 if (adjacency)
4838 {
4839 if (FAILED(hr = D3DXCreateBuffer(sizeof(adjacency_table), adjacency)))
4840 {
4841 box->lpVtbl->Release(box);
4842 return hr;
4843 }
4844
4845 adjacency_buf = ID3DXBuffer_GetBufferPointer(*adjacency);
4846 memcpy(adjacency_buf, adjacency_table, sizeof(adjacency_table));
4847 }
4848
4849 *mesh = box;
4850
4851 return D3D_OK;
4852}
#define D3DFVF_XYZ
Definition: d3d8types.h:113
#define D3DFVF_NORMAL
Definition: d3d8types.h:120
HRESULT WINAPI D3DXCreateMeshFVF(DWORD face_count, DWORD vertex_count, DWORD options, DWORD fvf, struct IDirect3DDevice9 *device, struct ID3DXMesh **mesh)
Definition: mesh.c:2577
@ D3DXMESH_MANAGED
Definition: d3dx9mesh.h:64
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
Definition: palette.c:466

Referenced by D3DXCreateBoxTest(), test_box(), and test_compute_normals().

◆ D3DXCreateCylinder()

HRESULT WINAPI D3DXCreateCylinder ( struct IDirect3DDevice9 *  device,
float  radius1,
float  radius2,
float  length,
UINT  slices,
UINT  stacks,
struct ID3DXMesh **  mesh,
struct ID3DXBuffer **  adjacency 
)

Definition at line 5082 of file mesh.c.

5084{
5085 DWORD number_of_vertices, number_of_faces;
5086 HRESULT hr;
5087 ID3DXMesh *cylinder;
5088 struct vertex *vertices;
5089 face *faces;
5090 float theta_step, theta_start;
5091 struct sincos_table theta;
5092 float delta_radius, radius, radius_step;
5093 float z, z_step, z_normal;
5095
5096 TRACE("(%p, %f, %f, %f, %u, %u, %p, %p)\n", device, radius1, radius2, length, slices, stacks, mesh, adjacency);
5097
5098 if (device == NULL || radius1 < 0.0f || radius2 < 0.0f || length < 0.0f || slices < 2 || stacks < 1 || mesh == NULL)
5099 {
5100 return D3DERR_INVALIDCALL;
5101 }
5102
5103 number_of_vertices = 2 + (slices * (3 + stacks));
5104 number_of_faces = 2 * slices + stacks * (2 * slices);
5105
5106 hr = D3DXCreateMeshFVF(number_of_faces, number_of_vertices, D3DXMESH_MANAGED,
5108 if (FAILED(hr))
5109 {
5110 return hr;
5111 }
5112
5113 if (FAILED(hr = cylinder->lpVtbl->LockVertexBuffer(cylinder, 0, (void **)&vertices)))
5114 {
5115 cylinder->lpVtbl->Release(cylinder);
5116 return hr;
5117 }
5118
5119 if (FAILED(hr = cylinder->lpVtbl->LockIndexBuffer(cylinder, 0, (void **)&faces)))
5120 {
5121 cylinder->lpVtbl->UnlockVertexBuffer(cylinder);
5122 cylinder->lpVtbl->Release(cylinder);
5123 return hr;
5124 }
5125
5126 /* theta = angle on xy plane wrt x axis */
5127 theta_step = -2.0f * D3DX_PI / slices;
5128 theta_start = D3DX_PI / 2.0f;
5129
5130 if (!compute_sincos_table(&theta, theta_start, theta_step, slices))
5131 {
5132 cylinder->lpVtbl->UnlockIndexBuffer(cylinder);
5133 cylinder->lpVtbl->UnlockVertexBuffer(cylinder);
5134 cylinder->lpVtbl->Release(cylinder);
5135 return E_OUTOFMEMORY;
5136 }
5137
5138 vertex = 0;
5139 face = 0;
5140
5141 delta_radius = radius1 - radius2;
5142 radius = radius1;
5143 radius_step = delta_radius / stacks;
5144
5145 z = -length / 2;
5146 z_step = length / stacks;
5147 z_normal = delta_radius / length;
5148 if (isnan(z_normal))
5149 {
5150 z_normal = 0.0f;
5151 }
5152
5153 vertices[vertex].normal.x = 0.0f;
5154 vertices[vertex].normal.y = 0.0f;
5155 vertices[vertex].normal.z = -1.0f;
5156 vertices[vertex].position.x = 0.0f;
5157 vertices[vertex].position.y = 0.0f;
5158 vertices[vertex++].position.z = z;
5159
5160 for (slice = 0; slice < slices; slice++, vertex++)
5161 {
5162 vertices[vertex].normal.x = 0.0f;
5163 vertices[vertex].normal.y = 0.0f;
5164 vertices[vertex].normal.z = -1.0f;
5165 vertices[vertex].position.x = radius * theta.cos[slice];
5166 vertices[vertex].position.y = radius * theta.sin[slice];
5167 vertices[vertex].position.z = z;
5168
5169 if (slice > 0)
5170 {
5171 faces[face][0] = 0;
5172 faces[face][1] = slice;
5173 faces[face++][2] = slice + 1;
5174 }
5175 }
5176
5177 faces[face][0] = 0;
5178 faces[face][1] = slice;
5179 faces[face++][2] = 1;
5180
5181 for (stack = 1; stack <= stacks+1; stack++)
5182 {
5183 for (slice = 0; slice < slices; slice++, vertex++)
5184 {
5185 vertices[vertex].normal.x = theta.cos[slice];
5186 vertices[vertex].normal.y = theta.sin[slice];
5187 vertices[vertex].normal.z = z_normal;
5188 D3DXVec3Normalize(&vertices[vertex].normal, &vertices[vertex].normal);
5189 vertices[vertex].position.x = radius * theta.cos[slice];
5190 vertices[vertex].position.y = radius * theta.sin[slice];
5191 vertices[vertex].position.z = z;
5192
5193 if (stack > 1 && slice > 0)
5194 {
5195 faces[face][0] = vertex_index(slices, slice-1, stack-1);
5196 faces[face][1] = vertex_index(slices, slice-1, stack);
5197 faces[face++][2] = vertex_index(slices, slice, stack-1);
5198
5199 faces[face][0] = vertex_index(slices, slice, stack-1);
5200 faces[face][1] = vertex_index(slices, slice-1, stack);
5201 faces[face++][2] = vertex_index(slices, slice, stack);
5202 }
5203 }
5204
5205 if (stack > 1)
5206 {
5207 faces[face][0] = vertex_index(slices, slice-1, stack-1);
5208 faces[face][1] = vertex_index(slices, slice-1, stack);
5209 faces[face++][2] = vertex_index(slices, 0, stack-1);
5210
5211 faces[face][0] = vertex_index(slices, 0, stack-1);
5212 faces[face][1] = vertex_index(slices, slice-1, stack);
5213 faces[face++][2] = vertex_index(slices, 0, stack);
5214 }
5215
5216 if (stack < stacks + 1)
5217 {
5218 z += z_step;
5219 radius -= radius_step;
5220 }
5221 }
5222
5223 for (slice = 0; slice < slices; slice++, vertex++)
5224 {
5225 vertices[vertex].normal.x = 0.0f;
5226 vertices[vertex].normal.y = 0.0f;
5227 vertices[vertex].normal.z = 1.0f;
5228 vertices[vertex].position.x = radius * theta.cos[slice];
5229 vertices[vertex].position.y = radius * theta.sin[slice];
5230 vertices[vertex].position.z = z;
5231
5232 if (slice > 0)
5233 {
5234 faces[face][0] = vertex_index(slices, slice-1, stack);
5235 faces[face][1] = number_of_vertices - 1;
5236 faces[face++][2] = vertex_index(slices, slice, stack);
5237 }
5238 }
5239
5240 vertices[vertex].position.x = 0.0f;
5241 vertices[vertex].position.y = 0.0f;
5242 vertices[vertex].position.z = z;
5243 vertices[vertex].normal.x = 0.0f;
5244 vertices[vertex].normal.y = 0.0f;
5245 vertices[vertex].normal.z = 1.0f;
5246
5247 faces[face][0] = vertex_index(slices, slice-1, stack);
5248 faces[face][1] = number_of_vertices - 1;
5249 faces[face][2] = vertex_index(slices, 0, stack);
5250
5251 free_sincos_table(&theta);
5252 cylinder->lpVtbl->UnlockIndexBuffer(cylinder);
5253 cylinder->lpVtbl->UnlockVertexBuffer(cylinder);
5254
5255 if (adjacency)
5256 {
5257 if (FAILED(hr = D3DXCreateBuffer(number_of_faces * sizeof(DWORD) * 3, adjacency)))
5258 {
5259 cylinder->lpVtbl->Release(cylinder);
5260 return hr;
5261 }
5262
5263 if (FAILED(hr = cylinder->lpVtbl->GenerateAdjacency(cylinder, 0.0f, (*adjacency)->lpVtbl->GetBufferPointer(*adjacency))))
5264 {
5265 (*adjacency)->lpVtbl->Release(*adjacency);
5266 cylinder->lpVtbl->Release(cylinder);
5267 return hr;
5268 }
5269 }
5270
5271 *mesh = cylinder;
5272
5273 return D3D_OK;
5274}
GLUquadricObj * cylinder
Definition: cylfrac.c:44
static void free_sincos_table(struct sincos_table *sincos_table)
Definition: mesh.c:4862
static BOOL compute_sincos_table(struct sincos_table *sincos_table, float angle_start, float angle_step, int n)
Definition: mesh.c:4869
#define isnan(x)
Definition: math.h:360
#define D3DX_PI
Definition: d3dx9math.h:27
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLdouble GLdouble z
Definition: glext.h:5874
ULONG Release()
Definition: format.c:80

Referenced by D3DXCreateCylinderTest(), and test_cylinder().

◆ D3DXCreateMesh()

HRESULT WINAPI D3DXCreateMesh ( DWORD  numfaces,
DWORD  numvertices,
DWORD  options,
const D3DVERTEXELEMENT9 *  declaration,
struct IDirect3DDevice9 *  device,
struct ID3DXMesh **  mesh 
)

Definition at line 2431 of file mesh.c.

2433{
2434 HRESULT hr;
2435 DWORD fvf;
2436 IDirect3DVertexDeclaration9 *vertex_declaration;
2437 UINT vertex_declaration_size;
2438 UINT num_elem;
2439 IDirect3DVertexBuffer9 *vertex_buffer;
2440 IDirect3DIndexBuffer9 *index_buffer;
2441 DWORD *attrib_buffer;
2442 struct d3dx9_mesh *object;
2443 DWORD index_usage = 0;
2444 D3DPOOL index_pool = D3DPOOL_DEFAULT;
2445 D3DFORMAT index_format = D3DFMT_INDEX16;
2446 DWORD vertex_usage = 0;
2447 D3DPOOL vertex_pool = D3DPOOL_DEFAULT;
2448 int i;
2449
2450 TRACE("numfaces %lu, numvertices %lu, options %#lx, declaration %p, device %p, mesh %p.\n",
2452
2453 if (numfaces == 0 || numvertices == 0 || declaration == NULL || device == NULL || mesh == NULL ||
2454 /* D3DXMESH_VB_SHARE is for cloning, and D3DXMESH_USEHWONLY is for ConvertToBlendedMesh */
2455 (options & (D3DXMESH_VB_SHARE | D3DXMESH_USEHWONLY | 0xfffe0000)))
2456 {
2457 return D3DERR_INVALIDCALL;
2458 }
2459 for (i = 0; declaration[i].Stream != 0xff; i++)
2460 if (declaration[i].Stream != 0)
2461 return D3DERR_INVALIDCALL;
2462 num_elem = i + 1;
2463
2464 if (options & D3DXMESH_32BIT)
2465 index_format = D3DFMT_INDEX32;
2466
2468 index_usage |= D3DUSAGE_DONOTCLIP;
2469 vertex_usage |= D3DUSAGE_DONOTCLIP;
2470 }
2471 if (options & D3DXMESH_POINTS) {
2472 index_usage |= D3DUSAGE_POINTS;
2473 vertex_usage |= D3DUSAGE_POINTS;
2474 }
2476 index_usage |= D3DUSAGE_RTPATCHES;
2477 vertex_usage |= D3DUSAGE_RTPATCHES;
2478 }
2479 if (options & D3DXMESH_NPATCHES) {
2480 index_usage |= D3DUSAGE_NPATCHES;
2481 vertex_usage |= D3DUSAGE_NPATCHES;
2482 }
2483
2485 vertex_pool = D3DPOOL_SYSTEMMEM;
2486 else if (options & D3DXMESH_VB_MANAGED)
2487 vertex_pool = D3DPOOL_MANAGED;
2488
2490 vertex_usage |= D3DUSAGE_WRITEONLY;
2492 vertex_usage |= D3DUSAGE_DYNAMIC;
2494 vertex_usage |= D3DUSAGE_SOFTWAREPROCESSING;
2495
2497 index_pool = D3DPOOL_SYSTEMMEM;
2498 else if (options & D3DXMESH_IB_MANAGED)
2499 index_pool = D3DPOOL_MANAGED;
2500
2502 index_usage |= D3DUSAGE_WRITEONLY;
2504 index_usage |= D3DUSAGE_DYNAMIC;
2506 index_usage |= D3DUSAGE_SOFTWAREPROCESSING;
2507
2509 if (hr != D3D_OK)
2510 {
2511 fvf = 0;
2512 }
2513
2515 {
2516 WARN("Failed to create vertex declaration, hr %#lx.\n", hr);
2517 return hr;
2518 }
2520
2522 vertex_usage, fvf, vertex_pool, &vertex_buffer, NULL)))
2523 {
2524 WARN("Failed to create vertex buffer, hr %#lx.\n", hr);
2526 return hr;
2527 }
2528
2530 numfaces * 3 * ((index_format == D3DFMT_INDEX16) ? 2 : 4), index_usage, index_format,
2531 index_pool, &index_buffer, NULL)))
2532 {
2533 WARN("Failed to create index buffer, hr %#lx.\n", hr);
2536 return hr;
2537 }
2538
2540 object = calloc(1, sizeof(*object));
2541 if (object == NULL || attrib_buffer == NULL)
2542 {
2543 free(object);
2548 *mesh = NULL;
2549 return E_OUTOFMEMORY;
2550 }
2551 object->ID3DXMesh_iface.lpVtbl = &D3DXMesh_Vtbl;
2552 object->ref = 1;
2553
2554 object->numfaces = numfaces;
2555 object->numvertices = numvertices;
2556 object->options = options;
2557 object->fvf = fvf;
2558 object->device = device;
2560
2561 copy_declaration(object->cached_declaration, declaration, num_elem);
2562 object->vertex_declaration = vertex_declaration;
2563 object->vertex_declaration_size = vertex_declaration_size;
2564 object->num_elem = num_elem;
2565 object->vertex_buffer = vertex_buffer;
2566 object->index_buffer = index_buffer;
2567 object->attrib_buffer = attrib_buffer;
2568
2569 *mesh = &object->ID3DXMesh_iface;
2570
2571 return D3D_OK;
2572}
#define D3DUSAGE_NPATCHES
Definition: d3d8types.h:98
#define D3DUSAGE_POINTS
Definition: d3d8types.h:96
#define D3DUSAGE_DONOTCLIP
Definition: d3d8types.h:95
@ D3DFMT_INDEX16
Definition: d3d8types.h:649
@ D3DFMT_INDEX32
Definition: d3d8types.h:650
#define D3DUSAGE_DYNAMIC
Definition: d3d8types.h:99
#define D3DUSAGE_WRITEONLY
Definition: d3d8types.h:93
enum _D3DPOOL D3DPOOL
@ D3DPOOL_DEFAULT
Definition: d3d8types.h:709
@ D3DPOOL_SYSTEMMEM
Definition: d3d8types.h:711
@ D3DPOOL_MANAGED
Definition: d3d8types.h:710
enum _D3DFORMAT D3DFORMAT
#define D3DUSAGE_SOFTWAREPROCESSING
Definition: d3d8types.h:94
#define D3DUSAGE_RTPATCHES
Definition: d3d8types.h:97
#define IDirect3DDevice9_CreateIndexBuffer(p, a, b, c, d, e, f)
Definition: d3d9.h:1362
HRESULT WINAPI D3DXFVFFromDeclarator(const D3DVERTEXELEMENT9 *declaration, DWORD *fvf)
Definition: mesh.c:2132
@ D3DXMESH_NPATCHES
Definition: d3dx9mesh.h:50
@ D3DXMESH_VB_MANAGED
Definition: d3dx9mesh.h:52
@ D3DXMESH_USEHWONLY
Definition: d3dx9mesh.h:62
@ D3DXMESH_DONOTCLIP
Definition: d3dx9mesh.h:47
@ D3DXMESH_VB_SOFTWAREPROCESSING
Definition: d3dx9mesh.h:55
@ D3DXMESH_VB_WRITEONLY
Definition: d3dx9mesh.h:53
@ D3DXMESH_POINTS
Definition: d3dx9mesh.h:48
@ D3DXMESH_IB_MANAGED
Definition: d3dx9mesh.h:57
@ D3DXMESH_IB_WRITEONLY
Definition: d3dx9mesh.h:58
@ D3DXMESH_VB_SYSTEMMEM
Definition: d3dx9mesh.h:51
@ D3DXMESH_RTPATCHES
Definition: d3dx9mesh.h:49
@ D3DXMESH_IB_SYSTEMMEM
Definition: d3dx9mesh.h:56
@ D3DXMESH_IB_SOFTWAREPROCESSING
Definition: d3dx9mesh.h:60
@ D3DXMESH_IB_DYNAMIC
Definition: d3dx9mesh.h:59
@ D3DXMESH_VB_DYNAMIC
Definition: d3dx9mesh.h:54
#define calloc
Definition: rosglue.h:14
DWORD fvf
Definition: mesh.c:53
UINT num_elem
Definition: mesh.c:58
DWORD numvertices
Definition: mesh.c:51
IDirect3DDevice9 * device
Definition: mesh.c:54
DWORD options
Definition: mesh.c:52
IDirect3DVertexDeclaration9 * vertex_declaration
Definition: mesh.c:56

Referenced by d3dx9_mesh_CloneMesh(), D3DXCreateMeshFVF(), D3DXCreateMeshTest(), init_test_mesh(), test_convert_adjacency_to_point_reps(), test_convert_point_reps_to_adjacency(), and test_update_semantics().

◆ D3DXCreateMeshFVF()

HRESULT WINAPI D3DXCreateMeshFVF ( DWORD  face_count,
DWORD  vertex_count,
DWORD  options,
DWORD  fvf,
struct IDirect3DDevice9 *  device,
struct ID3DXMesh **  mesh 
)

Definition at line 2577 of file mesh.c.

2579{
2580 HRESULT hr;
2582
2583 TRACE("face_count %lu, vertex_count %lu, options %#lx, fvf %#lx, device %p, mesh %p.\n",
2585
2587 if (FAILED(hr)) return hr;
2588
2590}
int face_count
Definition: d3drm.c:3529
int vertex_count
Definition: d3drm.c:3528

Referenced by D3DXCreateBox(), D3DXCreateCylinder(), D3DXCreateMeshFVFTest(), D3DXCreatePolygon(), D3DXCreateSphere(), D3DXCreateTextW(), D3DXCreateTorus(), D3DXGenerateAdjacencyTest(), D3DXLoadMeshFromXInMemory(), D3DXLoadSkinMeshFromXof(), and test_mesh_optimize().

◆ D3DXCreatePolygon()

HRESULT WINAPI D3DXCreatePolygon ( struct IDirect3DDevice9 *  device,
float  length,
UINT  sides,
struct ID3DXMesh **  mesh,
struct ID3DXBuffer **  adjacency 
)

Definition at line 4670 of file mesh.c.

4672{
4673 HRESULT hr;
4674 ID3DXMesh *polygon;
4675 struct vertex *vertices;
4676 WORD (*faces)[3];
4677 DWORD (*adjacency_buf)[3];
4678 float angle, scale;
4679 unsigned int i;
4680
4681 TRACE("device %p, length %f, sides %u, mesh %p, adjacency %p.\n",
4682 device, length, sides, mesh, adjacency);
4683
4684 if (!device || length < 0.0f || sides < 3 || !mesh)
4685 return D3DERR_INVALIDCALL;
4686
4687 if (FAILED(hr = D3DXCreateMeshFVF(sides, sides + 1, D3DXMESH_MANAGED,
4688 D3DFVF_XYZ | D3DFVF_NORMAL, device, &polygon)))
4689 {
4690 return hr;
4691 }
4692
4693 if (FAILED(hr = polygon->lpVtbl->LockVertexBuffer(polygon, 0, (void **)&vertices)))
4694 {
4695 polygon->lpVtbl->Release(polygon);
4696 return hr;
4697 }
4698
4699 if (FAILED(hr = polygon->lpVtbl->LockIndexBuffer(polygon, 0, (void **)&faces)))
4700 {
4701 polygon->lpVtbl->UnlockVertexBuffer(polygon);
4702 polygon->lpVtbl->Release(polygon);
4703 return hr;
4704 }
4705
4706 angle = D3DX_PI / sides;
4707 scale = 0.5f * length / sinf(angle);
4708 angle *= 2.0f;
4709
4710 vertices[0].position.x = 0.0f;
4711 vertices[0].position.y = 0.0f;
4712 vertices[0].position.z = 0.0f;
4713 vertices[0].normal.x = 0.0f;
4714 vertices[0].normal.y = 0.0f;
4715 vertices[0].normal.z = 1.0f;
4716
4717 for (i = 0; i < sides; ++i)
4718 {
4719 vertices[i + 1].position.x = cosf(angle * i) * scale;
4720 vertices[i + 1].position.y = sinf(angle * i) * scale;
4721 vertices[i + 1].position.z = 0.0f;
4722 vertices[i + 1].normal.x = 0.0f;
4723 vertices[i + 1].normal.y = 0.0f;
4724 vertices[i + 1].normal.z = 1.0f;
4725
4726 faces[i][0] = 0;
4727 faces[i][1] = i + 1;
4728 faces[i][2] = i + 2;
4729 }
4730
4731 faces[sides - 1][2] = 1;
4732
4733 polygon->lpVtbl->UnlockVertexBuffer(polygon);
4734 polygon->lpVtbl->UnlockIndexBuffer(polygon);
4735
4736 if (adjacency)
4737 {
4738 if (FAILED(hr = D3DXCreateBuffer(sides * sizeof(DWORD) * 3, adjacency)))
4739 {
4740 polygon->lpVtbl->Release(polygon);
4741 return hr;
4742 }
4743
4744 adjacency_buf = ID3DXBuffer_GetBufferPointer(*adjacency);
4745 for (i = 0; i < sides; ++i)
4746 {
4747 adjacency_buf[i][0] = i - 1;
4748 adjacency_buf[i][1] = ~0U;
4749 adjacency_buf[i][2] = i + 1;
4750 }
4751 adjacency_buf[0][0] = sides - 1;
4752 adjacency_buf[sides - 1][2] = 0;
4753 }
4754
4755 *mesh = polygon;
4756
4757 return D3D_OK;
4758}
#define U(x)
Definition: wordpad.c:45
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:9032
nsrefcnt Release()
#define DWORD
Definition: nt_native.h:44

Referenced by D3DXCreatePolygonTest(), and test_polygon().

◆ D3DXCreateSphere()

HRESULT WINAPI D3DXCreateSphere ( struct IDirect3DDevice9 *  device,
float  radius,
UINT  slices,
UINT  stacks,
struct ID3DXMesh **  mesh,
struct ID3DXBuffer **  adjacency 
)

Definition at line 4902 of file mesh.c.

4904{
4905 DWORD number_of_vertices, number_of_faces;
4906 HRESULT hr;
4907 ID3DXMesh *sphere;
4908 struct vertex *vertices;
4909 face *faces;
4910 float phi_step, phi_start;
4911 struct sincos_table phi;
4912 float theta_step, theta, sin_theta, cos_theta;
4914
4915 TRACE("(%p, %f, %u, %u, %p, %p)\n", device, radius, slices, stacks, mesh, adjacency);
4916
4917 if (!device || radius < 0.0f || slices < 2 || stacks < 2 || !mesh)
4918 {
4919 return D3DERR_INVALIDCALL;
4920 }
4921
4922 number_of_vertices = 2 + slices * (stacks-1);
4923 number_of_faces = 2 * slices + (stacks - 2) * (2 * slices);
4924
4925 hr = D3DXCreateMeshFVF(number_of_faces, number_of_vertices, D3DXMESH_MANAGED,
4926 D3DFVF_XYZ | D3DFVF_NORMAL, device, &sphere);
4927 if (FAILED(hr))
4928 {
4929 return hr;
4930 }
4931
4932 if (FAILED(hr = sphere->lpVtbl->LockVertexBuffer(sphere, 0, (void **)&vertices)))
4933 {
4934 sphere->lpVtbl->Release(sphere);
4935 return hr;
4936 }
4937
4938 if (FAILED(hr = sphere->lpVtbl->LockIndexBuffer(sphere, 0, (void **)&faces)))
4939 {
4940 sphere->lpVtbl->UnlockVertexBuffer(sphere);
4941 sphere->lpVtbl->Release(sphere);
4942 return hr;
4943 }
4944
4945 /* phi = angle on xz plane wrt z axis */
4946 phi_step = -2.0f * D3DX_PI / slices;
4947 phi_start = D3DX_PI / 2.0f;
4948
4949 if (!compute_sincos_table(&phi, phi_start, phi_step, slices))
4950 {
4951 sphere->lpVtbl->UnlockIndexBuffer(sphere);
4952 sphere->lpVtbl->UnlockVertexBuffer(sphere);
4953 sphere->lpVtbl->Release(sphere);
4954 return E_OUTOFMEMORY;
4955 }
4956
4957 /* theta = angle on xy plane wrt x axis */
4958 theta_step = D3DX_PI / stacks;
4959 theta = theta_step;
4960
4961 vertex = 0;
4962 face = 0;
4963
4964 vertices[vertex].normal.x = 0.0f;
4965 vertices[vertex].normal.y = 0.0f;
4966 vertices[vertex].normal.z = 1.0f;
4967 vertices[vertex].position.x = 0.0f;
4968 vertices[vertex].position.y = 0.0f;
4969 vertices[vertex].position.z = radius;
4970 vertex++;
4971
4972 for (stack = 0; stack < stacks - 1; stack++)
4973 {
4974 sin_theta = sinf(theta);
4975 cos_theta = cosf(theta);
4976
4977 for (slice = 0; slice < slices; slice++)
4978 {
4979 vertices[vertex].normal.x = sin_theta * phi.cos[slice];
4980 vertices[vertex].normal.y = sin_theta * phi.sin[slice];
4981 vertices[vertex].normal.z = cos_theta;
4982 vertices[vertex].position.x = radius * sin_theta * phi.cos[slice];
4983 vertices[vertex].position.y = radius * sin_theta * phi.sin[slice];
4984 vertices[vertex].position.z = radius * cos_theta;
4985 vertex++;
4986
4987 if (slice > 0)
4988 {
4989 if (stack == 0)
4990 {
4991 /* top stack is triangle fan */
4992 faces[face][0] = 0;
4993 faces[face][1] = slice + 1;
4994 faces[face][2] = slice;
4995 face++;
4996 }
4997 else
4998 {
4999 /* stacks in between top and bottom are quad strips */
5000 faces[face][0] = vertex_index(slices, slice-1, stack-1);
5001 faces[face][1] = vertex_index(slices, slice, stack-1);
5002 faces[face][2] = vertex_index(slices, slice-1, stack);
5003 face++;
5004
5005 faces[face][0] = vertex_index(slices, slice, stack-1);
5006 faces[face][1] = vertex_index(slices, slice, stack);
5007 faces[face][2] = vertex_index(slices, slice-1, stack);
5008 face++;
5009 }
5010 }
5011 }
5012
5013 theta += theta_step;
5014
5015 if (stack == 0)
5016 {
5017 faces[face][0] = 0;
5018 faces[face][1] = 1;
5019 faces[face][2] = slice;
5020 face++;
5021 }
5022 else
5023 {
5024 faces[face][0] = vertex_index(slices, slice-1, stack-1);
5025 faces[face][1] = vertex_index(slices, 0, stack-1);
5026 faces[face][2] = vertex_index(slices, slice-1, stack);
5027 face++;
5028
5029 faces[face][0] = vertex_index(slices, 0, stack-1);
5030 faces[face][1] = vertex_index(slices, 0, stack);
5031 faces[face][2] = vertex_index(slices, slice-1, stack);
5032 face++;
5033 }
5034 }
5035
5036 vertices[vertex].position.x = 0.0f;
5037 vertices[vertex].position.y = 0.0f;
5038 vertices[vertex].position.z = -radius;
5039 vertices[vertex].normal.x = 0.0f;
5040 vertices[vertex].normal.y = 0.0f;
5041 vertices[vertex].normal.z = -1.0f;
5042
5043 /* bottom stack is triangle fan */
5044 for (slice = 1; slice < slices; slice++)
5045 {
5046 faces[face][0] = vertex_index(slices, slice-1, stack-1);
5047 faces[face][1] = vertex_index(slices, slice, stack-1);
5048 faces[face][2] = vertex;
5049 face++;
5050 }
5051
5052 faces[face][0] = vertex_index(slices, slice-1, stack-1);
5053 faces[face][1] = vertex_index(slices, 0, stack-1);
5054 faces[face][2] = vertex;
5055
5056 free_sincos_table(&phi);
5057 sphere->lpVtbl->UnlockIndexBuffer(sphere);
5058 sphere->lpVtbl->UnlockVertexBuffer(sphere);
5059
5060
5061 if (adjacency)
5062 {
5063 if (FAILED(hr = D3DXCreateBuffer(number_of_faces * sizeof(DWORD) * 3, adjacency)))
5064 {
5065 sphere->lpVtbl->Release(sphere);
5066 return hr;
5067 }
5068
5069 if (FAILED(hr = sphere->lpVtbl->GenerateAdjacency(sphere, 0.0f, (*adjacency)->lpVtbl->GetBufferPointer(*adjacency))))
5070 {
5071 (*adjacency)->lpVtbl->Release(*adjacency);
5072 sphere->lpVtbl->Release(sphere);
5073 return hr;
5074 }
5075 }
5076
5077 *mesh = sphere;
5078
5079 return D3D_OK;
5080}

Referenced by D3DXCreateSphereTest(), D3DXCreateTeapot(), test_compute_normals(), and test_sphere().

◆ D3DXCreateTeapot()

HRESULT WINAPI D3DXCreateTeapot ( struct IDirect3DDevice9 *  device,
struct ID3DXMesh **  mesh,
struct ID3DXBuffer **  adjacency 
)

Definition at line 5276 of file mesh.c.

5278{
5279 FIXME("device %p, mesh %p, adjacency %p semi-stub.\n", device, mesh, adjacency);
5280
5281 return D3DXCreateSphere(device, 1.0f, 4, 4, mesh, adjacency);
5282}
HRESULT WINAPI D3DXCreateSphere(struct IDirect3DDevice9 *device, float radius, UINT slices, UINT stacks, struct ID3DXMesh **mesh, struct ID3DXBuffer **adjacency)
Definition: mesh.c:4902

◆ D3DXCreateTextA()

HRESULT WINAPI D3DXCreateTextA ( struct IDirect3DDevice9 *  device,
HDC  hdc,
const char *  text,
float  deviation,
float  extrusion,
struct ID3DXMesh **  mesh,
struct ID3DXBuffer **  adjacency,
GLYPHMETRICSFLOAT *  glyphmetrics 
)

Definition at line 5284 of file mesh.c.

5286{
5287 WCHAR *textW;
5288 HRESULT hr;
5289 int len;
5290
5291 TRACE("device %p, hdc %p, text %s, deviation %.8e, extrusion %.8e, mesh %p, adjacency %p, glyphmetrics %p.\n",
5292 device, hdc, debugstr_a(text), deviation, extrusion, mesh, adjacency, glyphmetrics);
5293
5294 if (!text)
5295 return D3DERR_INVALIDCALL;
5296
5297 len = MultiByteToWideChar(CP_ACP, 0, text, -1, NULL, 0);
5298 textW = malloc(len * sizeof(WCHAR));
5300
5301 hr = D3DXCreateTextW(device, hdc, textW, deviation, extrusion,
5302 mesh, adjacency, glyphmetrics);
5303 free(textW);
5304
5305 return hr;
5306}
HRESULT WINAPI D3DXCreateTextW(struct IDirect3DDevice9 *device, HDC hdc, const WCHAR *text, float deviation, float extrusion, struct ID3DXMesh **mesh_ptr, struct ID3DXBuffer **adjacency, GLYPHMETRICSFLOAT *glyphmetrics)
Definition: mesh.c:6192
#define CP_ACP
Definition: compat.h:109
#define MultiByteToWideChar
Definition: compat.h:110
const WCHAR * text
Definition: package.c:1826
GLenum GLsizei len
Definition: glext.h:6722
#define debugstr_a
Definition: kernel32.h:31
HDC hdc
Definition: main.c:9
static const WCHAR textW[]
Definition: itemdlg.c:1621
short WCHAR
Definition: pedump.c:58

Referenced by D3DXCreateTextTest(), and test_createtext().

◆ D3DXCreateTextW()

HRESULT WINAPI D3DXCreateTextW ( struct IDirect3DDevice9 *  device,
HDC  hdc,
const WCHAR *  text,
float  deviation,
float  extrusion,
struct ID3DXMesh **  mesh_ptr,
struct ID3DXBuffer **  adjacency,
GLYPHMETRICSFLOAT *  glyphmetrics 
)

Definition at line 6192 of file mesh.c.

6194{
6195 HRESULT hr;
6196 ID3DXMesh *mesh = NULL;
6197 DWORD nb_vertices, nb_faces;
6198 DWORD nb_front_faces, nb_corners, nb_outline_points;
6199 struct vertex *vertices = NULL;
6200 face *faces = NULL;
6201 int textlen = 0;
6202 float offset_x;
6203 LOGFONTW lf;
6205 HFONT font = NULL, oldfont = NULL;
6206 const MAT2 identity = {{0, 1}, {0, 0}, {0, 0}, {0, 1}};
6207 void *raw_outline = NULL;
6208 int bufsize = 0;
6209 struct glyphinfo *glyphs = NULL;
6210 GLYPHMETRICS gm;
6211 struct triangulation_array triangulations = {0, 0, NULL};
6212 int i;
6213 struct vertex *vertex_ptr;
6214 face *face_ptr;
6215 float max_deviation_sq;
6216 const struct cos_table cos_table = {
6217 cosf(D3DXToRadian(0.5f)),
6218 cosf(D3DXToRadian(45.0f)),
6219 cosf(D3DXToRadian(90.0f)),
6220 };
6221 int f1, f2;
6222
6223 TRACE("(%p, %p, %s, %f, %f, %p, %p, %p)\n", device, hdc,
6224 debugstr_w(text), deviation, extrusion, mesh_ptr, adjacency, glyphmetrics);
6225
6226 if (!device || !hdc || !text || !*text || deviation < 0.0f || extrusion < 0.0f || !mesh_ptr)
6227 return D3DERR_INVALIDCALL;
6228
6229 if (adjacency)
6230 {
6231 FIXME("Case of adjacency != NULL not implemented.\n");
6232 return E_NOTIMPL;
6233 }
6234
6235 if (!GetObjectW(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), &lf) ||
6236 !GetOutlineTextMetricsW(hdc, sizeof(otm), &otm))
6237 {
6238 return D3DERR_INVALIDCALL;
6239 }
6240
6241 if (deviation == 0.0f)
6242 deviation = 1.0f / otm.otmEMSquare;
6243 max_deviation_sq = deviation * deviation;
6244
6245 lf.lfHeight = otm.otmEMSquare;
6246 lf.lfWidth = 0;
6248 if (!font) {
6249 hr = E_OUTOFMEMORY;
6250 goto error;
6251 }
6252 oldfont = SelectObject(hdc, font);
6253
6254 textlen = lstrlenW(text);
6255 for (i = 0; i < textlen; i++)
6256 {
6258 if (datasize < 0)
6259 return D3DERR_INVALIDCALL;
6260 if (bufsize < datasize)
6261 bufsize = datasize;
6262 }
6263 if (!bufsize) { /* e.g. text == " " */
6265 goto error;
6266 }
6267
6268 glyphs = calloc(textlen, sizeof(*glyphs));
6269 raw_outline = malloc(bufsize);
6270 if (!glyphs || !raw_outline) {
6271 hr = E_OUTOFMEMORY;
6272 goto error;
6273 }
6274
6275 offset_x = 0.0f;
6276 for (i = 0; i < textlen; i++)
6277 {
6278 /* get outline points from data returned from GetGlyphOutline */
6279 int datasize;
6280
6281 glyphs[i].offset_x = offset_x;
6282
6283 datasize = GetGlyphOutlineW(hdc, text[i], GGO_NATIVE, &gm, bufsize, raw_outline, &identity);
6284 hr = create_outline(&glyphs[i], raw_outline, datasize,
6285 max_deviation_sq, otm.otmEMSquare, &cos_table);
6286 if (hr != S_OK) goto error;
6287
6288 triangulations.glyph = &glyphs[i];
6289 hr = triangulate(&triangulations);
6290 if (hr != S_OK) goto error;
6291 if (triangulations.count) {
6292 ERR("%d incomplete triangulations of glyph (%u).\n", triangulations.count, text[i]);
6293 triangulations.count = 0;
6294 }
6295
6296 if (glyphmetrics)
6297 {
6298 glyphmetrics[i].gmfBlackBoxX = gm.gmBlackBoxX / (float)otm.otmEMSquare;
6299 glyphmetrics[i].gmfBlackBoxY = gm.gmBlackBoxY / (float)otm.otmEMSquare;
6300 glyphmetrics[i].gmfptGlyphOrigin.x = gm.gmptGlyphOrigin.x / (float)otm.otmEMSquare;
6301 glyphmetrics[i].gmfptGlyphOrigin.y = gm.gmptGlyphOrigin.y / (float)otm.otmEMSquare;
6302 glyphmetrics[i].gmfCellIncX = gm.gmCellIncX / (float)otm.otmEMSquare;
6303 glyphmetrics[i].gmfCellIncY = gm.gmCellIncY / (float)otm.otmEMSquare;
6304 }
6305 offset_x += gm.gmCellIncX / (float)otm.otmEMSquare;
6306 }
6307
6308 /* corner points need an extra vertex for the different side faces normals */
6309 nb_corners = 0;
6310 nb_outline_points = 0;
6311 nb_front_faces = 0;
6312 for (i = 0; i < textlen; i++)
6313 {
6314 int j;
6315 nb_outline_points += glyphs[i].ordered_vertices.count;
6316 nb_front_faces += glyphs[i].faces.count;
6317 for (j = 0; j < glyphs[i].outlines.count; j++)
6318 {
6319 int k;
6320 struct outline *outline = &glyphs[i].outlines.items[j];
6321 nb_corners++; /* first outline point always repeated as a corner */
6322 for (k = 1; k < outline->count; k++)
6323 if (outline->items[k].corner)
6324 nb_corners++;
6325 }
6326 }
6327
6328 nb_vertices = (nb_outline_points + nb_corners) * 2 + nb_outline_points * 2;
6329 nb_faces = nb_outline_points * 2 + nb_front_faces * 2;
6330
6331
6332 hr = D3DXCreateMeshFVF(nb_faces, nb_vertices, D3DXMESH_MANAGED,
6334 if (FAILED(hr))
6335 goto error;
6336
6337 if (FAILED(hr = mesh->lpVtbl->LockVertexBuffer(mesh, 0, (void **)&vertices)))
6338 goto error;
6339
6340 if (FAILED(hr = mesh->lpVtbl->LockIndexBuffer(mesh, 0, (void **)&faces)))
6341 goto error;
6342
6343 /* convert 2D vertices and faces into 3D mesh */
6344 vertex_ptr = vertices;
6345 face_ptr = faces;
6346 if (extrusion == 0.0f) {
6347 f1 = 1;
6348 f2 = 2;
6349 } else {
6350 f1 = 2;
6351 f2 = 1;
6352 }
6353 for (i = 0; i < textlen; i++)
6354 {
6355 int j;
6356 int count;
6357 struct vertex *back_vertices;
6358 face *back_faces;
6359
6360 /* side vertices and faces */
6361 for (j = 0; j < glyphs[i].outlines.count; j++)
6362 {
6363 struct vertex *outline_vertices = vertex_ptr;
6364 struct outline *outline = &glyphs[i].outlines.items[j];
6365 int k;
6366 struct point2d *prevpt = &outline->items[outline->count - 1];
6367 struct point2d *pt = &outline->items[0];
6368
6369 for (k = 1; k <= outline->count; k++)
6370 {
6371 struct vertex vtx;
6372 struct point2d *nextpt = &outline->items[k % outline->count];
6373 WORD vtx_idx = vertex_ptr - vertices;
6375
6376 if (pt->corner == POINTTYPE_CURVE_START)
6377 D3DXVec2Subtract(&vec, &pt->pos, &prevpt->pos);
6378 else if (pt->corner)
6379 D3DXVec2Subtract(&vec, &nextpt->pos, &pt->pos);
6380 else
6381 D3DXVec2Subtract(&vec, &nextpt->pos, &prevpt->pos);
6383 vtx.normal.x = -vec.y;
6384 vtx.normal.y = vec.x;
6385 vtx.normal.z = 0;
6386
6387 vtx.position.x = pt->pos.x + glyphs[i].offset_x;
6388 vtx.position.y = pt->pos.y;
6389 vtx.position.z = 0;
6390 *vertex_ptr++ = vtx;
6391
6392 vtx.position.z = -extrusion;
6393 *vertex_ptr++ = vtx;
6394
6395 vtx.position.x = nextpt->pos.x + glyphs[i].offset_x;
6396 vtx.position.y = nextpt->pos.y;
6397 if (pt->corner && nextpt->corner && nextpt->corner != POINTTYPE_CURVE_END) {
6398 vtx.position.z = -extrusion;
6399 *vertex_ptr++ = vtx;
6400 vtx.position.z = 0;
6401 *vertex_ptr++ = vtx;
6402
6403 (*face_ptr)[0] = vtx_idx;
6404 (*face_ptr)[1] = vtx_idx + 2;
6405 (*face_ptr)[2] = vtx_idx + 1;
6406 face_ptr++;
6407
6408 (*face_ptr)[0] = vtx_idx;
6409 (*face_ptr)[1] = vtx_idx + 3;
6410 (*face_ptr)[2] = vtx_idx + 2;
6411 face_ptr++;
6412 } else {
6413 if (nextpt->corner) {
6414 if (nextpt->corner == POINTTYPE_CURVE_END) {
6415 D3DXVECTOR2 *nextpt2 = &outline->items[(k + 1) % outline->count].pos;
6416 D3DXVec2Subtract(&vec, nextpt2, &nextpt->pos);
6417 } else {
6418 D3DXVec2Subtract(&vec, &nextpt->pos, &pt->pos);
6419 }
6421 vtx.normal.x = -vec.y;
6422 vtx.normal.y = vec.x;
6423
6424 vtx.position.z = 0;
6425 *vertex_ptr++ = vtx;
6426 vtx.position.z = -extrusion;
6427 *vertex_ptr++ = vtx;
6428 }
6429
6430 (*face_ptr)[0] = vtx_idx;
6431 (*face_ptr)[1] = vtx_idx + 3;
6432 (*face_ptr)[2] = vtx_idx + 1;
6433 face_ptr++;
6434
6435 (*face_ptr)[0] = vtx_idx;
6436 (*face_ptr)[1] = vtx_idx + 2;
6437 (*face_ptr)[2] = vtx_idx + 3;
6438 face_ptr++;
6439 }
6440
6441 prevpt = pt;
6442 pt = nextpt;
6443 }
6444 if (!pt->corner) {
6445 *vertex_ptr++ = *outline_vertices++;
6446 *vertex_ptr++ = *outline_vertices++;
6447 }
6448 }
6449
6450 /* back vertices and faces */
6451 back_faces = face_ptr;
6452 back_vertices = vertex_ptr;
6453 for (j = 0; j < glyphs[i].ordered_vertices.count; j++)
6454 {
6455 D3DXVECTOR2 *pt = get_ordered_vertex(&glyphs[i], j);
6456 vertex_ptr->position.x = pt->x + glyphs[i].offset_x;
6457 vertex_ptr->position.y = pt->y;
6458 vertex_ptr->position.z = 0;
6459 vertex_ptr->normal.x = 0;
6460 vertex_ptr->normal.y = 0;
6461 vertex_ptr->normal.z = 1;
6462 vertex_ptr++;
6463 }
6464 count = back_vertices - vertices;
6465 for (j = 0; j < glyphs[i].faces.count; j++)
6466 {
6467 face *f = &glyphs[i].faces.items[j];
6468 (*face_ptr)[0] = (*f)[0] + count;
6469 (*face_ptr)[1] = (*f)[1] + count;
6470 (*face_ptr)[2] = (*f)[2] + count;
6471 face_ptr++;
6472 }
6473
6474 /* front vertices and faces */
6475 j = count = vertex_ptr - back_vertices;
6476 while (j--)
6477 {
6478 vertex_ptr->position.x = back_vertices->position.x;
6479 vertex_ptr->position.y = back_vertices->position.y;
6480 vertex_ptr->position.z = -extrusion;
6481 vertex_ptr->normal.x = 0;
6482 vertex_ptr->normal.y = 0;
6483 vertex_ptr->normal.z = extrusion == 0.0f ? 1.0f : -1.0f;
6484 vertex_ptr++;
6485 back_vertices++;
6486 }
6487 j = face_ptr - back_faces;
6488 while (j--)
6489 {
6490 (*face_ptr)[0] = (*back_faces)[0] + count;
6491 (*face_ptr)[1] = (*back_faces)[f1] + count;
6492 (*face_ptr)[2] = (*back_faces)[f2] + count;
6493 face_ptr++;
6494 back_faces++;
6495 }
6496 }
6497
6498 *mesh_ptr = mesh;
6499 hr = D3D_OK;
6500error:
6501 if (mesh) {
6502 if (faces) mesh->lpVtbl->UnlockIndexBuffer(mesh);
6503 if (vertices) mesh->lpVtbl->UnlockVertexBuffer(mesh);
6504 if (hr != D3D_OK) mesh->lpVtbl->Release(mesh);
6505 }
6506 if (glyphs) {
6507 for (i = 0; i < textlen; i++)
6508 {
6509 int j;
6510 for (j = 0; j < glyphs[i].outlines.count; j++)
6511 free(glyphs[i].outlines.items[j].items);
6512 free(glyphs[i].outlines.items);
6513 free(glyphs[i].faces.items);
6514 free(glyphs[i].ordered_vertices.items);
6515 }
6516 free(glyphs);
6517 }
6518 if (triangulations.items) {
6519 int i;
6520 for (i = 0; i < triangulations.count; i++)
6521 free(triangulations.items[i].vertex_stack.items);
6522 free(triangulations.items);
6523 }
6524 free(raw_outline);
6525 if (oldfont) SelectObject(hdc, oldfont);
6526 if (font) DeleteObject(font);
6527
6528 return hr;
6529}
D3DXVECTOR2 *WINAPI D3DXVec2Normalize(D3DXVECTOR2 *pout, const D3DXVECTOR2 *pv)
Definition: math.c:1659
static HRESULT create_outline(struct glyphinfo *glyph, void *raw_outline, int datasize, float max_deviation_sq, unsigned int emsquare, const struct cos_table *cos_table)
Definition: mesh.c:5671
static HRESULT triangulate(struct triangulation_array *triangulations)
Definition: mesh.c:5959
static D3DXVECTOR2 * get_ordered_vertex(struct glyphinfo *glyph, WORD index)
Definition: mesh.c:5839
#define lstrlenW
Definition: compat.h:750
#define D3DXToRadian(degree)
Definition: d3dx9math.h:33
pKey DeleteObject()
GLfloat f
Definition: glext.h:7540
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
#define debugstr_w
Definition: kernel32.h:32
Definition: mk_font.cpp:20
#define OBJ_FONT
Definition: objidl.idl:1019
#define f2(x, y, z)
Definition: sha1.c:31
#define f1(x, y, z)
Definition: sha1.c:30
LONG lfHeight
Definition: dimm.idl:59
LONG lfWidth
Definition: dimm.idl:60
long y
Definition: dcommon.idl:24
long x
Definition: dcommon.idl:24
FLOAT gmfBlackBoxX
Definition: wingdi.h:3172
POINTFLOAT gmfptGlyphOrigin
Definition: wingdi.h:3174
short gmCellIncX
Definition: wingdi.h:2891
UINT gmBlackBoxY
Definition: wingdi.h:2889
UINT gmBlackBoxX
Definition: wingdi.h:2888
short gmCellIncY
Definition: wingdi.h:2892
POINT gmptGlyphOrigin
Definition: wingdi.h:2890
Definition: wingdi.h:2918
FLOAT x
Definition: wingdi.h:3168
float offset_x
Definition: mesh.c:5472
struct point2d_index_array ordered_vertices
Definition: mesh.c:5471
struct face_array faces
Definition: mesh.c:5470
struct triangulation * items
Definition: mesh.c:5494
struct glyphinfo * glyph
Definition: mesh.c:5496
D3DXVECTOR3 normal
Definition: mesh.c:4667
D3DXVECTOR3 position
Definition: mesh.c:4666
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
HGDIOBJ WINAPI GetCurrentObject(_In_ HDC, _In_ UINT)
Definition: dc.c:428
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
UINT WINAPI GetOutlineTextMetricsW(_In_ HDC hdc, _In_ UINT cjCopy, _Out_writes_bytes_opt_(cjCopy) LPOUTLINETEXTMETRICW potm)
HFONT WINAPI CreateFontIndirectW(_In_ const LOGFONTW *)
#define GGO_NATIVE
Definition: wingdi.h:850
DWORD WINAPI GetGlyphOutlineW(_In_ HDC hdc, _In_ UINT uChar, _In_ UINT fuFormat, _Out_ LPGLYPHMETRICS lpgm, _In_ DWORD cjBuffer, _Out_writes_bytes_opt_(cjBuffer) LPVOID pvBuffer, _In_ CONST MAT2 *lpmat2)

Referenced by D3DXCreateTextA(), and D3DXCreateTextTest().

◆ D3DXCreateTorus()

HRESULT WINAPI D3DXCreateTorus ( struct IDirect3DDevice9 *  device,
float  innerradius,
float  outerradius,
UINT  sides,
UINT  rings,
struct ID3DXMesh **  mesh,
ID3DXBuffer **  adjacency 
)

Definition at line 5308 of file mesh.c.

5310{
5311 HRESULT hr;
5312 ID3DXMesh *torus;
5313 WORD (*faces)[3];
5314 struct vertex *vertices;
5315 float phi, phi_step, sin_phi, cos_phi;
5316 float theta, theta_step, sin_theta, cos_theta;
5317 unsigned int i, j, numvert, numfaces;
5318
5319 TRACE("device %p, innerradius %.8e, outerradius %.8e, sides %u, rings %u, mesh %p, adjacency %p.\n",
5320 device, innerradius, outerradius, sides, rings, mesh, adjacency);
5321
5322 numvert = sides * rings;
5323 numfaces = numvert * 2;
5324
5325 if (!device || innerradius < 0.0f || outerradius < 0.0f || sides < 3 || rings < 3 || !mesh)
5326 {
5327 WARN("Invalid arguments.\n");
5328 return D3DERR_INVALIDCALL;
5329 }
5330
5331 if (FAILED(hr = D3DXCreateMeshFVF(numfaces, numvert, D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_NORMAL, device, &torus)))
5332 return hr;
5333
5334 if (FAILED(hr = torus->lpVtbl->LockVertexBuffer(torus, 0, (void **)&vertices)))
5335 {
5336 torus->lpVtbl->Release(torus);
5337 return hr;
5338 }
5339
5340 if (FAILED(hr = torus->lpVtbl->LockIndexBuffer(torus, 0, (void **)&faces)))
5341 {
5342 torus->lpVtbl->UnlockVertexBuffer(torus);
5343 torus->lpVtbl->Release(torus);
5344 return hr;
5345 }
5346
5347 phi_step = D3DX_PI / sides * 2.0f;
5348 theta_step = D3DX_PI / rings * -2.0f;
5349
5350 theta = 0.0f;
5351
5352 for (i = 0; i < rings; ++i)
5353 {
5354 phi = 0.0f;
5355
5356 sin_theta = sinf(theta);
5357 cos_theta = cosf(theta);
5358
5359 for (j = 0; j < sides; ++j)
5360 {
5361 sin_phi = sinf(phi);
5362 cos_phi = cosf(phi);
5363
5364 vertices[i * sides + j].position.x = (innerradius * cos_phi + outerradius) * cos_theta;
5365 vertices[i * sides + j].position.y = (innerradius * cos_phi + outerradius) * sin_theta;
5366 vertices[i * sides + j].position.z = innerradius * sin_phi;
5367 vertices[i * sides + j].normal.x = cos_phi * cos_theta;
5368 vertices[i * sides + j].normal.y = cos_phi * sin_theta;
5369 vertices[i * sides + j].normal.z = sin_phi;
5370
5371 phi += phi_step;
5372 }
5373
5374 theta += theta_step;
5375 }
5376
5377 for (i = 0; i < numfaces - sides * 2; ++i)
5378 {
5379 faces[i][0] = i % 2 ? i / 2 + sides : i / 2;
5380 faces[i][1] = (i / 2 + 1) % sides ? i / 2 + 1 : i / 2 + 1 - sides;
5381 faces[i][2] = (i + 1) % (sides * 2) ? (i + 1) / 2 + sides : (i + 1) / 2;
5382 }
5383
5384 for (j = 0; i < numfaces; ++i, ++j)
5385 {
5386 faces[i][0] = i % 2 ? j / 2 : i / 2;
5387 faces[i][1] = (i / 2 + 1) % sides ? i / 2 + 1 : i / 2 + 1 - sides;
5388 faces[i][2] = i == numfaces - 1 ? 0 : (j + 1) / 2;
5389 }
5390
5391 torus->lpVtbl->UnlockIndexBuffer(torus);
5392 torus->lpVtbl->UnlockVertexBuffer(torus);
5393
5394 if (adjacency)
5395 {
5396 if (FAILED(hr = D3DXCreateBuffer(numfaces * sizeof(DWORD) * 3, adjacency)))
5397 {
5398 torus->lpVtbl->Release(torus);
5399 return hr;
5400 }
5401
5402 if (FAILED(hr = torus->lpVtbl->GenerateAdjacency(torus, 0.0f, (*adjacency)->lpVtbl->GetBufferPointer(*adjacency))))
5403 {
5404 (*adjacency)->lpVtbl->Release(*adjacency);
5405 torus->lpVtbl->Release(torus);
5406 return hr;
5407 }
5408 }
5409
5410 *mesh = torus;
5411
5412 return D3D_OK;
5413}

Referenced by D3DXCreateTorusTest(), and test_torus().

◆ D3DXDeclaratorFromFVF()

HRESULT WINAPI D3DXDeclaratorFromFVF ( DWORD  fvf,
D3DVERTEXELEMENT9  declaration[MAX_FVF_DECL_SIZE] 
)

Definition at line 2034 of file mesh.c.

2035{
2036 static const D3DVERTEXELEMENT9 end_element = D3DDECL_END();
2037 DWORD tex_count = (fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
2038 unsigned int offset = 0;
2039 unsigned int idx = 0;
2040 unsigned int i;
2041
2042 TRACE("fvf %#lx, declaration %p.\n", fvf, declaration);
2043
2045
2046 if (fvf & D3DFVF_POSITION_MASK)
2047 {
2048 BOOL has_blend = (fvf & D3DFVF_XYZB5) >= D3DFVF_XYZB1;
2049 DWORD blend_count = 1 + (((fvf & D3DFVF_XYZB5) - D3DFVF_XYZB1) >> 1);
2050 BOOL has_blend_idx = (fvf & D3DFVF_LASTBETA_D3DCOLOR) || (fvf & D3DFVF_LASTBETA_UBYTE4);
2051
2052 if (has_blend_idx) --blend_count;
2053
2054 if ((fvf & D3DFVF_POSITION_MASK) == D3DFVF_XYZW
2055 || (has_blend && blend_count > 4))
2056 return D3DERR_INVALIDCALL;
2057
2058 if ((fvf & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)
2060 else
2062
2063 if (has_blend)
2064 {
2065 switch (blend_count)
2066 {
2067 case 0:
2068 break;
2069 case 1:
2071 break;
2072 case 2:
2074 break;
2075 case 3:
2077 break;
2078 case 4:
2080 break;
2081 default:
2082 ERR("Invalid blend count %lu.\n", blend_count);
2083 break;
2084 }
2085
2086 if (has_blend_idx)
2087 {
2088 if (fvf & D3DFVF_LASTBETA_UBYTE4)
2090 else if (fvf & D3DFVF_LASTBETA_D3DCOLOR)
2092 }
2093 }
2094 }
2095
2096 if (fvf & D3DFVF_NORMAL)
2098 if (fvf & D3DFVF_PSIZE)
2100 if (fvf & D3DFVF_DIFFUSE)
2102 if (fvf & D3DFVF_SPECULAR)
2104
2105 for (i = 0; i < tex_count; ++i)
2106 {
2107 switch ((fvf >> (16 + 2 * i)) & 0x03)
2108 {
2111 break;
2114 break;
2117 break;
2120 break;
2121 }
2122 }
2123
2124 declaration[idx] = end_element;
2125
2126 return D3D_OK;
2127}
#define D3DFVF_DIFFUSE
Definition: d3d8types.h:122
#define D3DFVF_RESERVED2
Definition: d3d8types.h:136
#define D3DFVF_TEXCOUNT_SHIFT
Definition: d3d8types.h:125
#define D3DFVF_XYZB1
Definition: d3d8types.h:115
#define D3DFVF_LASTBETA_UBYTE4
Definition: d3d8types.h:135
#define D3DFVF_XYZB5
Definition: d3d8types.h:119
#define D3DFVF_XYZRHW
Definition: d3d8types.h:114
#define D3DFVF_TEXTUREFORMAT4
Definition: d3d8types.h:63
#define D3DFVF_TEXTUREFORMAT3
Definition: d3d8types.h:62
#define D3DFVF_TEXCOUNT_MASK
Definition: d3d8types.h:124
#define D3DFVF_TEXTUREFORMAT1
Definition: d3d8types.h:60
#define D3DFVF_PSIZE
Definition: d3d8types.h:121
#define D3DFVF_TEXTUREFORMAT2
Definition: d3d8types.h:61
#define D3DFVF_SPECULAR
Definition: d3d8types.h:123
#define D3DFVF_POSITION_MASK
Definition: d3d8types.h:112
#define D3DFVF_RESERVED0
Definition: d3d8types.h:111
@ D3DDECLUSAGE_BLENDWEIGHT
Definition: d3d9types.h:237
@ D3DDECLUSAGE_BLENDINDICES
Definition: d3d9types.h:238
@ D3DDECLUSAGE_POSITIONT
Definition: d3d9types.h:245
@ D3DDECLUSAGE_TEXCOORD
Definition: d3d9types.h:241
@ D3DDECLUSAGE_PSIZE
Definition: d3d9types.h:240
@ D3DDECLUSAGE_COLOR
Definition: d3d9types.h:246
#define D3DFVF_LASTBETA_D3DCOLOR
Definition: d3d9types.h:169
#define D3DFVF_XYZW
Definition: d3d9types.h:152
static void append_decl_element(D3DVERTEXELEMENT9 *declaration, UINT *idx, UINT *offset, D3DDECLTYPE type, D3DDECLUSAGE usage, UINT usage_idx)
Definition: mesh.c:2017

Referenced by d3dx9_mesh_CloneMeshFVF(), d3dx9_skin_info_SetFVF(), D3DXCreateMeshFVF(), D3DXCreateSkinInfoFVF(), test_create_skin_info(), and test_fvf_to_decl().

◆ D3DXFrameDestroy()

HRESULT WINAPI D3DXFrameDestroy ( D3DXFRAME *  frame,
ID3DXAllocateHierarchy *  alloc_hier 
)

Definition at line 4101 of file mesh.c.

4102{
4103 HRESULT hr;
4104 BOOL last = FALSE;
4105
4106 TRACE("(%p, %p)\n", frame, alloc_hier);
4107
4108 if (!frame || !alloc_hier)
4109 return D3DERR_INVALIDCALL;
4110
4111 while (!last) {
4113 D3DXFRAME *current_frame;
4114
4115 if (frame->pFrameSibling) {
4116 current_frame = frame->pFrameSibling;
4117 frame->pFrameSibling = current_frame->pFrameSibling;
4118 current_frame->pFrameSibling = NULL;
4119 } else {
4120 current_frame = frame;
4121 last = TRUE;
4122 }
4123
4124 if (current_frame->pFrameFirstChild) {
4126 if (FAILED(hr)) return hr;
4127 current_frame->pFrameFirstChild = NULL;
4128 }
4129
4130 container = current_frame->pMeshContainer;
4131 while (container) {
4132 D3DXMESHCONTAINER *next_container = container->pNextMeshContainer;
4133 hr = alloc_hier->lpVtbl->DestroyMeshContainer(alloc_hier, container);
4134 if (FAILED(hr)) return hr;
4135 container = next_container;
4136 }
4137 hr = alloc_hier->lpVtbl->DestroyFrame(alloc_hier, current_frame);
4138 if (FAILED(hr)) return hr;
4139 }
4140 return D3D_OK;
4141}
HRESULT WINAPI D3DXFrameDestroy(D3DXFRAME *frame, ID3DXAllocateHierarchy *alloc_hier)
Definition: mesh.c:4101
static ID3DXAllocateHierarchy alloc_hier
Definition: mesh.c:1991
static const LARGE_INTEGER *static const HANDLE const LARGE_INTEGER *static PSLIST_ENTRY PSLIST_ENTRY last
Definition: sync.c:64
struct _D3DXFRAME * pFrameSibling
Definition: d3dx9anim.h:110
LPD3DXMESHCONTAINER pMeshContainer
Definition: d3dx9anim.h:109
struct _D3DXFRAME * pFrameFirstChild
Definition: d3dx9anim.h:111

Referenced by D3DXFrameDestroy(), D3DXLoadMeshHierarchyFromXInMemory(), and D3DXLoadMeshTest().

◆ D3DXFrameFind()

D3DXFRAME *WINAPI D3DXFrameFind ( const D3DXFRAME *  root,
const char *  name 
)

Definition at line 7716 of file mesh.c.

7717{
7718 D3DXFRAME *found = NULL, *frame;
7719 struct list queue;
7720
7721 TRACE("root frame %p, name %s.\n", root, debugstr_a(name));
7722
7723 if (!root)
7724 return NULL;
7725
7726 list_init(&queue);
7727
7728 frame = (D3DXFRAME *)root;
7729
7730 for (;;)
7731 {
7732 struct frame_node *node;
7733
7734 while (frame)
7735 {
7736 if ((name && frame->Name && !strcmp(frame->Name, name)) || (!name && !frame->Name))
7737 {
7738 found = frame;
7739 goto cleanup;
7740 }
7741
7743 goto cleanup;
7744
7746 }
7747
7748 if (list_empty(&queue))
7749 break;
7750
7752 list_remove(&node->entry);
7753 frame = node->frame->pFrameFirstChild;
7754 free(node);
7755 }
7756
7757cleanup:
7759
7760 return found;
7761}
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static int list_empty(struct list_entry *head)
Definition: list.h:58
static void list_init(struct list_entry *head)
Definition: list.h:51
Definition: list.h:39
static void empty_frame_queue(struct list *queue)
Definition: mesh.c:7706
static BOOL queue_frame_node(struct list *queue, D3DXFRAME *frame)
Definition: mesh.c:7689
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3324
uint32_t entry
Definition: isohybrid.c:63
char * Name
Definition: d3dx9anim.h:107
D3DXFRAME * frame
Definition: mesh.c:7686
Definition: list.h:15
Definition: name.c:39
Definition: queue.c:179
#define LIST_ENTRY(type)
Definition: queue.h:175
Definition: dlist.c:348

Referenced by test_D3DXFrameFind().

◆ D3DXFVFFromDeclarator()

HRESULT WINAPI D3DXFVFFromDeclarator ( const D3DVERTEXELEMENT9 *  declaration,
DWORD *  fvf 
)

Definition at line 2132 of file mesh.c.

2133{
2134 unsigned int i = 0, texture, offset;
2135
2136 TRACE("(%p, %p)\n", declaration, fvf);
2137
2138 *fvf = 0;
2140 {
2142 declaration[1].UsageIndex == 0) &&
2144 declaration[2].UsageIndex == 0))
2145 {
2146 return D3DERR_INVALIDCALL;
2147 }
2149 declaration[1].Usage == D3DDECLUSAGE_BLENDINDICES && declaration[1].UsageIndex == 0)
2150 {
2152 {
2154 }
2155 else
2156 {
2158 }
2159 i = 2;
2160 }
2162 declaration[1].UsageIndex == 0)
2163 {
2165 declaration[2].Usage == D3DDECLUSAGE_BLENDINDICES && declaration[2].UsageIndex == 0)
2166 {
2168 {
2169 *fvf |= D3DFVF_LASTBETA_UBYTE4;
2170 }
2171 else
2172 {
2174 }
2175 switch (declaration[1].Type)
2176 {
2177 case D3DDECLTYPE_FLOAT1: *fvf |= D3DFVF_XYZB2; break;
2178 case D3DDECLTYPE_FLOAT2: *fvf |= D3DFVF_XYZB3; break;
2179 case D3DDECLTYPE_FLOAT3: *fvf |= D3DFVF_XYZB4; break;
2180 case D3DDECLTYPE_FLOAT4: *fvf |= D3DFVF_XYZB5; break;
2181 }
2182 i = 3;
2183 }
2184 else
2185 {
2186 switch (declaration[1].Type)
2187 {
2188 case D3DDECLTYPE_FLOAT1: *fvf |= D3DFVF_XYZB1; break;
2189 case D3DDECLTYPE_FLOAT2: *fvf |= D3DFVF_XYZB2; break;
2190 case D3DDECLTYPE_FLOAT3: *fvf |= D3DFVF_XYZB3; break;
2191 case D3DDECLTYPE_FLOAT4: *fvf |= D3DFVF_XYZB4; break;
2192 }
2193 i = 2;
2194 }
2195 }
2196 else
2197 {
2198 *fvf |= D3DFVF_XYZ;
2199 i = 1;
2200 }
2201 }
2203 declaration[0].UsageIndex == 0)
2204 {
2205 *fvf |= D3DFVF_XYZRHW;
2206 i = 1;
2207 }
2208
2210 {
2211 *fvf |= D3DFVF_NORMAL;
2212 i++;
2213 }
2215 declaration[i].UsageIndex == 0)
2216 {
2217 *fvf |= D3DFVF_PSIZE;
2218 i++;
2219 }
2221 declaration[i].UsageIndex == 0)
2222 {
2223 *fvf |= D3DFVF_DIFFUSE;
2224 i++;
2225 }
2227 declaration[i].UsageIndex == 1)
2228 {
2229 *fvf |= D3DFVF_SPECULAR;
2230 i++;
2231 }
2232
2233 for (texture = 0; texture < D3DDP_MAXTEXCOORD; i++, texture++)
2234 {
2235 if (declaration[i].Stream == 0xFF)
2236 {
2237 break;
2238 }
2240 declaration[i].UsageIndex == texture)
2241 {
2242 *fvf |= D3DFVF_TEXCOORDSIZE1(declaration[i].UsageIndex);
2243 }
2245 declaration[i].UsageIndex == texture)
2246 {
2247 *fvf |= D3DFVF_TEXCOORDSIZE2(declaration[i].UsageIndex);
2248 }
2250 declaration[i].UsageIndex == texture)
2251 {
2252 *fvf |= D3DFVF_TEXCOORDSIZE3(declaration[i].UsageIndex);
2253 }
2255 declaration[i].UsageIndex == texture)
2256 {
2257 *fvf |= D3DFVF_TEXCOORDSIZE4(declaration[i].UsageIndex);
2258 }
2259 else
2260 {
2261 return D3DERR_INVALIDCALL;
2262 }
2263 }
2264
2265 *fvf |= (texture << D3DFVF_TEXCOUNT_SHIFT);
2266
2267 for (offset = 0, i = 0; declaration[i].Stream != 0xFF;
2269 {
2270 if (declaration[i].Offset != offset)
2271 {
2272 return D3DERR_INVALIDCALL;
2273 }
2274 }
2275
2276 return D3D_OK;
2277}
#define D3DFVF_XYZB4
Definition: d3d8types.h:118
#define D3DFVF_XYZB3
Definition: d3d8types.h:117
#define D3DDP_MAXTEXCOORD
Definition: d3d8types.h:303
#define D3DFVF_XYZB2
Definition: d3d8types.h:116
#define D3DFVF_TEXCOORDSIZE4(CoordIndex)
Definition: d3d8types.h:67
#define D3DFVF_TEXCOORDSIZE3(CoordIndex)
Definition: d3d8types.h:66
#define D3DFVF_TEXCOORDSIZE2(CoordIndex)
Definition: d3d8types.h:65
#define D3DFVF_TEXCOORDSIZE1(CoordIndex)
Definition: d3d8types.h:64
GLenum GLuint texture
Definition: glext.h:6295
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101

Referenced by d3dx9_skin_info_SetDeclaration(), D3DXCreateMesh(), test_create_skin_info(), and test_decl_to_fvf().

◆ D3DXGetDeclLength()

UINT WINAPI D3DXGetDeclLength ( const D3DVERTEXELEMENT9 *  decl)

Definition at line 2352 of file mesh.c.

2353{
2355
2356 TRACE("decl %p\n", decl);
2357
2358 /* null decl results in exception on Windows XP */
2359
2360 for (element = decl; element->Stream != 0xff; ++element);
2361
2362 return element - decl;
2363}

Referenced by test_clone_mesh(), and test_get_decl_length().

◆ D3DXGetDeclVertexSize()

UINT WINAPI D3DXGetDeclVertexSize ( const D3DVERTEXELEMENT9 *  decl,
DWORD  stream_idx 
)

Definition at line 2321 of file mesh.c.

2322{
2324 UINT size = 0;
2325
2326 TRACE("decl %p, stream_idx %lu.\n", decl, stream_idx);
2327
2328 if (!decl) return 0;
2329
2330 for (element = decl; element->Stream != 0xff; ++element)
2331 {
2332 UINT type_size;
2333
2334 if (element->Stream != stream_idx) continue;
2335
2337 {
2338 FIXME("Unhandled element type %#x, size will be incorrect.\n", element->Type);
2339 continue;
2340 }
2341
2342 type_size = d3dx_decltype_size[element->Type];
2343 if (element->Offset + type_size > size) size = element->Offset + type_size;
2344 }
2345
2346 return size;
2347}
#define ARRAY_SIZE(A)
Definition: main.h:20

Referenced by d3dx9_mesh_UpdateSemantics(), D3DXCreateMesh(), D3DXLoadMeshFromXInMemory(), test_clone_mesh(), and test_get_decl_vertex_size().

◆ D3DXGetFVFVertexSize()

UINT WINAPI D3DXGetFVFVertexSize ( DWORD  FVF)

Definition at line 2287 of file mesh.c.

2288{
2289 DWORD size = 0;
2290 UINT i;
2291 UINT numTextures = (FVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
2292
2293 if (FVF & D3DFVF_NORMAL) size += sizeof(D3DXVECTOR3);
2294 if (FVF & D3DFVF_DIFFUSE) size += sizeof(DWORD);
2295 if (FVF & D3DFVF_SPECULAR) size += sizeof(DWORD);
2296 if (FVF & D3DFVF_PSIZE) size += sizeof(DWORD);
2297
2298 switch (FVF & D3DFVF_POSITION_MASK)
2299 {
2300 case D3DFVF_XYZ: size += sizeof(D3DXVECTOR3); break;
2301 case D3DFVF_XYZRHW: size += 4 * sizeof(FLOAT); break;
2302 case D3DFVF_XYZB1: size += 4 * sizeof(FLOAT); break;
2303 case D3DFVF_XYZB2: size += 5 * sizeof(FLOAT); break;
2304 case D3DFVF_XYZB3: size += 6 * sizeof(FLOAT); break;
2305 case D3DFVF_XYZB4: size += 7 * sizeof(FLOAT); break;
2306 case D3DFVF_XYZB5: size += 8 * sizeof(FLOAT); break;
2307 case D3DFVF_XYZW: size += 4 * sizeof(FLOAT); break;
2308 }
2309
2310 for (i = 0; i < numTextures; i++)
2311 {
2312 size += Get_TexCoord_Size_From_FVF(FVF, i) * sizeof(FLOAT);
2313 }
2314
2315 return size;
2316}
static UINT Get_TexCoord_Size_From_FVF(DWORD FVF, int tex_num)
Definition: mesh.c:2282

Referenced by check_vertex_buffer_(), compare_mesh(), compare_text_outline_mesh(), D3DXComputeBoundingBoxTest(), D3DXComputeBoundingSphereTest(), and D3DXLoadSkinMeshFromXof().

◆ D3DXIntersect()

HRESULT WINAPI D3DXIntersect ( ID3DXBaseMesh *  mesh,
const D3DXVECTOR3 *  ray_pos,
const D3DXVECTOR3 *  ray_dir,
BOOL *  hit,
DWORD *  face_index,
float *  u,
float *  v,
float *  distance,
ID3DXBuffer **  all_hits,
DWORD *  count_of_hits 
)

Definition at line 7656 of file mesh.c.

7658{
7659 FIXME("mesh %p, ray_pos %p, ray_dir %p, hit %p, face_index %p, u %p, v %p, distance %p, all_hits %p, "
7660 "count_of_hits %p stub!\n", mesh, ray_pos, ray_dir, hit, face_index, u, v, distance, all_hits, count_of_hits);
7661
7662 return E_NOTIMPL;
7663}
const GLdouble * v
Definition: gl.h:2040
GLsizei GLsizei GLfloat distance
Definition: glext.h:11755
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240

◆ D3DXIntersectTri()

BOOL WINAPI D3DXIntersectTri ( const D3DXVECTOR3 *  p0,
const D3DXVECTOR3 *  p1,
const D3DXVECTOR3 *  p2,
const D3DXVECTOR3 *  praypos,
const D3DXVECTOR3 *  praydir,
float *  pu,
float *  pv,
float *  pdist 
)

Definition at line 2365 of file mesh.c.

2367{
2368 D3DXMATRIX m;
2370
2371 TRACE("p0 %p, p1 %p, p2 %p, praypos %p, praydir %p, pu %p, pv %p, pdist %p.\n",
2372 p0, p1, p2, praypos, praydir, pu, pv, pdist);
2373
2374 m.m[0][0] = p1->x - p0->x;
2375 m.m[1][0] = p2->x - p0->x;
2376 m.m[2][0] = -praydir->x;
2377 m.m[3][0] = 0.0f;
2378 m.m[0][1] = p1->y - p0->y;
2379 m.m[1][1] = p2->y - p0->y;
2380 m.m[2][1] = -praydir->y;
2381 m.m[3][1] = 0.0f;
2382 m.m[0][2] = p1->z - p0->z;
2383 m.m[1][2] = p2->z - p0->z;
2384 m.m[2][2] = -praydir->z;
2385 m.m[3][2] = 0.0f;
2386 m.m[0][3] = 0.0f;
2387 m.m[1][3] = 0.0f;
2388 m.m[2][3] = 0.0f;
2389 m.m[3][3] = 1.0f;
2390
2391 vec.x = praypos->x - p0->x;
2392 vec.y = praypos->y - p0->y;
2393 vec.z = praypos->z - p0->z;
2394 vec.w = 0.0f;
2395
2396 if ( D3DXMatrixInverse(&m, NULL, &m) )
2397 {
2398 D3DXVec4Transform(&vec, &vec, &m);
2399 if ( (vec.x >= 0.0f) && (vec.y >= 0.0f) && (vec.x + vec.y <= 1.0f) && (vec.z >= 0.0f) )
2400 {
2401 if (pu) *pu = vec.x;
2402 if (pv) *pv = vec.y;
2403 if (pdist) *pdist = fabsf( vec.z );
2404 return TRUE;
2405 }
2406 }
2407
2408 return FALSE;
2409}
D3DXVECTOR4 *WINAPI D3DXVec4Transform(D3DXVECTOR4 *pout, const D3DXVECTOR4 *pv, const D3DXMATRIX *pm)
Definition: math.c:2073
D3DXMATRIX *WINAPI D3DXMatrixInverse(D3DXMATRIX *pout, FLOAT *pdeterminant, const D3DXMATRIX *pm)
Definition: math.c:254
const GLfloat * m
Definition: glext.h:10848

Referenced by D3DXIntersectTriTest().

◆ D3DXLoadMeshFromXA()

HRESULT WINAPI D3DXLoadMeshFromXA ( const char *  filename,
DWORD  options,
struct IDirect3DDevice9 *  device,
struct ID3DXBuffer **  adjacency,
struct ID3DXBuffer **  materials,
struct ID3DXBuffer **  effect_instances,
DWORD *  num_materials,
struct ID3DXMesh **  mesh 
)

Definition at line 4143 of file mesh.c.

4146{
4148 HRESULT hr;
4149 int len;
4150
4151 TRACE("filename %s, options %#lx, device %p, adjacency %p, materials %p, "
4152 "effect_instances %p, num_materials %p, mesh %p.\n",
4153 debugstr_a(filename), options, device, adjacency, materials,
4154 effect_instances, num_materials, mesh);
4155
4156 if (!filename)
4157 return D3DERR_INVALIDCALL;
4158
4160 filenameW = malloc(len * sizeof(WCHAR));
4161 if (!filenameW) return E_OUTOFMEMORY;
4163
4164 hr = D3DXLoadMeshFromXW(filenameW, options, device, adjacency, materials,
4165 effect_instances, num_materials, mesh);
4166 free(filenameW);
4167
4168 return hr;
4169}
HRESULT WINAPI D3DXLoadMeshFromXW(const WCHAR *filename, DWORD options, struct IDirect3DDevice9 *device, struct ID3DXBuffer **adjacency, struct ID3DXBuffer **materials, struct ID3DXBuffer **effect_instances, DWORD *num_materials, struct ID3DXMesh **mesh)
Definition: mesh.c:4171
const char * filename
Definition: ioapi.h:137
static const WCHAR filenameW[]
Definition: resource.c:27

◆ D3DXLoadMeshFromXInMemory()

HRESULT WINAPI D3DXLoadMeshFromXInMemory ( const void *  memory,
DWORD  memory_size,
DWORD  options,
struct IDirect3DDevice9 *  device,
struct ID3DXBuffer **  adjacency_out,
struct ID3DXBuffer **  materials_out,
struct ID3DXBuffer **  effects_out,
DWORD *  num_materials_out,
struct ID3DXMesh **  mesh_out 
)

Definition at line 4297 of file mesh.c.

4300{
4301 HRESULT hr;
4302 ID3DXFile *d3dxfile = NULL;
4303 ID3DXFileEnumObject *enumobj = NULL;
4304 ID3DXFileData *filedata = NULL;
4306 ID3DXBuffer *materials = NULL;
4307 ID3DXBuffer *effects = NULL;
4308 ID3DXBuffer *adjacency = NULL;
4309 struct list container_list = LIST_INIT(container_list);
4310 struct mesh_container *container_ptr, *next_container_ptr;
4312 DWORD num_faces, num_vertices;
4314 DWORD provide_flags = 0;
4315 DWORD fvf;
4316 ID3DXMesh *concat_mesh = NULL;
4318 BYTE *concat_vertices = NULL;
4319 void *concat_indices = NULL;
4320 DWORD index_offset;
4321 DWORD concat_vertex_size;
4322 SIZE_T i, nb_children;
4323 GUID guid;
4324
4325 TRACE("memory %p, memory_size %lu, options %#lx, device %p, adjacency_out %p, materials_out %p, "
4326 "effects_out %p, num_materials_out %p, mesh_out %p.\n", memory, memory_size, options,
4327 device, adjacency_out, materials_out, effects_out, num_materials_out, mesh_out);
4328
4329 if (!memory || !memory_size || !device || !mesh_out)
4330 return D3DERR_INVALIDCALL;
4331
4332 hr = D3DXFileCreate(&d3dxfile);
4333 if (FAILED(hr)) goto cleanup;
4334
4335 hr = d3dxfile->lpVtbl->RegisterTemplates(d3dxfile, D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES);
4336 if (FAILED(hr)) goto cleanup;
4337
4338 source.lpMemory = (void*)memory;
4339 source.dSize = memory_size;
4340 hr = d3dxfile->lpVtbl->CreateEnumObject(d3dxfile, &source, D3DXF_FILELOAD_FROMMEMORY, &enumobj);
4341 if (FAILED(hr)) goto cleanup;
4342
4343 D3DXMatrixIdentity(&identity);
4344 if (adjacency_out) provide_flags |= PROVIDE_ADJACENCY;
4345 if (materials_out || effects_out) provide_flags |= PROVIDE_MATERIALS;
4346
4347 hr = enumobj->lpVtbl->GetChildren(enumobj, &nb_children);
4348 if (FAILED(hr))
4349 goto cleanup;
4350
4351 for (i = 0; i < nb_children; i++)
4352 {
4353 hr = enumobj->lpVtbl->GetChild(enumobj, i, &filedata);
4354 if (FAILED(hr))
4355 goto cleanup;
4356
4357 hr = filedata->lpVtbl->GetType(filedata, &guid);
4358 if (SUCCEEDED(hr)) {
4359 if (IsEqualGUID(&guid, &TID_D3DRMMesh)) {
4360 container_ptr = calloc(1, sizeof(*container_ptr));
4361 if (!container_ptr) {
4362 hr = E_OUTOFMEMORY;
4363 goto cleanup;
4364 }
4365
4367 (provide_flags & PROVIDE_ADJACENCY) ? &container_ptr->adjacency : NULL,
4368 (provide_flags & PROVIDE_MATERIALS) ? &container_ptr->materials : NULL,
4369 NULL, &container_ptr->num_materials, NULL, &container_ptr->mesh);
4370 if (container_ptr->mesh)
4371 {
4372 list_add_tail(&container_list, &container_ptr->entry);
4373 D3DXMatrixIdentity(&container_ptr->transform);
4374 }
4375 else
4376 {
4377 free(container_ptr);
4378 }
4379 } else if (IsEqualGUID(&guid, &TID_D3DRMFrame)) {
4380 hr = parse_frame(filedata, options, device, &identity, &container_list, provide_flags);
4381 }
4382 if (FAILED(hr)) goto cleanup;
4383 }
4384 filedata->lpVtbl->Release(filedata);
4385 filedata = NULL;
4386 if (FAILED(hr))
4387 goto cleanup;
4388 }
4389
4390 enumobj->lpVtbl->Release(enumobj);
4391 enumobj = NULL;
4392 d3dxfile->lpVtbl->Release(d3dxfile);
4393 d3dxfile = NULL;
4394
4395 if (list_empty(&container_list)) {
4396 hr = E_FAIL;
4397 goto cleanup;
4398 }
4399
4400 fvf = D3DFVF_XYZ;
4401 num_faces = 0;
4402 num_vertices = 0;
4403 num_materials = 0;
4404 LIST_FOR_EACH_ENTRY(container_ptr, &container_list, struct mesh_container, entry)
4405 {
4406 ID3DXMesh *mesh = container_ptr->mesh;
4407 fvf |= mesh->lpVtbl->GetFVF(mesh);
4408 num_faces += mesh->lpVtbl->GetNumFaces(mesh);
4409 num_vertices += mesh->lpVtbl->GetNumVertices(mesh);
4410 num_materials += container_ptr->num_materials;
4411 }
4412
4413 hr = D3DXCreateMeshFVF(num_faces, num_vertices, options, fvf, device, &concat_mesh);
4414 if (FAILED(hr)) goto cleanup;
4415
4416 hr = concat_mesh->lpVtbl->GetDeclaration(concat_mesh, concat_decl);
4417 if (FAILED(hr)) goto cleanup;
4418
4419 concat_vertex_size = D3DXGetDeclVertexSize(concat_decl, 0);
4420
4421 hr = concat_mesh->lpVtbl->LockVertexBuffer(concat_mesh, 0, (void**)&concat_vertices);
4422 if (FAILED(hr)) goto cleanup;
4423
4424 LIST_FOR_EACH_ENTRY(container_ptr, &container_list, struct mesh_container, entry)
4425 {
4427 ID3DXMesh *mesh = container_ptr->mesh;
4428 DWORD num_mesh_vertices = mesh->lpVtbl->GetNumVertices(mesh);
4429 DWORD mesh_vertex_size;
4430 const BYTE *mesh_vertices;
4431 DWORD i;
4432
4433 hr = mesh->lpVtbl->GetDeclaration(mesh, mesh_decl);
4434 if (FAILED(hr)) goto cleanup;
4435
4436 mesh_vertex_size = D3DXGetDeclVertexSize(mesh_decl, 0);
4437
4438 hr = mesh->lpVtbl->LockVertexBuffer(mesh, D3DLOCK_READONLY, (void**)&mesh_vertices);
4439 if (FAILED(hr)) goto cleanup;
4440
4441 for (i = 0; i < num_mesh_vertices; i++) {
4442 int j;
4443 int k = 1;
4444
4445 D3DXVec3TransformCoord((D3DXVECTOR3*)concat_vertices,
4446 (D3DXVECTOR3*)mesh_vertices,
4447 &container_ptr->transform);
4448 for (j = 1; concat_decl[j].Stream != 0xff; j++)
4449 {
4450 if (concat_decl[j].Usage == mesh_decl[k].Usage &&
4451 concat_decl[j].UsageIndex == mesh_decl[k].UsageIndex)
4452 {
4453 if (concat_decl[j].Usage == D3DDECLUSAGE_NORMAL) {
4454 D3DXVec3TransformCoord((D3DXVECTOR3*)(concat_vertices + concat_decl[j].Offset),
4455 (D3DXVECTOR3*)(mesh_vertices + mesh_decl[k].Offset),
4456 &container_ptr->transform);
4457 } else {
4458 memcpy(concat_vertices + concat_decl[j].Offset,
4459 mesh_vertices + mesh_decl[k].Offset,
4460 d3dx_decltype_size[mesh_decl[k].Type]);
4461 }
4462 k++;
4463 }
4464 }
4465 mesh_vertices += mesh_vertex_size;
4466 concat_vertices += concat_vertex_size;
4467 }
4468
4469 mesh->lpVtbl->UnlockVertexBuffer(mesh);
4470 }
4471
4472 concat_mesh->lpVtbl->UnlockVertexBuffer(concat_mesh);
4473 concat_vertices = NULL;
4474
4475 hr = concat_mesh->lpVtbl->LockIndexBuffer(concat_mesh, 0, &concat_indices);
4476 if (FAILED(hr)) goto cleanup;
4477
4478 index_offset = 0;
4479 LIST_FOR_EACH_ENTRY(container_ptr, &container_list, struct mesh_container, entry)
4480 {
4481 ID3DXMesh *mesh = container_ptr->mesh;
4482 const void *mesh_indices;
4483 DWORD num_mesh_faces = mesh->lpVtbl->GetNumFaces(mesh);
4484 DWORD i;
4485
4486 hr = mesh->lpVtbl->LockIndexBuffer(mesh, D3DLOCK_READONLY, (void**)&mesh_indices);
4487 if (FAILED(hr)) goto cleanup;
4488
4489 if (options & D3DXMESH_32BIT) {
4490 DWORD *dest = concat_indices;
4491 const DWORD *src = mesh_indices;
4492 for (i = 0; i < num_mesh_faces * 3; i++)
4493 *dest++ = index_offset + *src++;
4494 concat_indices = dest;
4495 } else {
4496 WORD *dest = concat_indices;
4497 const WORD *src = mesh_indices;
4498 for (i = 0; i < num_mesh_faces * 3; i++)
4499 *dest++ = index_offset + *src++;
4500 concat_indices = dest;
4501 }
4502 mesh->lpVtbl->UnlockIndexBuffer(mesh);
4503
4504 index_offset += num_mesh_faces * 3;
4505 }
4506
4507 concat_mesh->lpVtbl->UnlockIndexBuffer(concat_mesh);
4508 concat_indices = NULL;
4509
4510 if (num_materials) {
4511 DWORD *concat_attrib_buffer = NULL;
4512 DWORD offset = 0;
4513
4514 hr = concat_mesh->lpVtbl->LockAttributeBuffer(concat_mesh, 0, &concat_attrib_buffer);
4515 if (FAILED(hr)) goto cleanup;
4516
4517 LIST_FOR_EACH_ENTRY(container_ptr, &container_list, struct mesh_container, entry)
4518 {
4519 ID3DXMesh *mesh = container_ptr->mesh;
4520 const DWORD *mesh_attrib_buffer = NULL;
4521 DWORD count = mesh->lpVtbl->GetNumFaces(mesh);
4522
4523 hr = mesh->lpVtbl->LockAttributeBuffer(mesh, D3DLOCK_READONLY, (DWORD**)&mesh_attrib_buffer);
4524 if (FAILED(hr)) {
4525 concat_mesh->lpVtbl->UnlockAttributeBuffer(concat_mesh);
4526 goto cleanup;
4527 }
4528
4529 while (count--)
4530 *concat_attrib_buffer++ = offset + *mesh_attrib_buffer++;
4531
4532 mesh->lpVtbl->UnlockAttributeBuffer(mesh);
4533 offset += container_ptr->num_materials;
4534 }
4535 concat_mesh->lpVtbl->UnlockAttributeBuffer(concat_mesh);
4536 }
4537
4538 if (materials_out || effects_out) {
4539 D3DXMATERIAL *out_ptr;
4540 if (!num_materials) {
4541 /* create default material */
4543 if (FAILED(hr)) goto cleanup;
4544
4546 out_ptr->MatD3D.Diffuse.r = 0.5f;
4547 out_ptr->MatD3D.Diffuse.g = 0.5f;
4548 out_ptr->MatD3D.Diffuse.b = 0.5f;
4549 out_ptr->MatD3D.Specular.r = 0.5f;
4550 out_ptr->MatD3D.Specular.g = 0.5f;
4551 out_ptr->MatD3D.Specular.b = 0.5f;
4552 /* D3DXCreateBuffer initializes the rest to zero */
4553 } else {
4555 char *strings_out_ptr;
4556
4557 LIST_FOR_EACH_ENTRY(container_ptr, &container_list, struct mesh_container, entry)
4558 {
4559 if (container_ptr->materials) {
4560 DWORD i;
4561 const D3DXMATERIAL *in_ptr = ID3DXBuffer_GetBufferPointer(container_ptr->materials);
4562 for (i = 0; i < container_ptr->num_materials; i++)
4563 {
4564 if (in_ptr->pTextureFilename)
4565 buffer_size += strlen(in_ptr->pTextureFilename) + 1;
4566 in_ptr++;
4567 }
4568 }
4569 }
4570
4572 if (FAILED(hr)) goto cleanup;
4574 strings_out_ptr = (char*)(out_ptr + num_materials);
4575
4576 LIST_FOR_EACH_ENTRY(container_ptr, &container_list, struct mesh_container, entry)
4577 {
4578 if (container_ptr->materials) {
4579 DWORD i;
4580 const D3DXMATERIAL *in_ptr = ID3DXBuffer_GetBufferPointer(container_ptr->materials);
4581 for (i = 0; i < container_ptr->num_materials; i++)
4582 {
4583 out_ptr->MatD3D = in_ptr->MatD3D;
4584 if (in_ptr->pTextureFilename) {
4585 out_ptr->pTextureFilename = strings_out_ptr;
4586 strcpy(out_ptr->pTextureFilename, in_ptr->pTextureFilename);
4587 strings_out_ptr += strlen(in_ptr->pTextureFilename) + 1;
4588 }
4589 in_ptr++;
4590 out_ptr++;
4591 }
4592 }
4593 }
4594 }
4595 }
4596 if (!num_materials)
4597 num_materials = 1;
4598
4599 if (effects_out) {
4601 if (!materials_out) {
4603 materials = NULL;
4604 }
4605 }
4606
4607 if (adjacency_out) {
4608 if (!list_next(&container_list, list_head(&container_list))) {
4609 container_ptr = LIST_ENTRY(list_head(&container_list), struct mesh_container, entry);
4610 adjacency = container_ptr->adjacency;
4611 container_ptr->adjacency = NULL;
4612 } else {
4613 DWORD offset = 0;
4614 DWORD *out_ptr;
4615
4616 hr = D3DXCreateBuffer(num_faces * 3 * sizeof(DWORD), &adjacency);
4617 if (FAILED(hr)) goto cleanup;
4618
4620 LIST_FOR_EACH_ENTRY(container_ptr, &container_list, struct mesh_container, entry)
4621 {
4622 DWORD i;
4623 DWORD count = 3 * container_ptr->mesh->lpVtbl->GetNumFaces(container_ptr->mesh);
4624 DWORD *in_ptr = ID3DXBuffer_GetBufferPointer(container_ptr->adjacency);
4625
4626 for (i = 0; i < count; i++)
4627 *out_ptr++ = offset + *in_ptr++;
4628
4629 offset += count;
4630 }
4631 }
4632 }
4633
4634 *mesh_out = concat_mesh;
4635 if (adjacency_out) *adjacency_out = adjacency;
4636 if (materials_out) *materials_out = materials;
4637 if (effects_out) *effects_out = effects;
4638 if (num_materials_out) *num_materials_out = num_materials;
4639
4640 hr = D3D_OK;
4641cleanup:
4642 if (concat_indices) concat_mesh->lpVtbl->UnlockIndexBuffer(concat_mesh);
4643 if (concat_vertices) concat_mesh->lpVtbl->UnlockVertexBuffer(concat_mesh);
4644 if (filedata) filedata->lpVtbl->Release(filedata);
4645 if (enumobj) enumobj->lpVtbl->Release(enumobj);
4646 if (d3dxfile) d3dxfile->lpVtbl->Release(d3dxfile);
4647 if (FAILED(hr)) {
4648 if (concat_mesh) IUnknown_Release(concat_mesh);
4652 }
4653 LIST_FOR_EACH_ENTRY_SAFE(container_ptr, next_container_ptr, &container_list, struct mesh_container, entry)
4654 {
4655 if (container_ptr->mesh) IUnknown_Release(container_ptr->mesh);
4656 if (container_ptr->adjacency) ID3DXBuffer_Release(container_ptr->adjacency);
4657 if (container_ptr->materials) ID3DXBuffer_Release(container_ptr->materials);
4658 if (container_ptr->effects) ID3DXBuffer_Release(container_ptr->effects);
4659 free(container_ptr);
4660 }
4661 return hr;
4662}
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
D3DXVECTOR3 *WINAPI D3DXVec3TransformCoord(D3DXVECTOR3 *pout, const D3DXVECTOR3 *pv, const D3DXMATRIX *pm)
Definition: math.c:1895
#define PROVIDE_MATERIALS
Definition: mesh.c:41
HRESULT WINAPI D3DXLoadSkinMeshFromXof(struct ID3DXFileData *filedata, DWORD options, struct IDirect3DDevice9 *device, struct ID3DXBuffer **adjacency_out, struct ID3DXBuffer **materials_out, struct ID3DXBuffer **effects_out, DWORD *num_materials_out, struct ID3DXSkinInfo **skin_info_out, struct ID3DXMesh **mesh_out)
Definition: mesh.c:3487
#define PROVIDE_ADJACENCY
Definition: mesh.c:43
static HRESULT parse_frame(struct ID3DXFileData *filedata, DWORD options, struct IDirect3DDevice9 *device, const D3DXMATRIX *parent_transform, struct list *container_list, DWORD provide_flags)
Definition: mesh.c:4234
static HRESULT generate_effects(ID3DXBuffer *materials, DWORD num_materials, ID3DXBuffer **effects)
Definition: mesh.c:3389
HRESULT WINAPI D3DXFileCreate(ID3DXFile **d3dxfile)
Definition: xfile.c:693
GUID guid
Definition: version.c:147
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1597
struct tagD3DXMATERIAL D3DXMATERIAL
#define D3DXF_FILELOAD_FROMMEMORY
Definition: d3dx9xof.h:41
static char memory[1024 *256]
Definition: process.c:122
static char * dest
Definition: rtl.c:149
#define D3DRM_XTEMPLATE_BYTES
Definition: rmxftmpl.h:283
unsigned char D3DRM_XTEMPLATES[]
Definition: rmxftmpl.h:6
strcpy
Definition: string.h:131
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:236
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:242
__WINE_SERVER_LIST_INLINE struct list * list_next(const struct list *list, const struct list *elem)
Definition: list.h:117
D3DCOLORVALUE Diffuse
Definition: d3d8types.h:1101
D3DCOLORVALUE Specular
Definition: d3d8types.h:1103
ID3DXBuffer * materials
Definition: mesh.c:4228
ID3DXMesh * mesh
Definition: mesh.c:4226
struct list entry
Definition: mesh.c:4225
ID3DXBuffer * adjacency
Definition: mesh.c:4227
ID3DXBuffer * effects
Definition: mesh.c:4229
D3DXMATRIX transform
Definition: mesh.c:4231
DWORD num_materials
Definition: mesh.c:4230
D3DMATERIAL8 MatD3D
Definition: dx8vb.idl:77
#define LIST_INIT(head)
Definition: queue.h:197
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by D3DXLoadMeshFromXResource(), D3DXLoadMeshFromXW(), D3DXLoadMeshTest(), and test_LoadMeshFromX_().

◆ D3DXLoadMeshFromXResource()

HRESULT WINAPI D3DXLoadMeshFromXResource ( HMODULE  module,
const char *  name,
const char *  type,
DWORD  options,
struct IDirect3DDevice9 *  device,
struct ID3DXBuffer **  adjacency,
struct ID3DXBuffer **  materials,
struct ID3DXBuffer **  effect_instances,
DWORD *  num_materials,
struct ID3DXMesh **  mesh 
)

Definition at line 4199 of file mesh.c.

4202{
4203 HRESULT hr;
4204 HRSRC resinfo;
4205 void *buffer;
4206 DWORD size;
4207
4208 TRACE("module %p, name %s, type %s, options %#lx, device %p, adjacency %p, "
4209 "materials %p, effect_instances %p, num_materials %p, mesh %p.\n",
4211 materials, effect_instances, num_materials, mesh);
4212
4213 resinfo = FindResourceA(module, name, type);
4214 if (!resinfo) return D3DXERR_INVALIDDATA;
4215
4217 if (FAILED(hr)) return D3DXERR_INVALIDDATA;
4218
4219 return D3DXLoadMeshFromXInMemory(buffer, size, options, device, adjacency,
4220 materials, effect_instances, num_materials, mesh);
4221}
#define D3DXERR_INVALIDDATA
Definition: compiler.c:53
HRESULT load_resource_into_memory(HMODULE module, HRSRC resinfo, void **buffer, DWORD *length)
Definition: util.c:261
HRESULT WINAPI D3DXLoadMeshFromXInMemory(const void *memory, DWORD memory_size, DWORD options, struct IDirect3DDevice9 *device, struct ID3DXBuffer **adjacency_out, struct ID3DXBuffer **materials_out, struct ID3DXBuffer **effects_out, DWORD *num_materials_out, struct ID3DXMesh **mesh_out)
Definition: mesh.c:4297
HRSRC WINAPI FindResourceA(HMODULE hModule, LPCSTR name, LPCSTR type)
Definition: res.c:155
GLuint buffer
Definition: glext.h:5915

◆ D3DXLoadMeshFromXW()

HRESULT WINAPI D3DXLoadMeshFromXW ( const WCHAR *  filename,
DWORD  options,
struct IDirect3DDevice9 *  device,
struct ID3DXBuffer **  adjacency,
struct ID3DXBuffer **  materials,
struct ID3DXBuffer **  effect_instances,
DWORD *  num_materials,
struct ID3DXMesh **  mesh 
)

Definition at line 4171 of file mesh.c.

4174{
4175 void *buffer;
4176 HRESULT hr;
4177 DWORD size;
4178
4179 TRACE("filename %s, options %#lx, device %p, adjacency %p, materials %p, "
4180 "effect_instances %p, num_materials %p, mesh %p.\n",
4181 debugstr_w(filename), options, device, adjacency, materials,
4182 effect_instances, num_materials, mesh);
4183
4184 if (!filename)
4185 return D3DERR_INVALIDCALL;
4186
4188 if (FAILED(hr))
4189 return D3DXERR_INVALIDDATA;
4190
4192 materials, effect_instances, num_materials, mesh);
4193
4195
4196 return hr;
4197}
HRESULT map_view_of_file(const WCHAR *filename, void **buffer, DWORD *length)
Definition: util.c:211
#define UnmapViewOfFile
Definition: compat.h:746

Referenced by D3DXLoadMeshFromXA().

◆ D3DXLoadMeshHierarchyFromXA()

HRESULT WINAPI D3DXLoadMeshHierarchyFromXA ( const char *  filename,
DWORD  options,
struct IDirect3DDevice9 *  device,
struct ID3DXAllocateHierarchy *  alloc_hier,
struct ID3DXLoadUserData *  load_user_data,
D3DXFRAME **  frame_hierarchy,
struct ID3DXAnimationController **  anim_controller 
)

Definition at line 3746 of file mesh.c.

3749{
3751 HRESULT hr;
3752 int len;
3753
3754 TRACE("filename %s, options %#lx, device %p, alloc_hier %p, "
3755 "load_user_data %p, frame_hierarchy %p, anim_controller %p.\n",
3757 load_user_data, frame_hierarchy, anim_controller);
3758
3759 if (!filename)
3760 return D3DERR_INVALIDCALL;
3761
3763 filenameW = malloc(len * sizeof(WCHAR));
3764 if (!filenameW) return E_OUTOFMEMORY;
3766
3768 alloc_hier, load_user_data, frame_hierarchy, anim_controller);
3769 free(filenameW);
3770
3771 return hr;
3772}
HRESULT WINAPI D3DXLoadMeshHierarchyFromXW(const WCHAR *filename, DWORD options, struct IDirect3DDevice9 *device, struct ID3DXAllocateHierarchy *alloc_hier, struct ID3DXLoadUserData *load_user_data, D3DXFRAME **frame_hierarchy, struct ID3DXAnimationController **anim_controller)
Definition: mesh.c:3774

◆ D3DXLoadMeshHierarchyFromXInMemory()

HRESULT WINAPI D3DXLoadMeshHierarchyFromXInMemory ( const void *  memory,
DWORD  memory_size,
DWORD  options,
struct IDirect3DDevice9 *  device,
struct ID3DXAllocateHierarchy *  alloc_hier,
struct ID3DXLoadUserData *  load_user_data,
D3DXFRAME **  frame_hierarchy,
struct ID3DXAnimationController **  anim_controller 
)

Definition at line 3987 of file mesh.c.

3991{
3992 HRESULT hr;
3993 ID3DXFile *d3dxfile = NULL;
3994 ID3DXFileEnumObject *enumobj = NULL;
3995 ID3DXFileData *filedata = NULL;
3997 D3DXFRAME *first_frame = NULL;
3998 D3DXFRAME **next_frame = &first_frame;
3999 SIZE_T i, nb_children;
4000 GUID guid;
4001
4002 TRACE("memory %p, memory_size %lu, options %#lx, device %p, alloc_hier %p, load_user_data %p, "
4003 "frame_hierarchy %p, anim_controller %p.\n", memory, memory_size, options,
4004 device, alloc_hier, load_user_data, frame_hierarchy, anim_controller);
4005
4006 if (!memory || !memory_size || !device || !frame_hierarchy || !alloc_hier)
4007 return D3DERR_INVALIDCALL;
4008
4009 hr = D3DXFileCreate(&d3dxfile);
4010 if (FAILED(hr)) goto cleanup;
4011
4012 hr = d3dxfile->lpVtbl->RegisterTemplates(d3dxfile, D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES);
4013 if (FAILED(hr)) goto cleanup;
4014
4015 source.lpMemory = (void*)memory;
4016 source.dSize = memory_size;
4017 hr = d3dxfile->lpVtbl->CreateEnumObject(d3dxfile, &source, D3DXF_FILELOAD_FROMMEMORY, &enumobj);
4018 if (FAILED(hr)) goto cleanup;
4019
4020 hr = enumobj->lpVtbl->GetChildren(enumobj, &nb_children);
4021 if (FAILED(hr))
4022 goto cleanup;
4023
4024 for (i = 0; i < nb_children; i++)
4025 {
4026 hr = enumobj->lpVtbl->GetChild(enumobj, i, &filedata);
4027 if (FAILED(hr))
4028 goto cleanup;
4029
4030 hr = filedata->lpVtbl->GetType(filedata, &guid);
4031 if (SUCCEEDED(hr)) {
4032 if (IsEqualGUID(&guid, &TID_D3DRMMesh)) {
4033 hr = alloc_hier->lpVtbl->CreateFrame(alloc_hier, NULL, next_frame);
4034 if (FAILED(hr)) {
4035 hr = E_FAIL;
4036 goto cleanup;
4037 }
4038
4039 D3DXMatrixIdentity(&(*next_frame)->TransformationMatrix);
4040
4041 hr = load_mesh_container(filedata, options, device, alloc_hier, &(*next_frame)->pMeshContainer,
4042 load_user_data);
4043 if (FAILED(hr)) goto cleanup;
4044 } else if (IsEqualGUID(&guid, &TID_D3DRMFrame)) {
4045 hr = load_frame(filedata, options, device, alloc_hier, next_frame, load_user_data);
4046 if (FAILED(hr)) goto cleanup;
4047 } else if (load_user_data) {
4048 TRACE("Loading %s as user data.\n", debugstr_guid(&guid));
4049 hr = load_user_data->lpVtbl->LoadTopLevelData(load_user_data, filedata);
4050 }
4051 while (*next_frame)
4052 next_frame = &(*next_frame)->pFrameSibling;
4053 }
4054
4055 filedata->lpVtbl->Release(filedata);
4056 filedata = NULL;
4057 if (FAILED(hr))
4058 goto cleanup;
4059 }
4060
4061 if (!first_frame) {
4062 hr = E_FAIL;
4063 } else if (first_frame->pFrameSibling) {
4064 D3DXFRAME *root_frame = NULL;
4065 hr = alloc_hier->lpVtbl->CreateFrame(alloc_hier, NULL, &root_frame);
4066 if (FAILED(hr)) {
4067 hr = E_FAIL;
4068 goto cleanup;
4069 }
4070 D3DXMatrixIdentity(&root_frame->TransformationMatrix);
4071 root_frame->pFrameFirstChild = first_frame;
4072 *frame_hierarchy = root_frame;
4073 hr = D3D_OK;
4074 } else {
4075 *frame_hierarchy = first_frame;
4076 hr = D3D_OK;
4077 }
4078
4079 if (anim_controller)
4080 {
4081 *anim_controller = NULL;
4082 FIXME("Animation controller creation not implemented.\n");
4083 }
4084
4085cleanup:
4086 if (FAILED(hr) && first_frame) D3DXFrameDestroy(first_frame, alloc_hier);
4087 if (filedata) filedata->lpVtbl->Release(filedata);
4088 if (enumobj) enumobj->lpVtbl->Release(enumobj);
4089 if (d3dxfile) d3dxfile->lpVtbl->Release(d3dxfile);
4090 return hr;
4091}
static HRESULT load_frame(struct ID3DXFileData *filedata, DWORD options, struct IDirect3DDevice9 *device, struct ID3DXAllocateHierarchy *alloc_hier, D3DXFRAME **frame_out, struct ID3DXLoadUserData *load_user_data)
Definition: mesh.c:3924
static HRESULT load_mesh_container(struct ID3DXFileData *filedata, DWORD options, struct IDirect3DDevice9 *device, struct ID3DXAllocateHierarchy *alloc_hier, D3DXMESHCONTAINER **mesh_container, struct ID3DXLoadUserData *load_user_data)
Definition: mesh.c:3824
#define next_frame(vp)
Definition: raisecond.c:84
D3DXMATRIX TransformationMatrix
Definition: d3dx9anim.h:108

Referenced by D3DXLoadMeshHierarchyFromXW(), and D3DXLoadMeshTest().

◆ D3DXLoadMeshHierarchyFromXW()

HRESULT WINAPI D3DXLoadMeshHierarchyFromXW ( const WCHAR *  filename,
DWORD  options,
struct IDirect3DDevice9 *  device,
struct ID3DXAllocateHierarchy *  alloc_hier,
struct ID3DXLoadUserData *  load_user_data,
D3DXFRAME **  frame_hierarchy,
struct ID3DXAnimationController **  anim_controller 
)

Definition at line 3774 of file mesh.c.

3777{
3778 void *buffer;
3779 HRESULT hr;
3780 DWORD size;
3781
3782 TRACE("filename %s, options %#lx, device %p, alloc_hier %p, "
3783 "load_user_data %p, frame_hierarchy %p, anim_controller %p.\n",
3785 load_user_data, frame_hierarchy, anim_controller);
3786
3787 if (!filename)
3788 return D3DERR_INVALIDCALL;
3789
3791 if (FAILED(hr))
3792 return D3DXERR_INVALIDDATA;
3793
3795 alloc_hier, load_user_data, frame_hierarchy, anim_controller);
3796
3798
3799 return hr;
3800}
HRESULT WINAPI D3DXLoadMeshHierarchyFromXInMemory(const void *memory, DWORD memory_size, DWORD options, struct IDirect3DDevice9 *device, struct ID3DXAllocateHierarchy *alloc_hier, struct ID3DXLoadUserData *load_user_data, D3DXFRAME **frame_hierarchy, struct ID3DXAnimationController **anim_controller)
Definition: mesh.c:3987

Referenced by D3DXLoadMeshHierarchyFromXA().

◆ D3DXLoadSkinMeshFromXof()

HRESULT WINAPI D3DXLoadSkinMeshFromXof ( struct ID3DXFileData *  filedata,
DWORD  options,
struct IDirect3DDevice9 *  device,
struct ID3DXBuffer **  adjacency_out,
struct ID3DXBuffer **  materials_out,
struct ID3DXBuffer **  effects_out,
DWORD *  num_materials_out,
struct ID3DXSkinInfo **  skin_info_out,
struct ID3DXMesh **  mesh_out 
)

Definition at line 3487 of file mesh.c.

3491{
3492 HRESULT hr;
3493 DWORD *index_in_ptr;
3494 struct mesh_data mesh_data;
3495 DWORD total_vertices;
3496 ID3DXMesh *d3dxmesh = NULL;
3497 ID3DXBuffer *adjacency = NULL;
3499 ID3DXBuffer *effects = NULL;
3500 struct vertex_duplication {
3501 DWORD normal_index;
3502 struct list entry;
3503 } *duplications = NULL;
3504 DWORD i;
3505 void *vertices = NULL;
3506 void *indices = NULL;
3507 BYTE *out_ptr;
3508 DWORD provide_flags = 0;
3509
3510 TRACE("filedata %p, options %#lx, device %p, adjacency_out %p, materials_out %p, "
3511 "effects_out %p, num_materials_out %p, skin_info_out %p, mesh_out %p.\n",
3512 filedata, options, device, adjacency_out, materials_out,
3513 effects_out, num_materials_out, skin_info_out, mesh_out);
3514
3515 ZeroMemory(&mesh_data, sizeof(mesh_data));
3516
3517 if (num_materials_out || materials_out || effects_out)
3518 provide_flags |= PROVIDE_MATERIALS;
3519 if (skin_info_out)
3520 provide_flags |= PROVIDE_SKININFO;
3521
3522 hr = parse_mesh(filedata, &mesh_data, provide_flags);
3523 if (FAILED(hr)) goto cleanup;
3524
3526 {
3527 if (adjacency_out)
3528 *adjacency_out = NULL;
3529 if (materials_out)
3530 *materials_out = NULL;
3531 if (effects_out)
3532 *effects_out = NULL;
3533 *mesh_out = NULL;
3534 hr = D3D_OK;
3535 goto cleanup;
3536 }
3537
3538 total_vertices = mesh_data.num_vertices;
3539 if (mesh_data.fvf & D3DFVF_NORMAL) {
3540 /* duplicate vertices with multiple normals */
3541 DWORD num_face_indices = mesh_data.num_poly_faces * 2 + mesh_data.num_tri_faces;
3542 duplications = malloc((mesh_data.num_vertices + num_face_indices) * sizeof(*duplications));
3543 if (!duplications) {
3544 hr = E_OUTOFMEMORY;
3545 goto cleanup;
3546 }
3547 for (i = 0; i < total_vertices; i++)
3548 {
3549 duplications[i].normal_index = -1;
3550 list_init(&duplications[i].entry);
3551 }
3552 for (i = 0; i < num_face_indices; i++) {
3554 DWORD normal_index = mesh_data.normal_indices[i];
3555 struct vertex_duplication *dup_ptr = &duplications[vertex_index];
3556
3557 if (dup_ptr->normal_index == -1) {
3558 dup_ptr->normal_index = normal_index;
3559 } else {
3560 D3DXVECTOR3 *new_normal = &mesh_data.normals[normal_index];
3561 struct list *dup_list = &dup_ptr->entry;
3562 while (TRUE) {
3563 D3DXVECTOR3 *cur_normal = &mesh_data.normals[dup_ptr->normal_index];
3564 if (new_normal->x == cur_normal->x &&
3565 new_normal->y == cur_normal->y &&
3566 new_normal->z == cur_normal->z)
3567 {
3568 mesh_data.indices[i] = dup_ptr - duplications;
3569 break;
3570 } else if (!list_next(dup_list, &dup_ptr->entry)) {
3571 dup_ptr = &duplications[total_vertices++];
3572 dup_ptr->normal_index = normal_index;
3573 list_add_tail(dup_list, &dup_ptr->entry);
3574 mesh_data.indices[i] = dup_ptr - duplications;
3575 break;
3576 } else {
3577 dup_ptr = LIST_ENTRY(list_next(dup_list, &dup_ptr->entry),
3578 struct vertex_duplication, entry);
3579 }
3580 }
3581 }
3582 }
3583 }
3584
3585 hr = D3DXCreateMeshFVF(mesh_data.num_tri_faces, total_vertices, options, mesh_data.fvf, device, &d3dxmesh);
3586 if (FAILED(hr)) goto cleanup;
3587
3588 hr = d3dxmesh->lpVtbl->LockVertexBuffer(d3dxmesh, 0, &vertices);
3589 if (FAILED(hr)) goto cleanup;
3590
3591 out_ptr = vertices;
3592 for (i = 0; i < mesh_data.num_vertices; i++) {
3593 *(D3DXVECTOR3*)out_ptr = mesh_data.vertices[i];
3594 out_ptr += sizeof(D3DXVECTOR3);
3595 if (mesh_data.fvf & D3DFVF_NORMAL) {
3596 if (duplications[i].normal_index == -1)
3597 ZeroMemory(out_ptr, sizeof(D3DXVECTOR3));
3598 else
3599 *(D3DXVECTOR3*)out_ptr = mesh_data.normals[duplications[i].normal_index];
3600 out_ptr += sizeof(D3DXVECTOR3);
3601 }
3603 *(DWORD*)out_ptr = mesh_data.vertex_colors[i];
3604 out_ptr += sizeof(DWORD);
3605 }
3606 if (mesh_data.fvf & D3DFVF_TEX1) {
3607 *(D3DXVECTOR2*)out_ptr = mesh_data.tex_coords[i];
3608 out_ptr += sizeof(D3DXVECTOR2);
3609 }
3610 }
3611 if (mesh_data.fvf & D3DFVF_NORMAL) {
3612 DWORD vertex_size = D3DXGetFVFVertexSize(mesh_data.fvf);
3613 out_ptr = vertices;
3614 for (i = 0; i < mesh_data.num_vertices; i++) {
3615 struct vertex_duplication *dup_ptr;
3616 LIST_FOR_EACH_ENTRY(dup_ptr, &duplications[i].entry, struct vertex_duplication, entry)
3617 {
3618 int j = dup_ptr - duplications;
3619 BYTE *dest_vertex = (BYTE*)vertices + j * vertex_size;
3620
3621 memcpy(dest_vertex, out_ptr, vertex_size);
3622 dest_vertex += sizeof(D3DXVECTOR3);
3623 *(D3DXVECTOR3*)dest_vertex = mesh_data.normals[dup_ptr->normal_index];
3624 }
3625 out_ptr += vertex_size;
3626 }
3627 }
3628 d3dxmesh->lpVtbl->UnlockVertexBuffer(d3dxmesh);
3629
3630 hr = d3dxmesh->lpVtbl->LockIndexBuffer(d3dxmesh, 0, &indices);
3631 if (FAILED(hr)) goto cleanup;
3632
3633 index_in_ptr = mesh_data.indices;
3634#define FILL_INDEX_BUFFER(indices_var) \
3635 for (i = 0; i < mesh_data.num_poly_faces; i++) \
3636 { \
3637 DWORD count = mesh_data.num_tri_per_face[i]; \
3638 WORD first_index = *index_in_ptr++; \
3639 while (count--) { \
3640 *indices_var++ = first_index; \
3641 *indices_var++ = *index_in_ptr; \
3642 index_in_ptr++; \
3643 *indices_var++ = *index_in_ptr; \
3644 } \
3645 index_in_ptr++; \
3646 }
3647 if (options & D3DXMESH_32BIT) {
3648 DWORD *dword_indices = indices;
3649 FILL_INDEX_BUFFER(dword_indices)
3650 } else {
3651 WORD *word_indices = indices;
3652 FILL_INDEX_BUFFER(word_indices)
3653 }
3654#undef FILL_INDEX_BUFFER
3655 d3dxmesh->lpVtbl->UnlockIndexBuffer(d3dxmesh);
3656
3658 DWORD *attrib_buffer = NULL;
3659 hr = d3dxmesh->lpVtbl->LockAttributeBuffer(d3dxmesh, 0, &attrib_buffer);
3660 if (FAILED(hr)) goto cleanup;
3661 for (i = 0; i < mesh_data.num_poly_faces; i++)
3662 {
3664 while (count--)
3665 *attrib_buffer++ = mesh_data.material_indices[i];
3666 }
3667 d3dxmesh->lpVtbl->UnlockAttributeBuffer(d3dxmesh);
3668
3669 hr = d3dxmesh->lpVtbl->OptimizeInplace(d3dxmesh,
3671 NULL, NULL, NULL, NULL);
3672 if (FAILED(hr)) goto cleanup;
3673 }
3674
3675 if (mesh_data.num_materials && (materials_out || effects_out)) {
3677 char *strings_out_ptr;
3678 D3DXMATERIAL *materials_ptr;
3679
3680 for (i = 0; i < mesh_data.num_materials; i++) {
3681 if (mesh_data.materials[i].pTextureFilename)
3682 buffer_size += strlen(mesh_data.materials[i].pTextureFilename) + 1;
3683 }
3684
3685 hr = D3DXCreateBuffer(buffer_size, &materials);
3686 if (FAILED(hr)) goto cleanup;
3687
3688 materials_ptr = ID3DXBuffer_GetBufferPointer(materials);
3689 memcpy(materials_ptr, mesh_data.materials, mesh_data.num_materials * sizeof(D3DXMATERIAL));
3690 strings_out_ptr = (char*)(materials_ptr + mesh_data.num_materials);
3691 for (i = 0; i < mesh_data.num_materials; i++) {
3692 if (materials_ptr[i].pTextureFilename) {
3693 strcpy(strings_out_ptr, mesh_data.materials[i].pTextureFilename);
3694 materials_ptr[i].pTextureFilename = strings_out_ptr;
3695 strings_out_ptr += strlen(mesh_data.materials[i].pTextureFilename) + 1;
3696 }
3697 }
3698 }
3699
3700 if (mesh_data.num_materials && effects_out) {
3701 hr = generate_effects(materials, mesh_data.num_materials, &effects);
3702 if (FAILED(hr)) goto cleanup;
3703
3704 if (!materials_out) {
3705 ID3DXBuffer_Release(materials);
3706 materials = NULL;
3707 }
3708 }
3709
3710 if (adjacency_out) {
3711 hr = D3DXCreateBuffer(mesh_data.num_tri_faces * 3 * sizeof(DWORD), &adjacency);
3712 if (FAILED(hr)) goto cleanup;
3713 hr = d3dxmesh->lpVtbl->GenerateAdjacency(d3dxmesh, 0.0f, ID3DXBuffer_GetBufferPointer(adjacency));
3714 if (FAILED(hr)) goto cleanup;
3715 }
3716
3717 *mesh_out = d3dxmesh;
3718 if (adjacency_out) *adjacency_out = adjacency;
3719 if (num_materials_out) *num_materials_out = mesh_data.num_materials;
3720 if (materials_out) *materials_out = materials;
3721 if (effects_out) *effects_out = effects;
3722 if (skin_info_out) *skin_info_out = mesh_data.skin_info;
3723
3724 hr = D3D_OK;
3725cleanup:
3726 if (FAILED(hr)) {
3727 if (d3dxmesh) IUnknown_Release(d3dxmesh);
3728 if (adjacency) ID3DXBuffer_Release(adjacency);
3729 if (materials) ID3DXBuffer_Release(materials);
3730 if (effects) ID3DXBuffer_Release(effects);
3732 if (skin_info_out) *skin_info_out = NULL;
3733 }
3742 free(duplications);
3743 return hr;
3744}
#define D3DFVF_TEX1
Definition: d3d8types.h:127
UINT WINAPI D3DXGetFVFVertexSize(DWORD FVF)
Definition: mesh.c:2287
#define PROVIDE_SKININFO
Definition: mesh.c:42
static HRESULT parse_mesh(ID3DXFileData *filedata, struct mesh_data *mesh_data, DWORD provide_flags)
Definition: mesh.c:3231
#define FILL_INDEX_BUFFER(indices_var)
static void destroy_materials(struct mesh_data *mesh)
Definition: mesh.c:2743
@ D3DXMESHOPT_DONOTSPLIT
Definition: d3dx9mesh.h:78
unsigned int num_materials
Definition: mesh.c:2613
DWORD * vertex_colors
Definition: mesh.c:2611
DWORD * normal_indices
Definition: mesh.c:2607
D3DXVECTOR3 * vertices
Definition: mesh.c:2597
struct ID3DXSkinInfo * skin_info
Definition: mesh.c:2617
DWORD * material_indices
Definition: mesh.c:2615
DWORD fvf
Definition: mesh.c:2601
D3DXVECTOR2 * tex_coords
Definition: mesh.c:2609
unsigned int num_vertices
Definition: mesh.c:2594
D3DXMATERIAL * materials
Definition: mesh.c:2614
D3DXVECTOR3 * normals
Definition: mesh.c:2606
unsigned int num_tri_faces
Definition: mesh.c:2596
DWORD * indices
Definition: mesh.c:2599

Referenced by D3DXLoadMeshFromXInMemory(), load_mesh_container(), parse_frame(), and test_load_skin_mesh_from_xof().

◆ D3DXOptimizeFaces()

HRESULT WINAPI D3DXOptimizeFaces ( const void *  indices,
UINT  num_faces,
UINT  num_vertices,
BOOL  indices_are_32bit,
DWORD *  face_remap 
)

Definition at line 7311 of file mesh.c.

7313{
7314 UINT i;
7315 UINT j = num_faces - 1;
7316 UINT limit_16_bit = 2 << 15; /* According to MSDN */
7317 HRESULT hr = D3D_OK;
7318
7319 FIXME("indices %p, num_faces %u, num_vertices %u, indices_are_32bit %#x, face_remap %p semi-stub. "
7320 "Face order will not be optimal.\n",
7321 indices, num_faces, num_vertices, indices_are_32bit, face_remap);
7322
7323 if (!indices_are_32bit && num_faces >= limit_16_bit)
7324 {
7325 WARN("Number of faces must be less than %d when using 16-bit indices.\n",
7326 limit_16_bit);
7328 goto error;
7329 }
7330
7331 if (!face_remap)
7332 {
7333 WARN("Face remap pointer is NULL.\n");
7335 goto error;
7336 }
7337
7338 /* The faces are drawn in reverse order for simple meshes. This ordering
7339 * is not optimal for complicated meshes, but will not break anything
7340 * either. The ordering should be changed to take advantage of the vertex
7341 * cache on the graphics card.
7342 *
7343 * TODO Re-order to take advantage of vertex cache.
7344 */
7345 for (i = 0; i < num_faces; i++)
7346 {
7347 face_remap[i] = j--;
7348 }
7349
7350 return D3D_OK;
7351
7352error:
7353 return hr;
7354}

Referenced by test_optimize_faces().

◆ D3DXOptimizeVertices()

HRESULT WINAPI D3DXOptimizeVertices ( const void *  indices,
UINT  face_count,
UINT  vertex_count,
BOOL  indices_are_32bit,
DWORD *  vertex_remap 
)

Definition at line 7356 of file mesh.c.

7358{
7359 unsigned int i;
7360
7361 FIXME("indices %p, face_count %u, vertex_count %u, indices_are_32bit %#x, vertex_remap %p semi-stub.\n",
7362 indices, face_count, vertex_count, indices_are_32bit, vertex_remap);
7363
7364 if (!indices || !face_count || !vertex_count || !vertex_remap)
7365 return D3DERR_INVALIDCALL;
7366
7367 for (i = 0; i < vertex_count; ++i)
7368 vertex_remap[i] = i;
7369
7370 return D3D_OK;
7371}

Referenced by test_optimize_vertices().

◆ D3DXSphereBoundProbe()

BOOL WINAPI D3DXSphereBoundProbe ( const D3DXVECTOR3 *  center,
float  radius,
const D3DXVECTOR3 *  ray_position,
const D3DXVECTOR3 *  ray_direction 
)

Definition at line 2411 of file mesh.c.

2413{
2414 D3DXVECTOR3 difference = {0};
2415 float a, b, c, d;
2416
2417 D3DXVec3Subtract(&difference, ray_position, center);
2418 c = D3DXVec3LengthSq(&difference) - radius * radius;
2419 if (c < 0.0f)
2420 return TRUE;
2421 a = D3DXVec3LengthSq(ray_direction);
2422 b = D3DXVec3Dot(&difference, ray_direction);
2423 d = b * b - a * c;
2424
2425 return d >= 0.0f && (b <= 0.0f || d > b * b);
2426}
const GLubyte * c
Definition: glext.h:8905
#define c
Definition: ke_i.h:80

Referenced by D3DXBoundProbeTest().

◆ D3DXTessellateNPatches()

HRESULT WINAPI D3DXTessellateNPatches ( ID3DXMesh *  mesh,
const DWORD *  adjacency_in,
float  num_segs,
BOOL  quadratic_normals,
ID3DXMesh **  mesh_out,
ID3DXBuffer **  adjacency_out 
)

Definition at line 7665 of file mesh.c.

7667{
7668 FIXME("mesh %p, adjacency_in %p, num_segs %f, quadratic_normals %d, mesh_out %p, adjacency_out %p stub.\n",
7669 mesh, adjacency_in, num_segs, quadratic_normals, mesh_out, adjacency_out);
7670
7671 return E_NOTIMPL;
7672}

◆ D3DXValidMesh()

HRESULT WINAPI D3DXValidMesh ( ID3DXMesh *  mesh,
const DWORD *  adjacency,
ID3DXBuffer **  errors_and_warnings 
)

Definition at line 6531 of file mesh.c.

6532{
6533 FIXME("mesh %p, adjacency %p, errors_and_warnings %p stub.\n", mesh, adjacency, errors_and_warnings);
6534
6535 return E_NOTIMPL;
6536}

Referenced by test_valid_mesh().

◆ D3DXWeldVertices()

HRESULT WINAPI D3DXWeldVertices ( ID3DXMesh *  mesh,
DWORD  flags,
const D3DXWELDEPSILONS *  epsilons,
const DWORD *  adjacency,
DWORD *  adjacency_out,
DWORD *  face_remap_out,
ID3DXBuffer **  vertex_remap_out 
)

Definition at line 7104 of file mesh.c.

7106{
7107 DWORD *adjacency_generated = NULL;
7108 const DWORD *adjacency_ptr;
7110 const FLOAT DEFAULT_EPSILON = 1.0e-6f;
7111 HRESULT hr;
7112 DWORD i;
7113 void *indices = NULL;
7114 BOOL indices_are_32bit = mesh->lpVtbl->GetOptions(mesh) & D3DXMESH_32BIT;
7115 DWORD optimize_flags;
7116 DWORD *point_reps = NULL;
7118 DWORD *vertex_face_map = NULL;
7119 BYTE *vertices = NULL;
7120
7121 TRACE("mesh %p, flags %#lx, epsilons %p, adjacency %p, adjacency_out %p, face_remap_out %p, "
7122 "vertex_remap_out %p.\n",
7123 mesh, flags, epsilons, adjacency, adjacency_out, face_remap_out, vertex_remap_out);
7124
7125 if (flags == 0)
7126 {
7127 WARN("No flags are undefined. Using D3DXWELDEPSILONS_WELDPARTIALMATCHES instead.\n");
7129 }
7130
7131 if (adjacency) /* Use supplied adjacency. */
7132 {
7133 adjacency_ptr = adjacency;
7134 }
7135 else /* Adjacency has to be generated. */
7136 {
7137 adjacency_generated = malloc(3 * This->numfaces * sizeof(*adjacency_generated));
7138 if (!adjacency_generated)
7139 {
7140 ERR("Couldn't allocate memory for adjacency_generated.\n");
7141 hr = E_OUTOFMEMORY;
7142 goto cleanup;
7143 }
7144 hr = mesh->lpVtbl->GenerateAdjacency(mesh, DEFAULT_EPSILON, adjacency_generated);
7145 if (FAILED(hr))
7146 {
7147 ERR("Couldn't generate adjacency.\n");
7148 goto cleanup;
7149 }
7150 adjacency_ptr = adjacency_generated;
7151 }
7152
7153 /* Point representation says which vertices can be replaced. */
7154 point_reps = malloc(This->numvertices * sizeof(*point_reps));
7155 if (!point_reps)
7156 {
7157 hr = E_OUTOFMEMORY;
7158 ERR("Couldn't allocate memory for point_reps.\n");
7159 goto cleanup;
7160 }
7161 hr = mesh->lpVtbl->ConvertAdjacencyToPointReps(mesh, adjacency_ptr, point_reps);
7162 if (FAILED(hr))
7163 {
7164 ERR("ConvertAdjacencyToPointReps failed.\n");
7165 goto cleanup;
7166 }
7167
7168 hr = mesh->lpVtbl->LockIndexBuffer(mesh, 0, &indices);
7169 if (FAILED(hr))
7170 {
7171 ERR("Couldn't lock index buffer.\n");
7172 goto cleanup;
7173 }
7174
7175 hr = mesh->lpVtbl->LockAttributeBuffer(mesh, 0, &attributes);
7176 if (FAILED(hr))
7177 {
7178 ERR("Couldn't lock attribute buffer.\n");
7179 goto cleanup;
7180 }
7181 vertex_face_map = malloc(This->numvertices * sizeof(*vertex_face_map));
7182 if (!vertex_face_map)
7183 {
7184 hr = E_OUTOFMEMORY;
7185 ERR("Couldn't allocate memory for vertex_face_map.\n");
7186 goto cleanup;
7187 }
7188 /* Build vertex face map, so that a vertex's face can be looked up. */
7189 for (i = 0; i < This->numfaces; i++)
7190 {
7191 DWORD j;
7192 for (j = 0; j < 3; j++)
7193 {
7194 DWORD index = read_ib(indices, indices_are_32bit, 3*i + j);
7195 vertex_face_map[index] = i;
7196 }
7197 }
7198
7200 {
7201 hr = mesh->lpVtbl->LockVertexBuffer(mesh, 0, (void**)&vertices);
7202 if (FAILED(hr))
7203 {
7204 ERR("Couldn't lock vertex buffer.\n");
7205 goto cleanup;
7206 }
7207 /* For each vertex that can be removed, compare its vertex components
7208 * with the vertex components from the vertex that can replace it. A
7209 * vertex is only fully replaced if all the components match and the
7210 * flag D3DXWELDEPSILONS_DONOTREMOVEVERTICES is not set, and they
7211 * belong to the same attribute group. Otherwise the vertex components
7212 * that are within epsilon are set to the same value.
7213 */
7214 for (i = 0; i < 3 * This->numfaces; i++)
7215 {
7216 D3DVERTEXELEMENT9 *decl_ptr;
7217 DWORD vertex_size = mesh->lpVtbl->GetNumBytesPerVertex(mesh);
7218 DWORD num_vertex_components;
7219 INT matches = 0;
7220 BOOL all_match;
7221 DWORD index = read_ib(indices, indices_are_32bit, i);
7222
7223 for (decl_ptr = This->cached_declaration, num_vertex_components = 0; decl_ptr->Stream != 0xFF; decl_ptr++, num_vertex_components++)
7224 {
7225 BYTE *to = &vertices[vertex_size*index + decl_ptr->Offset];
7226 BYTE *from = &vertices[vertex_size*point_reps[index] + decl_ptr->Offset];
7227 FLOAT epsilon = get_component_epsilon(decl_ptr, epsilons);
7228
7229 /* Don't weld self */
7230 if (index == point_reps[index])
7231 {
7232 matches++;
7233 continue;
7234 }
7235
7236 if (weld_component(to, from, decl_ptr->Type, epsilon))
7237 matches++;
7238 }
7239
7240 all_match = (num_vertex_components == matches);
7241 if (all_match && !(flags & D3DXWELDEPSILONS_DONOTREMOVEVERTICES))
7242 {
7243 DWORD to_face = vertex_face_map[index];
7244 DWORD from_face = vertex_face_map[point_reps[index]];
7245 if(attributes[to_face] != attributes[from_face] && !(flags & D3DXWELDEPSILONS_DONOTSPLIT))
7246 continue;
7247 write_ib(indices, indices_are_32bit, i, point_reps[index]);
7248 }
7249 }
7250 mesh->lpVtbl->UnlockVertexBuffer(mesh);
7251 vertices = NULL;
7252 }
7254 {
7255 for (i = 0; i < 3 * This->numfaces; i++)
7256 {
7257 DWORD index = read_ib(indices, indices_are_32bit, i);
7258 DWORD to_face = vertex_face_map[index];
7259 DWORD from_face = vertex_face_map[point_reps[index]];
7260 if(attributes[to_face] != attributes[from_face] && !(flags & D3DXWELDEPSILONS_DONOTSPLIT))
7261 continue;
7262 write_ib(indices, indices_are_32bit, i, point_reps[index]);
7263 }
7264 }
7265 mesh->lpVtbl->UnlockAttributeBuffer(mesh);
7266 attributes = NULL;
7267 mesh->lpVtbl->UnlockIndexBuffer(mesh);
7268 indices = NULL;
7269
7270 /* Compact mesh using OptimizeInplace */
7271 optimize_flags = D3DXMESHOPT_COMPACT;
7272 hr = mesh->lpVtbl->OptimizeInplace(mesh, optimize_flags, adjacency_ptr, adjacency_out, face_remap_out, vertex_remap_out);
7273 if (FAILED(hr))
7274 {
7275 ERR("Couldn't compact mesh.\n");
7276 goto cleanup;
7277 }
7278
7279 hr = D3D_OK;
7280cleanup:
7281 free(adjacency_generated);
7282 free(point_reps);
7283 free(vertex_face_map);
7284 if (attributes) mesh->lpVtbl->UnlockAttributeBuffer(mesh);
7285 if (indices) mesh->lpVtbl->UnlockIndexBuffer(mesh);
7286 if (vertices) mesh->lpVtbl->UnlockVertexBuffer(mesh);
7287
7288 return hr;
7289}
static void write_ib(void *index_buffer, BOOL indices_are_32bit, DWORD index, DWORD value)
Definition: mesh.c:7065
static FLOAT get_component_epsilon(const D3DVERTEXELEMENT9 *decl_ptr, const D3DXWELDEPSILONS *epsilons)
Definition: mesh.c:6969
static BOOL weld_component(void *to, void *from, D3DDECLTYPE type, FLOAT epsilon)
Definition: mesh.c:6896
@ D3DXWELDEPSILONS_DONOTREMOVEVERTICES
Definition: d3dx9mesh.h:151
@ D3DXWELDEPSILONS_DONOTSPLIT
Definition: d3dx9mesh.h:152
@ D3DXWELDEPSILONS_WELDALL
Definition: d3dx9mesh.h:149
@ D3DXWELDEPSILONS_WELDPARTIALMATCHES
Definition: d3dx9mesh.h:150
#define matches(FN)
Definition: match.h:70
static HANDLE ACCESS_MASK ULONG attributes
Definition: om.c:94
CardRegion * from
Definition: spigame.cpp:19

Referenced by test_weld_vertices().

◆ declaration_equals()

static BOOL declaration_equals ( const D3DVERTEXELEMENT9 *  declaration1,
const D3DVERTEXELEMENT9 *  declaration2 
)
static

Definition at line 658 of file mesh.c.

659{
660 UINT size1 = 0, size2 = 0;
661
662 /* Find the size of each declaration */
663 while (declaration1[size1].Stream != 0xff) size1++;
664 while (declaration2[size2].Stream != 0xff) size2++;
665
666 /* If not same size then they are definitely not equal */
667 if (size1 != size2)
668 return FALSE;
669
670 /* Check that all components are the same */
671 if (memcmp(declaration1, declaration2, size1*sizeof(*declaration1)) == 0)
672 return TRUE;
673
674 return FALSE;
675}
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807

Referenced by d3dx9_mesh_CloneMesh().

◆ destroy_materials()

static void destroy_materials ( struct mesh_data *  mesh)
static

Definition at line 2743 of file mesh.c.

2744{
2745 unsigned int i;
2746
2747 for (i = 0; i < mesh->num_materials; ++i)
2748 free(mesh->materials[i].pTextureFilename);
2749 free(mesh->materials);
2750 free(mesh->material_indices);
2751 mesh->num_materials = 0;
2752 mesh->materials = NULL;
2753 mesh->material_indices = NULL;
2754}

Referenced by D3DXLoadSkinMeshFromXof(), and parse_material_list().

◆ dword_to_dec3n()

static struct dec3n dword_to_dec3n ( DWORD  d)
static

Definition at line 6793 of file mesh.c.

6794{
6795 struct dec3n v;
6796
6797 v.x = d & 0x3ff;
6798 v.y = (d & 0xffc00) >> 10;
6799 v.z = (d & 0x3ff00000) >> 20;
6800 v.w = (d & 0xc0000000) >> 30;
6801
6802 return v;
6803}
Definition: mesh.c:6786
INT x
Definition: mesh.c:6787

Referenced by check_vertex_components(), and weld_dec3n().

◆ dword_to_udec3()

static struct udec3 dword_to_udec3 ( DWORD  d)
static

Definition at line 6748 of file mesh.c.

6749{
6750 struct udec3 v;
6751
6752 v.x = d & 0x3ff;
6753 v.y = (d & 0xffc00) >> 10;
6754 v.z = (d & 0x3ff00000) >> 20;
6755 v.w = (d & 0xc0000000) >> 30;
6756
6757 return v;
6758}
Definition: mesh.c:6741
UINT x
Definition: mesh.c:6742

Referenced by check_vertex_components(), and weld_udec3().

◆ empty_frame_queue()

static void empty_frame_queue ( struct list *  queue)
static

Definition at line 7706 of file mesh.c.

7707{
7708 struct frame_node *cur, *cur2;
7710 {
7711 list_remove(&cur->entry);
7712 free(cur);
7713 }
7714}
FxCollectionEntry * cur

Referenced by D3DXFrameFind().

◆ filedata_get_name()

static HRESULT filedata_get_name ( ID3DXFileData *  filedata,
char **  name 
)
static

Definition at line 3802 of file mesh.c.

3803{
3804 HRESULT hr;
3805 SIZE_T name_len;
3806
3807 hr = filedata->lpVtbl->GetName(filedata, NULL, &name_len);
3808 if (FAILED(hr)) return hr;
3809
3810 if (!name_len)
3811 name_len++;
3812 *name = malloc(name_len);
3813 if (!*name) return E_OUTOFMEMORY;
3814
3815 hr = filedata->lpVtbl->GetName(filedata, *name, &name_len);
3816 if (FAILED(hr))
3817 free(*name);
3818 else if (!name_len)
3819 (*name)[0] = 0;
3820
3821 return hr;
3822}

Referenced by load_frame(), and load_mesh_container().

◆ fill_attribute_table()

static void fill_attribute_table ( DWORD *  attrib_buffer,
DWORD  numfaces,
void *  indices,
BOOL  is_32bit_indices,
D3DXATTRIBUTERANGE *  attrib_table 
)
static

Definition at line 1543 of file mesh.c.

1545{
1546 DWORD attrib_table_size = 0;
1547 DWORD last_attribute = attrib_buffer[0];
1548 DWORD min_vertex, max_vertex;
1549 DWORD i;
1550
1551 attrib_table[0].AttribId = last_attribute;
1552 attrib_table[0].FaceStart = 0;
1553 min_vertex = (DWORD)-1;
1554 max_vertex = 0;
1555 for (i = 0; i < numfaces; i++) {
1556 DWORD j;
1557
1558 if (attrib_buffer[i] != last_attribute) {
1559 last_attribute = attrib_buffer[i];
1560 attrib_table[attrib_table_size].FaceCount = i - attrib_table[attrib_table_size].FaceStart;
1561 attrib_table[attrib_table_size].VertexStart = min_vertex;
1562 attrib_table[attrib_table_size].VertexCount = max_vertex - min_vertex + 1;
1563 attrib_table_size++;
1564 attrib_table[attrib_table_size].AttribId = attrib_buffer[i];
1565 attrib_table[attrib_table_size].FaceStart = i;
1566 min_vertex = (DWORD)-1;
1567 max_vertex = 0;
1568 }
1569 for (j = 0; j < 3; j++) {
1570 DWORD vertex_index = is_32bit_indices ? ((DWORD*)indices)[i * 3 + j] : ((WORD*)indices)[i * 3 + j];
1571 if (vertex_index < min_vertex)
1572 min_vertex = vertex_index;
1573 if (vertex_index > max_vertex)
1574 max_vertex = vertex_index;
1575 }
1576 }
1577 attrib_table[attrib_table_size].FaceCount = i - attrib_table[attrib_table_size].FaceStart;
1578 attrib_table[attrib_table_size].VertexStart = min_vertex;
1579 attrib_table[attrib_table_size].VertexCount = max_vertex - min_vertex + 1;
1580 attrib_table_size++;
1581}

Referenced by d3dx9_mesh_OptimizeInplace().

◆ find_adjacent_face()

static DWORD find_adjacent_face ( struct edge_face_map *  edge_face_map,
DWORD  vertex1,
DWORD  vertex2,
DWORD  num_faces 
)
static

Definition at line 923 of file mesh.c.

924{
925 struct edge_face *edge_face_ptr;
926
927 LIST_FOR_EACH_ENTRY(edge_face_ptr, &edge_face_map->lists[vertex2], struct edge_face, entry)
928 {
929 if (edge_face_ptr->v2 == vertex1)
930 return edge_face_ptr->face;
931 }
932
933 return -1;
934}
DWORD v2
Definition: mesh.c:862
DWORD face
Definition: mesh.c:863

Referenced by d3dx9_mesh_ConvertPointRepsToAdjacency().

◆ free_sincos_table()

static void free_sincos_table ( struct sincos_table *  sincos_table)
static

Definition at line 4862 of file mesh.c.

4863{
4866}

Referenced by compute_cylinder(), compute_sphere(), D3DXCreateCylinder(), and D3DXCreateSphere().

◆ generate_effects()

static HRESULT generate_effects ( ID3DXBuffer *  materials,
DWORD  num_materials,
ID3DXBuffer **  effects 
)
static

Definition at line 3389 of file mesh.c.

3391{
3392 HRESULT hr;
3393 D3DXEFFECTINSTANCE *effect_ptr;
3394 BYTE *out_ptr;
3395 const D3DXMATERIAL *material_ptr = ID3DXBuffer_GetBufferPointer(materials);
3396 static const struct {
3397 const char *param_name;
3398 DWORD name_size;
3399 DWORD num_bytes;
3400 DWORD value_offset;
3401 } material_effects[] = {
3402#define EFFECT_TABLE_ENTRY(str, field) \
3403 {str, sizeof(str), sizeof(material_ptr->MatD3D.field), offsetof(D3DXMATERIAL, MatD3D.field)}
3404 EFFECT_TABLE_ENTRY("Diffuse", Diffuse),
3405 EFFECT_TABLE_ENTRY("Power", Power),
3406 EFFECT_TABLE_ENTRY("Specular", Specular),
3407 EFFECT_TABLE_ENTRY("Emissive", Emissive),
3408 EFFECT_TABLE_ENTRY("Ambient", Ambient),
3409#undef EFFECT_TABLE_ENTRY
3410 };
3411 static const char texture_paramname[] = "Texture0@Name";
3413 DWORD i;
3414
3415 /* effects buffer layout:
3416 *
3417 * D3DXEFFECTINSTANCE effects[num_materials];
3418 * for (effect in effects)
3419 * {
3420 * D3DXEFFECTDEFAULT defaults[effect.NumDefaults];
3421 * for (default in defaults)
3422 * {
3423 * *default.pParamName;
3424 * *default.pValue;
3425 * }
3426 * }
3427 */
3429 buffer_size += sizeof(D3DXEFFECTDEFAULT) * ARRAY_SIZE(material_effects);
3430 for (i = 0; i < ARRAY_SIZE(material_effects); i++) {
3431 buffer_size += material_effects[i].name_size;
3432 buffer_size += material_effects[i].num_bytes;
3433 }
3434 buffer_size *= num_materials;
3435 for (i = 0; i < num_materials; i++) {
3436 if (material_ptr[i].pTextureFilename) {
3437 buffer_size += sizeof(D3DXEFFECTDEFAULT);
3438 buffer_size += sizeof(texture_paramname);
3439 buffer_size += strlen(material_ptr[i].pTextureFilename) + 1;
3440 }
3441 }
3442
3443 hr = D3DXCreateBuffer(buffer_size, effects);
3444 if (FAILED(hr)) return hr;
3445 effect_ptr = ID3DXBuffer_GetBufferPointer(*effects);
3446 out_ptr = (BYTE*)(effect_ptr + num_materials);
3447
3448 for (i = 0; i < num_materials; i++)
3449 {
3450 DWORD j;
3452
3453 effect_ptr->pDefaults = defaults;
3454 effect_ptr->NumDefaults = material_ptr->pTextureFilename ? 6 : 5;
3455 out_ptr = (BYTE*)(effect_ptr->pDefaults + effect_ptr->NumDefaults);
3456
3457 for (j = 0; j < ARRAY_SIZE(material_effects); j++)
3458 {
3459 defaults->pParamName = (char *)out_ptr;
3460 strcpy(defaults->pParamName, material_effects[j].param_name);
3461 defaults->pValue = defaults->pParamName + material_effects[j].name_size;
3462 defaults->Type = D3DXEDT_FLOATS;
3463 defaults->NumBytes = material_effects[j].num_bytes;
3464 memcpy(defaults->pValue, (BYTE*)material_ptr + material_effects[j].value_offset, defaults->NumBytes);
3465 out_ptr = (BYTE*)defaults->pValue + defaults->NumBytes;
3466 defaults++;
3467 }
3468
3469 if (material_ptr->pTextureFilename)
3470 {
3471 defaults->pParamName = (char *)out_ptr;
3472 strcpy(defaults->pParamName, texture_paramname);
3473 defaults->pValue = defaults->pParamName + sizeof(texture_paramname);
3474 defaults->Type = D3DXEDT_STRING;
3475 defaults->NumBytes = strlen(material_ptr->pTextureFilename) + 1;
3476 strcpy(defaults->pValue, material_ptr->pTextureFilename);
3477 out_ptr = (BYTE*)defaults->pValue + defaults->NumBytes;
3478 }
3479 material_ptr++;
3480 effect_ptr++;
3481 }
3482 assert(out_ptr - (BYTE*)ID3DXBuffer_GetBufferPointer(*effects) == buffer_size);
3483
3484 return D3D_OK;
3485}
#define EFFECT_TABLE_ENTRY(str, field)
#define assert(_expr)
Definition: assert.h:32
@ D3DXEDT_FLOATS
Definition: d3dx9mesh.h:142
@ D3DXEDT_STRING
Definition: d3dx9mesh.h:141
struct _D3DXEFFECTDEFAULT D3DXEFFECTDEFAULT
struct _D3DXEFFECTINSTANCE D3DXEFFECTINSTANCE
static const ASMPROP_RES defaults[ASM_NAME_MAX_PARAMS]
Definition: asmname.c:80
LPD3DXEFFECTDEFAULT pDefaults
Definition: d3dx9mesh.h:211

Referenced by D3DXLoadMeshFromXInMemory(), and D3DXLoadSkinMeshFromXof().

◆ generate_identity_point_reps()

static DWORD * generate_identity_point_reps ( DWORD  num_vertices)
static

Definition at line 936 of file mesh.c.

937{
938 DWORD *id_point_reps;
939 DWORD i;
940
941 id_point_reps = malloc(num_vertices * sizeof(*id_point_reps));
942 if (!id_point_reps)
943 return NULL;
944
945 for (i = 0; i < num_vertices; i++)
946 {
947 id_point_reps[i] = i;
948 }
949
950 return id_point_reps;
951}

Referenced by d3dx9_mesh_ConvertPointRepsToAdjacency().

◆ get_component_epsilon()

static FLOAT get_component_epsilon ( const D3DVERTEXELEMENT9 *  decl_ptr,
const D3DXWELDEPSILONS *  epsilons 
)
static

Definition at line 6969 of file mesh.c.

6970{
6971 FLOAT epsilon = 0.0f;
6972 /* Quiet FIXMEs as this is in a loop with potentially thousand of iterations. */
6973 static BOOL fixme_once_blendindices = FALSE;
6974 static BOOL fixme_once_positiont = FALSE;
6975 static BOOL fixme_once_fog = FALSE;
6976 static BOOL fixme_once_depth = FALSE;
6977 static BOOL fixme_once_sample = FALSE;
6978 static BOOL fixme_once_unknown = FALSE;
6979
6980 switch (decl_ptr->Usage)
6981 {
6983 epsilon = epsilons->Position;
6984 break;
6986 epsilon = epsilons->BlendWeights;
6987 break;
6989 epsilon = epsilons->Normals;
6990 break;
6991 case D3DDECLUSAGE_PSIZE:
6992 epsilon = epsilons->PSize;
6993 break;
6995 {
6996 BYTE usage_index = decl_ptr->UsageIndex;
6997 if (usage_index > 7)
6998 usage_index = 7;
6999 epsilon = epsilons->Texcoords[usage_index];
7000 break;
7001 }
7003 epsilon = epsilons->Tangent;
7004 break;
7006 epsilon = epsilons->Binormal;
7007 break;
7009 epsilon = epsilons->TessFactor;
7010 break;
7011 case D3DDECLUSAGE_COLOR:
7012 if (decl_ptr->UsageIndex == 0)
7013 epsilon = epsilons->Diffuse;
7014 else if (decl_ptr->UsageIndex == 1)
7015 epsilon = epsilons->Specular;
7016 else
7017 epsilon = 1e-6f;
7018 break;
7020 if (!fixme_once_blendindices++)
7021 FIXME("D3DDECLUSAGE_BLENDINDICES welding not implemented.\n");
7022 break;
7024 if (!fixme_once_positiont++)
7025 FIXME("D3DDECLUSAGE_POSITIONT welding not implemented.\n");
7026 break;
7027 case D3DDECLUSAGE_FOG:
7028 if (!fixme_once_fog++)
7029 FIXME("D3DDECLUSAGE_FOG welding not implemented.\n");
7030 break;
7031 case D3DDECLUSAGE_DEPTH:
7032 if (!fixme_once_depth++)
7033 FIXME("D3DDECLUSAGE_DEPTH welding not implemented.\n");
7034 break;
7036 if (!fixme_once_sample++)
7037 FIXME("D3DDECLUSAGE_SAMPLE welding not implemented.\n");
7038 break;
7039 default:
7040 if (!fixme_once_unknown++)
7041 FIXME("Unknown usage %x\n", decl_ptr->Usage);
7042 break;
7043 }
7044
7045 return epsilon;
7046}
@ D3DDECLUSAGE_TANGENT
Definition: d3d9types.h:242
@ D3DDECLUSAGE_TESSFACTOR
Definition: d3d9types.h:244
@ D3DDECLUSAGE_FOG
Definition: d3d9types.h:247
@ D3DDECLUSAGE_BINORMAL
Definition: d3d9types.h:243
@ D3DDECLUSAGE_DEPTH
Definition: d3d9types.h:248
@ D3DDECLUSAGE_SAMPLE
Definition: d3d9types.h:249
FLOAT Texcoords[8]
Definition: d3dx9mesh.h:234

Referenced by D3DXWeldVertices().

◆ get_equivalent_declaration_index()

static INT get_equivalent_declaration_index ( D3DVERTEXELEMENT9  orig_declaration,
D3DVERTEXELEMENT9 *  declaration 
)
static

Definition at line 588 of file mesh.c.

589{
590 INT i;
591
592 for (i = 0; declaration[i].Stream != 0xff; i++)
593 {
594 if (orig_declaration.Usage == declaration[i].Usage
595 && orig_declaration.UsageIndex == declaration[i].UsageIndex)
596 {
597 return i;
598 }
599 }
600
601 return -1;
602}

Referenced by convert_vertex_buffer().

◆ get_indexed_point()

static D3DXVECTOR2 * get_indexed_point ( struct point2d_index *  pt_idx)
static

Definition at line 5834 of file mesh.c.

5835{
5836 return &pt_idx->outline->items[pt_idx->vertex].pos;
5837}

Referenced by get_ordered_vertex().

◆ get_line_to_point_y_distance()

static float get_line_to_point_y_distance ( D3DXVECTOR2 *  line_pt1,
D3DXVECTOR2 *  line_pt2,
D3DXVECTOR2 *  point 
)
static

Definition at line 5820 of file mesh.c.

5823{
5824 D3DXVECTOR2 line_vec = {0, 0};
5825 float line_pt_dx;
5826 float line_y;
5827
5828 D3DXVec2Subtract(&line_vec, line_pt2, line_pt1);
5829 line_pt_dx = point->x - line_pt1->x;
5830 line_y = line_pt1->y + (line_vec.y * line_pt_dx) / line_vec.x;
5831 return point->y - line_y;
5832}
POINTL point
Definition: edittest.c:50
LONG y
Definition: windef.h:130
LONG x
Definition: windef.h:129

Referenced by triangulate(), and triangulation_add_point().

◆ get_ordered_vertex()

static D3DXVECTOR2 * get_ordered_vertex ( struct glyphinfo *  glyph,
WORD  index 
)
static

Definition at line 5839 of file mesh.c.

5840{
5841 return get_indexed_point(&glyph->ordered_vertices.items[index]);
5842}
static D3DXVECTOR2 * get_indexed_point(struct point2d_index *pt_idx)
Definition: mesh.c:5834

Referenced by D3DXCreateTextW(), triangulate(), and triangulation_add_point().

◆ Get_TexCoord_Size_From_FVF()

static UINT Get_TexCoord_Size_From_FVF ( DWORD  FVF,
int  tex_num 
)
static

Definition at line 2282 of file mesh.c.

2283{
2284 return (((((FVF) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1);
2285}

Referenced by D3DXGetFVFVertexSize().

◆ impl_from_ID3DXMesh()

◆ init_edge_face_map()

static HRESULT init_edge_face_map ( struct edge_face_map *  edge_face_map,
const DWORD *  index_buffer,
const DWORD *  point_reps,
DWORD  num_faces 
)
static

Definition at line 882 of file mesh.c.

884{
885 DWORD face, edge;
886 DWORD i;
887
888 edge_face_map->lists = malloc(3 * num_faces * sizeof(*edge_face_map->lists));
889 if (!edge_face_map->lists) return E_OUTOFMEMORY;
890
891 edge_face_map->entries = malloc(3 * num_faces * sizeof(*edge_face_map->entries));
892 if (!edge_face_map->entries) return E_OUTOFMEMORY;
893
894
895 /* Initialize all lists */
896 for (i = 0; i < 3 * num_faces; i++)
897 {
899 }
900 /* Build edge face mapping */
901 for (face = 0; face < num_faces; face++)
902 {
903 for (edge = 0; edge < 3; edge++)
904 {
905 DWORD v1 = index_buffer[3*face + edge];
906 DWORD v2 = index_buffer[3*face + (edge+1)%3];
907 DWORD new_v1 = point_reps[v1]; /* What v1 has been replaced with */
908 DWORD new_v2 = point_reps[v2];
909
910 if (v1 != v2) /* Only map non-collapsed edges */
911 {
912 i = 3*face + edge;
913 edge_face_map->entries[i].v2 = new_v2;
914 edge_face_map->entries[i].face = face;
916 }
917 }
918 }
919
920 return D3D_OK;
921}
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76

Referenced by d3dx9_mesh_ConvertPointRepsToAdjacency().

◆ is_direction_similar()

static BOOL is_direction_similar ( D3DXVECTOR2 *  dir1,
D3DXVECTOR2 *  dir2,
float  cos_theta 
)
inlinestatic

Definition at line 5609 of file mesh.c.

5610{
5611 /* dot product = cos(theta) */
5612 return D3DXVec2Dot(dir1, dir2) > cos_theta;
5613}

Referenced by attempt_line_merge(), and create_outline().

◆ load_frame()

static HRESULT load_frame ( struct ID3DXFileData *  filedata,
DWORD  options,
struct IDirect3DDevice9 *  device,
struct ID3DXAllocateHierarchy *  alloc_hier,
D3DXFRAME **  frame_out,
struct ID3DXLoadUserData *  load_user_data 
)
static

Definition at line 3924 of file mesh.c.

3926{
3927 HRESULT hr;
3928 GUID type;
3929 ID3DXFileData *child;
3930 char *name = NULL;
3931 D3DXFRAME *frame = NULL;
3932 D3DXMESHCONTAINER **next_container;
3933 D3DXFRAME **next_child;
3934 SIZE_T i, nb_children;
3935
3936 hr = filedata_get_name(filedata, &name);
3937 if (FAILED(hr)) return hr;
3938
3939 hr = alloc_hier->lpVtbl->CreateFrame(alloc_hier, name, frame_out);
3940 free(name);
3941 if (FAILED(hr)) return E_FAIL;
3942
3943 frame = *frame_out;
3944 D3DXMatrixIdentity(&frame->TransformationMatrix);
3945 next_child = &frame->pFrameFirstChild;
3946 next_container = &frame->pMeshContainer;
3947
3948 hr = filedata->lpVtbl->GetChildren(filedata, &nb_children);
3949 if (FAILED(hr))
3950 return hr;
3951
3952 for (i = 0; i < nb_children; i++)
3953 {
3954 hr = filedata->lpVtbl->GetChild(filedata, i, &child);
3955 if (FAILED(hr))
3956 return hr;
3957 hr = child->lpVtbl->GetType(child, &type);
3958 if (FAILED(hr))
3959 goto err;
3960
3961 if (IsEqualGUID(&type, &TID_D3DRMMesh)) {
3962 hr = load_mesh_container(child, options, device, alloc_hier, next_container, load_user_data);
3963 if (SUCCEEDED(hr))
3964 next_container = &(*next_container)->pNextMeshContainer;
3965 } else if (IsEqualGUID(&type, &TID_D3DRMFrameTransformMatrix)) {
3967 } else if (IsEqualGUID(&type, &TID_D3DRMFrame)) {
3968 hr = load_frame(child, options, device, alloc_hier, next_child, load_user_data);
3969 if (SUCCEEDED(hr))
3970 next_child = &(*next_child)->pFrameSibling;
3971 } else if (load_user_data) {
3972 TRACE("Loading %s as user data.\n", debugstr_guid(&type));
3973 hr = load_user_data->lpVtbl->LoadFrameChildData(load_user_data, frame, child);
3974 }
3975 if (FAILED(hr))
3976 goto err;
3977
3978 IUnknown_Release(child);
3979 }
3980 return D3D_OK;
3981
3982err:
3983 IUnknown_Release(child);
3984 return hr;
3985}
static HRESULT parse_transform_matrix(ID3DXFileData *filedata, D3DXMATRIX *transform)
Definition: mesh.c:3893
static HRESULT filedata_get_name(ID3DXFileData *filedata, char **name)
Definition: mesh.c:3802
static HWND child
Definition: cursoricon.c:298
#define err(...)
struct _D3DXMESHCONTAINER * pNextMeshContainer
Definition: d3dx9anim.h:102

Referenced by D3DXLoadMeshHierarchyFromXInMemory(), and load_frame().

◆ load_mesh_container()

static HRESULT load_mesh_container ( struct ID3DXFileData *  filedata,
DWORD  options,
struct IDirect3DDevice9 *  device,
struct ID3DXAllocateHierarchy *  alloc_hier,
D3DXMESHCONTAINER **  mesh_container,
struct ID3DXLoadUserData *  load_user_data 
)
static

Definition at line 3824 of file mesh.c.

3827{
3828 HRESULT hr;
3829 ID3DXBuffer *adjacency = NULL;
3830 ID3DXBuffer *materials = NULL;
3831 ID3DXBuffer *effects = NULL;
3832 ID3DXSkinInfo *skin_info = NULL;
3834 DWORD num_materials = 0;
3835 char *name = NULL;
3836 SIZE_T child_count;
3837 ID3DXFileData *child = NULL;
3838 GUID type;
3839 unsigned int i;
3840
3842 mesh_data.pMesh = NULL;
3843
3845 &adjacency, &materials, &effects, &num_materials,
3846 &skin_info, &mesh_data.pMesh);
3847 if (FAILED(hr)) return hr;
3848
3849 hr = filedata_get_name(filedata, &name);
3850 if (FAILED(hr)) goto cleanup;
3851
3852 if (!mesh_data.pMesh)
3853 goto cleanup;
3854 hr = alloc_hier->lpVtbl->CreateMeshContainer(alloc_hier, name, &mesh_data,
3855 materials ? ID3DXBuffer_GetBufferPointer(materials) : NULL,
3856 effects ? ID3DXBuffer_GetBufferPointer(effects) : NULL,
3857 num_materials,
3858 adjacency ? ID3DXBuffer_GetBufferPointer(adjacency) : NULL,
3859 skin_info, mesh_container);
3860 if (FAILED(hr) || !load_user_data)
3861 goto cleanup;
3862
3863 hr = filedata->lpVtbl->GetChildren(filedata, &child_count);
3864 if (FAILED(hr))
3865 goto cleanup;
3866
3867 for (i = 0; i < child_count; i++)
3868 {
3869 if (FAILED(hr = filedata->lpVtbl->GetChild(filedata, i, &child)))
3870 goto cleanup;
3871 if (FAILED(hr = child->lpVtbl->GetType(child, &type)))
3872 goto cleanup;
3873
3875 && FAILED(hr = load_user_data->lpVtbl->LoadMeshChildData(load_user_data, *mesh_container, child)))
3876 goto cleanup;
3877
3878 IUnknown_Release(child);
3879 child = NULL;
3880 }
3881
3882cleanup:
3883 if (child) IUnknown_Release(child);
3884 if (materials) ID3DXBuffer_Release(materials);
3885 if (effects) ID3DXBuffer_Release(effects);
3886 if (adjacency) ID3DXBuffer_Release(adjacency);
3887 if (skin_info) IUnknown_Release(skin_info);
3888 if (mesh_data.pMesh) IUnknown_Release(mesh_data.pMesh);
3889 free(name);
3890 return hr;
3891}
static mesh_parse_func mesh_get_parse_func(const GUID *type)
Definition: mesh.c:3206
@ D3DXMESHTYPE_MESH
Definition: d3dx9anim.h:29

Referenced by D3DXLoadMeshHierarchyFromXInMemory(), and load_frame().

◆ mesh_get_parse_func()

static mesh_parse_func mesh_get_parse_func ( const GUID *  type)
static

Definition at line 3206 of file mesh.c.

3207{
3208 static const struct
3209 {
3210 const GUID *type;
3212 }
3213 funcs[] =
3214 {
3215 {&TID_D3DRMMeshNormals, parse_normals},
3216 {&TID_D3DRMMeshVertexColors, parse_vertex_colors},
3217 {&TID_D3DRMMeshTextureCoords, parse_texture_coords},
3218 {&TID_D3DRMMeshMaterialList, parse_material_list},
3219 {&DXFILEOBJ_XSkinMeshHeader, parse_skin_mesh_header},
3220 {&DXFILEOBJ_SkinWeights, parse_skin_weights_info},
3221 };
3222 unsigned int i;
3223
3224 for (i = 0; i < ARRAY_SIZE(funcs); ++i)
3225 if (IsEqualGUID(type, funcs[i].type))
3226 return funcs[i].func;
3227
3228 return NULL;
3229}
static HRESULT parse_skin_weights_info(ID3DXFileData *filedata, struct mesh_data *mesh_data, DWORD flags)
Definition: mesh.c:3152
static HRESULT parse_normals(ID3DXFileData *filedata, struct mesh_data *mesh, DWORD flags)
Definition: mesh.c:3011
static HRESULT parse_vertex_colors(ID3DXFileData *filedata, struct mesh_data *mesh, DWORD flags)
Definition: mesh.c:2932
static HRESULT parse_texture_coords(ID3DXFileData *filedata, struct mesh_data *mesh, DWORD flags)
Definition: mesh.c:2874
static HRESULT parse_material_list(ID3DXFileData *filedata, struct mesh_data *mesh, DWORD flags)
Definition: mesh.c:2756
static HRESULT parse_skin_mesh_header(ID3DXFileData *filedata, struct mesh_data *mesh_data, DWORD flags)
Definition: mesh.c:3117
HRESULT(* mesh_parse_func)(ID3DXFileData *, struct mesh_data *, DWORD)
Definition: mesh.c:3204
GLenum func
Definition: glext.h:6028
static struct __wine_debug_functions funcs
Definition: debug.c:48

Referenced by load_mesh_container(), and parse_mesh().

◆ parse_frame()

static HRESULT parse_frame ( struct ID3DXFileData *  filedata,
DWORD  options,
struct IDirect3DDevice9 *  device,
const D3DXMATRIX *  parent_transform,
struct list *  container_list,
DWORD  provide_flags 
)
static

Definition at line 4234 of file mesh.c.

4236{
4237 HRESULT hr;
4238 D3DXMATRIX transform = *parent_transform;
4239 ID3DXFileData *child;
4240 GUID type;
4241 SIZE_T i, nb_children;
4242
4243 hr = filedata->lpVtbl->GetChildren(filedata, &nb_children);
4244 if (FAILED(hr))
4245 return hr;
4246
4247 for (i = 0; i < nb_children; i++)
4248 {
4249 hr = filedata->lpVtbl->GetChild(filedata, i, &child);
4250 if (FAILED(hr))
4251 return hr;
4252 hr = child->lpVtbl->GetType(child, &type);
4253 if (FAILED(hr))
4254 goto err;
4255
4256 if (IsEqualGUID(&type, &TID_D3DRMMesh)) {
4257 struct mesh_container *container = calloc(1, sizeof(*container));
4258 if (!container)
4259 {
4260 hr = E_OUTOFMEMORY;
4261 goto err;
4262 }
4263
4265 (provide_flags & PROVIDE_ADJACENCY) ? &container->adjacency : NULL,
4266 (provide_flags & PROVIDE_MATERIALS) ? &container->materials : NULL,
4267 NULL, &container->num_materials, NULL, &container->mesh);
4268
4269 if (container->mesh)
4270 {
4271 list_add_tail(container_list, &container->entry);
4272 container->transform = transform;
4273 }
4274 else
4275 {
4276 free(container);
4277 }
4278 } else if (IsEqualGUID(&type, &TID_D3DRMFrameTransformMatrix)) {
4279 D3DXMATRIX new_transform;
4280 hr = parse_transform_matrix(child, &new_transform);
4281 D3DXMatrixMultiply(&transform, &transform, &new_transform);
4282 } else if (IsEqualGUID(&type, &TID_D3DRMFrame)) {
4283 hr = parse_frame(child, options, device, &transform, container_list, provide_flags);
4284 }
4285 if (FAILED(hr))
4286 goto err;
4287
4288 IUnknown_Release(child);
4289 }
4290 return D3D_OK;
4291
4292err:
4293 IUnknown_Release(child);
4294 return hr;
4295}
D3DXMATRIX *WINAPI D3DXMatrixMultiply(D3DXMATRIX *pout, const D3DXMATRIX *pm1, const D3DXMATRIX *pm2)
Definition: math.c:393
GLuint GLenum GLenum transform
Definition: glext.h:9407
struct list entry
Definition: metafile.c:157

Referenced by D3DXLoadMeshFromXInMemory(), and parse_frame().

◆ parse_material()

static HRESULT parse_material ( ID3DXFileData *  filedata,
D3DXMATERIAL *  material 
)
static

Definition at line 2659 of file mesh.c.

2660{
2661 HRESULT hr;
2662 SIZE_T data_size;
2663 const BYTE *data;
2664 GUID type;
2665 ID3DXFileData *child;
2666 SIZE_T i, nb_children;
2667
2668 material->pTextureFilename = NULL;
2669
2670 hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void**)&data);
2671 if (FAILED(hr)) return hr;
2672
2673 /*
2674 * template ColorRGBA {
2675 * FLOAT red;
2676 * FLOAT green;
2677 * FLOAT blue;
2678 * FLOAT alpha;
2679 * }
2680 * template ColorRGB {
2681 * FLOAT red;
2682 * FLOAT green;
2683 * FLOAT blue;
2684 * }
2685 * template Material {
2686 * ColorRGBA faceColor;
2687 * FLOAT power;
2688 * ColorRGB specularColor;
2689 * ColorRGB emissiveColor;
2690 * [ ... ]
2691 * }
2692 */
2693 if (data_size != sizeof(float) * 11)
2694 {
2695 WARN("Incorrect data size (%Id bytes).\n", data_size);
2696 filedata->lpVtbl->Unlock(filedata);
2697 return E_FAIL;
2698 }
2699
2700 memcpy(&material->MatD3D.Diffuse, data, sizeof(D3DCOLORVALUE));
2701 data += sizeof(D3DCOLORVALUE);
2702 material->MatD3D.Power = *(FLOAT*)data;
2703 data += sizeof(FLOAT);
2704 memcpy(&material->MatD3D.Specular, data, sizeof(FLOAT) * 3);
2705 material->MatD3D.Specular.a = 1.0f;
2706 data += 3 * sizeof(FLOAT);
2707 memcpy(&material->MatD3D.Emissive, data, sizeof(FLOAT) * 3);
2708 material->MatD3D.Emissive.a = 1.0f;
2709 material->MatD3D.Ambient.r = 0.0f;
2710 material->MatD3D.Ambient.g = 0.0f;
2711 material->MatD3D.Ambient.b = 0.0f;
2712 material->MatD3D.Ambient.a = 1.0f;
2713
2714 filedata->lpVtbl->Unlock(filedata);
2715
2716 hr = filedata->lpVtbl->GetChildren(filedata, &nb_children);
2717 if (FAILED(hr))
2718 return hr;
2719
2720 for (i = 0; i < nb_children; i++)
2721 {
2722 hr = filedata->lpVtbl->GetChild(filedata, i, &child);
2723 if (FAILED(hr))
2724 return hr;
2725 hr = child->lpVtbl->GetType(child, &type);
2726 if (FAILED(hr))
2727 goto err;
2728
2729 if (IsEqualGUID(&type, &TID_D3DRMTextureFilename)) {
2730 hr = parse_texture_filename(child, &material->pTextureFilename);
2731 if (FAILED(hr))
2732 goto err;
2733 }
2734 IUnknown_Release(child);
2735 }
2736 return D3D_OK;
2737
2738err:
2739 IUnknown_Release(child);
2740 return hr;
2741}
static HRESULT parse_texture_filename(ID3DXFileData *filedata, char **filename_out)
Definition: mesh.c:2622
D3DCOLORVALUE Emissive
Definition: d3d8types.h:1104
D3DCOLORVALUE Ambient
Definition: d3d8types.h:1102

Referenced by parse_material_list().

◆ parse_material_list()

static HRESULT parse_material_list ( ID3DXFileData *  filedata,
struct mesh_data *  mesh,
DWORD  flags 
)
static

Definition at line 2756 of file mesh.c.

2757{
2758 ID3DXFileData *child = NULL;
2759 unsigned int material_count;
2760 const uint32_t *in_ptr;
2761 SIZE_T nb_children;
2762 SIZE_T data_size;
2763 const void *data;
2764 unsigned int i;
2765 HRESULT hr;
2766 GUID type;
2767
2768 if (!(flags & PROVIDE_MATERIALS))
2769 return S_OK;
2770
2772
2773 hr = filedata->lpVtbl->Lock(filedata, &data_size, &data);
2774 if (FAILED(hr)) return hr;
2775
2776 /* template MeshMaterialList {
2777 * DWORD nMaterials;
2778 * DWORD nFaceIndexes;
2779 * array DWORD faceIndexes[nFaceIndexes];
2780 * [ Material ]
2781 * }
2782 */
2783
2784 in_ptr = data;
2785 hr = E_FAIL;
2786
2787 if (data_size < sizeof(uint32_t))
2788 {
2789 WARN("Truncated data (%Id bytes).\n", data_size);
2790 goto end;
2791 }
2792 material_count = *in_ptr++;
2793 if (!material_count) {
2794 hr = D3D_OK;
2795 goto end;
2796 }
2797
2798 if (data_size < 2 * sizeof(uint32_t))
2799 {
2800 WARN("Truncated data (%Id bytes).\n", data_size);
2801 goto end;
2802 }
2803 if (*in_ptr++ != mesh->num_poly_faces)
2804 {
2805 WARN("Number of material face indices (%u) doesn't match number of faces (%u).\n",
2806 *(in_ptr - 1), mesh->num_poly_faces);
2807 goto end;
2808 }
2809 if (data_size < 2 * sizeof(uint32_t) + mesh->num_poly_faces * sizeof(uint32_t))
2810 {
2811 WARN("Truncated data (%Id bytes).\n", data_size);
2812 goto end;
2813 }
2814 for (i = 0; i < mesh->num_poly_faces; ++i)
2815 {
2816 if (*in_ptr++ >= material_count)
2817 {
2818 WARN("Face %u: reference to undefined material %u (only %u materials).\n",
2819 i, *(in_ptr - 1), material_count);
2820 goto end;
2821 }
2822 }
2823
2824 mesh->materials = malloc(material_count * sizeof(*mesh->materials));
2825 mesh->material_indices = malloc(mesh->num_poly_faces * sizeof(*mesh->material_indices));
2826 if (!mesh->materials || !mesh->material_indices) {
2827 hr = E_OUTOFMEMORY;
2828 goto end;
2829 }
2830 memcpy(mesh->material_indices, (const uint32_t *)data + 2, mesh->num_poly_faces * sizeof(uint32_t));
2831
2832 hr = filedata->lpVtbl->GetChildren(filedata, &nb_children);
2833 if (FAILED(hr))
2834 goto end;
2835
2836 for (i = 0; i < nb_children; i++)
2837 {
2838 hr = filedata->lpVtbl->GetChild(filedata, i, &child);
2839 if (FAILED(hr))
2840 goto end;
2841 hr = child->lpVtbl->GetType(child, &type);
2842 if (FAILED(hr))
2843 goto end;
2844
2845 if (IsEqualGUID(&type, &TID_D3DRMMaterial))
2846 {
2847 if (mesh->num_materials >= material_count)
2848 {
2849 WARN("%u materials defined, only %u declared.\n", mesh->num_materials, material_count);
2850 hr = E_FAIL;
2851 goto end;
2852 }
2853 hr = parse_material(child, &mesh->materials[mesh->num_materials++]);
2854 if (FAILED(hr))
2855 goto end;
2856 }
2857
2858 IUnknown_Release(child);
2859 child = NULL;
2860 }
2861 if (material_count != mesh->num_materials)
2862 {
2863 WARN("Only %u of %u materials defined.\n", material_count, mesh->num_materials);
2864 hr = E_FAIL;
2865 }
2866
2867end:
2868 if (child)
2869 IUnknown_Release(child);
2870 filedata->lpVtbl->Unlock(filedata);
2871 return hr;
2872}
static HRESULT parse_material(ID3DXFileData *filedata, D3DXMATERIAL *material)
Definition: mesh.c:2659
GLuint GLuint end
Definition: gl.h:1545

Referenced by mesh_get_parse_func().

◆ parse_mesh()

static HRESULT parse_mesh ( ID3DXFileData *  filedata,
struct mesh_data *  mesh_data,
DWORD  provide_flags 
)
static

Definition at line 3231 of file mesh.c.

3232{
3233 ID3DXFileData *child = NULL;
3234 mesh_parse_func parse_func;
3235 const BYTE *data, *in_ptr;
3236 DWORD *index_out_ptr;
3237 SIZE_T child_count;
3238 SIZE_T data_size;
3239 unsigned int i;
3240 HRESULT hr;
3241 GUID type;
3242
3243 /*
3244 * template Mesh {
3245 * DWORD nVertices;
3246 * array Vector vertices[nVertices];
3247 * DWORD nFaces;
3248 * array MeshFace faces[nFaces];
3249 * [ ... ]
3250 * }
3251 */
3252
3254
3255 hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void **)&data);
3256 if (FAILED(hr)) return hr;
3257
3258 in_ptr = data;
3259 hr = E_FAIL;
3260
3261 if (data_size < sizeof(uint32_t) * 2)
3262 {
3263 WARN("Truncated data (%Id bytes).\n", data_size);
3264 goto end;
3265 }
3266 mesh_data->num_vertices = *(uint32_t *)in_ptr;
3267 if (data_size < sizeof(uint32_t) * 2 + mesh_data->num_vertices * sizeof(D3DXVECTOR3))
3268 {
3269 WARN("Truncated data (%Id bytes).\n", data_size);
3270 goto end;
3271 }
3272 in_ptr += sizeof(uint32_t) + mesh_data->num_vertices * sizeof(D3DXVECTOR3);
3273
3274 mesh_data->num_poly_faces = *(uint32_t *)in_ptr;
3275 in_ptr += sizeof(uint32_t);
3276
3278 for (i = 0; i < mesh_data->num_poly_faces; i++)
3279 {
3280 unsigned int poly_vertices_count;
3281 unsigned int j;
3282
3283 if (data_size - (in_ptr - data) < sizeof(uint32_t))
3284 {
3285 WARN("Truncated data (%Id bytes).\n", data_size);
3286 goto end;
3287 }
3288 poly_vertices_count = *(uint32_t *)in_ptr;
3289 in_ptr += sizeof(uint32_t);
3290 if (data_size - (in_ptr - data) < poly_vertices_count * sizeof(uint32_t))
3291 {
3292 WARN("Truncated data (%Id bytes).\n", data_size);
3293 goto end;
3294 }
3295 if (poly_vertices_count < 3)
3296 {
3297 WARN("Face %u has only %u vertices.\n", i, poly_vertices_count);
3298 goto end;
3299 }
3300 for (j = 0; j < poly_vertices_count; j++)
3301 {
3302 if (*(uint32_t *)in_ptr >= mesh_data->num_vertices)
3303 {
3304 WARN("Face %u, index %u: undefined vertex %u (only %u vertices).\n",
3305 i, j, *(uint32_t *)in_ptr, mesh_data->num_vertices);
3306 goto end;
3307 }
3308 in_ptr += sizeof(uint32_t);
3309 }
3310 mesh_data->num_tri_faces += poly_vertices_count - 2;
3311 }
3312
3314
3319 hr = E_OUTOFMEMORY;
3320 goto end;
3321 }
3322
3323 in_ptr = data + sizeof(uint32_t);
3325 in_ptr += mesh_data->num_vertices * sizeof(D3DXVECTOR3) + sizeof(uint32_t);
3326
3327 index_out_ptr = mesh_data->indices;
3328 for (i = 0; i < mesh_data->num_poly_faces; i++)
3329 {
3330 unsigned int count;
3331
3332 count = *(uint32_t *)in_ptr;
3333 in_ptr += sizeof(uint32_t);
3335
3336 while (count--)
3337 {
3338 *index_out_ptr++ = *(uint32_t *)in_ptr;
3339 in_ptr += sizeof(uint32_t);
3340 }
3341 }
3342
3343 hr = filedata->lpVtbl->GetChildren(filedata, &child_count);
3344 if (FAILED(hr))
3345 goto end;
3346
3347 for (i = 0; i < child_count; i++)
3348 {
3349 hr = filedata->lpVtbl->GetChild(filedata, i, &child);
3350 if (FAILED(hr))
3351 goto end;
3352 hr = child->lpVtbl->GetType(child, &type);
3353 if (FAILED(hr))
3354 goto end;
3355
3356 if ((parse_func = mesh_get_parse_func(&type)))
3357 hr = parse_func(child, mesh_data, provide_flags);
3358 if (FAILED(hr))
3359 goto end;
3360
3361 IUnknown_Release(child);
3362 child = NULL;
3363 }
3364
3366 {
3367 WARN("Mismatch between skin weights info count %u and bones count %u from skin mesh header.\n",
3369 hr = E_FAIL;
3370 goto end;
3371 }
3372
3373 if ((provide_flags & PROVIDE_SKININFO) && !mesh_data->skin_info)
3374 {
3377 goto end;
3378 }
3379
3380 hr = D3D_OK;
3381
3382end:
3383 if (child)
3384 IUnknown_Release(child);
3385 filedata->lpVtbl->Unlock(filedata);
3386 return hr;
3387}
#define uint32_t
Definition: nsiface.idl:61
HRESULT WINAPI D3DXCreateSkinInfoFVF(DWORD vertex_count, DWORD fvf, DWORD bone_count, ID3DXSkinInfo **skin_info)
Definition: skin.c:505
unsigned int skin_weights_info_count
Definition: mesh.c:2619
unsigned int bone_count
Definition: mesh.c:2618

Referenced by D3DXLoadSkinMeshFromXof().

◆ parse_normals()

static HRESULT parse_normals ( ID3DXFileData *  filedata,
struct mesh_data *  mesh,
DWORD  flags 
)
static

Definition at line 3011 of file mesh.c.

3012{
3013 unsigned int num_face_indices = mesh->num_poly_faces * 2 + mesh->num_tri_faces;
3014 DWORD *index_out_ptr;
3015 SIZE_T data_size;
3016 const BYTE *data;
3017 unsigned int i;
3018 HRESULT hr;
3019
3020 free(mesh->normals);
3021 mesh->num_normals = 0;
3022 mesh->normals = NULL;
3023 mesh->normal_indices = NULL;
3025
3026 hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void **)&data);
3027 if (FAILED(hr)) return hr;
3028
3029 /* template Vector {
3030 * FLOAT x;
3031 * FLOAT y;
3032 * FLOAT z;
3033 * }
3034 * template MeshFace {
3035 * DWORD nFaceVertexIndices;
3036 * array DWORD faceVertexIndices[nFaceVertexIndices];
3037 * }
3038 * template MeshNormals {
3039 * DWORD nNormals;
3040 * array Vector normals[nNormals];
3041 * DWORD nFaceNormals;
3042 * array MeshFace faceNormals[nFaceNormals];
3043 * }
3044 */
3045
3046 hr = E_FAIL;
3047
3048 if (data_size < sizeof(uint32_t) * 2)
3049 {
3050 WARN("Truncated data (%Id bytes).\n", data_size);
3051 goto end;
3052 }
3053 mesh->num_normals = *(uint32_t *)data;
3054 data += sizeof(uint32_t);
3055 if (data_size < sizeof(uint32_t) * 2 + mesh->num_normals * sizeof(D3DXVECTOR3) +
3056 num_face_indices * sizeof(uint32_t))
3057 {
3058 WARN("Truncated data (%Id bytes).\n", data_size);
3059 goto end;
3060 }
3061
3062 mesh->normals = malloc(mesh->num_normals * sizeof(D3DXVECTOR3));
3063 mesh->normal_indices = malloc(num_face_indices * sizeof(*mesh->normal_indices));
3064 if (!mesh->normals || !mesh->normal_indices) {
3065 hr = E_OUTOFMEMORY;
3066 goto end;
3067 }
3068
3069 memcpy(mesh->normals, data, mesh->num_normals * sizeof(D3DXVECTOR3));
3070 data += mesh->num_normals * sizeof(D3DXVECTOR3);
3071 for (i = 0; i < mesh->num_normals; i++)
3072 D3DXVec3Normalize(&mesh->normals[i], &mesh->normals[i]);
3073
3074 if (*(uint32_t *)data != mesh->num_poly_faces)
3075 {
3076 WARN("Number of face normals (%u) doesn't match number of faces (%u).\n",
3077 *(uint32_t *)data, mesh->num_poly_faces);
3078 goto end;
3079 }
3080 data += sizeof(uint32_t);
3081 index_out_ptr = mesh->normal_indices;
3082 for (i = 0; i < mesh->num_poly_faces; i++)
3083 {
3084 unsigned int count = *(uint32_t *)data;
3085 unsigned int j;
3086
3087 if (count != mesh->num_tri_per_face[i] + 2)
3088 {
3089 WARN("Face %u: number of normals (%u) doesn't match number of vertices (%u).\n",
3090 i, count, mesh->num_tri_per_face[i] + 2);
3091 goto end;
3092 }
3093 data += sizeof(uint32_t);
3094
3095 for (j = 0; j < count; j++)
3096 {
3097 uint32_t normal_index = *(uint32_t *)data;
3098
3099 if (normal_index >= mesh->num_normals)
3100 {
3101 WARN("Face %u, normal index %u: reference to undefined normal %u (only %u normals).\n",
3102 i, j, normal_index, mesh->num_normals);
3103 goto end;
3104 }
3105 *index_out_ptr++ = normal_index;
3106 data += sizeof(uint32_t);
3107 }
3108 }
3109
3110 hr = D3D_OK;
3111
3112end:
3113 filedata->lpVtbl->Unlock(filedata);
3114 return hr;
3115}

Referenced by mesh_get_parse_func().

◆ parse_skin_mesh_header()

static HRESULT parse_skin_mesh_header ( ID3DXFileData *  filedata,
struct mesh_data *  mesh_data,
DWORD  flags 
)
static

Definition at line 3117 of file mesh.c.

3118{
3119 const BYTE *data;
3120 SIZE_T data_size;
3121 HRESULT hr;
3122
3123 TRACE("filedata %p, mesh_data %p.\n", filedata, mesh_data);
3124
3125 if (!(flags & PROVIDE_SKININFO))
3126 return S_OK;
3127
3128 if (mesh_data->skin_info)
3129 {
3130 WARN("Skin mesh header already encountered\n");
3131 return E_FAIL;
3132 }
3133
3134 if (FAILED(hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void **)&data)))
3135 return hr;
3136
3137 if (data_size < sizeof(WORD) * 3)
3138 {
3139 WARN("Truncated data (%Id bytes).\n", data_size);
3140 filedata->lpVtbl->Unlock(filedata);
3141 return E_FAIL;
3142 }
3143 /* Skip nMaxSkinWeightsPerVertex and nMaxSkinWeightsPerFace */
3144 data += 2 * sizeof(WORD);
3148
3149 return hr;
3150}

Referenced by mesh_get_parse_func().

◆ parse_skin_weights_info()

static HRESULT parse_skin_weights_info ( ID3DXFileData *  filedata,
struct mesh_data *  mesh_data,
DWORD  flags 
)
static

Definition at line 3152 of file mesh.c.

3153{
3154 unsigned int index = mesh_data->skin_weights_info_count;
3155 unsigned int influence_count;
3156 const char *name;
3157 const BYTE *data;
3158 SIZE_T data_size;
3159 HRESULT hr;
3160
3161 TRACE("filedata %p, mesh_data %p, index %u.\n", filedata, mesh_data, index);
3162
3163 if (!(flags & PROVIDE_SKININFO))
3164 return S_OK;
3165
3166 if (!mesh_data->skin_info)
3167 {
3168 WARN("Skin weights found but skin mesh header not encountered yet.\n");
3169 return E_FAIL;
3170 }
3171
3172 if (FAILED(hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void **)&data)))
3173 return hr;
3174
3175 /* FIXME: String will have to be retrieved directly instead of through a
3176 * pointer once our ID3DXFileData implementation is fixed. */
3177 name = *(const char **)data;
3178 data += sizeof(char *);
3179
3180 influence_count = *(uint32_t *)data;
3181 data += sizeof(uint32_t);
3182
3183 if (data_size < (sizeof(char *) + sizeof(uint32_t) + influence_count * (sizeof(uint32_t) + sizeof(float))
3184 + 16 * sizeof(float)))
3185 {
3186 WARN("Truncated data (%Id bytes).\n", data_size);
3187 filedata->lpVtbl->Unlock(filedata);
3188 return E_FAIL;
3189 }
3190
3191 hr = mesh_data->skin_info->lpVtbl->SetBoneName(mesh_data->skin_info, index, name);
3192 if (SUCCEEDED(hr))
3193 hr = mesh_data->skin_info->lpVtbl->SetBoneInfluence(mesh_data->skin_info, index, influence_count,
3194 (const DWORD *)data, (const float *)(data + influence_count * sizeof(uint32_t)));
3195 if (SUCCEEDED(hr))
3196 hr = mesh_data->skin_info->lpVtbl->SetBoneOffsetMatrix(mesh_data->skin_info, index,
3197 (const D3DMATRIX *)(data + influence_count * (sizeof(uint32_t) + sizeof(float))));
3198
3199 if (SUCCEEDED(hr))
3201 return hr;
3202}

Referenced by mesh_get_parse_func().

◆ parse_texture_coords()

static HRESULT parse_texture_coords ( ID3DXFileData *  filedata,
struct mesh_data *  mesh,
DWORD  flags 
)
static

Definition at line 2874 of file mesh.c.

2875{
2876 const uint32_t *data;
2877 SIZE_T data_size;
2878 HRESULT hr;
2879
2880 free(mesh->tex_coords);
2881 mesh->tex_coords = NULL;
2882
2883 hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void **)&data);
2884 if (FAILED(hr)) return hr;
2885
2886 /* template Coords2d {
2887 * FLOAT u;
2888 * FLOAT v;
2889 * }
2890 * template MeshTextureCoords {
2891 * DWORD nTextureCoords;
2892 * array Coords2d textureCoords[nTextureCoords];
2893 * }
2894 */
2895
2896 hr = E_FAIL;
2897
2898 if (data_size < sizeof(uint32_t))
2899 {
2900 WARN("Truncated data (%Id bytes).\n", data_size);
2901 goto end;
2902 }
2903 if (*data != mesh->num_vertices)
2904 {
2905 WARN("Number of texture coordinates (%u) doesn't match number of vertices (%u).\n",
2906 *data, mesh->num_vertices);
2907 goto end;
2908 }
2909 ++data;
2910 if (data_size < sizeof(uint32_t) + mesh->num_vertices * sizeof(*mesh->tex_coords))
2911 {
2912 WARN("Truncated data (%Id bytes).\n", data_size);
2913 goto end;
2914 }
2915
2916 mesh->tex_coords = malloc(mesh->num_vertices * sizeof(*mesh->tex_coords));
2917 if (!mesh->tex_coords) {
2918 hr = E_OUTOFMEMORY;
2919 goto end;
2920 }
2921 memcpy(mesh->tex_coords, data, mesh->num_vertices * sizeof(*mesh->tex_coords));
2922
2923 mesh->fvf |= D3DFVF_TEX1;
2924
2925 hr = D3D_OK;
2926
2927end:
2928 filedata->lpVtbl->Unlock(filedata);
2929 return hr;
2930}

Referenced by mesh_get_parse_func().

◆ parse_texture_filename()

static HRESULT parse_texture_filename ( ID3DXFileData *  filedata,
char **  filename_out 
)
static

Definition at line 2622 of file mesh.c.

2623{
2624 HRESULT hr;
2625 SIZE_T data_size;
2626 BYTE *data;
2627 char *filename_in;
2628
2629 /* template TextureFilename {
2630 * STRING filename;
2631 * }
2632 */
2633
2634 free(*filename_out);
2635 *filename_out = NULL;
2636
2637 hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void**)&data);
2638 if (FAILED(hr)) return hr;
2639
2640 /* FIXME: String must be retrieved directly instead of through a pointer once ID3DXFILE is fixed */
2641 if (data_size < sizeof(filename_in))
2642 {
2643 WARN("Truncated data (%Iu bytes).\n", data_size);
2644 filedata->lpVtbl->Unlock(filedata);
2645 return E_FAIL;
2646 }
2647 filename_in = *(char **)data;
2648
2649 if (!(*filename_out = strdup(filename_in))) {
2650 filedata->lpVtbl->Unlock(filedata);
2651 return E_OUTOFMEMORY;
2652 }
2653
2654 filedata->lpVtbl->Unlock(filedata);
2655
2656 return D3D_OK;
2657}
static char * strdup(const char *buf)
Definition: string.h:83

Referenced by parse_material().

◆ parse_transform_matrix()

static HRESULT parse_transform_matrix ( ID3DXFileData *  filedata,
D3DXMATRIX *  transform 
)
static

Definition at line 3893 of file mesh.c.

3894{
3895 SIZE_T data_size;
3896 const BYTE *data;
3897 HRESULT hr;
3898
3899 /* template Matrix4x4 {
3900 * array FLOAT matrix[16];
3901 * }
3902 * template FrameTransformMatrix {
3903 * Matrix4x4 frameMatrix;
3904 * }
3905 */
3906
3907 hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void **)&data);
3908 if (FAILED(hr))
3909 return hr;
3910
3911 if (data_size != sizeof(D3DXMATRIX))
3912 {
3913 WARN("Incorrect data size (%Id bytes).\n", data_size);
3914 filedata->lpVtbl->Unlock(filedata);
3915 return E_FAIL;
3916 }
3917
3918 memcpy(transform, data, sizeof(D3DXMATRIX));
3919
3920 filedata->lpVtbl->Unlock(filedata);
3921 return D3D_OK;
3922}

Referenced by load_frame(), and parse_frame().

◆ parse_vertex_colors()

static HRESULT parse_vertex_colors ( ID3DXFileData *  filedata,
struct mesh_data *  mesh,
DWORD  flags 
)
static

Definition at line 2932 of file mesh.c.

2933{
2934 unsigned int color_count, i;
2935 const uint32_t *data;
2936 SIZE_T data_size;
2937 HRESULT hr;
2938
2939 free(mesh->vertex_colors);
2940 mesh->vertex_colors = NULL;
2941
2942 hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void **)&data);
2943 if (FAILED(hr)) return hr;
2944
2945 /* template IndexedColor {
2946 * DWORD index;
2947 * ColorRGBA indexColor;
2948 * }
2949 * template MeshVertexColors {
2950 * DWORD nVertexColors;
2951 * array IndexedColor vertexColors[nVertexColors];
2952 * }
2953 */
2954
2955 hr = E_FAIL;
2956
2957 if (data_size < sizeof(uint32_t))
2958 {
2959 WARN("Truncated data (%Id bytes).\n", data_size);
2960 goto end;
2961 }
2962 color_count = *data;
2963 ++data;
2964 if (data_size < sizeof(uint32_t) + color_count * (sizeof(uint32_t) + sizeof(D3DCOLORVALUE)))
2965 {
2966 WARN("Truncated data (%Id bytes).\n", data_size);
2967 goto end;
2968 }
2969
2970 mesh->vertex_colors = malloc(mesh->num_vertices * sizeof(*mesh->vertex_colors));
2971 if (!mesh->vertex_colors) {
2972 hr = E_OUTOFMEMORY;
2973 goto end;
2974 }
2975
2976 for (i = 0; i < mesh->num_vertices; i++)
2977 mesh->vertex_colors[i] = D3DCOLOR_ARGB(0, 0xff, 0xff, 0xff);
2978 for (i = 0; i < color_count; ++i)
2979 {
2981 unsigned int index = *data;
2982
2983 ++data;
2984 if (index >= mesh->num_vertices)
2985 {
2986 WARN("Vertex color %u references undefined vertex %u (only %u vertices).\n",
2987 i, index, mesh->num_vertices);
2988 goto end;
2989 }
2990 memcpy(&color, data, sizeof(color));
2991 data += sizeof(color) / sizeof(*data);
2992 color.r = min(1.0f, max(0.0f, color.r));
2993 color.g = min(1.0f, max(0.0f, color.g));
2994 color.b = min(1.0f, max(0.0f, color.b));
2995 color.a = min(1.0f, max(0.0f, color.a));
2996 mesh->vertex_colors[index] = D3DCOLOR_ARGB((BYTE)(color.a * 255.0f + 0.5f),
2997 (BYTE)(color.r * 255.0f + 0.5f),
2998 (BYTE)(color.g * 255.0f + 0.5f),
2999 (BYTE)(color.b * 255.0f + 0.5f));
3000 }
3001
3003
3004 hr = D3D_OK;
3005
3006end:
3007 filedata->lpVtbl->Unlock(filedata);
3008 return hr;
3009}
#define D3DCOLOR_ARGB(a, r, g, b)
Definition: d3d8types.h:41
GLuint color
Definition: glext.h:6243
#define min(a, b)
Definition: monoChain.cc:55
#define max(a, b)
Definition: svc.c:63

Referenced by mesh_get_parse_func().

◆ propagate_face_vertices()

static HRESULT propagate_face_vertices ( const DWORD *  adjacency,
DWORD *  point_reps,
const uint32_t *  indices,
uint32_t *  new_indices,
unsigned int  face_idx,
unsigned int  face_count 
)
static

Definition at line 1054 of file mesh.c.

1056{
1057 unsigned int face_base = 3 * face_idx;
1058 unsigned int edge, opp_edge;
1059
1060 for (edge = 0; edge < 3; ++edge)
1061 {
1062 unsigned int adj_face = adjacency[face_base + edge];
1063 unsigned int adj_face_base;
1064 unsigned int i;
1065
1066 if (adj_face == ~0u) /* No adjacent face. */
1067 continue;
1068 else if (adj_face >= face_count)
1069 {
1070 /* This crashes on Windows. */
1071 WARN("Index out of bounds. Got %u, expected less than %u.\n", adj_face, face_count);
1072 return D3DERR_INVALIDCALL;
1073 }
1074 adj_face_base = 3 * adj_face;
1075
1076 /* Find opposite edge in adjacent face. */
1077 for (opp_edge = 0; opp_edge < 3; ++opp_edge)
1078 {
1079 unsigned int opp_edge_index = adj_face_base + opp_edge;
1080
1081 if (adjacency[opp_edge_index] == face_idx)
1082 break; /* Found opposite edge. */
1083 }
1084
1085 /* Replaces vertices in opposite edge with vertices from current edge. */
1086 for (i = 0; i < 2; ++i)
1087 {
1088 unsigned int from = face_base + (edge + (1 - i)) % 3;
1089 unsigned int to = adj_face_base + (opp_edge + i) % 3;
1090
1091 /* Propagate lowest index. */
1092 if (new_indices[to] > new_indices[from])
1093 {
1094 new_indices[to] = new_indices[from];
1095 point_reps[indices[to]] = new_indices[from];
1096 }
1097 }
1098 }
1099
1100 return D3D_OK;
1101}

Referenced by d3dx9_mesh_ConvertAdjacencyToPointReps().

◆ queue_frame_node()

static BOOL queue_frame_node ( struct list *  queue,
D3DXFRAME *  frame 
)
static

Definition at line 7689 of file mesh.c.

7690{
7691 struct frame_node *node;
7692
7693 if (!frame->pFrameFirstChild)
7694 return TRUE;
7695
7696 node = malloc(sizeof(*node));
7697 if (!node)
7698 return FALSE;
7699
7700 node->frame = frame;
7701 list_add_tail(queue, &node->entry);
7702
7703 return TRUE;
7704}

Referenced by D3DXFrameFind().

◆ read_ib()

static DWORD read_ib ( void *  index_buffer,
BOOL  indices_are_32bit,
DWORD  index 
)
inlinestatic

Definition at line 7049 of file mesh.c.

7051{
7052 if (indices_are_32bit)
7053 {
7054 DWORD *indices = index_buffer;
7055 return indices[index];
7056 }
7057 else
7058 {
7059 WORD *indices = index_buffer;
7060 return indices[index];
7061 }
7062}

Referenced by D3DXComputeTangentFrameEx(), and D3DXWeldVertices().

◆ read_vec3()

static D3DXVECTOR3 read_vec3 ( BYTE *  vertices,
const D3DVERTEXELEMENT9 *  declaration,
DWORD  vertex_stride,
DWORD  index 
)
static

Definition at line 7379 of file mesh.c.

7381{
7382 D3DXVECTOR3 vec3 = {0};
7383 const D3DXVECTOR3 *src = vertex_element_vec3(vertices, declaration, vertex_stride, index);
7384
7385 switch (declaration->Type)
7386 {
7387 case D3DDECLTYPE_FLOAT1:
7388 vec3.x = src->x;
7389 break;
7390 case D3DDECLTYPE_FLOAT2:
7391 vec3.x = src->x;
7392 vec3.y = src->y;
7393 break;
7394 case D3DDECLTYPE_FLOAT3:
7395 case D3DDECLTYPE_FLOAT4:
7396 vec3 = *src;
7397 break;
7398 default:
7399 ERR("Cannot read vec3\n");
7400 break;
7401 }
7402
7403 return vec3;
7404}
Definition: shader.c:383
float x
Definition: shader.c:384
float y
Definition: shader.c:384

Referenced by D3DXComputeTangentFrameEx().

◆ remap_faces_for_attrsort()

static HRESULT remap_faces_for_attrsort ( struct d3dx9_mesh *  This,
const DWORD *  indices,
DWORD *  attrib_buffer,
DWORD **  sorted_attrib_buffer,
DWORD **  face_remap 
)
static

Definition at line 1597 of file mesh.c.

1599{
1600 DWORD **sorted_attrib_ptr_buffer = NULL;
1601 DWORD i;
1602
1603 sorted_attrib_ptr_buffer = malloc(This->numfaces * sizeof(*sorted_attrib_ptr_buffer));
1604 if (!sorted_attrib_ptr_buffer)
1605 return E_OUTOFMEMORY;
1606
1607 *face_remap = malloc(This->numfaces * sizeof(**face_remap));
1608 if (!*face_remap)
1609 {
1610 free(sorted_attrib_ptr_buffer);
1611 return E_OUTOFMEMORY;
1612 }
1613
1614 for (i = 0; i < This->numfaces; i++)
1615 sorted_attrib_ptr_buffer[i] = &attrib_buffer[i];
1616 qsort(sorted_attrib_ptr_buffer, This->numfaces, sizeof(*sorted_attrib_ptr_buffer), attrib_entry_compare);
1617
1618 for (i = 0; i < This->numfaces; i++)
1619 {
1620 DWORD old_face = sorted_attrib_ptr_buffer[i] - attrib_buffer;
1621 (*face_remap)[old_face] = i;
1622 }
1623
1624 /* overwrite sorted_attrib_ptr_buffer with the values themselves */
1625 *sorted_attrib_buffer = (DWORD*)sorted_attrib_ptr_buffer;
1626 for (i = 0; i < This->numfaces; i++)
1627 (*sorted_attrib_buffer)[(*face_remap)[i]] = attrib_buffer[i];
1628
1629 return D3D_OK;
1630}
static int __cdecl attrib_entry_compare(const void *a, const void *b)
Definition: mesh.c:1583

Referenced by d3dx9_mesh_OptimizeInplace().

◆ remove_triangulation()

static void remove_triangulation ( struct triangulation_array *  array,
struct triangulation *  item 
)
static

Definition at line 5844 of file mesh.c.

5845{
5846 free(item->vertex_stack.items);
5847 MoveMemory(item, item + 1, (char*)&array->items[array->count] - (char*)(item + 1));
5848 array->count--;
5849}
#define MoveMemory
Definition: minwinbase.h:28

Referenced by triangulate(), and triangulation_add_point().

◆ reserve()

static BOOL reserve ( struct dynamic_array *  array,
int  count,
int  itemsize 
)
static

Definition at line 5499 of file mesh.c.

5500{
5501 if (count > array->capacity) {
5502 void *new_buffer;
5503 int new_capacity = max(array->capacity ? array->capacity * 2 : 16, count);
5504 new_buffer = realloc(array->items, new_capacity * itemsize);
5505 if (!new_buffer)
5506 return FALSE;
5507 array->items = new_buffer;
5508 array->capacity = new_capacity;
5509 }
5510 return TRUE;
5511}
#define realloc
Definition: debug_ros.c:6

Referenced by add_outline(), add_point(), add_points(), add_triangulation(), add_vertex_index(), dxil_block_add_record(), dxil_block_read(), shader_instruction_array_init(), shader_instruction_array_reserve(), sm6_function_blocks_reserve(), test_not_full(), test_RtlCreateHeap(), test_RtlCreateUserStack(), vsir_program_init(), and write_cabinet().

◆ scale_clamp_shortn()

static FLOAT scale_clamp_shortn ( FLOAT  value)
static

Definition at line 301 of file mesh.c.

302{
303 value = value * SHRT_MAX;
304
305 /* The tests show that the range is SHRT_MIN + 1 to SHRT_MAX. */
306 if (value <= SHRT_MIN)
307 {
308 return SHRT_MIN + 1;
309 }
310 else if (value > SHRT_MAX)
311 {
312 return SHRT_MAX;
313 }
314 else
315 {
316 return value;
317 }
318}
#define SHRT_MIN
Definition: limits.h:21
Definition: pdh_main.c:64

Referenced by convert_float4().

◆ scale_clamp_ubyten()

static FLOAT scale_clamp_ubyten ( FLOAT  value)
static

Definition at line 284 of file mesh.c.

285{
287
288 if (value < 0.0f)
289 {
290 return 0.0f;
291 }
292 else
293 {
294 if (value > UCHAR_MAX) /* Clamp at 255 */
295 return UCHAR_MAX;
296 else
297 return value;
298 }
299}

Referenced by convert_float4().

◆ scale_clamp_ushortn()

static FLOAT scale_clamp_ushortn ( FLOAT  value)
static

Definition at line 320 of file mesh.c.

321{
323
324 if (value < 0.0f)
325 {
326 return 0.0f;
327 }
328 else
329 {
330 if (value > USHRT_MAX) /* Clamp at 65535 */
331 return USHRT_MAX;
332 else
333 return value;
334 }
335}
#define USHRT_MAX
Definition: limits.h:23

Referenced by convert_float4().

◆ simple_round()

static INT simple_round ( FLOAT  value)
static

Definition at line 337 of file mesh.c.

338{
339 int res = (INT)(value + 0.5f);
340
341 return res;
342}
GLuint res
Definition: glext.h:9613
#define INT
Definition: polytest.cpp:20

Referenced by convert_float4().

◆ triangulate()

static HRESULT triangulate ( struct triangulation_array *  triangulations)
static

Definition at line 5959 of file mesh.c.

5960{
5961 int sweep_idx;
5962 HRESULT hr;
5963 struct glyphinfo *glyph = triangulations->glyph;
5964 int nb_vertices = 0;
5965 int i;
5966 struct point2d_index *idx_ptr;
5967
5968 /* Glyphs without outlines do not generate any vertices. */
5969 if (!glyph->outlines.count)
5970 return D3D_OK;
5971
5972 for (i = 0; i < glyph->outlines.count; i++)
5973 nb_vertices += glyph->outlines.items[i].count;
5974
5975 glyph->ordered_vertices.items = malloc(nb_vertices * sizeof(*glyph->ordered_vertices.items));
5976 if (!glyph->ordered_vertices.items)
5977 return E_OUTOFMEMORY;
5978
5979 idx_ptr = glyph->ordered_vertices.items;
5980 for (i = 0; i < glyph->outlines.count; i++)
5981 {
5982 struct outline *outline = &glyph->outlines.items[i];
5983 int j;
5984
5985 idx_ptr->outline = outline;
5986 idx_ptr->vertex = 0;
5987 idx_ptr++;
5988 for (j = outline->count - 1; j > 0; j--)
5989 {
5990 idx_ptr->outline = outline;
5991 idx_ptr->vertex = j;
5992 idx_ptr++;
5993 }
5994 }
5995 glyph->ordered_vertices.count = nb_vertices;
5996
5997 /* Native implementation seems to try to create a triangle fan from
5998 * the first outline point if the glyph only has one outline. */
5999 if (glyph->outlines.count == 1)
6000 {
6001 struct outline *outline = glyph->outlines.items;
6002 D3DXVECTOR2 *base = &outline->items[0].pos;
6003 D3DXVECTOR2 *last = &outline->items[1].pos;
6004 float ccw = 0;
6005
6006 for (i = 2; i < outline->count; i++)
6007 {
6008 D3DXVECTOR2 *next = &outline->items[i].pos;
6009 D3DXVECTOR2 v1 = {0.0f, 0.0f};
6010 D3DXVECTOR2 v2 = {0.0f, 0.0f};
6011
6012 D3DXVec2Subtract(&v1, base, last);
6013 D3DXVec2Subtract(&v2, last, next);
6014 ccw = D3DXVec2CCW(&v1, &v2);
6015 if (ccw > 0.0f)
6016 break;
6017
6018 last = next;
6019 }
6020 if (ccw <= 0)
6021 {
6022 glyph->faces.items = malloc((outline->count - 2) * sizeof(glyph->faces.items[0]));
6023 if (!glyph->faces.items)
6024 return E_OUTOFMEMORY;
6025
6026 glyph->faces.count = outline->count - 2;
6027 for (i = 0; i < glyph->faces.count; i++)
6028 {
6029 glyph->faces.items[i][0] = 0;
6030 glyph->faces.items[i][1] = i + 1;
6031 glyph->faces.items[i][2] = i + 2;
6032 }
6033 return S_OK;
6034 }
6035 }
6036
6037 /* Perform 2D polygon triangulation for complex glyphs.
6038 * Triangulation is performed using a sweep line concept, from right to left,
6039 * by processing vertices in sorted order. Complex polygons are split into
6040 * monotone polygons which are triangulated separately. */
6041 /* FIXME: The order of the faces is not consistent with the native implementation. */
6042
6043 /* Reserve space for maximum possible faces from triangulation.
6044 * # faces for outer outlines = outline->count - 2
6045 * # faces for inner outlines = outline->count + 2
6046 * There must be at least 1 outer outline. */
6047 glyph->faces.items = malloc((nb_vertices + glyph->outlines.count * 2 - 4) * sizeof(glyph->faces.items[0]));
6048 if (!glyph->faces.items)
6049 return E_OUTOFMEMORY;
6050
6051 qsort(glyph->ordered_vertices.items, nb_vertices,
6052 sizeof(glyph->ordered_vertices.items[0]), compare_vertex_indices);
6053 for (sweep_idx = 0; sweep_idx < glyph->ordered_vertices.count; sweep_idx++)
6054 {
6055 int start = 0;
6056 int end = triangulations->count;
6057
6058 while (start < end)
6059 {
6060 D3DXVECTOR2 *sweep_vtx = get_ordered_vertex(glyph, sweep_idx);
6061 int current = (start + end) / 2;
6062 struct triangulation *t = &triangulations->items[current];
6063 BOOL on_top_outline = FALSE;
6064 D3DXVECTOR2 *top_next, *bottom_next;
6065 WORD top_idx, bottom_idx;
6066
6067 if (t->merging && t->last_on_top)
6068 top_next = triangulation_get_next_point(t + 1, glyph, TRUE);
6069 else
6070 top_next = triangulation_get_next_point(t, glyph, TRUE);
6071 if (sweep_vtx == top_next)
6072 {
6073 if (t->merging && t->last_on_top)
6074 t++;
6075 hr = triangulation_add_point(&t, triangulations, sweep_idx, TRUE);
6076 if (hr != S_OK) return hr;
6077
6078 if (t + 1 < &triangulations->items[triangulations->count] &&
6079 triangulation_get_next_point(t + 1, glyph, FALSE) == sweep_vtx)
6080 {
6081 /* point also on bottom outline of higher triangulation */
6082 struct triangulation *t2 = t + 1;
6083 hr = triangulation_add_point(&t2, triangulations, sweep_idx, FALSE);
6084 if (hr != S_OK) return hr;
6085
6086 t->merging = TRUE;
6087 t2->merging = TRUE;
6088 }
6089 on_top_outline = TRUE;
6090 }
6091
6092 if (t->merging && !t->last_on_top)
6093 bottom_next = triangulation_get_next_point(t - 1, glyph, FALSE);
6094 else
6095 bottom_next = triangulation_get_next_point(t, glyph, FALSE);
6096 if (sweep_vtx == bottom_next)
6097 {
6098 if (t->merging && !t->last_on_top)
6099 t--;
6100 if (on_top_outline) {
6101 /* outline finished */
6102 remove_triangulation(triangulations, t);
6103 break;
6104 }
6105
6106 hr = triangulation_add_point(&t, triangulations, sweep_idx, FALSE);
6107 if (hr != S_OK) return hr;
6108
6109 if (t > triangulations->items &&
6110 triangulation_get_next_point(t - 1, glyph, TRUE) == sweep_vtx)
6111 {
6112 struct triangulation *t2 = t - 1;
6113 /* point also on top outline of lower triangulation */
6114 hr = triangulation_add_point(&t2, triangulations, sweep_idx, TRUE);
6115 if (hr != S_OK) return hr;
6116 t = t2 + 1; /* t may be invalidated by triangulation merging */
6117
6118 t->merging = TRUE;
6119 t2->merging = TRUE;
6120 }
6121 break;
6122 }
6123 if (on_top_outline)
6124 break;
6125
6126 if (t->last_on_top) {
6127 top_idx = t->vertex_stack.items[t->vertex_stack.count - 1];
6128 bottom_idx = t->vertex_stack.items[0];
6129 } else {
6130 top_idx = t->vertex_stack.items[0];
6131 bottom_idx = t->vertex_stack.items[t->vertex_stack.count - 1];
6132 }
6133
6134 /* check if the point is inside or outside this polygon */
6136 top_next, sweep_vtx) > 0)
6137 { /* above */
6138 start = current + 1;
6139 } else if (get_line_to_point_y_distance(get_ordered_vertex(glyph, bottom_idx),
6140 bottom_next, sweep_vtx) < 0)
6141 { /* below */
6142 end = current;
6143 } else if (t->merging) {
6144 /* inside, so cancel merging */
6145 struct triangulation *t2 = t->last_on_top ? t + 1 : t - 1;
6146 t->merging = FALSE;
6147 t2->merging = FALSE;
6148 hr = triangulation_add_point(&t, triangulations, sweep_idx, t->last_on_top);
6149 if (hr != S_OK) return hr;
6150 hr = triangulation_add_point(&t2, triangulations, sweep_idx, t2->last_on_top);
6151 if (hr != S_OK) return hr;
6152 break;
6153 } else {
6154 /* inside, so split polygon into two monotone parts */
6155 struct triangulation *t2 = add_triangulation(triangulations);
6156 if (!t2) return E_OUTOFMEMORY;
6157 MoveMemory(t + 1, t, (char*)(t2 + 1) - (char*)t);
6158 if (t->last_on_top) {
6159 t2 = t + 1;
6160 } else {
6161 t2 = t;
6162 t++;
6163 }
6164
6165 ZeroMemory(&t2->vertex_stack, sizeof(t2->vertex_stack));
6166 hr = add_vertex_index(&t2->vertex_stack, t->vertex_stack.items[t->vertex_stack.count - 1]);
6167 if (hr != S_OK) return hr;
6168 hr = add_vertex_index(&t2->vertex_stack, sweep_idx);
6169 if (hr != S_OK) return hr;
6170 t2->last_on_top = !t->last_on_top;
6171
6172 hr = triangulation_add_point(&t, triangulations, sweep_idx, t->last_on_top);
6173 if (hr != S_OK) return hr;
6174 break;
6175 }
6176 }
6177 if (start >= end)
6178 {
6179 struct triangulation *t;
6180 struct triangulation *t2 = add_triangulation(triangulations);
6181 if (!t2) return E_OUTOFMEMORY;
6182 t = &triangulations->items[start];
6183 MoveMemory(t + 1, t, (char*)(t2 + 1) - (char*)t);
6184 ZeroMemory(t, sizeof(*t));
6185 hr = add_vertex_index(&t->vertex_stack, sweep_idx);
6186 if (hr != S_OK) return hr;
6187 }
6188 }
6189 return S_OK;
6190}
static HRESULT triangulation_add_point(struct triangulation **t_ptr, struct triangulation_array *triangulations, WORD vtx_idx, BOOL to_top)
Definition: mesh.c:5851
static void remove_triangulation(struct triangulation_array *array, struct triangulation *item)
Definition: mesh.c:5844
static struct triangulation * add_triangulation(struct triangulation_array *array)
Definition: mesh.c:5542
static HRESULT add_vertex_index(struct word_array *array, WORD vertex_index)
Definition: mesh.c:5554
static D3DXVECTOR2 * triangulation_get_next_point(struct triangulation *t, struct glyphinfo *glyph, BOOL on_top)
Definition: mesh.c:5931
static int __cdecl compare_vertex_indices(const void *a, const void *b)
Definition: mesh.c:5946
static float get_line_to_point_y_distance(D3DXVECTOR2 *line_pt1, D3DXVECTOR2 *line_pt2, D3DXVECTOR2 *point)
Definition: mesh.c:5820
GLuint start
Definition: gl.h:1545
GLdouble GLdouble t
Definition: gl.h:2047
struct task_struct * current
Definition: linux.c:32
static unsigned __int64 next
Definition: rand_nt.c:6
BOOL last_on_top
Definition: mesh.c:5487
struct word_array vertex_stack
Definition: mesh.c:5486
BOOL merging
Definition: mesh.c:5487

Referenced by D3DXCreateTextW().

◆ triangulation_add_point()

static HRESULT triangulation_add_point ( struct triangulation **  t_ptr,
struct triangulation_array *  triangulations,
WORD  vtx_idx,
BOOL  to_top 
)
static

Definition at line 5851 of file mesh.c.

5855{
5856 struct glyphinfo *glyph = triangulations->glyph;
5857 struct triangulation *t = *t_ptr;
5858 HRESULT hr;
5859 face *face;
5860 int f1, f2;
5861
5862 if (t->last_on_top) {
5863 f1 = 1;
5864 f2 = 2;
5865 } else {
5866 f1 = 2;
5867 f2 = 1;
5868 }
5869
5870 if (t->last_on_top != to_top && t->vertex_stack.count > 1) {
5871 /* consume all vertices on the stack */
5872 WORD last_pt = t->vertex_stack.items[0];
5873 int i;
5874 for (i = 1; i < t->vertex_stack.count; i++)
5875 {
5876 face = add_face(&glyph->faces);
5877 if (!face) return E_OUTOFMEMORY;
5878 (*face)[0] = vtx_idx;
5879 (*face)[f1] = last_pt;
5880 (*face)[f2] = last_pt = t->vertex_stack.items[i];
5881 }
5882 t->vertex_stack.items[0] = last_pt;
5883 t->vertex_stack.count = 1;
5884 } else if (t->vertex_stack.count > 1) {
5885 int i = t->vertex_stack.count - 1;
5886 D3DXVECTOR2 *point = get_ordered_vertex(glyph, vtx_idx);
5887 WORD top_idx = t->vertex_stack.items[i--];
5888 D3DXVECTOR2 *top_pt = get_ordered_vertex(glyph, top_idx);
5889
5890 while (i >= 0)
5891 {
5892 WORD prev_idx = t->vertex_stack.items[i--];
5893 D3DXVECTOR2 *prev_pt = get_ordered_vertex(glyph, prev_idx);
5894
5895 if (prev_pt->x != top_pt->x &&
5896 ((to_top && get_line_to_point_y_distance(prev_pt, top_pt, point) > 0) ||
5897 (!to_top && get_line_to_point_y_distance(prev_pt, top_pt, point) < 0)))
5898 break;
5899
5900 face = add_face(&glyph->faces);
5901 if (!face) return E_OUTOFMEMORY;
5902 (*face)[0] = vtx_idx;
5903 (*face)[f1] = prev_idx;
5904 (*face)[f2] = top_idx;
5905
5906 top_pt = prev_pt;
5907 top_idx = prev_idx;
5908 t->vertex_stack.count--;
5909 }
5910 }
5911 t->last_on_top = to_top;
5912
5913 hr = add_vertex_index(&t->vertex_stack, vtx_idx);
5914
5915 if (hr == S_OK && t->merging) {
5916 struct triangulation *t2;
5917
5918 t2 = to_top ? t - 1 : t + 1;
5919 t2->merging = FALSE;
5920 hr = triangulation_add_point(&t2, triangulations, vtx_idx, to_top);
5921 if (hr != S_OK) return hr;
5922 remove_triangulation(triangulations, t);
5923 if (t2 > t)
5924 t2--;
5925 *t_ptr = t2;
5926 }
5927 return hr;
5928}
static face * add_face(struct face_array *array)
Definition: mesh.c:5537

Referenced by triangulate(), and triangulation_add_point().

◆ triangulation_get_next_point()

static D3DXVECTOR2 * triangulation_get_next_point ( struct triangulation *  t,
struct glyphinfo *  glyph,
BOOL  on_top 
)
static

Definition at line 5931 of file mesh.c.

5932{
5933 int i = t->last_on_top == on_top ? t->vertex_stack.count - 1 : 0;
5934 WORD idx = t->vertex_stack.items[i];
5935 struct point2d_index *pt_idx = &glyph->ordered_vertices.items[idx];
5936 struct outline *outline = pt_idx->outline;
5937
5938 if (on_top)
5939 i = (pt_idx->vertex + outline->count - 1) % outline->count;
5940 else
5941 i = (pt_idx->vertex + 1) % outline->count;
5942
5943 return &outline->items[i].pos;
5944}

Referenced by triangulate().

◆ unit_vec2()

static D3DXVECTOR2 * unit_vec2 ( D3DXVECTOR2 *  dir,
const D3DXVECTOR2 *  pt1,
const D3DXVECTOR2 *  pt2 
)
inlinestatic

Definition at line 5615 of file mesh.c.

5616{
5617 return D3DXVec2Normalize(dir, D3DXVec2Subtract(dir, pt2, pt1));
5618}
unsigned int dir
Definition: maze.c:112

Referenced by attempt_line_merge(), and create_outline().

◆ vertex_element_vec3()

static D3DXVECTOR3 * vertex_element_vec3 ( BYTE *  vertices,
const D3DVERTEXELEMENT9 *  declaration,
DWORD  vertex_stride,
DWORD  index 
)
static

Definition at line 7373 of file mesh.c.

7375{
7376 return (D3DXVECTOR3 *)(vertices + declaration->Offset + index * vertex_stride);
7377}

Referenced by D3DXComputeTangentFrameEx(), and read_vec3().

◆ vertex_index()

static WORD vertex_index ( UINT  slices,
int  slice,
int  stack 
)
static

◆ weld_component()

static BOOL weld_component ( void *  to,
void *  from,
D3DDECLTYPE  type,
FLOAT  epsilon 
)
static

Definition at line 6896 of file mesh.c.

6897{
6898 /* Quiet FIXMEs as this is in a loop with potentially thousand of iterations. */
6899 BOOL fixme_once_unused = FALSE;
6900 BOOL fixme_once_unknown = FALSE;
6901
6902 switch (type)
6903 {
6904 case D3DDECLTYPE_FLOAT1:
6905 return weld_float1(to, from, epsilon);
6906
6907 case D3DDECLTYPE_FLOAT2:
6908 return weld_float2(to, from, epsilon);
6909
6910 case D3DDECLTYPE_FLOAT3:
6911 return weld_float3(to, from, epsilon);
6912
6913 case D3DDECLTYPE_FLOAT4:
6914 return weld_float4(to, from, epsilon);
6915
6917 return weld_d3dcolor(to, from, epsilon);
6918
6919 case D3DDECLTYPE_UBYTE4:
6920 return weld_ubyte4(to, from, epsilon);
6921
6922 case D3DDECLTYPE_SHORT2:
6923 return weld_short2(to, from, epsilon);
6924
6925 case D3DDECLTYPE_SHORT4:
6926 return weld_short4(to, from, epsilon);
6927
6929 return weld_ubyte4n(to, from, epsilon);
6930
6932 return weld_short2n(to, from, epsilon);
6933
6935 return weld_short4n(to, from, epsilon);
6936
6938 return weld_ushort2n(to, from, epsilon);
6939
6941 return weld_ushort4n(to, from, epsilon);
6942
6943 case D3DDECLTYPE_UDEC3:
6944 return weld_udec3(to, from, epsilon);
6945
6946 case D3DDECLTYPE_DEC3N:
6947 return weld_dec3n(to, from, epsilon);
6948
6950 return weld_float16_2(to, from, epsilon);
6951
6953 return weld_float16_4(to, from, epsilon);
6954
6955 case D3DDECLTYPE_UNUSED:
6956 if (!fixme_once_unused++)
6957 FIXME("D3DDECLTYPE_UNUSED welding not implemented.\n");
6958 break;
6959
6960 default:
6961 if (!fixme_once_unknown++)
6962 FIXME("Welding of unknown declaration type %d is not implemented.\n", type);
6963 break;
6964 }
6965
6966 return FALSE;
6967}
@ D3DDECLTYPE_UNUSED
Definition: d3d9types.h:289
@ D3DDECLTYPE_UDEC3
Definition: d3d9types.h:285
@ D3DDECLTYPE_DEC3N
Definition: d3d9types.h:286
static BOOL weld_float2(void *to, void *from, FLOAT epsilon)
Definition: mesh.c:6553
static BOOL weld_d3dcolor(void *to, void *from, FLOAT epsilon)
Definition: mesh.c:6641
static BOOL weld_float1(void *to, void *from, FLOAT epsilon)
Definition: mesh.c:6538
static BOOL weld_float3(void *to, void *from, FLOAT epsilon)
Definition: mesh.c:6571
static BOOL weld_short2(void *to, void *from, FLOAT epsilon)
Definition: mesh.c:6646
static BOOL weld_dec3n(void *to, void *from, FLOAT epsilon)
Definition: mesh.c:6805
static BOOL weld_ubyte4(void *to, void *from, FLOAT epsilon)
Definition: mesh.c:6613
static BOOL weld_ushort4n(void *to, void *from, FLOAT epsilon)
Definition: mesh.c:6717
static BOOL weld_short2n(void *to, void *from, FLOAT epsilon)
Definition: mesh.c:6665
static BOOL weld_float16_2(void *to, void *from, FLOAT epsilon)
Definition: mesh.c:6831
static BOOL weld_float4(void *to, void *from, FLOAT epsilon)
Definition: mesh.c:6591
static BOOL weld_float16_4(void *to, void *from, FLOAT epsilon)
Definition: mesh.c:6860
static BOOL weld_ushort2n(void *to, void *from, FLOAT epsilon)
Definition: mesh.c:6698
static BOOL weld_ubyte4n(void *to, void *from, FLOAT epsilon)
Definition: mesh.c:6636
static BOOL weld_short4(void *to, void *from, FLOAT epsilon)
Definition: mesh.c:6670
static BOOL weld_udec3(void *to, void *from, FLOAT epsilon)
Definition: mesh.c:6760
static BOOL weld_short4n(void *to, void *from, FLOAT epsilon)
Definition: mesh.c:6693

Referenced by D3DXWeldVertices().

◆ weld_d3dcolor()

static BOOL weld_d3dcolor ( void *  to,
void *  from,
FLOAT  epsilon 
)
static

Definition at line 6641 of file mesh.c.

6642{
6643 return weld_ubyte4n(to, from, epsilon);
6644}

Referenced by weld_component().

◆ weld_dec3n()

static BOOL weld_dec3n ( void *  to,
void *  from,
FLOAT  epsilon 
)
static

Definition at line 6805 of file mesh.c.

6806{
6807 const UINT MAX_DEC3N = 511;
6808 DWORD *d1 = to;
6809 DWORD *d2 = from;
6810 struct dec3n v1 = dword_to_dec3n(*d1);
6811 struct dec3n v2 = dword_to_dec3n(*d2);
6812 INT scaled_epsilon = (INT)(epsilon * MAX_DEC3N);
6813 INT diff_x = abs(v1.x - v2.x);
6814 INT diff_y = abs(v1.y - v2.y);
6815 INT diff_z = abs(v1.z - v2.z);
6816 INT diff_w = abs(v1.w - v2.w);
6817 INT max_abs_diff = max(diff_x, diff_y);
6818 max_abs_diff = max(diff_z, max_abs_diff);
6819 max_abs_diff = max(diff_w, max_abs_diff);
6820
6821 if (max_abs_diff <= scaled_epsilon)
6822 {
6823 memcpy(to, from, sizeof(DWORD));
6824
6825 return TRUE;
6826 }
6827
6828 return FALSE;
6829}
static struct dec3n dword_to_dec3n(DWORD d)
Definition: mesh.c:6793
#define abs(i)
Definition: fconv.c:206

Referenced by weld_component().

◆ weld_float1()

static BOOL weld_float1 ( void *  to,
void *  from,
FLOAT  epsilon 
)
static

Definition at line 6538 of file mesh.c.

6539{
6540 FLOAT *v1 = to;
6541 FLOAT *v2 = from;
6542
6543 if (fabsf(*v1 - *v2) <= epsilon)
6544 {
6545 *v1 = *v2;
6546
6547 return TRUE;
6548 }
6549
6550 return FALSE;
6551}

Referenced by weld_component().

◆ weld_float16_2()

static BOOL weld_float16_2 ( void *  to,
void *  from,
FLOAT  epsilon 
)
static

Definition at line 6831 of file mesh.c.

6832{
6833 D3DXFLOAT16 *v1_float16 = to;
6834 D3DXFLOAT16 *v2_float16 = from;
6835 FLOAT diff_x;
6836 FLOAT diff_y;
6837 FLOAT max_abs_diff;
6838#define NUM_ELEM 2
6839 FLOAT v1[NUM_ELEM];
6840 FLOAT v2[NUM_ELEM];
6841
6842 D3DXFloat16To32Array(v1, v1_float16, NUM_ELEM);
6843 D3DXFloat16To32Array(v2, v2_float16, NUM_ELEM);
6844
6845 diff_x = fabsf(v1[0] - v2[0]);
6846 diff_y = fabsf(v1[1] - v2[1]);
6847 max_abs_diff = max(diff_x, diff_y);
6848
6849 if (max_abs_diff <= epsilon)
6850 {
6851 memcpy(to, from, NUM_ELEM * sizeof(D3DXFLOAT16));
6852
6853 return TRUE;
6854 }
6855
6856 return FALSE;
6857#undef NUM_ELEM
6858}
#define NUM_ELEM

Referenced by weld_component().

◆ weld_float16_4()

static BOOL weld_float16_4 ( void *  to,
void *  from,
FLOAT  epsilon 
)
static

Definition at line 6860 of file mesh.c.

6861{
6862 D3DXFLOAT16 *v1_float16 = to;
6863 D3DXFLOAT16 *v2_float16 = from;
6864 FLOAT diff_x;
6865 FLOAT diff_y;
6866 FLOAT diff_z;
6867 FLOAT diff_w;
6868 FLOAT max_abs_diff;
6869#define NUM_ELEM 4
6870 FLOAT v1[NUM_ELEM];
6871 FLOAT v2[NUM_ELEM];
6872
6873 D3DXFloat16To32Array(v1, v1_float16, NUM_ELEM);
6874 D3DXFloat16To32Array(v2, v2_float16, NUM_ELEM);
6875
6876 diff_x = fabsf(v1[0] - v2[0]);
6877 diff_y = fabsf(v1[1] - v2[1]);
6878 diff_z = fabsf(v1[2] - v2[2]);
6879 diff_w = fabsf(v1[3] - v2[3]);
6880 max_abs_diff = max(diff_x, diff_y);
6881 max_abs_diff = max(diff_z, max_abs_diff);
6882 max_abs_diff = max(diff_w, max_abs_diff);
6883
6884 if (max_abs_diff <= epsilon)
6885 {
6886 memcpy(to, from, NUM_ELEM * sizeof(D3DXFLOAT16));
6887
6888 return TRUE;
6889 }
6890
6891 return FALSE;
6892#undef NUM_ELEM
6893}

Referenced by weld_component().

◆ weld_float2()

static BOOL weld_float2 ( void *  to,
void *  from,
FLOAT  epsilon 
)
static

Definition at line 6553 of file mesh.c.

6554{
6555 D3DXVECTOR2 *v1 = to;
6556 D3DXVECTOR2 *v2 = from;
6557 FLOAT diff_x = fabsf(v1->x - v2->x);
6558 FLOAT diff_y = fabsf(v1->y - v2->y);
6559 FLOAT max_abs_diff = max(diff_x, diff_y);
6560
6561 if (max_abs_diff <= epsilon)
6562 {
6563 memcpy(to, from, sizeof(D3DXVECTOR2));
6564
6565 return TRUE;
6566 }
6567
6568 return FALSE;
6569}

Referenced by weld_component().

◆ weld_float3()

static BOOL weld_float3 ( void *  to,
void *  from,
FLOAT  epsilon 
)
static

Definition at line 6571 of file mesh.c.

6572{
6573 D3DXVECTOR3 *v1 = to;
6574 D3DXVECTOR3 *v2 = from;
6575 FLOAT diff_x = fabsf(v1->x - v2->x);
6576 FLOAT diff_y = fabsf(v1->y - v2->y);
6577 FLOAT diff_z = fabsf(v1->z - v2->z);
6578 FLOAT max_abs_diff = max(diff_x, diff_y);
6579 max_abs_diff = max(diff_z, max_abs_diff);
6580
6581 if (max_abs_diff <= epsilon)
6582 {
6583 memcpy(to, from, sizeof(D3DXVECTOR3));
6584
6585 return TRUE;
6586 }
6587
6588 return FALSE;
6589}

Referenced by weld_component().

◆ weld_float4()

static BOOL weld_float4 ( void *  to,
void *  from,
FLOAT  epsilon 
)
static

Definition at line 6591 of file mesh.c.

6592{
6593 D3DXVECTOR4 *v1 = to;
6594 D3DXVECTOR4 *v2 = from;
6595 FLOAT diff_x = fabsf(v1->x - v2->x);
6596 FLOAT diff_y = fabsf(v1->y - v2->y);
6597 FLOAT diff_z = fabsf(v1->z - v2->z);
6598 FLOAT diff_w = fabsf(v1->w - v2->w);
6599 FLOAT max_abs_diff = max(diff_x, diff_y);
6600 max_abs_diff = max(diff_z, max_abs_diff);
6601 max_abs_diff = max(diff_w, max_abs_diff);
6602
6603 if (max_abs_diff <= epsilon)
6604 {
6605 memcpy(to, from, sizeof(D3DXVECTOR4));
6606
6607 return TRUE;
6608 }
6609
6610 return FALSE;
6611}

Referenced by weld_component().

◆ weld_short2()

static BOOL weld_short2 ( void *  to,
void *  from,
FLOAT  epsilon 
)
static

Definition at line 6646 of file mesh.c.

6647{
6648 SHORT *s1 = to;
6649 SHORT *s2 = from;
6650 SHORT truncated_epsilon = (SHORT)epsilon;
6651 SHORT diff_x = abs(s1[0] - s2[0]);
6652 SHORT diff_y = abs(s1[1] - s2[1]);
6653 SHORT max_abs_diff = max(diff_x, diff_y);
6654
6655 if (max_abs_diff <= truncated_epsilon)
6656 {
6657 memcpy(to, from, 2 * sizeof(SHORT));
6658
6659 return TRUE;
6660 }
6661
6662 return FALSE;
6663}
struct S1 s1
PCWSTR s2
Definition: shell32_main.h:38

Referenced by weld_component(), and weld_short2n().

◆ weld_short2n()

static BOOL weld_short2n ( void *  to,
void *  from,
FLOAT  epsilon 
)
static

Definition at line 6665 of file mesh.c.

6666{
6667 return weld_short2(to, from, epsilon * SHRT_MAX);
6668}

Referenced by weld_component().

◆ weld_short4()

static BOOL weld_short4 ( void *  to,
void *  from,
FLOAT  epsilon 
)
static

Definition at line 6670 of file mesh.c.

6671{
6672 SHORT *s1 = to;
6673 SHORT *s2 = from;
6674 SHORT truncated_epsilon = (SHORT)epsilon;
6675 SHORT diff_x = abs(s1[0] - s2[0]);
6676 SHORT diff_y = abs(s1[1] - s2[1]);
6677 SHORT diff_z = abs(s1[2] - s2[2]);
6678 SHORT diff_w = abs(s1[3] - s2[3]);
6679 SHORT max_abs_diff = max(diff_x, diff_y);
6680 max_abs_diff = max(diff_z, max_abs_diff);
6681 max_abs_diff = max(diff_w, max_abs_diff);
6682
6683 if (max_abs_diff <= truncated_epsilon)
6684 {
6685 memcpy(to, from, 4 * sizeof(SHORT));
6686
6687 return TRUE;
6688 }
6689
6690 return FALSE;
6691}

Referenced by weld_component(), and weld_short4n().

◆ weld_short4n()

static BOOL weld_short4n ( void *  to,
void *  from,
FLOAT  epsilon 
)
static

Definition at line 6693 of file mesh.c.

6694{
6695 return weld_short4(to, from, epsilon * SHRT_MAX);
6696}

Referenced by weld_component().

◆ weld_ubyte4()

static BOOL weld_ubyte4 ( void *  to,
void *  from,
FLOAT  epsilon 
)
static

Definition at line 6613 of file mesh.c.

6614{
6615 BYTE *b1 = to;
6616 BYTE *b2 = from;
6617 BYTE truncated_epsilon = (BYTE)epsilon;
6618 BYTE diff_x = b1[0] > b2[0] ? b1[0] - b2[0] : b2[0] - b1[0];
6619 BYTE diff_y = b1[1] > b2[1] ? b1[1] - b2[1] : b2[1] - b1[1];
6620 BYTE diff_z = b1[2] > b2[2] ? b1[2] - b2[2] : b2[2] - b1[2];
6621 BYTE diff_w = b1[3] > b2[3] ? b1[3] - b2[3] : b2[3] - b1[3];
6622 BYTE max_diff = max(diff_x, diff_y);
6623 max_diff = max(diff_z, max_diff);
6624 max_diff = max(diff_w, max_diff);
6625
6626 if (max_diff <= truncated_epsilon)
6627 {
6628 memcpy(to, from, 4 * sizeof(BYTE));
6629
6630 return TRUE;
6631 }
6632
6633 return FALSE;
6634}
static CRYPT_DATA_BLOB b2[]
Definition: msg.c:538
static CRYPT_DATA_BLOB b1[]
Definition: msg.c:529

Referenced by weld_component(), and weld_ubyte4n().

◆ weld_ubyte4n()

static BOOL weld_ubyte4n ( void *  to,
void *  from,
FLOAT  epsilon 
)
static

Definition at line 6636 of file mesh.c.

6637{
6638 return weld_ubyte4(to, from, epsilon * UCHAR_MAX);
6639}

Referenced by weld_component(), and weld_d3dcolor().

◆ weld_udec3()

static BOOL weld_udec3 ( void *  to,
void *  from,
FLOAT  epsilon 
)
static

Definition at line 6760 of file mesh.c.

6761{
6762 DWORD *d1 = to;
6763 DWORD *d2 = from;
6764 struct udec3 v1 = dword_to_udec3(*d1);
6765 struct udec3 v2 = dword_to_udec3(*d2);
6766 UINT truncated_epsilon = (UINT)epsilon;
6767 UINT diff_x = v1.x > v2.x ? v1.x - v2.x : v2.x - v1.x;
6768 UINT diff_y = v1.y > v2.y ? v1.y - v2.y : v2.y - v1.y;
6769 UINT diff_z = v1.z > v2.z ? v1.z - v2.z : v2.z - v1.z;
6770 UINT diff_w = v1.w > v2.w ? v1.w - v2.w : v2.w - v1.w;
6771 UINT max_diff = max(diff_x, diff_y);
6772 max_diff = max(diff_z, max_diff);
6773 max_diff = max(diff_w, max_diff);
6774
6775 if (max_diff <= truncated_epsilon)
6776 {
6777 memcpy(to, from, sizeof(DWORD));
6778
6779 return TRUE;
6780 }
6781
6782 return FALSE;
6783}
static struct udec3 dword_to_udec3(DWORD d)
Definition: mesh.c:6748
#define UINT
Definition: utils.c:29

Referenced by weld_component().

◆ weld_ushort2n()

static BOOL weld_ushort2n ( void *  to,
void *  from,
FLOAT  epsilon 
)
static

Definition at line 6698 of file mesh.c.

6699{
6700 USHORT *s1 = to;
6701 USHORT *s2 = from;
6702 USHORT scaled_epsilon = (USHORT)(epsilon * USHRT_MAX);
6703 USHORT diff_x = s1[0] > s2[0] ? s1[0] - s2[0] : s2[0] - s1[0];
6704 USHORT diff_y = s1[1] > s2[1] ? s1[1] - s2[1] : s2[1] - s1[1];
6705 USHORT max_diff = max(diff_x, diff_y);
6706
6707 if (max_diff <= scaled_epsilon)
6708 {
6709 memcpy(to, from, 2 * sizeof(USHORT));
6710
6711 return TRUE;
6712 }
6713
6714 return FALSE;
6715}

Referenced by weld_component().

◆ weld_ushort4n()

static BOOL weld_ushort4n ( void *  to,
void *  from,
FLOAT  epsilon 
)
static

Definition at line 6717 of file mesh.c.

6718{
6719 USHORT *s1 = to;
6720 USHORT *s2 = from;
6721 USHORT scaled_epsilon = (USHORT)(epsilon * USHRT_MAX);
6722 USHORT diff_x = s1[0] > s2[0] ? s1[0] - s2[0] : s2[0] - s1[0];
6723 USHORT diff_y = s1[1] > s2[1] ? s1[1] - s2[1] : s2[1] - s1[1];
6724 USHORT diff_z = s1[2] > s2[2] ? s1[2] - s2[2] : s2[2] - s1[2];
6725 USHORT diff_w = s1[3] > s2[3] ? s1[3] - s2[3] : s2[3] - s1[3];
6726 USHORT max_diff = max(diff_x, diff_y);
6727 max_diff = max(diff_z, max_diff);
6728 max_diff = max(diff_w, max_diff);
6729
6730 if (max_diff <= scaled_epsilon)
6731 {
6732 memcpy(to, from, 4 * sizeof(USHORT));
6733
6734 return TRUE;
6735 }
6736
6737 return FALSE;
6738}

Referenced by weld_component().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( d3dx  )

◆ write_ib()

static void write_ib ( void *  index_buffer,
BOOL  indices_are_32bit,
DWORD  index,
DWORD  value 
)
inlinestatic

Definition at line 7065 of file mesh.c.

7067{
7068 if (indices_are_32bit)
7069 {
7070 DWORD *indices = index_buffer;
7071 indices[index] = value;
7072 }
7073 else
7074 {
7075 WORD *indices = index_buffer;
7076 indices[index] = value;
7077 }
7078}

Referenced by D3DXWeldVertices().

Variable Documentation

◆ d3dx_decltype_size

const UINT d3dx_decltype_size[]
static
Initial value:
=
{
sizeof(FLOAT),
sizeof(D3DXVECTOR2),
sizeof(D3DXVECTOR3),
sizeof(D3DXVECTOR4),
sizeof(D3DCOLOR),
4 * sizeof(BYTE),
2 * sizeof(SHORT),
4 * sizeof(SHORT),
4 * sizeof(BYTE),
2 * sizeof(SHORT),
4 * sizeof(SHORT),
2 * sizeof(USHORT),
4 * sizeof(USHORT),
4,
4,
2 * sizeof(D3DXFLOAT16),
4 * sizeof(D3DXFLOAT16),
}

Definition at line 67 of file mesh.c.

Referenced by append_decl_element(), convert_vertex_buffer(), D3DXFVFFromDeclarator(), D3DXGetDeclVertexSize(), and D3DXLoadMeshFromXInMemory().

◆ D3DXMesh_Vtbl

const struct ID3DXMeshVtbl D3DXMesh_Vtbl
static

Definition at line 1860 of file mesh.c.

Referenced by D3DXComputeNormals(), and D3DXCreateMesh().