2 * Copyright 2008 David Adam
3 * Copyright 2008 Luis Busquets
4 * Copyright 2009 Henri Verbeet for CodeWeavers
5 * Copyright 2011 Michael Mc Donnell
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "wine/test.h"
30 /* From wine/port.h */
31 static inline float __port_nan(void)
33 static const unsigned __nan_bytes
= 0x7fc00000;
34 return *(const float *)&__nan_bytes
;
36 #define NAN __port_nan()
39 /* Set the WINETEST_DEBUG environment variable to be greater than 1 for verbose
40 * function call traces of ID3DXAllocateHierarchy callbacks. */
41 #define TRACECALLBACK if(winetest_debug > 1) trace
43 #define admitted_error 0.0001f
45 #define ARRAY_SIZE(array) (sizeof(array)/sizeof(*array))
47 #define compare_vertex_sizes(type, exp) \
48 got=D3DXGetFVFVertexSize(type); \
49 ok(got==exp, "Expected: %d, Got: %d\n", exp, got);
51 #define compare_float(got, exp) \
55 ok(_got == _exp, "Expected: %g, Got: %g\n", _exp, _got); \
58 static BOOL
compare(FLOAT u
, FLOAT v
)
60 return (fabs(u
-v
) < admitted_error
);
63 static BOOL
compare_vec3(D3DXVECTOR3 u
, D3DXVECTOR3 v
)
65 return ( compare(u
.x
, v
.x
) && compare(u
.y
, v
.y
) && compare(u
.z
, v
.z
) );
68 #define check_floats(got, exp, dim) check_floats_(__LINE__, "", got, exp, dim)
69 static void check_floats_(int line
, const char *prefix
, const float *got
, const float *exp
, int dim
)
72 char exp_buffer
[256] = "";
73 char got_buffer
[256] = "";
74 char *exp_buffer_ptr
= exp_buffer
;
75 char *got_buffer_ptr
= got_buffer
;
78 for (i
= 0; i
< dim
; i
++) {
80 exp_buffer_ptr
+= sprintf(exp_buffer_ptr
, ", ");
81 got_buffer_ptr
+= sprintf(got_buffer_ptr
, ", ");
83 equal
= equal
&& compare(*exp
, *got
);
84 exp_buffer_ptr
+= sprintf(exp_buffer_ptr
, "%g", *exp
);
85 got_buffer_ptr
+= sprintf(got_buffer_ptr
, "%g", *got
);
88 ok_(__FILE__
,line
)(equal
, "%sExpected (%s), got (%s)", prefix
, exp_buffer
, got_buffer
);
99 static BOOL
compare_face(face a
, face b
)
101 return (a
[0]==b
[0] && a
[1] == b
[1] && a
[2] == b
[2]);
108 IDirect3DDevice9
*device
;
111 /* Initializes a test context struct. Use it to initialize DirectX.
113 * Returns NULL if an error occurred.
115 static struct test_context
*new_test_context(void)
119 IDirect3D9
*d3d
= NULL
;
120 IDirect3DDevice9
*device
= NULL
;
121 D3DPRESENT_PARAMETERS d3dpp
= {0};
122 struct test_context
*test_context
;
124 if (!(hwnd
= CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW
, 0, 0,
125 640, 480, NULL
, NULL
, NULL
, NULL
)))
127 skip("Couldn't create application window\n");
131 d3d
= Direct3DCreate9(D3D_SDK_VERSION
);
134 skip("Couldn't create IDirect3D9 object\n");
138 memset(&d3dpp
, 0, sizeof(d3dpp
));
139 d3dpp
.Windowed
= TRUE
;
140 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
141 hr
= IDirect3D9_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
142 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &device
);
145 skip("Couldn't create IDirect3DDevice9 object %#x\n", hr
);
149 test_context
= HeapAlloc(GetProcessHeap(), 0, sizeof(*test_context
));
152 skip("Couldn't allocate memory for test_context\n");
155 test_context
->hwnd
= hwnd
;
156 test_context
->d3d
= d3d
;
157 test_context
->device
= device
;
163 IDirect3DDevice9_Release(device
);
166 IDirect3D9_Release(d3d
);
174 static void free_test_context(struct test_context
*test_context
)
179 if (test_context
->device
)
180 IDirect3DDevice9_Release(test_context
->device
);
182 if (test_context
->d3d
)
183 IDirect3D9_Release(test_context
->d3d
);
185 if (test_context
->hwnd
)
186 DestroyWindow(test_context
->hwnd
);
188 HeapFree(GetProcessHeap(), 0, test_context
);
193 DWORD number_of_vertices
;
194 struct vertex
*vertices
;
196 DWORD number_of_faces
;
203 static void free_mesh(struct mesh
*mesh
)
205 HeapFree(GetProcessHeap(), 0, mesh
->faces
);
206 HeapFree(GetProcessHeap(), 0, mesh
->vertices
);
209 static BOOL
new_mesh(struct mesh
*mesh
, DWORD number_of_vertices
, DWORD number_of_faces
)
211 mesh
->vertices
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, number_of_vertices
* sizeof(*mesh
->vertices
));
216 mesh
->number_of_vertices
= number_of_vertices
;
218 mesh
->faces
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, number_of_faces
* sizeof(*mesh
->faces
));
221 HeapFree(GetProcessHeap(), 0, mesh
->vertices
);
224 mesh
->number_of_faces
= number_of_faces
;
229 static void compare_mesh(const char *name
, ID3DXMesh
*d3dxmesh
, struct mesh
*mesh
)
232 DWORD number_of_vertices
, number_of_faces
;
233 IDirect3DVertexBuffer9
*vertex_buffer
;
234 IDirect3DIndexBuffer9
*index_buffer
;
235 D3DVERTEXBUFFER_DESC vertex_buffer_description
;
236 D3DINDEXBUFFER_DESC index_buffer_description
;
237 struct vertex
*vertices
;
241 number_of_vertices
= d3dxmesh
->lpVtbl
->GetNumVertices(d3dxmesh
);
242 ok(number_of_vertices
== mesh
->number_of_vertices
, "Test %s, result %u, expected %d\n",
243 name
, number_of_vertices
, mesh
->number_of_vertices
);
245 number_of_faces
= d3dxmesh
->lpVtbl
->GetNumFaces(d3dxmesh
);
246 ok(number_of_faces
== mesh
->number_of_faces
, "Test %s, result %u, expected %d\n",
247 name
, number_of_faces
, mesh
->number_of_faces
);
250 hr
= d3dxmesh
->lpVtbl
->GetVertexBuffer(d3dxmesh
, &vertex_buffer
);
251 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
255 skip("Couldn't get vertex buffer\n");
259 hr
= IDirect3DVertexBuffer9_GetDesc(vertex_buffer
, &vertex_buffer_description
);
260 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
264 skip("Couldn't get vertex buffer description\n");
268 ok(vertex_buffer_description
.Format
== D3DFMT_VERTEXDATA
, "Test %s, result %x, expected %x (D3DFMT_VERTEXDATA)\n",
269 name
, vertex_buffer_description
.Format
, D3DFMT_VERTEXDATA
);
270 ok(vertex_buffer_description
.Type
== D3DRTYPE_VERTEXBUFFER
, "Test %s, result %x, expected %x (D3DRTYPE_VERTEXBUFFER)\n",
271 name
, vertex_buffer_description
.Type
, D3DRTYPE_VERTEXBUFFER
);
272 ok(vertex_buffer_description
.Usage
== 0, "Test %s, result %x, expected %x\n", name
, vertex_buffer_description
.Usage
, 0);
273 ok(vertex_buffer_description
.Pool
== D3DPOOL_MANAGED
, "Test %s, result %x, expected %x (D3DPOOL_MANAGED)\n",
274 name
, vertex_buffer_description
.Pool
, D3DPOOL_MANAGED
);
275 ok(vertex_buffer_description
.FVF
== mesh
->fvf
, "Test %s, result %x, expected %x\n",
276 name
, vertex_buffer_description
.FVF
, mesh
->fvf
);
279 expected
= number_of_vertices
* mesh
->vertex_size
;
283 expected
= number_of_vertices
* D3DXGetFVFVertexSize(mesh
->fvf
);
285 ok(vertex_buffer_description
.Size
== expected
, "Test %s, result %x, expected %x\n",
286 name
, vertex_buffer_description
.Size
, expected
);
289 /* specify offset and size to avoid potential overruns */
290 hr
= IDirect3DVertexBuffer9_Lock(vertex_buffer
, 0, number_of_vertices
* sizeof(D3DXVECTOR3
) * 2,
291 (void **)&vertices
, D3DLOCK_DISCARD
);
292 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
296 skip("Couldn't lock vertex buffer\n");
300 for (i
= 0; i
< number_of_vertices
; i
++)
302 ok(compare_vec3(vertices
[i
].position
, mesh
->vertices
[i
].position
),
303 "Test %s, vertex position %d, result (%g, %g, %g), expected (%g, %g, %g)\n", name
, i
,
304 vertices
[i
].position
.x
, vertices
[i
].position
.y
, vertices
[i
].position
.z
,
305 mesh
->vertices
[i
].position
.x
, mesh
->vertices
[i
].position
.y
, mesh
->vertices
[i
].position
.z
);
306 ok(compare_vec3(vertices
[i
].normal
, mesh
->vertices
[i
].normal
),
307 "Test %s, vertex normal %d, result (%g, %g, %g), expected (%g, %g, %g)\n", name
, i
,
308 vertices
[i
].normal
.x
, vertices
[i
].normal
.y
, vertices
[i
].normal
.z
,
309 mesh
->vertices
[i
].normal
.x
, mesh
->vertices
[i
].normal
.y
, mesh
->vertices
[i
].normal
.z
);
312 IDirect3DVertexBuffer9_Unlock(vertex_buffer
);
315 IDirect3DVertexBuffer9_Release(vertex_buffer
);
319 hr
= d3dxmesh
->lpVtbl
->GetIndexBuffer(d3dxmesh
, &index_buffer
);
320 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
324 skip("Couldn't get index buffer\n");
328 hr
= IDirect3DIndexBuffer9_GetDesc(index_buffer
, &index_buffer_description
);
329 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
333 skip("Couldn't get index buffer description\n");
337 ok(index_buffer_description
.Format
== D3DFMT_INDEX16
, "Test %s, result %x, expected %x (D3DFMT_INDEX16)\n",
338 name
, index_buffer_description
.Format
, D3DFMT_INDEX16
);
339 ok(index_buffer_description
.Type
== D3DRTYPE_INDEXBUFFER
, "Test %s, result %x, expected %x (D3DRTYPE_INDEXBUFFER)\n",
340 name
, index_buffer_description
.Type
, D3DRTYPE_INDEXBUFFER
);
341 ok(index_buffer_description
.Usage
== 0, "Test %s, result %#x, expected %#x.\n",
342 name
, index_buffer_description
.Usage
, 0);
343 ok(index_buffer_description
.Pool
== D3DPOOL_MANAGED
, "Test %s, result %x, expected %x (D3DPOOL_MANAGED)\n",
344 name
, index_buffer_description
.Pool
, D3DPOOL_MANAGED
);
345 expected
= number_of_faces
* sizeof(WORD
) * 3;
346 ok(index_buffer_description
.Size
== expected
, "Test %s, result %x, expected %x\n",
347 name
, index_buffer_description
.Size
, expected
);
350 /* specify offset and size to avoid potential overruns */
351 hr
= IDirect3DIndexBuffer9_Lock(index_buffer
, 0, number_of_faces
* sizeof(WORD
) * 3,
352 (void **)&faces
, D3DLOCK_DISCARD
);
353 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
357 skip("Couldn't lock index buffer\n");
361 for (i
= 0; i
< number_of_faces
; i
++)
363 ok(compare_face(faces
[i
], mesh
->faces
[i
]),
364 "Test %s, face %d, result (%u, %u, %u), expected (%u, %u, %u)\n", name
, i
,
365 faces
[i
][0], faces
[i
][1], faces
[i
][2],
366 mesh
->faces
[i
][0], mesh
->faces
[i
][1], mesh
->faces
[i
][2]);
369 IDirect3DIndexBuffer9_Unlock(index_buffer
);
372 IDirect3DIndexBuffer9_Release(index_buffer
);
376 static void D3DXBoundProbeTest(void)
379 D3DXVECTOR3 bottom_point
, center
, top_point
, raydirection
, rayposition
;
382 /*____________Test the Box case___________________________*/
383 bottom_point
.x
= -3.0f
; bottom_point
.y
= -2.0f
; bottom_point
.z
= -1.0f
;
384 top_point
.x
= 7.0f
; top_point
.y
= 8.0f
; top_point
.z
= 9.0f
;
386 raydirection
.x
= -4.0f
; raydirection
.y
= -5.0f
; raydirection
.z
= -6.0f
;
387 rayposition
.x
= 5.0f
; rayposition
.y
= 5.0f
; rayposition
.z
= 11.0f
;
388 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
389 ok(result
== TRUE
, "expected TRUE, received FALSE\n");
391 raydirection
.x
= 4.0f
; raydirection
.y
= 5.0f
; raydirection
.z
= 6.0f
;
392 rayposition
.x
= 5.0f
; rayposition
.y
= 5.0f
; rayposition
.z
= 11.0f
;
393 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
394 ok(result
== FALSE
, "expected FALSE, received TRUE\n");
396 rayposition
.x
= -4.0f
; rayposition
.y
= 1.0f
; rayposition
.z
= -2.0f
;
397 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
398 ok(result
== TRUE
, "expected TRUE, received FALSE\n");
400 bottom_point
.x
= 1.0f
; bottom_point
.y
= 0.0f
; bottom_point
.z
= 0.0f
;
401 top_point
.x
= 1.0f
; top_point
.y
= 0.0f
; top_point
.z
= 0.0f
;
402 rayposition
.x
= 0.0f
; rayposition
.y
= 1.0f
; rayposition
.z
= 0.0f
;
403 raydirection
.x
= 0.0f
; raydirection
.y
= 3.0f
; raydirection
.z
= 0.0f
;
404 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
405 ok(result
== FALSE
, "expected FALSE, received TRUE\n");
407 bottom_point
.x
= 1.0f
; bottom_point
.y
= 2.0f
; bottom_point
.z
= 3.0f
;
408 top_point
.x
= 10.0f
; top_point
.y
= 15.0f
; top_point
.z
= 20.0f
;
410 raydirection
.x
= 7.0f
; raydirection
.y
= 8.0f
; raydirection
.z
= 9.0f
;
411 rayposition
.x
= 3.0f
; rayposition
.y
= 7.0f
; rayposition
.z
= -6.0f
;
412 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
413 ok(result
== TRUE
, "expected TRUE, received FALSE\n");
415 bottom_point
.x
= 0.0f
; bottom_point
.y
= 0.0f
; bottom_point
.z
= 0.0f
;
416 top_point
.x
= 1.0f
; top_point
.y
= 1.0f
; top_point
.z
= 1.0f
;
418 raydirection
.x
= 0.0f
; raydirection
.y
= 1.0f
; raydirection
.z
= .0f
;
419 rayposition
.x
= -3.0f
; rayposition
.y
= 0.0f
; rayposition
.z
= 0.0f
;
420 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
421 ok(result
== FALSE
, "expected FALSE, received TRUE\n");
423 raydirection
.x
= 1.0f
; raydirection
.y
= 0.0f
; raydirection
.z
= .0f
;
424 rayposition
.x
= -3.0f
; rayposition
.y
= 0.0f
; rayposition
.z
= 0.0f
;
425 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
426 ok(result
== TRUE
, "expected TRUE, received FALSE\n");
428 /*____________Test the Sphere case________________________*/
429 radius
= sqrt(77.0f
);
430 center
.x
= 1.0f
; center
.y
= 2.0f
; center
.z
= 3.0f
;
431 raydirection
.x
= 2.0f
; raydirection
.y
= -4.0f
; raydirection
.z
= 2.0f
;
433 rayposition
.x
= 5.0f
; rayposition
.y
= 5.0f
; rayposition
.z
= 9.0f
;
434 result
= D3DXSphereBoundProbe(¢er
, radius
, &rayposition
, &raydirection
);
435 ok(result
== TRUE
, "expected TRUE, received FALSE\n");
437 rayposition
.x
= 45.0f
; rayposition
.y
= -75.0f
; rayposition
.z
= 49.0f
;
438 result
= D3DXSphereBoundProbe(¢er
, radius
, &rayposition
, &raydirection
);
439 ok(result
== FALSE
, "expected FALSE, received TRUE\n");
441 rayposition
.x
= 5.0f
; rayposition
.y
= 11.0f
; rayposition
.z
= 9.0f
;
442 result
= D3DXSphereBoundProbe(¢er
, radius
, &rayposition
, &raydirection
);
443 ok(result
== FALSE
, "expected FALSE, received TRUE\n");
446 static void D3DXComputeBoundingBoxTest(void)
448 D3DXVECTOR3 exp_max
, exp_min
, got_max
, got_min
, vertex
[5];
451 vertex
[0].x
= 1.0f
; vertex
[0].y
= 1.0f
; vertex
[0].z
= 1.0f
;
452 vertex
[1].x
= 1.0f
; vertex
[1].y
= 1.0f
; vertex
[1].z
= 1.0f
;
453 vertex
[2].x
= 1.0f
; vertex
[2].y
= 1.0f
; vertex
[2].z
= 1.0f
;
454 vertex
[3].x
= 1.0f
; vertex
[3].y
= 1.0f
; vertex
[3].z
= 1.0f
;
455 vertex
[4].x
= 9.0f
; vertex
[4].y
= 9.0f
; vertex
[4].z
= 9.0f
;
457 exp_min
.x
= 1.0f
; exp_min
.y
= 1.0f
; exp_min
.z
= 1.0f
;
458 exp_max
.x
= 9.0f
; exp_max
.y
= 9.0f
; exp_max
.z
= 9.0f
;
460 hr
= D3DXComputeBoundingBox(&vertex
[3],2,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_min
,&got_max
);
462 ok( hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
463 ok( compare_vec3(exp_min
,got_min
), "Expected min: (%f, %f, %f), got: (%f, %f, %f)\n", exp_min
.x
,exp_min
.y
,exp_min
.z
,got_min
.x
,got_min
.y
,got_min
.z
);
464 ok( compare_vec3(exp_max
,got_max
), "Expected max: (%f, %f, %f), got: (%f, %f, %f)\n", exp_max
.x
,exp_max
.y
,exp_max
.z
,got_max
.x
,got_max
.y
,got_max
.z
);
466 /*________________________*/
468 vertex
[0].x
= 2.0f
; vertex
[0].y
= 5.9f
; vertex
[0].z
= -1.2f
;
469 vertex
[1].x
= -1.87f
; vertex
[1].y
= 7.9f
; vertex
[1].z
= 7.4f
;
470 vertex
[2].x
= 7.43f
; vertex
[2].y
= -0.9f
; vertex
[2].z
= 11.9f
;
471 vertex
[3].x
= -6.92f
; vertex
[3].y
= 6.3f
; vertex
[3].z
= -3.8f
;
472 vertex
[4].x
= 11.4f
; vertex
[4].y
= -8.1f
; vertex
[4].z
= 4.5f
;
474 exp_min
.x
= -6.92f
; exp_min
.y
= -8.1f
; exp_min
.z
= -3.80f
;
475 exp_max
.x
= 11.4f
; exp_max
.y
= 7.90f
; exp_max
.z
= 11.9f
;
477 hr
= D3DXComputeBoundingBox(&vertex
[0],5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_min
,&got_max
);
479 ok( hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
480 ok( compare_vec3(exp_min
,got_min
), "Expected min: (%f, %f, %f), got: (%f, %f, %f)\n", exp_min
.x
,exp_min
.y
,exp_min
.z
,got_min
.x
,got_min
.y
,got_min
.z
);
481 ok( compare_vec3(exp_max
,got_max
), "Expected max: (%f, %f, %f), got: (%f, %f, %f)\n", exp_max
.x
,exp_max
.y
,exp_max
.z
,got_max
.x
,got_max
.y
,got_max
.z
);
483 /*________________________*/
485 vertex
[0].x
= 2.0f
; vertex
[0].y
= 5.9f
; vertex
[0].z
= -1.2f
;
486 vertex
[1].x
= -1.87f
; vertex
[1].y
= 7.9f
; vertex
[1].z
= 7.4f
;
487 vertex
[2].x
= 7.43f
; vertex
[2].y
= -0.9f
; vertex
[2].z
= 11.9f
;
488 vertex
[3].x
= -6.92f
; vertex
[3].y
= 6.3f
; vertex
[3].z
= -3.8f
;
489 vertex
[4].x
= 11.4f
; vertex
[4].y
= -8.1f
; vertex
[4].z
= 4.5f
;
491 exp_min
.x
= -6.92f
; exp_min
.y
= -0.9f
; exp_min
.z
= -3.8f
;
492 exp_max
.x
= 7.43f
; exp_max
.y
= 7.90f
; exp_max
.z
= 11.9f
;
494 hr
= D3DXComputeBoundingBox(&vertex
[0],4,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_min
,&got_max
);
496 ok( hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
497 ok( compare_vec3(exp_min
,got_min
), "Expected min: (%f, %f, %f), got: (%f, %f, %f)\n", exp_min
.x
,exp_min
.y
,exp_min
.z
,got_min
.x
,got_min
.y
,got_min
.z
);
498 ok( compare_vec3(exp_max
,got_max
), "Expected max: (%f, %f, %f), got: (%f, %f, %f)\n", exp_max
.x
,exp_max
.y
,exp_max
.z
,got_max
.x
,got_max
.y
,got_max
.z
);
500 /*________________________*/
501 hr
= D3DXComputeBoundingBox(NULL
,5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_min
,&got_max
);
502 ok( hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
504 /*________________________*/
505 hr
= D3DXComputeBoundingBox(&vertex
[3],5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),NULL
,&got_max
);
506 ok( hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
508 /*________________________*/
509 hr
= D3DXComputeBoundingBox(&vertex
[3],5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_min
,NULL
);
510 ok( hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
513 static void D3DXComputeBoundingSphereTest(void)
515 D3DXVECTOR3 exp_cen
, got_cen
, vertex
[5];
516 FLOAT exp_rad
, got_rad
;
519 vertex
[0].x
= 1.0f
; vertex
[0].y
= 1.0f
; vertex
[0].z
= 1.0f
;
520 vertex
[1].x
= 1.0f
; vertex
[1].y
= 1.0f
; vertex
[1].z
= 1.0f
;
521 vertex
[2].x
= 1.0f
; vertex
[2].y
= 1.0f
; vertex
[2].z
= 1.0f
;
522 vertex
[3].x
= 1.0f
; vertex
[3].y
= 1.0f
; vertex
[3].z
= 1.0f
;
523 vertex
[4].x
= 9.0f
; vertex
[4].y
= 9.0f
; vertex
[4].z
= 9.0f
;
526 exp_cen
.x
= 5.0; exp_cen
.y
= 5.0; exp_cen
.z
= 5.0;
528 hr
= D3DXComputeBoundingSphere(&vertex
[3],2,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_cen
,&got_rad
);
530 ok( hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
531 ok( compare(exp_rad
, got_rad
), "Expected radius: %f, got radius: %f\n", exp_rad
, got_rad
);
532 ok( compare_vec3(exp_cen
,got_cen
), "Expected center: (%f, %f, %f), got center: (%f, %f, %f)\n", exp_cen
.x
,exp_cen
.y
,exp_cen
.z
,got_cen
.x
,got_cen
.y
,got_cen
.z
);
534 /*________________________*/
536 vertex
[0].x
= 2.0f
; vertex
[0].y
= 5.9f
; vertex
[0].z
= -1.2f
;
537 vertex
[1].x
= -1.87f
; vertex
[1].y
= 7.9f
; vertex
[1].z
= 7.4f
;
538 vertex
[2].x
= 7.43f
; vertex
[2].y
= -0.9f
; vertex
[2].z
= 11.9f
;
539 vertex
[3].x
= -6.92f
; vertex
[3].y
= 6.3f
; vertex
[3].z
= -3.8f
;
540 vertex
[4].x
= 11.4f
; vertex
[4].y
= -8.1f
; vertex
[4].z
= 4.5f
;
542 exp_rad
= 13.707883f
;
543 exp_cen
.x
= 2.408f
; exp_cen
.y
= 2.22f
; exp_cen
.z
= 3.76f
;
545 hr
= D3DXComputeBoundingSphere(&vertex
[0],5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_cen
,&got_rad
);
547 ok( hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
548 ok( compare(exp_rad
, got_rad
), "Expected radius: %f, got radius: %f\n", exp_rad
, got_rad
);
549 ok( compare_vec3(exp_cen
,got_cen
), "Expected center: (%f, %f, %f), got center: (%f, %f, %f)\n", exp_cen
.x
,exp_cen
.y
,exp_cen
.z
,got_cen
.x
,got_cen
.y
,got_cen
.z
);
551 /*________________________*/
552 hr
= D3DXComputeBoundingSphere(NULL
,5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_cen
,&got_rad
);
553 ok( hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
555 /*________________________*/
556 hr
= D3DXComputeBoundingSphere(&vertex
[3],5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),NULL
,&got_rad
);
557 ok( hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
559 /*________________________*/
560 hr
= D3DXComputeBoundingSphere(&vertex
[3],5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_cen
,NULL
);
561 ok( hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
564 static void print_elements(const D3DVERTEXELEMENT9
*elements
)
566 D3DVERTEXELEMENT9 last
= D3DDECL_END();
567 const D3DVERTEXELEMENT9
*ptr
= elements
;
570 while (memcmp(ptr
, &last
, sizeof(D3DVERTEXELEMENT9
)))
573 "[Element %d] Stream = %d, Offset = %d, Type = %d, Method = %d, Usage = %d, UsageIndex = %d\n",
574 count
, ptr
->Stream
, ptr
->Offset
, ptr
->Type
, ptr
->Method
, ptr
->Usage
, ptr
->UsageIndex
);
580 static void compare_elements(const D3DVERTEXELEMENT9
*elements
, const D3DVERTEXELEMENT9
*expected_elements
,
581 unsigned int line
, unsigned int test_id
)
583 D3DVERTEXELEMENT9 last
= D3DDECL_END();
586 for (i
= 0; i
< MAX_FVF_DECL_SIZE
; i
++)
588 int end1
= memcmp(&elements
[i
], &last
, sizeof(last
));
589 int end2
= memcmp(&expected_elements
[i
], &last
, sizeof(last
));
592 if (!end1
&& !end2
) break;
594 status
= !end1
^ !end2
;
595 ok(!status
, "Line %u, test %u: Mismatch in size, test declaration is %s than expected.\n",
596 line
, test_id
, end1
? "shorter" : "longer");
599 print_elements(elements
);
603 status
= memcmp(&elements
[i
], &expected_elements
[i
], sizeof(D3DVERTEXELEMENT9
));
604 ok(!status
, "Line %u, test %u: Mismatch in element %u.\n", line
, test_id
, i
);
607 print_elements(elements
);
613 static void test_fvf_to_decl(DWORD test_fvf
, const D3DVERTEXELEMENT9 expected_elements
[],
614 HRESULT expected_hr
, unsigned int line
, unsigned int test_id
)
617 D3DVERTEXELEMENT9 decl
[MAX_FVF_DECL_SIZE
];
619 hr
= D3DXDeclaratorFromFVF(test_fvf
, decl
);
620 ok(hr
== expected_hr
,
621 "Line %u, test %u: D3DXDeclaratorFromFVF returned %#x, expected %#x.\n",
622 line
, test_id
, hr
, expected_hr
);
623 if (SUCCEEDED(hr
)) compare_elements(decl
, expected_elements
, line
, test_id
);
626 static void test_decl_to_fvf(const D3DVERTEXELEMENT9
*decl
, DWORD expected_fvf
,
627 HRESULT expected_hr
, unsigned int line
, unsigned int test_id
)
630 DWORD result_fvf
= 0xdeadbeef;
632 hr
= D3DXFVFFromDeclarator(decl
, &result_fvf
);
633 ok(hr
== expected_hr
,
634 "Line %u, test %u: D3DXFVFFromDeclarator returned %#x, expected %#x.\n",
635 line
, test_id
, hr
, expected_hr
);
638 ok(expected_fvf
== result_fvf
, "Line %u, test %u: Got FVF %#x, expected %#x.\n",
639 line
, test_id
, result_fvf
, expected_fvf
);
643 static void test_fvf_decl_conversion(void)
647 D3DVERTEXELEMENT9 decl
[MAXD3DDECLLENGTH
+ 1];
656 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
660 {0, 0, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_POSITIONT
, 0},
664 {0, 0, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_POSITIONT
, 0},
668 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
669 {0, 12, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
673 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
674 {0, 12, D3DDECLTYPE_UBYTE4
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
676 }, D3DFVF_XYZB1
| D3DFVF_LASTBETA_UBYTE4
},
678 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
679 {0, 12, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
681 }, D3DFVF_XYZB1
| D3DFVF_LASTBETA_D3DCOLOR
},
683 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
684 {0, 12, D3DDECLTYPE_FLOAT2
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
688 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
689 {0, 12, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
690 {0, 16, D3DDECLTYPE_UBYTE4
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
692 }, D3DFVF_XYZB2
| D3DFVF_LASTBETA_UBYTE4
},
694 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
695 {0, 12, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
696 {0, 16, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
698 }, D3DFVF_XYZB2
| D3DFVF_LASTBETA_D3DCOLOR
},
700 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
701 {0, 12, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
705 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
706 {0, 12, D3DDECLTYPE_FLOAT2
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
707 {0, 20, D3DDECLTYPE_UBYTE4
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
709 }, D3DFVF_XYZB3
| D3DFVF_LASTBETA_UBYTE4
},
711 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
712 {0, 12, D3DDECLTYPE_FLOAT2
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
713 {0, 20, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
715 }, D3DFVF_XYZB3
| D3DFVF_LASTBETA_D3DCOLOR
},
717 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
718 {0, 12, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
722 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
723 {0, 12, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
724 {0, 24, D3DDECLTYPE_UBYTE4
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
726 }, D3DFVF_XYZB4
| D3DFVF_LASTBETA_UBYTE4
},
728 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
729 {0, 12, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
730 {0, 24, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
732 }, D3DFVF_XYZB4
| D3DFVF_LASTBETA_D3DCOLOR
},
734 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
735 {0, 12, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
736 {0, 28, D3DDECLTYPE_UBYTE4
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
738 }, D3DFVF_XYZB5
| D3DFVF_LASTBETA_UBYTE4
},
740 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
741 {0, 12, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
742 {0, 28, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
744 }, D3DFVF_XYZB5
| D3DFVF_LASTBETA_D3DCOLOR
},
746 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_NORMAL
, 0},
750 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_NORMAL
, 0},
751 {0, 12, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 0},
753 }, D3DFVF_NORMAL
| D3DFVF_DIFFUSE
},
755 {0, 0, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_PSIZE
, 0},
759 {0, 0, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 0},
763 {0, 0, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 1},
766 /* Make sure textures of different sizes work. */
768 {0, 0, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_TEXCOORD
, 0},
770 }, D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEX1
},
772 {0, 0, D3DDECLTYPE_FLOAT2
, 0, D3DDECLUSAGE_TEXCOORD
, 0},
774 }, D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEX1
},
776 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_TEXCOORD
, 0},
778 }, D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1
},
780 {0, 0, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_TEXCOORD
, 0},
782 }, D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1
},
783 /* Make sure the TEXCOORD index works correctly - try several textures. */
785 {0, 0, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_TEXCOORD
, 0},
786 {0, 4, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_TEXCOORD
, 1},
787 {0, 16, D3DDECLTYPE_FLOAT2
, 0, D3DDECLUSAGE_TEXCOORD
, 2},
788 {0, 24, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_TEXCOORD
, 3},
790 }, D3DFVF_TEX4
| D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEXCOORDSIZE3(1)
791 | D3DFVF_TEXCOORDSIZE2(2) | D3DFVF_TEXCOORDSIZE4(3)},
792 /* Now try some combination tests. */
794 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
795 {0, 12, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
796 {0, 28, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 0},
797 {0, 32, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 1},
798 {0, 36, D3DDECLTYPE_FLOAT2
, 0, D3DDECLUSAGE_TEXCOORD
, 0},
799 {0, 44, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_TEXCOORD
, 1},
801 }, D3DFVF_XYZB4
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
| D3DFVF_TEX2
802 | D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE3(1)},
804 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
805 {0, 12, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_NORMAL
, 0},
806 {0, 24, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_PSIZE
, 0},
807 {0, 28, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 1},
808 {0, 32, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_TEXCOORD
, 0},
809 {0, 36, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_TEXCOORD
, 1},
811 }, D3DFVF_XYZ
| D3DFVF_NORMAL
| D3DFVF_PSIZE
| D3DFVF_SPECULAR
| D3DFVF_TEX2
812 | D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEXCOORDSIZE4(1)},
816 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
818 test_decl_to_fvf(test_data
[i
].decl
, test_data
[i
].fvf
, D3D_OK
, __LINE__
, i
);
819 test_fvf_to_decl(test_data
[i
].fvf
, test_data
[i
].decl
, D3D_OK
, __LINE__
, i
);
822 /* Usage indices for position and normal are apparently ignored. */
824 const D3DVERTEXELEMENT9 decl
[] =
826 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 1},
829 test_decl_to_fvf(decl
, D3DFVF_XYZ
, D3D_OK
, __LINE__
, 0);
832 const D3DVERTEXELEMENT9 decl
[] =
834 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_NORMAL
, 1},
837 test_decl_to_fvf(decl
, D3DFVF_NORMAL
, D3D_OK
, __LINE__
, 0);
839 /* D3DFVF_LASTBETA_UBYTE4 and D3DFVF_LASTBETA_D3DCOLOR are ignored if
840 * there are no blend matrices. */
842 const D3DVERTEXELEMENT9 decl
[] =
844 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
847 test_fvf_to_decl(D3DFVF_XYZ
| D3DFVF_LASTBETA_UBYTE4
, decl
, D3D_OK
, __LINE__
, 0);
850 const D3DVERTEXELEMENT9 decl
[] =
852 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
855 test_fvf_to_decl(D3DFVF_XYZ
| D3DFVF_LASTBETA_D3DCOLOR
, decl
, D3D_OK
, __LINE__
, 0);
857 /* D3DFVF_LASTBETA_UBYTE4 takes precedence over D3DFVF_LASTBETA_D3DCOLOR. */
859 const D3DVERTEXELEMENT9 decl
[] =
861 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
862 {0, 12, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
863 {0, 28, D3DDECLTYPE_UBYTE4
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
866 test_fvf_to_decl(D3DFVF_XYZB5
| D3DFVF_LASTBETA_D3DCOLOR
| D3DFVF_LASTBETA_UBYTE4
,
867 decl
, D3D_OK
, __LINE__
, 0);
869 /* These are supposed to fail, both ways. */
871 const D3DVERTEXELEMENT9 decl
[] =
873 {0, 0, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_POSITION
, 0},
876 test_decl_to_fvf(decl
, D3DFVF_XYZW
, D3DERR_INVALIDCALL
, __LINE__
, 0);
877 test_fvf_to_decl(D3DFVF_XYZW
, decl
, D3DERR_INVALIDCALL
, __LINE__
, 0);
880 const D3DVERTEXELEMENT9 decl
[] =
882 {0, 0, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_POSITION
, 0},
883 {0, 16, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_NORMAL
, 0},
886 test_decl_to_fvf(decl
, D3DFVF_XYZW
| D3DFVF_NORMAL
, D3DERR_INVALIDCALL
, __LINE__
, 0);
887 test_fvf_to_decl(D3DFVF_XYZW
| D3DFVF_NORMAL
, decl
, D3DERR_INVALIDCALL
, __LINE__
, 0);
890 const D3DVERTEXELEMENT9 decl
[] =
892 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
893 {0, 12, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
894 {0, 28, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
897 test_decl_to_fvf(decl
, D3DFVF_XYZB5
, D3DERR_INVALIDCALL
, __LINE__
, 0);
898 test_fvf_to_decl(D3DFVF_XYZB5
, decl
, D3DERR_INVALIDCALL
, __LINE__
, 0);
900 /* Test a declaration that can't be converted to an FVF. */
902 const D3DVERTEXELEMENT9 decl
[] =
904 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
905 {0, 12, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_NORMAL
, 0},
906 {0, 24, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_PSIZE
, 0},
907 {0, 28, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 1},
908 {0, 32, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_TEXCOORD
, 0},
909 /* 8 bytes padding */
910 {0, 44, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_TEXCOORD
, 1},
913 test_decl_to_fvf(decl
, 0, D3DERR_INVALIDCALL
, __LINE__
, 0);
915 /* Elements must be ordered by offset. */
917 const D3DVERTEXELEMENT9 decl
[] =
919 {0, 12, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 0},
920 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
923 test_decl_to_fvf(decl
, 0, D3DERR_INVALIDCALL
, __LINE__
, 0);
925 /* Basic tests for element order. */
927 const D3DVERTEXELEMENT9 decl
[] =
929 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
930 {0, 12, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 0},
931 {0, 16, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_NORMAL
, 0},
934 test_decl_to_fvf(decl
, 0, D3DERR_INVALIDCALL
, __LINE__
, 0);
937 const D3DVERTEXELEMENT9 decl
[] =
939 {0, 0, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 0},
940 {0, 4, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
943 test_decl_to_fvf(decl
, 0, D3DERR_INVALIDCALL
, __LINE__
, 0);
946 const D3DVERTEXELEMENT9 decl
[] =
948 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_NORMAL
, 0},
949 {0, 12, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
952 test_decl_to_fvf(decl
, 0, D3DERR_INVALIDCALL
, __LINE__
, 0);
954 /* Textures must be ordered by texcoords. */
956 const D3DVERTEXELEMENT9 decl
[] =
958 {0, 0, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_TEXCOORD
, 0},
959 {0, 4, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_TEXCOORD
, 2},
960 {0, 16, D3DDECLTYPE_FLOAT2
, 0, D3DDECLUSAGE_TEXCOORD
, 1},
961 {0, 24, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_TEXCOORD
, 3},
964 test_decl_to_fvf(decl
, 0, D3DERR_INVALIDCALL
, __LINE__
, 0);
966 /* Duplicate elements are not allowed. */
968 const D3DVERTEXELEMENT9 decl
[] =
970 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
971 {0, 12, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 0},
972 {0, 16, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 0},
975 test_decl_to_fvf(decl
, 0, D3DERR_INVALIDCALL
, __LINE__
, 0);
977 /* Invalid FVFs cannot be converted to a declarator. */
978 test_fvf_to_decl(0xdeadbeef, NULL
, D3DERR_INVALIDCALL
, __LINE__
, 0);
981 static void D3DXGetFVFVertexSizeTest(void)
985 compare_vertex_sizes (D3DFVF_XYZ
, 12);
987 compare_vertex_sizes (D3DFVF_XYZB3
, 24);
989 compare_vertex_sizes (D3DFVF_XYZB5
, 32);
991 compare_vertex_sizes (D3DFVF_XYZ
| D3DFVF_NORMAL
, 24);
993 compare_vertex_sizes (D3DFVF_XYZ
| D3DFVF_DIFFUSE
, 16);
995 compare_vertex_sizes (
998 D3DFVF_TEXCOORDSIZE1(0), 16);
999 compare_vertex_sizes (
1002 D3DFVF_TEXCOORDSIZE1(0) |
1003 D3DFVF_TEXCOORDSIZE1(1), 20);
1005 compare_vertex_sizes (
1008 D3DFVF_TEXCOORDSIZE2(0), 20);
1010 compare_vertex_sizes (
1013 D3DFVF_TEXCOORDSIZE2(0) |
1014 D3DFVF_TEXCOORDSIZE2(1), 28);
1016 compare_vertex_sizes (
1019 D3DFVF_TEXCOORDSIZE2(0) |
1020 D3DFVF_TEXCOORDSIZE2(1) |
1021 D3DFVF_TEXCOORDSIZE2(2) |
1022 D3DFVF_TEXCOORDSIZE2(3) |
1023 D3DFVF_TEXCOORDSIZE2(4) |
1024 D3DFVF_TEXCOORDSIZE2(5), 60);
1026 compare_vertex_sizes (
1029 D3DFVF_TEXCOORDSIZE2(0) |
1030 D3DFVF_TEXCOORDSIZE2(1) |
1031 D3DFVF_TEXCOORDSIZE2(2) |
1032 D3DFVF_TEXCOORDSIZE2(3) |
1033 D3DFVF_TEXCOORDSIZE2(4) |
1034 D3DFVF_TEXCOORDSIZE2(5) |
1035 D3DFVF_TEXCOORDSIZE2(6) |
1036 D3DFVF_TEXCOORDSIZE2(7), 76);
1038 compare_vertex_sizes (
1041 D3DFVF_TEXCOORDSIZE3(0), 24);
1043 compare_vertex_sizes (
1046 D3DFVF_TEXCOORDSIZE3(0) |
1047 D3DFVF_TEXCOORDSIZE3(1) |
1048 D3DFVF_TEXCOORDSIZE3(2) |
1049 D3DFVF_TEXCOORDSIZE3(3), 60);
1051 compare_vertex_sizes (
1054 D3DFVF_TEXCOORDSIZE4(0), 28);
1056 compare_vertex_sizes (
1059 D3DFVF_TEXCOORDSIZE4(0) |
1060 D3DFVF_TEXCOORDSIZE4(1), 44);
1062 compare_vertex_sizes (
1065 D3DFVF_TEXCOORDSIZE4(0) |
1066 D3DFVF_TEXCOORDSIZE4(1) |
1067 D3DFVF_TEXCOORDSIZE4(2), 60);
1069 compare_vertex_sizes (
1075 D3DFVF_TEXCOORDSIZE4(0) |
1076 D3DFVF_TEXCOORDSIZE4(1) |
1077 D3DFVF_TEXCOORDSIZE4(2) |
1078 D3DFVF_TEXCOORDSIZE4(3) |
1079 D3DFVF_TEXCOORDSIZE4(4) |
1080 D3DFVF_TEXCOORDSIZE4(5) |
1081 D3DFVF_TEXCOORDSIZE4(6) |
1082 D3DFVF_TEXCOORDSIZE4(7), 180);
1085 static void D3DXIntersectTriTest(void)
1087 BOOL exp_res
, got_res
;
1088 D3DXVECTOR3 position
, ray
, vertex
[3];
1089 FLOAT exp_dist
, got_dist
, exp_u
, got_u
, exp_v
, got_v
;
1091 vertex
[0].x
= 1.0f
; vertex
[0].y
= 0.0f
; vertex
[0].z
= 0.0f
;
1092 vertex
[1].x
= 2.0f
; vertex
[1].y
= 0.0f
; vertex
[1].z
= 0.0f
;
1093 vertex
[2].x
= 1.0f
; vertex
[2].y
= 1.0f
; vertex
[2].z
= 0.0f
;
1095 position
.x
= -14.5f
; position
.y
= -23.75f
; position
.z
= -32.0f
;
1097 ray
.x
= 2.0f
; ray
.y
= 3.0f
; ray
.z
= 4.0f
;
1099 exp_res
= TRUE
; exp_u
= 0.5f
; exp_v
= 0.25f
; exp_dist
= 8.0f
;
1101 got_res
= D3DXIntersectTri(&vertex
[0],&vertex
[1],&vertex
[2],&position
,&ray
,&got_u
,&got_v
,&got_dist
);
1102 ok( got_res
== exp_res
, "Expected result = %d, got %d\n",exp_res
,got_res
);
1103 ok( compare(exp_u
,got_u
), "Expected u = %f, got %f\n",exp_u
,got_u
);
1104 ok( compare(exp_v
,got_v
), "Expected v = %f, got %f\n",exp_v
,got_v
);
1105 ok( compare(exp_dist
,got_dist
), "Expected distance = %f, got %f\n",exp_dist
,got_dist
);
1107 /*Only positive ray is taken in account*/
1109 vertex
[0].x
= 1.0f
; vertex
[0].y
= 0.0f
; vertex
[0].z
= 0.0f
;
1110 vertex
[1].x
= 2.0f
; vertex
[1].y
= 0.0f
; vertex
[1].z
= 0.0f
;
1111 vertex
[2].x
= 1.0f
; vertex
[2].y
= 1.0f
; vertex
[2].z
= 0.0f
;
1113 position
.x
= 17.5f
; position
.y
= 24.25f
; position
.z
= 32.0f
;
1115 ray
.x
= 2.0f
; ray
.y
= 3.0f
; ray
.z
= 4.0f
;
1119 got_res
= D3DXIntersectTri(&vertex
[0],&vertex
[1],&vertex
[2],&position
,&ray
,&got_u
,&got_v
,&got_dist
);
1120 ok( got_res
== exp_res
, "Expected result = %d, got %d\n",exp_res
,got_res
);
1122 /*Intersection between ray and triangle in a same plane is considered as empty*/
1124 vertex
[0].x
= 4.0f
; vertex
[0].y
= 0.0f
; vertex
[0].z
= 0.0f
;
1125 vertex
[1].x
= 6.0f
; vertex
[1].y
= 0.0f
; vertex
[1].z
= 0.0f
;
1126 vertex
[2].x
= 4.0f
; vertex
[2].y
= 2.0f
; vertex
[2].z
= 0.0f
;
1128 position
.x
= 1.0f
; position
.y
= 1.0f
; position
.z
= 0.0f
;
1130 ray
.x
= 1.0f
; ray
.y
= 0.0f
; ray
.z
= 0.0f
;
1134 got_res
= D3DXIntersectTri(&vertex
[0],&vertex
[1],&vertex
[2],&position
,&ray
,&got_u
,&got_v
,&got_dist
);
1135 ok( got_res
== exp_res
, "Expected result = %d, got %d\n",exp_res
,got_res
);
1138 static void D3DXCreateMeshTest(void)
1143 IDirect3DDevice9
*device
, *test_device
;
1144 D3DPRESENT_PARAMETERS d3dpp
;
1145 ID3DXMesh
*d3dxmesh
;
1147 D3DVERTEXELEMENT9 test_decl
[MAX_FVF_DECL_SIZE
];
1151 static const D3DVERTEXELEMENT9 decl1
[3] = {
1152 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1153 {0, 12, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
1156 static const D3DVERTEXELEMENT9 decl2
[] = {
1157 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1158 {0, 12, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
1159 {0, 24, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_PSIZE
, 0},
1160 {0, 28, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 1},
1161 {0, 32, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
1162 /* 8 bytes padding */
1163 {0, 44, D3DDECLTYPE_FLOAT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 1},
1167 static const D3DVERTEXELEMENT9 decl3
[] = {
1168 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1169 {1, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
1173 hr
= D3DXCreateMesh(0, 0, 0, NULL
, NULL
, NULL
);
1174 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1176 hr
= D3DXCreateMesh(1, 3, D3DXMESH_MANAGED
, decl1
, NULL
, &d3dxmesh
);
1177 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1179 if (!(wnd
= CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW
, 0, 0,
1180 640, 480, NULL
, NULL
, NULL
, NULL
)))
1182 skip("Couldn't create application window\n");
1185 d3d
= Direct3DCreate9(D3D_SDK_VERSION
);
1188 skip("Couldn't create IDirect3D9 object\n");
1193 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
1194 d3dpp
.Windowed
= TRUE
;
1195 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1196 hr
= IDirect3D9_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, wnd
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &device
);
1199 skip("Failed to create IDirect3DDevice9 object %#x\n", hr
);
1200 IDirect3D9_Release(d3d
);
1205 hr
= D3DXCreateMesh(0, 3, D3DXMESH_MANAGED
, decl1
, device
, &d3dxmesh
);
1206 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1208 hr
= D3DXCreateMesh(1, 0, D3DXMESH_MANAGED
, decl1
, device
, &d3dxmesh
);
1209 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1211 hr
= D3DXCreateMesh(1, 3, 0, decl1
, device
, &d3dxmesh
);
1212 ok(hr
== D3D_OK
, "Got result %x, expected %x (D3D_OK)\n", hr
, D3D_OK
);
1216 d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
1219 hr
= D3DXCreateMesh(1, 3, D3DXMESH_MANAGED
, 0, device
, &d3dxmesh
);
1220 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1222 hr
= D3DXCreateMesh(1, 3, D3DXMESH_MANAGED
, decl1
, device
, NULL
);
1223 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1225 hr
= D3DXCreateMesh(1, 3, D3DXMESH_MANAGED
, decl1
, device
, &d3dxmesh
);
1226 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n", hr
);
1231 hr
= d3dxmesh
->lpVtbl
->GetDevice(d3dxmesh
, NULL
);
1232 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1234 hr
= d3dxmesh
->lpVtbl
->GetDevice(d3dxmesh
, &test_device
);
1235 ok(hr
== D3D_OK
, "Got result %x, expected %x (D3D_OK)\n", hr
, D3D_OK
);
1236 ok(test_device
== device
, "Got result %p, expected %p\n", test_device
, device
);
1240 IDirect3DDevice9_Release(device
);
1244 hr
= d3dxmesh
->lpVtbl
->GetDeclaration(d3dxmesh
, NULL
);
1245 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1247 hr
= d3dxmesh
->lpVtbl
->GetDeclaration(d3dxmesh
, test_decl
);
1248 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n", hr
);
1252 size
= sizeof(decl1
) / sizeof(decl1
[0]);
1253 for (i
= 0; i
< size
- 1; i
++)
1255 ok(test_decl
[i
].Stream
== decl1
[i
].Stream
, "Returned stream %d, expected %d\n", test_decl
[i
].Stream
, decl1
[i
].Stream
);
1256 ok(test_decl
[i
].Type
== decl1
[i
].Type
, "Returned type %d, expected %d\n", test_decl
[i
].Type
, decl1
[i
].Type
);
1257 ok(test_decl
[i
].Method
== decl1
[i
].Method
, "Returned method %d, expected %d\n", test_decl
[i
].Method
, decl1
[i
].Method
);
1258 ok(test_decl
[i
].Usage
== decl1
[i
].Usage
, "Returned usage %d, expected %d\n", test_decl
[i
].Usage
, decl1
[i
].Usage
);
1259 ok(test_decl
[i
].UsageIndex
== decl1
[i
].UsageIndex
, "Returned usage index %d, expected %d\n", test_decl
[i
].UsageIndex
, decl1
[i
].UsageIndex
);
1260 ok(test_decl
[i
].Offset
== decl1
[i
].Offset
, "Returned offset %d, expected %d\n", test_decl
[i
].Offset
, decl1
[i
].Offset
);
1262 ok(decl1
[size
-1].Stream
== 0xFF, "Returned too long vertex declaration\n"); /* end element */
1266 options
= d3dxmesh
->lpVtbl
->GetOptions(d3dxmesh
);
1267 ok(options
== D3DXMESH_MANAGED
, "Got result %x, expected %x (D3DXMESH_MANAGED)\n", options
, D3DXMESH_MANAGED
);
1270 if (!new_mesh(&mesh
, 3, 1))
1272 skip("Couldn't create mesh\n");
1276 memset(mesh
.vertices
, 0, mesh
.number_of_vertices
* sizeof(*mesh
.vertices
));
1277 memset(mesh
.faces
, 0, mesh
.number_of_faces
* sizeof(*mesh
.faces
));
1278 mesh
.fvf
= D3DFVF_XYZ
| D3DFVF_NORMAL
;
1280 compare_mesh("createmesh1", d3dxmesh
, &mesh
);
1285 d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
1288 /* Test a declaration that can't be converted to an FVF. */
1289 hr
= D3DXCreateMesh(1, 3, D3DXMESH_MANAGED
, decl2
, device
, &d3dxmesh
);
1290 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n", hr
);
1295 hr
= d3dxmesh
->lpVtbl
->GetDevice(d3dxmesh
, NULL
);
1296 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1298 hr
= d3dxmesh
->lpVtbl
->GetDevice(d3dxmesh
, &test_device
);
1299 ok(hr
== D3D_OK
, "Got result %x, expected %x (D3D_OK)\n", hr
, D3D_OK
);
1300 ok(test_device
== device
, "Got result %p, expected %p\n", test_device
, device
);
1304 IDirect3DDevice9_Release(device
);
1308 hr
= d3dxmesh
->lpVtbl
->GetDeclaration(d3dxmesh
, test_decl
);
1309 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n", hr
);
1313 size
= sizeof(decl2
) / sizeof(decl2
[0]);
1314 for (i
= 0; i
< size
- 1; i
++)
1316 ok(test_decl
[i
].Stream
== decl2
[i
].Stream
, "Returned stream %d, expected %d\n", test_decl
[i
].Stream
, decl2
[i
].Stream
);
1317 ok(test_decl
[i
].Type
== decl2
[i
].Type
, "Returned type %d, expected %d\n", test_decl
[i
].Type
, decl2
[i
].Type
);
1318 ok(test_decl
[i
].Method
== decl2
[i
].Method
, "Returned method %d, expected %d\n", test_decl
[i
].Method
, decl2
[i
].Method
);
1319 ok(test_decl
[i
].Usage
== decl2
[i
].Usage
, "Returned usage %d, expected %d\n", test_decl
[i
].Usage
, decl2
[i
].Usage
);
1320 ok(test_decl
[i
].UsageIndex
== decl2
[i
].UsageIndex
, "Returned usage index %d, expected %d\n", test_decl
[i
].UsageIndex
, decl2
[i
].UsageIndex
);
1321 ok(test_decl
[i
].Offset
== decl2
[i
].Offset
, "Returned offset %d, expected %d\n", test_decl
[i
].Offset
, decl2
[i
].Offset
);
1323 ok(decl2
[size
-1].Stream
== 0xFF, "Returned too long vertex declaration\n"); /* end element */
1327 options
= d3dxmesh
->lpVtbl
->GetOptions(d3dxmesh
);
1328 ok(options
== D3DXMESH_MANAGED
, "Got result %x, expected %x (D3DXMESH_MANAGED)\n", options
, D3DXMESH_MANAGED
);
1331 if (!new_mesh(&mesh
, 3, 1))
1333 skip("Couldn't create mesh\n");
1337 memset(mesh
.vertices
, 0, mesh
.number_of_vertices
* sizeof(*mesh
.vertices
));
1338 memset(mesh
.faces
, 0, mesh
.number_of_faces
* sizeof(*mesh
.faces
));
1340 mesh
.vertex_size
= 60;
1342 compare_mesh("createmesh2", d3dxmesh
, &mesh
);
1347 mesh
.vertex_size
= d3dxmesh
->lpVtbl
->GetNumBytesPerVertex(d3dxmesh
);
1348 ok(mesh
.vertex_size
== 60, "Got vertex size %u, expected %u\n", mesh
.vertex_size
, 60);
1350 d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
1353 /* Test a declaration with multiple streams. */
1354 hr
= D3DXCreateMesh(1, 3, D3DXMESH_MANAGED
, decl3
, device
, &d3dxmesh
);
1355 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1357 IDirect3DDevice9_Release(device
);
1358 IDirect3D9_Release(d3d
);
1362 static void D3DXCreateMeshFVFTest(void)
1367 IDirect3DDevice9
*device
, *test_device
;
1368 D3DPRESENT_PARAMETERS d3dpp
;
1369 ID3DXMesh
*d3dxmesh
;
1371 D3DVERTEXELEMENT9 test_decl
[MAX_FVF_DECL_SIZE
];
1375 static const D3DVERTEXELEMENT9 decl
[3] = {
1376 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1377 {0, 12, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
1380 hr
= D3DXCreateMeshFVF(0, 0, 0, 0, NULL
, NULL
);
1381 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1383 hr
= D3DXCreateMeshFVF(1, 3, D3DXMESH_MANAGED
, D3DFVF_XYZ
| D3DFVF_NORMAL
, NULL
, &d3dxmesh
);
1384 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1386 if (!(wnd
= CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW
, 0, 0,
1387 640, 480, NULL
, NULL
, NULL
, NULL
)))
1389 skip("Couldn't create application window\n");
1392 d3d
= Direct3DCreate9(D3D_SDK_VERSION
);
1395 skip("Couldn't create IDirect3D9 object\n");
1400 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
1401 d3dpp
.Windowed
= TRUE
;
1402 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1403 hr
= IDirect3D9_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, wnd
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &device
);
1406 skip("Failed to create IDirect3DDevice9 object %#x\n", hr
);
1407 IDirect3D9_Release(d3d
);
1412 hr
= D3DXCreateMeshFVF(0, 3, D3DXMESH_MANAGED
, D3DFVF_XYZ
| D3DFVF_NORMAL
, device
, &d3dxmesh
);
1413 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1415 hr
= D3DXCreateMeshFVF(1, 0, D3DXMESH_MANAGED
, D3DFVF_XYZ
| D3DFVF_NORMAL
, device
, &d3dxmesh
);
1416 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1418 hr
= D3DXCreateMeshFVF(1, 3, 0, D3DFVF_XYZ
| D3DFVF_NORMAL
, device
, &d3dxmesh
);
1419 ok(hr
== D3D_OK
, "Got result %x, expected %x (D3D_OK)\n", hr
, D3D_OK
);
1423 d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
1426 hr
= D3DXCreateMeshFVF(1, 3, D3DXMESH_MANAGED
, 0xdeadbeef, device
, &d3dxmesh
);
1427 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1429 hr
= D3DXCreateMeshFVF(1, 3, D3DXMESH_MANAGED
, D3DFVF_XYZ
| D3DFVF_NORMAL
, device
, NULL
);
1430 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1432 hr
= D3DXCreateMeshFVF(1, 3, D3DXMESH_MANAGED
, D3DFVF_XYZ
| D3DFVF_NORMAL
, device
, &d3dxmesh
);
1433 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n", hr
);
1438 hr
= d3dxmesh
->lpVtbl
->GetDevice(d3dxmesh
, NULL
);
1439 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1441 hr
= d3dxmesh
->lpVtbl
->GetDevice(d3dxmesh
, &test_device
);
1442 ok(hr
== D3D_OK
, "Got result %x, expected %x (D3D_OK)\n", hr
, D3D_OK
);
1443 ok(test_device
== device
, "Got result %p, expected %p\n", test_device
, device
);
1447 IDirect3DDevice9_Release(device
);
1451 hr
= d3dxmesh
->lpVtbl
->GetDeclaration(d3dxmesh
, NULL
);
1452 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1454 hr
= d3dxmesh
->lpVtbl
->GetDeclaration(d3dxmesh
, test_decl
);
1455 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n", hr
);
1459 size
= sizeof(decl
) / sizeof(decl
[0]);
1460 for (i
= 0; i
< size
- 1; i
++)
1462 ok(test_decl
[i
].Stream
== decl
[i
].Stream
, "Returned stream %d, expected %d\n", test_decl
[i
].Stream
, decl
[i
].Stream
);
1463 ok(test_decl
[i
].Type
== decl
[i
].Type
, "Returned type %d, expected %d\n", test_decl
[i
].Type
, decl
[i
].Type
);
1464 ok(test_decl
[i
].Method
== decl
[i
].Method
, "Returned method %d, expected %d\n", test_decl
[i
].Method
, decl
[i
].Method
);
1465 ok(test_decl
[i
].Usage
== decl
[i
].Usage
, "Returned usage %d, expected %d\n", test_decl
[i
].Usage
, decl
[i
].Usage
);
1466 ok(test_decl
[i
].UsageIndex
== decl
[i
].UsageIndex
, "Returned usage index %d, expected %d\n",
1467 test_decl
[i
].UsageIndex
, decl
[i
].UsageIndex
);
1468 ok(test_decl
[i
].Offset
== decl
[i
].Offset
, "Returned offset %d, expected %d\n", test_decl
[i
].Offset
, decl
[i
].Offset
);
1470 ok(decl
[size
-1].Stream
== 0xFF, "Returned too long vertex declaration\n"); /* end element */
1474 options
= d3dxmesh
->lpVtbl
->GetOptions(d3dxmesh
);
1475 ok(options
== D3DXMESH_MANAGED
, "Got result %x, expected %x (D3DXMESH_MANAGED)\n", options
, D3DXMESH_MANAGED
);
1478 if (!new_mesh(&mesh
, 3, 1))
1480 skip("Couldn't create mesh\n");
1484 memset(mesh
.vertices
, 0, mesh
.number_of_vertices
* sizeof(*mesh
.vertices
));
1485 memset(mesh
.faces
, 0, mesh
.number_of_faces
* sizeof(*mesh
.faces
));
1486 mesh
.fvf
= D3DFVF_XYZ
| D3DFVF_NORMAL
;
1488 compare_mesh("createmeshfvf", d3dxmesh
, &mesh
);
1493 d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
1496 IDirect3DDevice9_Release(device
);
1497 IDirect3D9_Release(d3d
);
1501 #define check_vertex_buffer(mesh, vertices, num_vertices, fvf) \
1502 check_vertex_buffer_(__LINE__, mesh, vertices, num_vertices, fvf)
1503 static void check_vertex_buffer_(int line
, ID3DXMesh
*mesh
, const void *vertices
, DWORD num_vertices
, DWORD fvf
)
1505 DWORD mesh_num_vertices
= mesh
->lpVtbl
->GetNumVertices(mesh
);
1506 DWORD mesh_fvf
= mesh
->lpVtbl
->GetFVF(mesh
);
1507 const void *mesh_vertices
;
1510 ok_(__FILE__
,line
)(fvf
== mesh_fvf
, "expected FVF %x, got %x\n", fvf
, mesh_fvf
);
1511 ok_(__FILE__
,line
)(num_vertices
== mesh_num_vertices
,
1512 "Expected %u vertices, got %u\n", num_vertices
, mesh_num_vertices
);
1514 hr
= mesh
->lpVtbl
->LockVertexBuffer(mesh
, D3DLOCK_READONLY
, (void**)&mesh_vertices
);
1515 ok_(__FILE__
,line
)(hr
== D3D_OK
, "LockVertexBuffer returned %x, expected %x (D3D_OK)\n", hr
, D3D_OK
);
1519 if (mesh_fvf
== fvf
) {
1520 DWORD vertex_size
= D3DXGetFVFVertexSize(fvf
);
1522 for (i
= 0; i
< min(num_vertices
, mesh_num_vertices
); i
++)
1524 const FLOAT
*exp_float
= vertices
;
1525 const FLOAT
*got_float
= mesh_vertices
;
1529 BOOL last_beta_dword
= FALSE
;
1532 switch (fvf
& D3DFVF_POSITION_MASK
) {
1533 case D3DFVF_XYZ
: pos_dim
= 3; break;
1534 case D3DFVF_XYZRHW
: pos_dim
= 4; break;
1540 pos_dim
= (fvf
& D3DFVF_POSITION_MASK
) - D3DFVF_XYZB1
+ 1;
1541 if (fvf
& (D3DFVF_LASTBETA_UBYTE4
| D3DFVF_LASTBETA_D3DCOLOR
))
1544 last_beta_dword
= TRUE
;
1547 case D3DFVF_XYZW
: pos_dim
= 4; break;
1549 sprintf(prefix
, "vertex[%u] position, ", i
);
1550 check_floats_(line
, prefix
, got_float
, exp_float
, pos_dim
);
1551 exp_float
+= pos_dim
;
1552 got_float
+= pos_dim
;
1554 if (last_beta_dword
) {
1555 ok_(__FILE__
,line
)(*(DWORD
*)exp_float
== *(DWORD
*)got_float
,
1556 "Vertex[%u]: Expected last beta %08x, got %08x\n", i
, *(DWORD
*)exp_float
, *(DWORD
*)got_float
);
1561 if (fvf
& D3DFVF_NORMAL
) {
1562 sprintf(prefix
, "vertex[%u] normal, ", i
);
1563 check_floats_(line
, prefix
, got_float
, exp_float
, 3);
1567 if (fvf
& D3DFVF_PSIZE
) {
1568 ok_(__FILE__
,line
)(compare(*exp_float
, *got_float
),
1569 "Vertex[%u]: Expected psize %g, got %g\n", i
, *exp_float
, *got_float
);
1573 if (fvf
& D3DFVF_DIFFUSE
) {
1574 ok_(__FILE__
,line
)(*(DWORD
*)exp_float
== *(DWORD
*)got_float
,
1575 "Vertex[%u]: Expected diffuse %08x, got %08x\n", i
, *(DWORD
*)exp_float
, *(DWORD
*)got_float
);
1579 if (fvf
& D3DFVF_SPECULAR
) {
1580 ok_(__FILE__
,line
)(*(DWORD
*)exp_float
== *(DWORD
*)got_float
,
1581 "Vertex[%u]: Expected specular %08x, got %08x\n", i
, *(DWORD
*)exp_float
, *(DWORD
*)got_float
);
1586 texcount
= (fvf
& D3DFVF_TEXCOUNT_MASK
) >> D3DFVF_TEXCOUNT_SHIFT
;
1587 for (j
= 0; j
< texcount
; j
++) {
1588 DWORD dim
= (((fvf
>> (16 + 2 * j
)) + 1) & 0x03) + 1;
1589 sprintf(prefix
, "vertex[%u] texture, ", i
);
1590 check_floats_(line
, prefix
, got_float
, exp_float
, dim
);
1595 vertices
= (BYTE
*)vertices
+ vertex_size
;
1596 mesh_vertices
= (BYTE
*)mesh_vertices
+ vertex_size
;
1600 mesh
->lpVtbl
->UnlockVertexBuffer(mesh
);
1603 #define check_index_buffer(mesh, indices, num_indices, index_size) \
1604 check_index_buffer_(__LINE__, mesh, indices, num_indices, index_size)
1605 static void check_index_buffer_(int line
, ID3DXMesh
*mesh
, const void *indices
, DWORD num_indices
, DWORD index_size
)
1607 DWORD mesh_index_size
= (mesh
->lpVtbl
->GetOptions(mesh
) & D3DXMESH_32BIT
) ? 4 : 2;
1608 DWORD mesh_num_indices
= mesh
->lpVtbl
->GetNumFaces(mesh
) * 3;
1609 const void *mesh_indices
;
1613 ok_(__FILE__
,line
)(index_size
== mesh_index_size
,
1614 "Expected index size %u, got %u\n", index_size
, mesh_index_size
);
1615 ok_(__FILE__
,line
)(num_indices
== mesh_num_indices
,
1616 "Expected %u indices, got %u\n", num_indices
, mesh_num_indices
);
1618 hr
= mesh
->lpVtbl
->LockIndexBuffer(mesh
, D3DLOCK_READONLY
, (void**)&mesh_indices
);
1619 ok_(__FILE__
,line
)(hr
== D3D_OK
, "LockIndexBuffer returned %x, expected %x (D3D_OK)\n", hr
, D3D_OK
);
1623 if (mesh_index_size
== index_size
) {
1624 for (i
= 0; i
< min(num_indices
, mesh_num_indices
); i
++)
1626 if (index_size
== 4)
1627 ok_(__FILE__
,line
)(*(DWORD
*)indices
== *(DWORD
*)mesh_indices
,
1628 "Index[%u]: expected %u, got %u\n", i
, *(DWORD
*)indices
, *(DWORD
*)mesh_indices
);
1630 ok_(__FILE__
,line
)(*(WORD
*)indices
== *(WORD
*)mesh_indices
,
1631 "Index[%u]: expected %u, got %u\n", i
, *(WORD
*)indices
, *(WORD
*)mesh_indices
);
1632 indices
= (BYTE
*)indices
+ index_size
;
1633 mesh_indices
= (BYTE
*)mesh_indices
+ index_size
;
1636 mesh
->lpVtbl
->UnlockIndexBuffer(mesh
);
1639 #define check_matrix(got, expected) check_matrix_(__LINE__, got, expected)
1640 static void check_matrix_(int line
, const D3DXMATRIX
*got
, const D3DXMATRIX
*expected
)
1643 for (i
= 0; i
< 4; i
++) {
1644 for (j
= 0; j
< 4; j
++) {
1645 ok_(__FILE__
,line
)(compare(U(*expected
).m
[i
][j
], U(*got
).m
[i
][j
]),
1646 "matrix[%u][%u]: expected %g, got %g\n",
1647 i
, j
, U(*expected
).m
[i
][j
], U(*got
).m
[i
][j
]);
1652 static void check_colorvalue_(int line
, const char *prefix
, const D3DCOLORVALUE got
, const D3DCOLORVALUE expected
)
1654 ok_(__FILE__
,line
)(expected
.r
== got
.r
&& expected
.g
== got
.g
&& expected
.b
== got
.b
&& expected
.a
== got
.a
,
1655 "%sExpected (%g, %g, %g, %g), got (%g, %g, %g, %g)\n", prefix
,
1656 expected
.r
, expected
.g
, expected
.b
, expected
.a
, got
.r
, got
.g
, got
.b
, got
.a
);
1659 #define check_materials(got, got_count, expected, expected_count) \
1660 check_materials_(__LINE__, got, got_count, expected, expected_count)
1661 static void check_materials_(int line
, const D3DXMATERIAL
*got
, DWORD got_count
, const D3DXMATERIAL
*expected
, DWORD expected_count
)
1664 ok_(__FILE__
,line
)(expected_count
== got_count
, "Expected %u materials, got %u\n", expected_count
, got_count
);
1666 ok_(__FILE__
,line
)(got
== NULL
, "Expected NULL material ptr, got %p\n", got
);
1669 for (i
= 0; i
< min(expected_count
, got_count
); i
++)
1671 if (!expected
[i
].pTextureFilename
)
1672 ok_(__FILE__
,line
)(got
[i
].pTextureFilename
== NULL
,
1673 "Expected NULL pTextureFilename, got %p\n", got
[i
].pTextureFilename
);
1675 ok_(__FILE__
,line
)(!strcmp(expected
[i
].pTextureFilename
, got
[i
].pTextureFilename
),
1676 "Expected '%s' for pTextureFilename, got '%s'\n", expected
[i
].pTextureFilename
, got
[i
].pTextureFilename
);
1677 check_colorvalue_(line
, "Diffuse: ", got
[i
].MatD3D
.Diffuse
, expected
[i
].MatD3D
.Diffuse
);
1678 check_colorvalue_(line
, "Ambient: ", got
[i
].MatD3D
.Ambient
, expected
[i
].MatD3D
.Ambient
);
1679 check_colorvalue_(line
, "Specular: ", got
[i
].MatD3D
.Specular
, expected
[i
].MatD3D
.Specular
);
1680 check_colorvalue_(line
, "Emissive: ", got
[i
].MatD3D
.Emissive
, expected
[i
].MatD3D
.Emissive
);
1681 ok_(__FILE__
,line
)(expected
[i
].MatD3D
.Power
== got
[i
].MatD3D
.Power
,
1682 "Power: Expected %g, got %g\n", expected
[i
].MatD3D
.Power
, got
[i
].MatD3D
.Power
);
1686 #define check_generated_adjacency(mesh, got, epsilon) check_generated_adjacency_(__LINE__, mesh, got, epsilon)
1687 static void check_generated_adjacency_(int line
, ID3DXMesh
*mesh
, const DWORD
*got
, FLOAT epsilon
)
1690 DWORD num_faces
= mesh
->lpVtbl
->GetNumFaces(mesh
);
1693 expected
= HeapAlloc(GetProcessHeap(), 0, num_faces
* sizeof(DWORD
) * 3);
1695 skip_(__FILE__
, line
)("Out of memory\n");
1698 hr
= mesh
->lpVtbl
->GenerateAdjacency(mesh
, epsilon
, expected
);
1699 ok_(__FILE__
, line
)(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
1703 for (i
= 0; i
< num_faces
; i
++)
1705 ok_(__FILE__
, line
)(expected
[i
* 3] == got
[i
* 3] &&
1706 expected
[i
* 3 + 1] == got
[i
* 3 + 1] &&
1707 expected
[i
* 3 + 2] == got
[i
* 3 + 2],
1708 "Face %u adjacencies: Expected (%u, %u, %u), got (%u, %u, %u)\n", i
,
1709 expected
[i
* 3], expected
[i
* 3 + 1], expected
[i
* 3 + 2],
1710 got
[i
* 3], got
[i
* 3 + 1], got
[i
* 3 + 2]);
1713 HeapFree(GetProcessHeap(), 0, expected
);
1716 #define check_generated_effects(materials, num_materials, effects) \
1717 check_generated_effects_(__LINE__, materials, num_materials, effects)
1718 static void check_generated_effects_(int line
, const D3DXMATERIAL
*materials
, DWORD num_materials
, const D3DXEFFECTINSTANCE
*effects
)
1721 static const struct {
1727 #define EFFECT_TABLE_ENTRY(str, field) \
1728 {str, sizeof(str), sizeof(materials->MatD3D.field), offsetof(D3DXMATERIAL, MatD3D.field)}
1729 EFFECT_TABLE_ENTRY("Diffuse", Diffuse
),
1730 EFFECT_TABLE_ENTRY("Power", Power
),
1731 EFFECT_TABLE_ENTRY("Specular", Specular
),
1732 EFFECT_TABLE_ENTRY("Emissive", Emissive
),
1733 EFFECT_TABLE_ENTRY("Ambient", Ambient
),
1734 #undef EFFECT_TABLE_ENTRY
1737 if (!num_materials
) {
1738 ok_(__FILE__
, line
)(effects
== NULL
, "Expected NULL effects, got %p\n", effects
);
1741 for (i
= 0; i
< num_materials
; i
++)
1744 DWORD expected_num_defaults
= ARRAY_SIZE(params
) + (materials
[i
].pTextureFilename
? 1 : 0);
1746 ok_(__FILE__
,line
)(expected_num_defaults
== effects
[i
].NumDefaults
,
1747 "effect[%u] NumDefaults: Expected %u, got %u\n", i
,
1748 expected_num_defaults
, effects
[i
].NumDefaults
);
1749 for (j
= 0; j
< min(ARRAY_SIZE(params
), effects
[i
].NumDefaults
); j
++)
1752 D3DXEFFECTDEFAULT
*got_param
= &effects
[i
].pDefaults
[j
];
1753 ok_(__FILE__
,line
)(!strcmp(params
[j
].name
, got_param
->pParamName
),
1754 "effect[%u].pDefaults[%u].pParamName: Expected '%s', got '%s'\n", i
, j
,
1755 params
[j
].name
, got_param
->pParamName
);
1756 ok_(__FILE__
,line
)(D3DXEDT_FLOATS
== got_param
->Type
,
1757 "effect[%u].pDefaults[%u].Type: Expected %u, got %u\n", i
, j
,
1758 D3DXEDT_FLOATS
, got_param
->Type
);
1759 ok_(__FILE__
,line
)(params
[j
].num_bytes
== got_param
->NumBytes
,
1760 "effect[%u].pDefaults[%u].NumBytes: Expected %u, got %u\n", i
, j
,
1761 params
[j
].num_bytes
, got_param
->NumBytes
);
1762 for (k
= 0; k
< min(params
[j
].num_bytes
, got_param
->NumBytes
) / 4; k
++)
1764 FLOAT expected
= ((FLOAT
*)((BYTE
*)&materials
[i
] + params
[j
].value_offset
))[k
];
1765 FLOAT got
= ((FLOAT
*)got_param
->pValue
)[k
];
1766 ok_(__FILE__
,line
)(compare(expected
, got
),
1767 "effect[%u].pDefaults[%u] float value %u: Expected %g, got %g\n", i
, j
, k
, expected
, got
);
1770 if (effects
[i
].NumDefaults
> ARRAY_SIZE(params
)) {
1771 D3DXEFFECTDEFAULT
*got_param
= &effects
[i
].pDefaults
[j
];
1772 static const char *expected_name
= "Texture0@Name";
1774 ok_(__FILE__
,line
)(!strcmp(expected_name
, got_param
->pParamName
),
1775 "effect[%u].pDefaults[%u].pParamName: Expected '%s', got '%s'\n", i
, j
,
1776 expected_name
, got_param
->pParamName
);
1777 ok_(__FILE__
,line
)(D3DXEDT_STRING
== got_param
->Type
,
1778 "effect[%u].pDefaults[%u].Type: Expected %u, got %u\n", i
, j
,
1779 D3DXEDT_STRING
, got_param
->Type
);
1780 if (materials
[i
].pTextureFilename
) {
1781 ok_(__FILE__
,line
)(strlen(materials
[i
].pTextureFilename
) + 1 == got_param
->NumBytes
,
1782 "effect[%u] texture filename length: Expected %u, got %u\n", i
,
1783 (DWORD
)strlen(materials
[i
].pTextureFilename
) + 1, got_param
->NumBytes
);
1784 ok_(__FILE__
,line
)(!strcmp(materials
[i
].pTextureFilename
, got_param
->pValue
),
1785 "effect[%u] texture filename: Expected '%s', got '%s'\n", i
,
1786 materials
[i
].pTextureFilename
, (char*)got_param
->pValue
);
1792 static char *strdupA(const char *p
)
1795 if (!p
) return NULL
;
1796 ret
= HeapAlloc(GetProcessHeap(), 0, strlen(p
) + 1);
1797 if (ret
) strcpy(ret
, p
);
1801 static HRESULT CALLBACK
ID3DXAllocateHierarchyImpl_DestroyFrame(ID3DXAllocateHierarchy
*iface
, LPD3DXFRAME frame
)
1803 TRACECALLBACK("ID3DXAllocateHierarchyImpl_DestroyFrame(%p, %p)\n", iface
, frame
);
1805 HeapFree(GetProcessHeap(), 0, frame
->Name
);
1806 HeapFree(GetProcessHeap(), 0, frame
);
1811 static HRESULT CALLBACK
ID3DXAllocateHierarchyImpl_CreateFrame(ID3DXAllocateHierarchy
*iface
,
1812 const char *name
, D3DXFRAME
**new_frame
)
1816 TRACECALLBACK("ID3DXAllocateHierarchyImpl_CreateFrame(%p, '%s', %p)\n", iface
, name
, new_frame
);
1817 frame
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*frame
));
1819 return E_OUTOFMEMORY
;
1821 frame
->Name
= strdupA(name
);
1823 HeapFree(GetProcessHeap(), 0, frame
);
1824 return E_OUTOFMEMORY
;
1831 static HRESULT
destroy_mesh_container(LPD3DXMESHCONTAINER mesh_container
)
1835 if (!mesh_container
)
1837 HeapFree(GetProcessHeap(), 0, mesh_container
->Name
);
1838 if (U(mesh_container
->MeshData
).pMesh
)
1839 IUnknown_Release(U(mesh_container
->MeshData
).pMesh
);
1840 if (mesh_container
->pMaterials
) {
1841 for (i
= 0; i
< mesh_container
->NumMaterials
; i
++)
1842 HeapFree(GetProcessHeap(), 0, mesh_container
->pMaterials
[i
].pTextureFilename
);
1843 HeapFree(GetProcessHeap(), 0, mesh_container
->pMaterials
);
1845 if (mesh_container
->pEffects
) {
1846 for (i
= 0; i
< mesh_container
->NumMaterials
; i
++) {
1847 HeapFree(GetProcessHeap(), 0, mesh_container
->pEffects
[i
].pEffectFilename
);
1848 if (mesh_container
->pEffects
[i
].pDefaults
) {
1850 for (j
= 0; j
< mesh_container
->pEffects
[i
].NumDefaults
; j
++) {
1851 HeapFree(GetProcessHeap(), 0, mesh_container
->pEffects
[i
].pDefaults
[j
].pParamName
);
1852 HeapFree(GetProcessHeap(), 0, mesh_container
->pEffects
[i
].pDefaults
[j
].pValue
);
1854 HeapFree(GetProcessHeap(), 0, mesh_container
->pEffects
[i
].pDefaults
);
1857 HeapFree(GetProcessHeap(), 0, mesh_container
->pEffects
);
1859 HeapFree(GetProcessHeap(), 0, mesh_container
->pAdjacency
);
1860 if (mesh_container
->pSkinInfo
)
1861 IUnknown_Release(mesh_container
->pSkinInfo
);
1862 HeapFree(GetProcessHeap(), 0, mesh_container
);
1866 static HRESULT CALLBACK
ID3DXAllocateHierarchyImpl_DestroyMeshContainer(ID3DXAllocateHierarchy
*iface
, LPD3DXMESHCONTAINER mesh_container
)
1868 TRACECALLBACK("ID3DXAllocateHierarchyImpl_DestroyMeshContainer(%p, %p)\n", iface
, mesh_container
);
1869 return destroy_mesh_container(mesh_container
);
1872 static HRESULT CALLBACK
ID3DXAllocateHierarchyImpl_CreateMeshContainer(ID3DXAllocateHierarchy
*iface
,
1873 const char *name
, const D3DXMESHDATA
*mesh_data
, const D3DXMATERIAL
*materials
,
1874 const D3DXEFFECTINSTANCE
*effects
, DWORD num_materials
, const DWORD
*adjacency
,
1875 ID3DXSkinInfo
*skin_info
, D3DXMESHCONTAINER
**new_mesh_container
)
1877 LPD3DXMESHCONTAINER mesh_container
= NULL
;
1880 TRACECALLBACK("ID3DXAllocateHierarchyImpl_CreateMeshContainer(%p, '%s', %u, %p, %p, %p, %d, %p, %p, %p)\n",
1881 iface
, name
, mesh_data
->Type
, U(*mesh_data
).pMesh
, materials
, effects
,
1882 num_materials
, adjacency
, skin_info
, *new_mesh_container
);
1884 mesh_container
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*mesh_container
));
1885 if (!mesh_container
)
1886 return E_OUTOFMEMORY
;
1889 mesh_container
->Name
= strdupA(name
);
1890 if (!mesh_container
->Name
)
1894 mesh_container
->NumMaterials
= num_materials
;
1895 if (num_materials
) {
1896 mesh_container
->pMaterials
= HeapAlloc(GetProcessHeap(), 0, num_materials
* sizeof(*materials
));
1897 if (!mesh_container
->pMaterials
)
1900 memcpy(mesh_container
->pMaterials
, materials
, num_materials
* sizeof(*materials
));
1901 for (i
= 0; i
< num_materials
; i
++)
1902 mesh_container
->pMaterials
[i
].pTextureFilename
= NULL
;
1903 for (i
= 0; i
< num_materials
; i
++) {
1904 if (materials
[i
].pTextureFilename
) {
1905 mesh_container
->pMaterials
[i
].pTextureFilename
= strdupA(materials
[i
].pTextureFilename
);
1906 if (!mesh_container
->pMaterials
[i
].pTextureFilename
)
1911 mesh_container
->pEffects
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, num_materials
* sizeof(*effects
));
1912 if (!mesh_container
->pEffects
)
1914 for (i
= 0; i
< num_materials
; i
++) {
1916 const D3DXEFFECTINSTANCE
*effect_src
= &effects
[i
];
1917 D3DXEFFECTINSTANCE
*effect_dest
= &mesh_container
->pEffects
[i
];
1919 if (effect_src
->pEffectFilename
) {
1920 effect_dest
->pEffectFilename
= strdupA(effect_src
->pEffectFilename
);
1921 if (!effect_dest
->pEffectFilename
)
1924 effect_dest
->pDefaults
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1925 effect_src
->NumDefaults
* sizeof(*effect_src
->pDefaults
));
1926 if (!effect_dest
->pDefaults
)
1928 effect_dest
->NumDefaults
= effect_src
->NumDefaults
;
1929 for (j
= 0; j
< effect_src
->NumDefaults
; j
++) {
1930 const D3DXEFFECTDEFAULT
*default_src
= &effect_src
->pDefaults
[j
];
1931 D3DXEFFECTDEFAULT
*default_dest
= &effect_dest
->pDefaults
[j
];
1933 if (default_src
->pParamName
) {
1934 default_dest
->pParamName
= strdupA(default_src
->pParamName
);
1935 if (!default_dest
->pParamName
)
1938 default_dest
->NumBytes
= default_src
->NumBytes
;
1939 default_dest
->Type
= default_src
->Type
;
1940 default_dest
->pValue
= HeapAlloc(GetProcessHeap(), 0, default_src
->NumBytes
);
1941 memcpy(default_dest
->pValue
, default_src
->pValue
, default_src
->NumBytes
);
1946 ok(adjacency
!= NULL
, "Expected non-NULL adjacency, got NULL\n");
1948 if (mesh_data
->Type
== D3DXMESHTYPE_MESH
|| mesh_data
->Type
== D3DXMESHTYPE_PMESH
) {
1949 ID3DXBaseMesh
*basemesh
= (ID3DXBaseMesh
*)U(*mesh_data
).pMesh
;
1950 DWORD num_faces
= basemesh
->lpVtbl
->GetNumFaces(basemesh
);
1951 size_t size
= num_faces
* sizeof(DWORD
) * 3;
1952 mesh_container
->pAdjacency
= HeapAlloc(GetProcessHeap(), 0, size
);
1953 if (!mesh_container
->pAdjacency
)
1955 memcpy(mesh_container
->pAdjacency
, adjacency
, size
);
1957 ok(mesh_data
->Type
== D3DXMESHTYPE_PATCHMESH
, "Unknown mesh type %u\n", mesh_data
->Type
);
1958 if (mesh_data
->Type
== D3DXMESHTYPE_PATCHMESH
)
1959 trace("FIXME: copying adjacency data for patch mesh not implemented\n");
1963 memcpy(&mesh_container
->MeshData
, mesh_data
, sizeof(*mesh_data
));
1964 if (U(*mesh_data
).pMesh
)
1965 IUnknown_AddRef(U(*mesh_data
).pMesh
);
1967 mesh_container
->pSkinInfo
= skin_info
;
1968 skin_info
->lpVtbl
->AddRef(skin_info
);
1970 *new_mesh_container
= mesh_container
;
1974 destroy_mesh_container(mesh_container
);
1975 return E_OUTOFMEMORY
;
1978 static ID3DXAllocateHierarchyVtbl ID3DXAllocateHierarchyImpl_Vtbl
= {
1979 ID3DXAllocateHierarchyImpl_CreateFrame
,
1980 ID3DXAllocateHierarchyImpl_CreateMeshContainer
,
1981 ID3DXAllocateHierarchyImpl_DestroyFrame
,
1982 ID3DXAllocateHierarchyImpl_DestroyMeshContainer
,
1984 static ID3DXAllocateHierarchy alloc_hier
= { &ID3DXAllocateHierarchyImpl_Vtbl
};
1986 #define test_LoadMeshFromX(device, xfile_str, vertex_array, fvf, index_array, materials_array, check_adjacency) \
1987 test_LoadMeshFromX_(__LINE__, device, xfile_str, sizeof(xfile_str) - 1, vertex_array, ARRAY_SIZE(vertex_array), fvf, \
1988 index_array, ARRAY_SIZE(index_array), sizeof(*index_array), materials_array, ARRAY_SIZE(materials_array), \
1990 static void test_LoadMeshFromX_(int line
, IDirect3DDevice9
*device
, const char *xfile_str
, size_t xfile_strlen
,
1991 const void *vertices
, DWORD num_vertices
, DWORD fvf
, const void *indices
, DWORD num_indices
, size_t index_size
,
1992 const D3DXMATERIAL
*expected_materials
, DWORD expected_num_materials
, BOOL check_adjacency
)
1995 ID3DXBuffer
*materials
= NULL
;
1996 ID3DXBuffer
*effects
= NULL
;
1997 ID3DXBuffer
*adjacency
= NULL
;
1998 ID3DXMesh
*mesh
= NULL
;
1999 DWORD num_materials
= 0;
2001 /* Adjacency is not checked when the X file contains multiple meshes,
2002 * since calling GenerateAdjacency on the merged mesh is not equivalent
2003 * to calling GenerateAdjacency on the individual meshes and then merging
2004 * the adjacency data. */
2005 hr
= D3DXLoadMeshFromXInMemory(xfile_str
, xfile_strlen
, D3DXMESH_MANAGED
, device
,
2006 check_adjacency
? &adjacency
: NULL
, &materials
, &effects
, &num_materials
, &mesh
);
2007 ok_(__FILE__
,line
)(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
2008 if (SUCCEEDED(hr
)) {
2009 D3DXMATERIAL
*materials_ptr
= materials
? ID3DXBuffer_GetBufferPointer(materials
) : NULL
;
2010 D3DXEFFECTINSTANCE
*effects_ptr
= effects
? ID3DXBuffer_GetBufferPointer(effects
) : NULL
;
2011 DWORD
*adjacency_ptr
= check_adjacency
? ID3DXBuffer_GetBufferPointer(adjacency
) : NULL
;
2013 check_vertex_buffer_(line
, mesh
, vertices
, num_vertices
, fvf
);
2014 check_index_buffer_(line
, mesh
, indices
, num_indices
, index_size
);
2015 check_materials_(line
, materials_ptr
, num_materials
, expected_materials
, expected_num_materials
);
2016 check_generated_effects_(line
, materials_ptr
, num_materials
, effects_ptr
);
2017 if (check_adjacency
)
2018 check_generated_adjacency_(line
, mesh
, adjacency_ptr
, 0.0f
);
2020 if (materials
) ID3DXBuffer_Release(materials
);
2021 if (effects
) ID3DXBuffer_Release(effects
);
2022 if (adjacency
) ID3DXBuffer_Release(adjacency
);
2023 IUnknown_Release(mesh
);
2027 static void D3DXLoadMeshTest(void)
2029 static const char empty_xfile
[] = "xof 0303txt 0032";
2030 /*________________________*/
2031 static const char simple_xfile
[] =
2041 static const WORD simple_index_buffer
[] = {0, 1, 2};
2042 static const D3DXVECTOR3 simple_vertex_buffer
[] = {
2043 {0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 1.0, 0.0}
2045 const DWORD simple_fvf
= D3DFVF_XYZ
;
2046 static const char framed_xfile
[] =
2049 "Mesh { 3; 0.0; 0.0; 0.0;, 0.0; 1.0; 0.0;, 1.0; 1.0; 0.0;; 1; 3; 0, 1, 2;; }"
2050 "FrameTransformMatrix {" /* translation (0.0, 0.0, 2.0) */
2051 "1.0, 0.0, 0.0, 0.0,"
2052 "0.0, 1.0, 0.0, 0.0,"
2053 "0.0, 0.0, 1.0, 0.0,"
2054 "0.0, 0.0, 2.0, 1.0;;"
2056 "Mesh { 3; 0.0; 0.0; 0.0;, 0.0; 1.0; 0.0;, 2.0; 1.0; 0.0;; 1; 3; 0, 1, 2;; }"
2057 "FrameTransformMatrix {" /* translation (0.0, 0.0, 3.0) */
2058 "1.0, 0.0, 0.0, 0.0,"
2059 "0.0, 1.0, 0.0, 0.0,"
2060 "0.0, 0.0, 1.0, 0.0,"
2061 "0.0, 0.0, 3.0, 1.0;;"
2063 "Mesh { 3; 0.0; 0.0; 0.0;, 0.0; 1.0; 0.0;, 3.0; 1.0; 0.0;; 1; 3; 0, 1, 2;; }"
2065 static const WORD framed_index_buffer
[] = { 0, 1, 2 };
2066 static const D3DXVECTOR3 framed_vertex_buffers
[3][3] = {
2067 {{0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 1.0, 0.0}},
2068 {{0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {2.0, 1.0, 0.0}},
2069 {{0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {3.0, 1.0, 0.0}},
2071 static const WORD merged_index_buffer
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
2072 /* frame transforms accumulates for D3DXLoadMeshFromX */
2073 static const D3DXVECTOR3 merged_vertex_buffer
[] = {
2074 {0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 1.0, 0.0},
2075 {0.0, 0.0, 2.0}, {0.0, 1.0, 2.0}, {2.0, 1.0, 2.0},
2076 {0.0, 0.0, 5.0}, {0.0, 1.0, 5.0}, {3.0, 1.0, 5.0},
2078 const DWORD framed_fvf
= D3DFVF_XYZ
;
2079 /*________________________*/
2080 static const char box_xfile
[] =
2083 "8;" /* DWORD nVertices; */
2084 /* array Vector vertices[nVertices]; */
2093 "6;" /* DWORD nFaces; */
2094 /* array MeshFace faces[nFaces]; */
2095 "4; 0, 1, 3, 2;," /* (left side) */
2096 "4; 2, 3, 7, 6;," /* (top side) */
2097 "4; 6, 7, 5, 4;," /* (right side) */
2098 "4; 1, 0, 4, 5;," /* (bottom side) */
2099 "4; 1, 5, 7, 3;," /* (back side) */
2100 "4; 0, 2, 6, 4;;" /* (front side) */
2102 "6;" /* DWORD nNormals; */
2103 /* array Vector normals[nNormals]; */
2110 "6;" /* DWORD nFaceNormals; */
2111 /* array MeshFace faceNormals[nFaceNormals]; */
2119 "MeshMaterialList materials {"
2120 "2;" /* DWORD nMaterials; */
2121 "6;" /* DWORD nFaceIndexes; */
2122 /* array DWORD faceIndexes[nFaceIndexes]; */
2123 "0, 0, 0, 1, 1, 1;;"
2125 /* ColorRGBA faceColor; */
2126 "0.0; 0.0; 1.0; 1.0;;"
2129 /* ColorRGB specularColor; */
2131 /* ColorRGB emissiveColor; */
2135 /* ColorRGBA faceColor; */
2136 "1.0; 1.0; 1.0; 1.0;;"
2139 /* ColorRGB specularColor; */
2141 /* ColorRGB emissiveColor; */
2143 "TextureFilename { \"texture.jpg\"; }"
2146 "MeshVertexColors {"
2147 "8;" /* DWORD nVertexColors; */
2148 /* array IndexedColor vertexColors[nVertexColors]; */
2149 "0; 0.0; 0.0; 0.0; 0.0;;"
2150 "1; 0.0; 0.0; 1.0; 0.1;;"
2151 "2; 0.0; 1.0; 0.0; 0.2;;"
2152 "3; 0.0; 1.0; 1.0; 0.3;;"
2153 "4; 1.0; 0.0; 0.0; 0.4;;"
2154 "5; 1.0; 0.0; 1.0; 0.5;;"
2155 "6; 1.0; 1.0; 0.0; 0.6;;"
2156 "7; 1.0; 1.0; 1.0; 0.7;;"
2158 "MeshTextureCoords {"
2159 "8;" /* DWORD nTextureCoords; */
2160 /* array Coords2d textureCoords[nTextureCoords]; */
2171 static const WORD box_index_buffer
[] = {
2185 static const struct {
2186 D3DXVECTOR3 position
;
2189 D3DXVECTOR2 tex_coords
;
2190 } box_vertex_buffer
[] = {
2191 {{0.0, 0.0, 0.0}, {-1.0, 0.0, 0.0}, 0x00000000, {0.0, 1.0}},
2192 {{0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0}, 0x1a0000ff, {1.0, 1.0}},
2193 {{0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0}, 0x3300ff00, {0.0, 0.0}},
2194 {{0.0, 1.0, 1.0}, {-1.0, 0.0, 0.0}, 0x4d00ffff, {1.0, 0.0}},
2195 {{1.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, 0x66ff0000, {1.0, 1.0}},
2196 {{1.0, 0.0, 1.0}, {1.0, 0.0, 0.0}, 0x80ff00ff, {0.0, 1.0}},
2197 {{1.0, 1.0, 0.0}, {0.0, 1.0, 0.0}, 0x99ffff00, {1.0, 0.0}},
2198 {{1.0, 1.0, 1.0}, {0.0, 1.0, 0.0}, 0xb3ffffff, {0.0, 0.0}},
2199 {{0.0, 1.0, 0.0}, {0.0, 1.0, 0.0}, 0x3300ff00, {0.0, 0.0}},
2200 {{0.0, 1.0, 1.0}, {0.0, 1.0, 0.0}, 0x4d00ffff, {1.0, 0.0}},
2201 {{1.0, 1.0, 0.0}, {1.0, 0.0, 0.0}, 0x99ffff00, {1.0, 0.0}},
2202 {{1.0, 1.0, 1.0}, {1.0, 0.0, 0.0}, 0xb3ffffff, {0.0, 0.0}},
2203 {{0.0, 0.0, 1.0}, {0.0, -1.0, 0.0}, 0x1a0000ff, {1.0, 1.0}},
2204 {{0.0, 0.0, 0.0}, {0.0, -1.0, 0.0}, 0x00000000, {0.0, 1.0}},
2205 {{1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}, 0x66ff0000, {1.0, 1.0}},
2206 {{1.0, 0.0, 1.0}, {0.0, -1.0, 0.0}, 0x80ff00ff, {0.0, 1.0}},
2207 {{0.0, 0.0, 1.0}, {0.0, 0.0, 1.0}, 0x1a0000ff, {1.0, 1.0}},
2208 {{1.0, 0.0, 1.0}, {0.0, 0.0, 1.0}, 0x80ff00ff, {0.0, 1.0}},
2209 {{1.0, 1.0, 1.0}, {0.0, 0.0, 1.0}, 0xb3ffffff, {0.0, 0.0}},
2210 {{0.0, 1.0, 1.0}, {0.0, 0.0, 1.0}, 0x4d00ffff, {1.0, 0.0}},
2211 {{0.0, 0.0, 0.0}, {0.0, 0.0, -1.0}, 0x00000000, {0.0, 1.0}},
2212 {{0.0, 1.0, 0.0}, {0.0, 0.0, -1.0}, 0x3300ff00, {0.0, 0.0}},
2213 {{1.0, 1.0, 0.0}, {0.0, 0.0, -1.0}, 0x99ffff00, {1.0, 0.0}},
2214 {{1.0, 0.0, 0.0}, {0.0, 0.0, -1.0}, 0x66ff0000, {1.0, 1.0}},
2216 static const D3DXMATERIAL box_materials
[] = {
2219 {0.0, 0.0, 1.0, 1.0}, /* Diffuse */
2220 {0.0, 0.0, 0.0, 1.0}, /* Ambient */
2221 {1.0, 1.0, 1.0, 1.0}, /* Specular */
2222 {0.0, 0.0, 0.0, 1.0}, /* Emissive */
2225 NULL
, /* pTextureFilename */
2229 {1.0, 1.0, 1.0, 1.0}, /* Diffuse */
2230 {0.0, 0.0, 0.0, 1.0}, /* Ambient */
2231 {1.0, 1.0, 1.0, 1.0}, /* Specular */
2232 {0.0, 0.0, 0.0, 1.0}, /* Emissive */
2235 (char *)"texture.jpg", /* pTextureFilename */
2238 const DWORD box_fvf
= D3DFVF_XYZ
| D3DFVF_NORMAL
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
;
2239 /*________________________*/
2240 static const D3DXMATERIAL default_materials
[] = {
2243 {0.5, 0.5, 0.5, 0.0}, /* Diffuse */
2244 {0.0, 0.0, 0.0, 0.0}, /* Ambient */
2245 {0.5, 0.5, 0.5, 0.0}, /* Specular */
2246 {0.0, 0.0, 0.0, 0.0}, /* Emissive */
2249 NULL
, /* pTextureFilename */
2254 IDirect3D9
*d3d
= NULL
;
2255 IDirect3DDevice9
*device
= NULL
;
2256 D3DPRESENT_PARAMETERS d3dpp
;
2257 ID3DXMesh
*mesh
= NULL
;
2258 D3DXFRAME
*frame_hier
= NULL
;
2259 D3DXMATRIX transform
;
2261 if (!(wnd
= CreateWindowA("static", "d3dx9_test", WS_POPUP
, 0, 0, 1000, 1000, NULL
, NULL
, NULL
, NULL
)))
2263 skip("Couldn't create application window\n");
2266 d3d
= Direct3DCreate9(D3D_SDK_VERSION
);
2269 skip("Couldn't create IDirect3D9 object\n");
2273 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
2274 d3dpp
.Windowed
= TRUE
;
2275 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2276 hr
= IDirect3D9_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, wnd
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &device
);
2279 skip("Failed to create IDirect3DDevice9 object %#x\n", hr
);
2283 hr
= D3DXLoadMeshHierarchyFromXInMemory(NULL
, sizeof(simple_xfile
) - 1,
2284 D3DXMESH_MANAGED
, device
, &alloc_hier
, NULL
, &frame_hier
, NULL
);
2285 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
2287 hr
= D3DXLoadMeshHierarchyFromXInMemory(simple_xfile
, 0,
2288 D3DXMESH_MANAGED
, device
, &alloc_hier
, NULL
, &frame_hier
, NULL
);
2289 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
2291 hr
= D3DXLoadMeshHierarchyFromXInMemory(simple_xfile
, sizeof(simple_xfile
) - 1,
2292 D3DXMESH_MANAGED
, NULL
, &alloc_hier
, NULL
, &frame_hier
, NULL
);
2293 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
2295 hr
= D3DXLoadMeshHierarchyFromXInMemory(simple_xfile
, sizeof(simple_xfile
) - 1,
2296 D3DXMESH_MANAGED
, device
, NULL
, NULL
, &frame_hier
, NULL
);
2297 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
2299 hr
= D3DXLoadMeshHierarchyFromXInMemory(empty_xfile
, sizeof(empty_xfile
) - 1,
2300 D3DXMESH_MANAGED
, device
, &alloc_hier
, NULL
, &frame_hier
, NULL
);
2301 ok(hr
== E_FAIL
, "Expected E_FAIL, got %#x\n", hr
);
2303 hr
= D3DXLoadMeshHierarchyFromXInMemory(simple_xfile
, sizeof(simple_xfile
) - 1,
2304 D3DXMESH_MANAGED
, device
, &alloc_hier
, NULL
, NULL
, NULL
);
2305 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
2307 hr
= D3DXLoadMeshHierarchyFromXInMemory(simple_xfile
, sizeof(simple_xfile
) - 1,
2308 D3DXMESH_MANAGED
, device
, &alloc_hier
, NULL
, &frame_hier
, NULL
);
2309 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
2310 if (SUCCEEDED(hr
)) {
2311 D3DXMESHCONTAINER
*container
= frame_hier
->pMeshContainer
;
2313 ok(frame_hier
->Name
== NULL
, "Expected NULL, got '%s'\n", frame_hier
->Name
);
2314 D3DXMatrixIdentity(&transform
);
2315 check_matrix(&frame_hier
->TransformationMatrix
, &transform
);
2317 ok(!strcmp(container
->Name
, ""), "Expected '', got '%s'\n", container
->Name
);
2318 ok(container
->MeshData
.Type
== D3DXMESHTYPE_MESH
, "Expected %d, got %d\n",
2319 D3DXMESHTYPE_MESH
, container
->MeshData
.Type
);
2320 mesh
= U(container
->MeshData
).pMesh
;
2321 check_vertex_buffer(mesh
, simple_vertex_buffer
, ARRAY_SIZE(simple_vertex_buffer
), simple_fvf
);
2322 check_index_buffer(mesh
, simple_index_buffer
, ARRAY_SIZE(simple_index_buffer
), sizeof(*simple_index_buffer
));
2323 check_materials(container
->pMaterials
, container
->NumMaterials
, NULL
, 0);
2324 check_generated_effects(container
->pMaterials
, container
->NumMaterials
, container
->pEffects
);
2325 check_generated_adjacency(mesh
, container
->pAdjacency
, 0.0f
);
2326 hr
= D3DXFrameDestroy(frame_hier
, &alloc_hier
);
2327 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
2331 hr
= D3DXLoadMeshHierarchyFromXInMemory(box_xfile
, sizeof(box_xfile
) - 1,
2332 D3DXMESH_MANAGED
, device
, &alloc_hier
, NULL
, &frame_hier
, NULL
);
2333 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
2334 if (SUCCEEDED(hr
)) {
2335 D3DXMESHCONTAINER
*container
= frame_hier
->pMeshContainer
;
2337 ok(frame_hier
->Name
== NULL
, "Expected NULL, got '%s'\n", frame_hier
->Name
);
2338 D3DXMatrixIdentity(&transform
);
2339 check_matrix(&frame_hier
->TransformationMatrix
, &transform
);
2341 ok(!strcmp(container
->Name
, ""), "Expected '', got '%s'\n", container
->Name
);
2342 ok(container
->MeshData
.Type
== D3DXMESHTYPE_MESH
, "Expected %d, got %d\n",
2343 D3DXMESHTYPE_MESH
, container
->MeshData
.Type
);
2344 mesh
= U(container
->MeshData
).pMesh
;
2345 check_vertex_buffer(mesh
, box_vertex_buffer
, ARRAY_SIZE(box_vertex_buffer
), box_fvf
);
2346 check_index_buffer(mesh
, box_index_buffer
, ARRAY_SIZE(box_index_buffer
), sizeof(*box_index_buffer
));
2347 check_materials(container
->pMaterials
, container
->NumMaterials
, box_materials
, ARRAY_SIZE(box_materials
));
2348 check_generated_effects(container
->pMaterials
, container
->NumMaterials
, container
->pEffects
);
2349 check_generated_adjacency(mesh
, container
->pAdjacency
, 0.0f
);
2350 hr
= D3DXFrameDestroy(frame_hier
, &alloc_hier
);
2351 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
2355 hr
= D3DXLoadMeshHierarchyFromXInMemory(framed_xfile
, sizeof(framed_xfile
) - 1,
2356 D3DXMESH_MANAGED
, device
, &alloc_hier
, NULL
, &frame_hier
, NULL
);
2357 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
2358 if (SUCCEEDED(hr
)) {
2359 D3DXMESHCONTAINER
*container
= frame_hier
->pMeshContainer
;
2362 ok(!strcmp(frame_hier
->Name
, ""), "Expected '', got '%s'\n", frame_hier
->Name
);
2363 /* last frame transform replaces the first */
2364 D3DXMatrixIdentity(&transform
);
2365 U(transform
).m
[3][2] = 3.0;
2366 check_matrix(&frame_hier
->TransformationMatrix
, &transform
);
2368 for (i
= 0; i
< 3; i
++) {
2369 ok(!strcmp(container
->Name
, ""), "Expected '', got '%s'\n", container
->Name
);
2370 ok(container
->MeshData
.Type
== D3DXMESHTYPE_MESH
, "Expected %d, got %d\n",
2371 D3DXMESHTYPE_MESH
, container
->MeshData
.Type
);
2372 mesh
= U(container
->MeshData
).pMesh
;
2373 check_vertex_buffer(mesh
, framed_vertex_buffers
[i
], ARRAY_SIZE(framed_vertex_buffers
[0]), framed_fvf
);
2374 check_index_buffer(mesh
, framed_index_buffer
, ARRAY_SIZE(framed_index_buffer
), sizeof(*framed_index_buffer
));
2375 check_materials(container
->pMaterials
, container
->NumMaterials
, NULL
, 0);
2376 check_generated_effects(container
->pMaterials
, container
->NumMaterials
, container
->pEffects
);
2377 check_generated_adjacency(mesh
, container
->pAdjacency
, 0.0f
);
2378 container
= container
->pNextMeshContainer
;
2380 ok(container
== NULL
, "Expected NULL, got %p\n", container
);
2381 hr
= D3DXFrameDestroy(frame_hier
, &alloc_hier
);
2382 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
2387 hr
= D3DXLoadMeshFromXInMemory(NULL
, 0, D3DXMESH_MANAGED
,
2388 device
, NULL
, NULL
, NULL
, NULL
, &mesh
);
2389 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
2391 hr
= D3DXLoadMeshFromXInMemory(NULL
, sizeof(simple_xfile
) - 1, D3DXMESH_MANAGED
,
2392 device
, NULL
, NULL
, NULL
, NULL
, &mesh
);
2393 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
2395 hr
= D3DXLoadMeshFromXInMemory(simple_xfile
, 0, D3DXMESH_MANAGED
,
2396 device
, NULL
, NULL
, NULL
, NULL
, &mesh
);
2397 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
2399 hr
= D3DXLoadMeshFromXInMemory(simple_xfile
, sizeof(simple_xfile
) - 1, D3DXMESH_MANAGED
,
2400 device
, NULL
, NULL
, NULL
, NULL
, NULL
);
2401 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
2403 hr
= D3DXLoadMeshFromXInMemory(simple_xfile
, sizeof(simple_xfile
) - 1, D3DXMESH_MANAGED
,
2404 NULL
, NULL
, NULL
, NULL
, NULL
, &mesh
);
2405 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
2407 hr
= D3DXLoadMeshFromXInMemory(empty_xfile
, sizeof(empty_xfile
) - 1, D3DXMESH_MANAGED
,
2408 device
, NULL
, NULL
, NULL
, NULL
, &mesh
);
2409 ok(hr
== E_FAIL
, "Expected E_FAIL, got %#x\n", hr
);
2411 hr
= D3DXLoadMeshFromXInMemory(simple_xfile
, sizeof(simple_xfile
) - 1, D3DXMESH_MANAGED
,
2412 device
, NULL
, NULL
, NULL
, NULL
, &mesh
);
2413 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
2415 IUnknown_Release(mesh
);
2417 test_LoadMeshFromX(device
, simple_xfile
, simple_vertex_buffer
, simple_fvf
, simple_index_buffer
, default_materials
, TRUE
);
2418 test_LoadMeshFromX(device
, box_xfile
, box_vertex_buffer
, box_fvf
, box_index_buffer
, box_materials
, TRUE
);
2419 test_LoadMeshFromX(device
, framed_xfile
, merged_vertex_buffer
, framed_fvf
, merged_index_buffer
, default_materials
, FALSE
);
2422 if (device
) IDirect3DDevice9_Release(device
);
2423 if (d3d
) IDirect3D9_Release(d3d
);
2424 if (wnd
) DestroyWindow(wnd
);
2427 static void D3DXCreateBoxTest(void)
2433 IDirect3DDevice9
* device
;
2434 D3DPRESENT_PARAMETERS d3dpp
;
2436 ID3DXBuffer
* ppBuffer
;
2438 static const DWORD adjacency
[36]=
2444 1, 3, 11, 5, 6, 10};
2447 wc
.lpfnWndProc
= DefWindowProcA
;
2448 wc
.lpszClassName
= "d3dx9_test_wc";
2449 if (!RegisterClassA(&wc
))
2451 skip("RegisterClass failed\n");
2455 wnd
= CreateWindowA("d3dx9_test_wc", "d3dx9_test", WS_OVERLAPPEDWINDOW
,
2456 0, 0, 640, 480, 0, 0, 0, 0);
2457 ok(wnd
!= NULL
, "Expected to have a window, received NULL\n");
2460 skip("Couldn't create application window\n");
2464 d3d
= Direct3DCreate9(D3D_SDK_VERSION
);
2467 skip("Couldn't create IDirect3D9 object\n");
2472 memset(&d3dpp
, 0, sizeof(d3dpp
));
2473 d3dpp
.Windowed
= TRUE
;
2474 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2475 hr
= IDirect3D9_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, wnd
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &device
);
2478 skip("Failed to create IDirect3DDevice9 object %#x\n", hr
);
2479 IDirect3D9_Release(d3d
);
2484 hr
= D3DXCreateBox(device
,2.0f
,20.0f
,4.9f
,NULL
, &ppBuffer
);
2485 ok(hr
==D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, received %#x\n", hr
);
2487 hr
= D3DXCreateBox(NULL
,22.0f
,20.0f
,4.9f
,&box
, &ppBuffer
);
2488 ok(hr
==D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, received %#x\n", hr
);
2490 hr
= D3DXCreateBox(device
,-2.0f
,20.0f
,4.9f
,&box
, &ppBuffer
);
2491 ok(hr
==D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, received %#x\n", hr
);
2493 hr
= D3DXCreateBox(device
,22.0f
,-20.0f
,4.9f
,&box
, &ppBuffer
);
2494 ok(hr
==D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, received %#x\n", hr
);
2496 hr
= D3DXCreateBox(device
,22.0f
,20.0f
,-4.9f
,&box
, &ppBuffer
);
2497 ok(hr
==D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, received %#x\n", hr
);
2500 hr
= D3DXCreateBox(device
,10.9f
,20.0f
,4.9f
,&box
, &ppBuffer
);
2501 ok(hr
==D3D_OK
, "Expected D3D_OK, received %#x\n", hr
);
2505 skip("D3DXCreateBox failed\n");
2509 buffer
= ID3DXBuffer_GetBufferPointer(ppBuffer
);
2511 ok(adjacency
[i
]==buffer
[i
], "expected adjacency %d: %#x, received %#x\n",i
,adjacency
[i
], buffer
[i
]);
2513 box
->lpVtbl
->Release(box
);
2516 IDirect3DDevice9_Release(device
);
2517 IDirect3D9_Release(d3d
);
2518 if (ppBuffer
) ID3DXBuffer_Release(ppBuffer
);
2528 static void free_sincos_table(struct sincos_table
*sincos_table
)
2530 HeapFree(GetProcessHeap(), 0, sincos_table
->cos
);
2531 HeapFree(GetProcessHeap(), 0, sincos_table
->sin
);
2534 /* pre compute sine and cosine tables; caller must free */
2535 static BOOL
compute_sincos_table(struct sincos_table
*sincos_table
, float angle_start
, float angle_step
, int n
)
2540 sincos_table
->sin
= HeapAlloc(GetProcessHeap(), 0, n
* sizeof(*sincos_table
->sin
));
2541 if (!sincos_table
->sin
)
2545 sincos_table
->cos
= HeapAlloc(GetProcessHeap(), 0, n
* sizeof(*sincos_table
->cos
));
2546 if (!sincos_table
->cos
)
2548 HeapFree(GetProcessHeap(), 0, sincos_table
->sin
);
2552 angle
= angle_start
;
2553 for (i
= 0; i
< n
; i
++)
2555 sincos_table
->sin
[i
] = sin(angle
);
2556 sincos_table
->cos
[i
] = cos(angle
);
2557 angle
+= angle_step
;
2563 static WORD
vertex_index(UINT slices
, int slice
, int stack
)
2565 return stack
*slices
+slice
+1;
2568 /* slices = subdivisions along xy plane, stacks = subdivisions along z axis */
2569 static BOOL
compute_sphere(struct mesh
*mesh
, FLOAT radius
, UINT slices
, UINT stacks
)
2571 float theta_step
, theta_start
;
2572 struct sincos_table theta
;
2573 float phi_step
, phi_start
;
2574 struct sincos_table phi
;
2575 DWORD number_of_vertices
, number_of_faces
;
2579 /* theta = angle on xy plane wrt x axis */
2580 theta_step
= D3DX_PI
/ stacks
;
2581 theta_start
= theta_step
;
2583 /* phi = angle on xz plane wrt z axis */
2584 phi_step
= -2 * D3DX_PI
/ slices
;
2585 phi_start
= D3DX_PI
/ 2;
2587 if (!compute_sincos_table(&theta
, theta_start
, theta_step
, stacks
))
2591 if (!compute_sincos_table(&phi
, phi_start
, phi_step
, slices
))
2593 free_sincos_table(&theta
);
2597 number_of_vertices
= 2 + slices
* (stacks
-1);
2598 number_of_faces
= 2 * slices
+ (stacks
- 2) * (2 * slices
);
2600 if (!new_mesh(mesh
, number_of_vertices
, number_of_faces
))
2602 free_sincos_table(&phi
);
2603 free_sincos_table(&theta
);
2610 mesh
->vertices
[vertex
].normal
.x
= 0.0f
;
2611 mesh
->vertices
[vertex
].normal
.y
= 0.0f
;
2612 mesh
->vertices
[vertex
].normal
.z
= 1.0f
;
2613 mesh
->vertices
[vertex
].position
.x
= 0.0f
;
2614 mesh
->vertices
[vertex
].position
.y
= 0.0f
;
2615 mesh
->vertices
[vertex
].position
.z
= radius
;
2618 for (stack
= 0; stack
< stacks
- 1; stack
++)
2620 for (slice
= 0; slice
< slices
; slice
++)
2622 mesh
->vertices
[vertex
].normal
.x
= theta
.sin
[stack
] * phi
.cos
[slice
];
2623 mesh
->vertices
[vertex
].normal
.y
= theta
.sin
[stack
] * phi
.sin
[slice
];
2624 mesh
->vertices
[vertex
].normal
.z
= theta
.cos
[stack
];
2625 mesh
->vertices
[vertex
].position
.x
= radius
* theta
.sin
[stack
] * phi
.cos
[slice
];
2626 mesh
->vertices
[vertex
].position
.y
= radius
* theta
.sin
[stack
] * phi
.sin
[slice
];
2627 mesh
->vertices
[vertex
].position
.z
= radius
* theta
.cos
[stack
];
2634 /* top stack is triangle fan */
2635 mesh
->faces
[face
][0] = 0;
2636 mesh
->faces
[face
][1] = slice
+ 1;
2637 mesh
->faces
[face
][2] = slice
;
2642 /* stacks in between top and bottom are quad strips */
2643 mesh
->faces
[face
][0] = vertex_index(slices
, slice
-1, stack
-1);
2644 mesh
->faces
[face
][1] = vertex_index(slices
, slice
, stack
-1);
2645 mesh
->faces
[face
][2] = vertex_index(slices
, slice
-1, stack
);
2648 mesh
->faces
[face
][0] = vertex_index(slices
, slice
, stack
-1);
2649 mesh
->faces
[face
][1] = vertex_index(slices
, slice
, stack
);
2650 mesh
->faces
[face
][2] = vertex_index(slices
, slice
-1, stack
);
2658 mesh
->faces
[face
][0] = 0;
2659 mesh
->faces
[face
][1] = 1;
2660 mesh
->faces
[face
][2] = slice
;
2665 mesh
->faces
[face
][0] = vertex_index(slices
, slice
-1, stack
-1);
2666 mesh
->faces
[face
][1] = vertex_index(slices
, 0, stack
-1);
2667 mesh
->faces
[face
][2] = vertex_index(slices
, slice
-1, stack
);
2670 mesh
->faces
[face
][0] = vertex_index(slices
, 0, stack
-1);
2671 mesh
->faces
[face
][1] = vertex_index(slices
, 0, stack
);
2672 mesh
->faces
[face
][2] = vertex_index(slices
, slice
-1, stack
);
2677 mesh
->vertices
[vertex
].position
.x
= 0.0f
;
2678 mesh
->vertices
[vertex
].position
.y
= 0.0f
;
2679 mesh
->vertices
[vertex
].position
.z
= -radius
;
2680 mesh
->vertices
[vertex
].normal
.x
= 0.0f
;
2681 mesh
->vertices
[vertex
].normal
.y
= 0.0f
;
2682 mesh
->vertices
[vertex
].normal
.z
= -1.0f
;
2684 /* bottom stack is triangle fan */
2685 for (slice
= 1; slice
< slices
; slice
++)
2687 mesh
->faces
[face
][0] = vertex_index(slices
, slice
-1, stack
-1);
2688 mesh
->faces
[face
][1] = vertex_index(slices
, slice
, stack
-1);
2689 mesh
->faces
[face
][2] = vertex
;
2693 mesh
->faces
[face
][0] = vertex_index(slices
, slice
-1, stack
-1);
2694 mesh
->faces
[face
][1] = vertex_index(slices
, 0, stack
-1);
2695 mesh
->faces
[face
][2] = vertex
;
2697 free_sincos_table(&phi
);
2698 free_sincos_table(&theta
);
2703 static void test_sphere(IDirect3DDevice9
*device
, FLOAT radius
, UINT slices
, UINT stacks
)
2710 hr
= D3DXCreateSphere(device
, radius
, slices
, stacks
, &sphere
, NULL
);
2711 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n", hr
);
2714 skip("Couldn't create sphere\n");
2718 if (!compute_sphere(&mesh
, radius
, slices
, stacks
))
2720 skip("Couldn't create mesh\n");
2721 sphere
->lpVtbl
->Release(sphere
);
2725 mesh
.fvf
= D3DFVF_XYZ
| D3DFVF_NORMAL
;
2727 sprintf(name
, "sphere (%g, %u, %u)", radius
, slices
, stacks
);
2728 compare_mesh(name
, sphere
, &mesh
);
2732 sphere
->lpVtbl
->Release(sphere
);
2735 static void D3DXCreateSphereTest(void)
2740 IDirect3DDevice9
* device
;
2741 D3DPRESENT_PARAMETERS d3dpp
;
2742 ID3DXMesh
* sphere
= NULL
;
2744 hr
= D3DXCreateSphere(NULL
, 0.0f
, 0, 0, NULL
, NULL
);
2745 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
2747 hr
= D3DXCreateSphere(NULL
, 0.1f
, 0, 0, NULL
, NULL
);
2748 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
2750 hr
= D3DXCreateSphere(NULL
, 0.0f
, 1, 0, NULL
, NULL
);
2751 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
2753 hr
= D3DXCreateSphere(NULL
, 0.0f
, 0, 1, NULL
, NULL
);
2754 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
2756 if (!(wnd
= CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW
, 0, 0,
2757 640, 480, NULL
, NULL
, NULL
, NULL
)))
2759 skip("Couldn't create application window\n");
2762 if (!(d3d
= Direct3DCreate9(D3D_SDK_VERSION
)))
2764 skip("Couldn't create IDirect3D9 object\n");
2769 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
2770 d3dpp
.Windowed
= TRUE
;
2771 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2772 hr
= IDirect3D9_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, wnd
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &device
);
2775 skip("Failed to create IDirect3DDevice9 object %#x\n", hr
);
2776 IDirect3D9_Release(d3d
);
2781 hr
= D3DXCreateSphere(device
, 1.0f
, 1, 1, &sphere
, NULL
);
2782 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
2784 hr
= D3DXCreateSphere(device
, 1.0f
, 2, 1, &sphere
, NULL
);
2785 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
2787 hr
= D3DXCreateSphere(device
, 1.0f
, 1, 2, &sphere
, NULL
);
2788 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
2790 hr
= D3DXCreateSphere(device
, -0.1f
, 1, 2, &sphere
, NULL
);
2791 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
2793 test_sphere(device
, 0.0f
, 2, 2);
2794 test_sphere(device
, 1.0f
, 2, 2);
2795 test_sphere(device
, 1.0f
, 3, 2);
2796 test_sphere(device
, 1.0f
, 4, 4);
2797 test_sphere(device
, 1.0f
, 3, 4);
2798 test_sphere(device
, 5.0f
, 6, 7);
2799 test_sphere(device
, 10.0f
, 11, 12);
2801 IDirect3DDevice9_Release(device
);
2802 IDirect3D9_Release(d3d
);
2806 static BOOL
compute_cylinder(struct mesh
*mesh
, FLOAT radius1
, FLOAT radius2
, FLOAT length
, UINT slices
, UINT stacks
)
2808 float theta_step
, theta_start
;
2809 struct sincos_table theta
;
2810 FLOAT delta_radius
, radius
, radius_step
;
2811 FLOAT z
, z_step
, z_normal
;
2812 DWORD number_of_vertices
, number_of_faces
;
2816 /* theta = angle on xy plane wrt x axis */
2817 theta_step
= -2 * D3DX_PI
/ slices
;
2818 theta_start
= D3DX_PI
/ 2;
2820 if (!compute_sincos_table(&theta
, theta_start
, theta_step
, slices
))
2825 number_of_vertices
= 2 + (slices
* (3 + stacks
));
2826 number_of_faces
= 2 * slices
+ stacks
* (2 * slices
);
2828 if (!new_mesh(mesh
, number_of_vertices
, number_of_faces
))
2830 free_sincos_table(&theta
);
2837 delta_radius
= radius1
- radius2
;
2839 radius_step
= delta_radius
/ stacks
;
2842 z_step
= length
/ stacks
;
2843 z_normal
= delta_radius
/ length
;
2844 if (isnan(z_normal
))
2849 mesh
->vertices
[vertex
].normal
.x
= 0.0f
;
2850 mesh
->vertices
[vertex
].normal
.y
= 0.0f
;
2851 mesh
->vertices
[vertex
].normal
.z
= -1.0f
;
2852 mesh
->vertices
[vertex
].position
.x
= 0.0f
;
2853 mesh
->vertices
[vertex
].position
.y
= 0.0f
;
2854 mesh
->vertices
[vertex
++].position
.z
= z
;
2856 for (slice
= 0; slice
< slices
; slice
++, vertex
++)
2858 mesh
->vertices
[vertex
].normal
.x
= 0.0f
;
2859 mesh
->vertices
[vertex
].normal
.y
= 0.0f
;
2860 mesh
->vertices
[vertex
].normal
.z
= -1.0f
;
2861 mesh
->vertices
[vertex
].position
.x
= radius
* theta
.cos
[slice
];
2862 mesh
->vertices
[vertex
].position
.y
= radius
* theta
.sin
[slice
];
2863 mesh
->vertices
[vertex
].position
.z
= z
;
2867 mesh
->faces
[face
][0] = 0;
2868 mesh
->faces
[face
][1] = slice
;
2869 mesh
->faces
[face
++][2] = slice
+ 1;
2873 mesh
->faces
[face
][0] = 0;
2874 mesh
->faces
[face
][1] = slice
;
2875 mesh
->faces
[face
++][2] = 1;
2877 for (stack
= 1; stack
<= stacks
+1; stack
++)
2879 for (slice
= 0; slice
< slices
; slice
++, vertex
++)
2881 mesh
->vertices
[vertex
].normal
.x
= theta
.cos
[slice
];
2882 mesh
->vertices
[vertex
].normal
.y
= theta
.sin
[slice
];
2883 mesh
->vertices
[vertex
].normal
.z
= z_normal
;
2884 D3DXVec3Normalize(&mesh
->vertices
[vertex
].normal
, &mesh
->vertices
[vertex
].normal
);
2885 mesh
->vertices
[vertex
].position
.x
= radius
* theta
.cos
[slice
];
2886 mesh
->vertices
[vertex
].position
.y
= radius
* theta
.sin
[slice
];
2887 mesh
->vertices
[vertex
].position
.z
= z
;
2889 if (stack
> 1 && slice
> 0)
2891 mesh
->faces
[face
][0] = vertex_index(slices
, slice
-1, stack
-1);
2892 mesh
->faces
[face
][1] = vertex_index(slices
, slice
-1, stack
);
2893 mesh
->faces
[face
++][2] = vertex_index(slices
, slice
, stack
-1);
2895 mesh
->faces
[face
][0] = vertex_index(slices
, slice
, stack
-1);
2896 mesh
->faces
[face
][1] = vertex_index(slices
, slice
-1, stack
);
2897 mesh
->faces
[face
++][2] = vertex_index(slices
, slice
, stack
);
2903 mesh
->faces
[face
][0] = vertex_index(slices
, slice
-1, stack
-1);
2904 mesh
->faces
[face
][1] = vertex_index(slices
, slice
-1, stack
);
2905 mesh
->faces
[face
++][2] = vertex_index(slices
, 0, stack
-1);
2907 mesh
->faces
[face
][0] = vertex_index(slices
, 0, stack
-1);
2908 mesh
->faces
[face
][1] = vertex_index(slices
, slice
-1, stack
);
2909 mesh
->faces
[face
++][2] = vertex_index(slices
, 0, stack
);
2912 if (stack
< stacks
+ 1)
2915 radius
-= radius_step
;
2919 for (slice
= 0; slice
< slices
; slice
++, vertex
++)
2921 mesh
->vertices
[vertex
].normal
.x
= 0.0f
;
2922 mesh
->vertices
[vertex
].normal
.y
= 0.0f
;
2923 mesh
->vertices
[vertex
].normal
.z
= 1.0f
;
2924 mesh
->vertices
[vertex
].position
.x
= radius
* theta
.cos
[slice
];
2925 mesh
->vertices
[vertex
].position
.y
= radius
* theta
.sin
[slice
];
2926 mesh
->vertices
[vertex
].position
.z
= z
;
2930 mesh
->faces
[face
][0] = vertex_index(slices
, slice
-1, stack
);
2931 mesh
->faces
[face
][1] = number_of_vertices
- 1;
2932 mesh
->faces
[face
++][2] = vertex_index(slices
, slice
, stack
);
2936 mesh
->vertices
[vertex
].position
.x
= 0.0f
;
2937 mesh
->vertices
[vertex
].position
.y
= 0.0f
;
2938 mesh
->vertices
[vertex
].position
.z
= z
;
2939 mesh
->vertices
[vertex
].normal
.x
= 0.0f
;
2940 mesh
->vertices
[vertex
].normal
.y
= 0.0f
;
2941 mesh
->vertices
[vertex
].normal
.z
= 1.0f
;
2943 mesh
->faces
[face
][0] = vertex_index(slices
, slice
-1, stack
);
2944 mesh
->faces
[face
][1] = number_of_vertices
- 1;
2945 mesh
->faces
[face
][2] = vertex_index(slices
, 0, stack
);
2947 free_sincos_table(&theta
);
2952 static void test_cylinder(IDirect3DDevice9
*device
, FLOAT radius1
, FLOAT radius2
, FLOAT length
, UINT slices
, UINT stacks
)
2955 ID3DXMesh
*cylinder
;
2959 hr
= D3DXCreateCylinder(device
, radius1
, radius2
, length
, slices
, stacks
, &cylinder
, NULL
);
2960 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n", hr
);
2963 skip("Couldn't create cylinder\n");
2967 if (!compute_cylinder(&mesh
, radius1
, radius2
, length
, slices
, stacks
))
2969 skip("Couldn't create mesh\n");
2970 cylinder
->lpVtbl
->Release(cylinder
);
2974 mesh
.fvf
= D3DFVF_XYZ
| D3DFVF_NORMAL
;
2976 sprintf(name
, "cylinder (%g, %g, %g, %u, %u)", radius1
, radius2
, length
, slices
, stacks
);
2977 compare_mesh(name
, cylinder
, &mesh
);
2981 cylinder
->lpVtbl
->Release(cylinder
);
2984 static void D3DXCreateCylinderTest(void)
2989 IDirect3DDevice9
* device
;
2990 D3DPRESENT_PARAMETERS d3dpp
;
2991 ID3DXMesh
* cylinder
= NULL
;
2993 hr
= D3DXCreateCylinder(NULL
, 0.0f
, 0.0f
, 0.0f
, 0, 0, NULL
, NULL
);
2994 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
2996 hr
= D3DXCreateCylinder(NULL
, 1.0f
, 1.0f
, 1.0f
, 2, 1, &cylinder
, NULL
);
2997 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
2999 if (!(wnd
= CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW
, 0, 0,
3000 640, 480, NULL
, NULL
, NULL
, NULL
)))
3002 skip("Couldn't create application window\n");
3005 if (!(d3d
= Direct3DCreate9(D3D_SDK_VERSION
)))
3007 skip("Couldn't create IDirect3D9 object\n");
3012 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
3013 d3dpp
.Windowed
= TRUE
;
3014 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
3015 hr
= IDirect3D9_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, wnd
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &device
);
3018 skip("Failed to create IDirect3DDevice9 object %#x\n", hr
);
3019 IDirect3D9_Release(d3d
);
3024 hr
= D3DXCreateCylinder(device
, -0.1f
, 1.0f
, 1.0f
, 2, 1, &cylinder
, NULL
);
3025 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
3027 hr
= D3DXCreateCylinder(device
, 0.0f
, 1.0f
, 1.0f
, 2, 1, &cylinder
, NULL
);
3028 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n",hr
);
3030 if (SUCCEEDED(hr
) && cylinder
)
3032 cylinder
->lpVtbl
->Release(cylinder
);
3035 hr
= D3DXCreateCylinder(device
, 1.0f
, -0.1f
, 1.0f
, 2, 1, &cylinder
, NULL
);
3036 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
3038 hr
= D3DXCreateCylinder(device
, 1.0f
, 0.0f
, 1.0f
, 2, 1, &cylinder
, NULL
);
3039 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n",hr
);
3041 if (SUCCEEDED(hr
) && cylinder
)
3043 cylinder
->lpVtbl
->Release(cylinder
);
3046 hr
= D3DXCreateCylinder(device
, 1.0f
, 1.0f
, -0.1f
, 2, 1, &cylinder
, NULL
);
3047 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
3049 /* Test with length == 0.0f succeeds */
3050 hr
= D3DXCreateCylinder(device
, 1.0f
, 1.0f
, 0.0f
, 2, 1, &cylinder
, NULL
);
3051 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n",hr
);
3053 if (SUCCEEDED(hr
) && cylinder
)
3055 cylinder
->lpVtbl
->Release(cylinder
);
3058 hr
= D3DXCreateCylinder(device
, 1.0f
, 1.0f
, 1.0f
, 1, 1, &cylinder
, NULL
);
3059 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
3061 hr
= D3DXCreateCylinder(device
, 1.0f
, 1.0f
, 1.0f
, 2, 0, &cylinder
, NULL
);
3062 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
3064 hr
= D3DXCreateCylinder(device
, 1.0f
, 1.0f
, 1.0f
, 2, 1, NULL
, NULL
);
3065 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
3067 test_cylinder(device
, 0.0f
, 0.0f
, 0.0f
, 2, 1);
3068 test_cylinder(device
, 1.0f
, 1.0f
, 1.0f
, 2, 1);
3069 test_cylinder(device
, 1.0f
, 1.0f
, 2.0f
, 3, 4);
3070 test_cylinder(device
, 3.0f
, 2.0f
, 4.0f
, 3, 4);
3071 test_cylinder(device
, 2.0f
, 3.0f
, 4.0f
, 3, 4);
3072 test_cylinder(device
, 3.0f
, 4.0f
, 5.0f
, 11, 20);
3074 IDirect3DDevice9_Release(device
);
3075 IDirect3D9_Release(d3d
);
3079 struct dynamic_array
3081 int count
, capacity
;
3086 POINTTYPE_CURVE
= 0,
3088 POINTTYPE_CURVE_START
,
3089 POINTTYPE_CURVE_END
,
3090 POINTTYPE_CURVE_MIDDLE
,
3096 enum pointtype corner
;
3099 /* is a dynamic_array */
3102 int count
, capacity
;
3103 struct point2d
*items
;
3106 /* is a dynamic_array */
3107 struct outline_array
3109 int count
, capacity
;
3110 struct outline
*items
;
3115 struct outline_array outlines
;
3119 static BOOL
reserve(struct dynamic_array
*array
, int count
, int itemsize
)
3121 if (count
> array
->capacity
) {
3124 if (array
->items
&& array
->capacity
) {
3125 new_capacity
= max(array
->capacity
* 2, count
);
3126 new_buffer
= HeapReAlloc(GetProcessHeap(), 0, array
->items
, new_capacity
* itemsize
);
3128 new_capacity
= max(16, count
);
3129 new_buffer
= HeapAlloc(GetProcessHeap(), 0, new_capacity
* itemsize
);
3133 array
->items
= new_buffer
;
3134 array
->capacity
= new_capacity
;
3139 static struct point2d
*add_point(struct outline
*array
)
3141 struct point2d
*item
;
3143 if (!reserve((struct dynamic_array
*)array
, array
->count
+ 1, sizeof(array
->items
[0])))
3146 item
= &array
->items
[array
->count
++];
3147 ZeroMemory(item
, sizeof(*item
));
3151 static struct outline
*add_outline(struct outline_array
*array
)
3153 struct outline
*item
;
3155 if (!reserve((struct dynamic_array
*)array
, array
->count
+ 1, sizeof(array
->items
[0])))
3158 item
= &array
->items
[array
->count
++];
3159 ZeroMemory(item
, sizeof(*item
));
3163 static inline D3DXVECTOR2
*convert_fixed_to_float(POINTFX
*pt
, int count
, float emsquare
)
3165 D3DXVECTOR2
*ret
= (D3DXVECTOR2
*)pt
;
3167 D3DXVECTOR2
*pt_flt
= (D3DXVECTOR2
*)pt
;
3168 pt_flt
->x
= (pt
->x
.value
+ pt
->x
.fract
/ (float)0x10000) / emsquare
;
3169 pt_flt
->y
= (pt
->y
.value
+ pt
->y
.fract
/ (float)0x10000) / emsquare
;
3175 static HRESULT
add_bezier_points(struct outline
*outline
, const D3DXVECTOR2
*p1
,
3176 const D3DXVECTOR2
*p2
, const D3DXVECTOR2
*p3
,
3177 float max_deviation
)
3179 D3DXVECTOR2 split1
= {0, 0}, split2
= {0, 0}, middle
, vec
;
3182 D3DXVec2Scale(&split1
, D3DXVec2Add(&split1
, p1
, p2
), 0.5f
);
3183 D3DXVec2Scale(&split2
, D3DXVec2Add(&split2
, p2
, p3
), 0.5f
);
3184 D3DXVec2Scale(&middle
, D3DXVec2Add(&middle
, &split1
, &split2
), 0.5f
);
3186 deviation
= D3DXVec2Length(D3DXVec2Subtract(&vec
, &middle
, p2
));
3187 if (deviation
< max_deviation
) {
3188 struct point2d
*pt
= add_point(outline
);
3189 if (!pt
) return E_OUTOFMEMORY
;
3191 pt
->corner
= POINTTYPE_CURVE
;
3192 /* the end point is omitted because the end line merges into the next segment of
3193 * the split bezier curve, and the end of the split bezier curve is added outside
3194 * this recursive function. */
3196 HRESULT hr
= add_bezier_points(outline
, p1
, &split1
, &middle
, max_deviation
);
3197 if (hr
!= S_OK
) return hr
;
3198 hr
= add_bezier_points(outline
, &middle
, &split2
, p3
, max_deviation
);
3199 if (hr
!= S_OK
) return hr
;
3205 static inline BOOL
is_direction_similar(D3DXVECTOR2
*dir1
, D3DXVECTOR2
*dir2
, float cos_theta
)
3207 /* dot product = cos(theta) */
3208 return D3DXVec2Dot(dir1
, dir2
) > cos_theta
;
3211 static inline D3DXVECTOR2
*unit_vec2(D3DXVECTOR2
*dir
, const D3DXVECTOR2
*pt1
, const D3DXVECTOR2
*pt2
)
3213 return D3DXVec2Normalize(D3DXVec2Subtract(dir
, pt2
, pt1
), dir
);
3216 static BOOL
attempt_line_merge(struct outline
*outline
,
3218 const D3DXVECTOR2
*nextpt
,
3221 D3DXVECTOR2 curdir
, lastdir
;
3222 struct point2d
*prevpt
, *pt
;
3224 const float cos_half
= cos(D3DXToRadian(0.5f
));
3226 pt
= &outline
->items
[pt_index
];
3227 pt_index
= (pt_index
- 1 + outline
->count
) % outline
->count
;
3228 prevpt
= &outline
->items
[pt_index
];
3231 pt
->corner
= pt
->corner
!= POINTTYPE_CORNER
? POINTTYPE_CURVE_MIDDLE
: POINTTYPE_CURVE_START
;
3233 if (outline
->count
< 2)
3236 /* remove last point if the next line continues the last line */
3237 unit_vec2(&lastdir
, &prevpt
->pos
, &pt
->pos
);
3238 unit_vec2(&curdir
, &pt
->pos
, nextpt
);
3239 if (is_direction_similar(&lastdir
, &curdir
, cos_half
))
3242 if (pt
->corner
== POINTTYPE_CURVE_END
)
3243 prevpt
->corner
= pt
->corner
;
3244 if (prevpt
->corner
== POINTTYPE_CURVE_END
&& to_curve
)
3245 prevpt
->corner
= POINTTYPE_CURVE_MIDDLE
;
3249 if (outline
->count
< 2)
3252 pt_index
= (pt_index
- 1 + outline
->count
) % outline
->count
;
3253 prevpt
= &outline
->items
[pt_index
];
3254 unit_vec2(&lastdir
, &prevpt
->pos
, &pt
->pos
);
3255 unit_vec2(&curdir
, &pt
->pos
, nextpt
);
3260 static HRESULT
create_outline(struct glyphinfo
*glyph
, void *raw_outline
, int datasize
,
3261 float max_deviation
, float emsquare
)
3263 const float cos_45
= cos(D3DXToRadian(45.0f
));
3264 const float cos_90
= cos(D3DXToRadian(90.0f
));
3265 TTPOLYGONHEADER
*header
= (TTPOLYGONHEADER
*)raw_outline
;
3267 while ((char *)header
< (char *)raw_outline
+ datasize
)
3269 TTPOLYCURVE
*curve
= (TTPOLYCURVE
*)(header
+ 1);
3270 struct point2d
*lastpt
, *pt
;
3271 D3DXVECTOR2 lastdir
;
3272 D3DXVECTOR2
*pt_flt
;
3274 struct outline
*outline
= add_outline(&glyph
->outlines
);
3277 return E_OUTOFMEMORY
;
3279 pt
= add_point(outline
);
3281 return E_OUTOFMEMORY
;
3282 pt_flt
= convert_fixed_to_float(&header
->pfxStart
, 1, emsquare
);
3284 pt
->corner
= POINTTYPE_CORNER
;
3286 if (header
->dwType
!= TT_POLYGON_TYPE
)
3287 trace("Unknown header type %d\n", header
->dwType
);
3289 while ((char *)curve
< (char *)header
+ header
->cb
)
3291 D3DXVECTOR2 bezier_start
= outline
->items
[outline
->count
- 1].pos
;
3292 BOOL to_curve
= curve
->wType
!= TT_PRIM_LINE
&& curve
->cpfx
> 1;
3295 curve
= (TTPOLYCURVE
*)&curve
->apfx
[curve
->cpfx
];
3299 pt_flt
= convert_fixed_to_float(curve
->apfx
, curve
->cpfx
, emsquare
);
3301 attempt_line_merge(outline
, outline
->count
- 1, &pt_flt
[0], to_curve
);
3306 int count
= curve
->cpfx
;
3311 D3DXVECTOR2 bezier_end
;
3313 D3DXVec2Scale(&bezier_end
, D3DXVec2Add(&bezier_end
, &pt_flt
[j
], &pt_flt
[j
+1]), 0.5f
);
3314 hr
= add_bezier_points(outline
, &bezier_start
, &pt_flt
[j
], &bezier_end
, max_deviation
);
3317 bezier_start
= bezier_end
;
3321 hr
= add_bezier_points(outline
, &bezier_start
, &pt_flt
[j
], &pt_flt
[j
+1], max_deviation
);
3325 pt
= add_point(outline
);
3327 return E_OUTOFMEMORY
;
3329 pt
->pos
= pt_flt
[j
];
3330 pt
->corner
= POINTTYPE_CURVE_END
;
3332 for (j
= 0; j
< curve
->cpfx
; j
++)
3334 pt
= add_point(outline
);
3336 return E_OUTOFMEMORY
;
3337 pt
->pos
= pt_flt
[j
];
3338 pt
->corner
= POINTTYPE_CORNER
;
3342 curve
= (TTPOLYCURVE
*)&curve
->apfx
[curve
->cpfx
];
3345 /* remove last point if the next line continues the last line */
3346 if (outline
->count
>= 3) {
3349 lastpt
= &outline
->items
[outline
->count
- 1];
3350 pt
= &outline
->items
[0];
3351 if (pt
->pos
.x
== lastpt
->pos
.x
&& pt
->pos
.y
== lastpt
->pos
.y
) {
3352 if (lastpt
->corner
== POINTTYPE_CURVE_END
)
3354 if (pt
->corner
== POINTTYPE_CURVE_START
)
3355 pt
->corner
= POINTTYPE_CURVE_MIDDLE
;
3357 pt
->corner
= POINTTYPE_CURVE_END
;
3360 lastpt
= &outline
->items
[outline
->count
- 1];
3362 /* outline closed with a line from end to start point */
3363 attempt_line_merge(outline
, outline
->count
- 1, &pt
->pos
, FALSE
);
3365 lastpt
= &outline
->items
[0];
3366 to_curve
= lastpt
->corner
!= POINTTYPE_CORNER
&& lastpt
->corner
!= POINTTYPE_CURVE_END
;
3367 if (lastpt
->corner
== POINTTYPE_CURVE_START
)
3368 lastpt
->corner
= POINTTYPE_CORNER
;
3369 pt
= &outline
->items
[1];
3370 if (attempt_line_merge(outline
, 0, &pt
->pos
, to_curve
))
3371 *lastpt
= outline
->items
[outline
->count
];
3374 lastpt
= &outline
->items
[outline
->count
- 1];
3375 pt
= &outline
->items
[0];
3376 unit_vec2(&lastdir
, &lastpt
->pos
, &pt
->pos
);
3377 for (j
= 0; j
< outline
->count
; j
++)
3382 pt
= &outline
->items
[(j
+ 1) % outline
->count
];
3383 unit_vec2(&curdir
, &lastpt
->pos
, &pt
->pos
);
3385 switch (lastpt
->corner
)
3387 case POINTTYPE_CURVE_START
:
3388 case POINTTYPE_CURVE_END
:
3389 if (!is_direction_similar(&lastdir
, &curdir
, cos_45
))
3390 lastpt
->corner
= POINTTYPE_CORNER
;
3392 case POINTTYPE_CURVE_MIDDLE
:
3393 if (!is_direction_similar(&lastdir
, &curdir
, cos_90
))
3394 lastpt
->corner
= POINTTYPE_CORNER
;
3396 lastpt
->corner
= POINTTYPE_CURVE
;
3404 header
= (TTPOLYGONHEADER
*)((char *)header
+ header
->cb
);
3409 static BOOL
compute_text_mesh(struct mesh
*mesh
, HDC hdc
, const char *text
,
3410 float deviation
, float extrusion
, float otmEMSquare
)
3412 HRESULT hr
= E_FAIL
;
3413 DWORD nb_vertices
, nb_faces
;
3414 DWORD nb_corners
, nb_outline_points
;
3417 char *raw_outline
= NULL
;
3418 struct glyphinfo
*glyphs
= NULL
;
3421 struct vertex
*vertex_ptr
;
3424 if (deviation
== 0.0f
)
3425 deviation
= 1.0f
/ otmEMSquare
;
3427 textlen
= strlen(text
);
3428 glyphs
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, textlen
* sizeof(*glyphs
));
3435 for (i
= 0; i
< textlen
; i
++)
3437 /* get outline points from data returned from GetGlyphOutline */
3438 const MAT2 identity
= {{0, 1}, {0, 0}, {0, 0}, {0, 1}};
3441 glyphs
[i
].offset_x
= offset_x
;
3443 datasize
= GetGlyphOutlineA(hdc
, text
[i
], GGO_NATIVE
, &gm
, 0, NULL
, &identity
);
3448 HeapFree(GetProcessHeap(), 0, raw_outline
);
3449 raw_outline
= HeapAlloc(GetProcessHeap(), 0, datasize
);
3454 datasize
= GetGlyphOutlineA(hdc
, text
[i
], GGO_NATIVE
, &gm
, datasize
, raw_outline
, &identity
);
3456 create_outline(&glyphs
[i
], raw_outline
, datasize
, deviation
, otmEMSquare
);
3458 offset_x
+= gm
.gmCellIncX
/ (float)otmEMSquare
;
3461 /* corner points need an extra vertex for the different side faces normals */
3463 nb_outline_points
= 0;
3464 for (i
= 0; i
< textlen
; i
++)
3467 for (j
= 0; j
< glyphs
[i
].outlines
.count
; j
++)
3470 struct outline
*outline
= &glyphs
[i
].outlines
.items
[j
];
3471 nb_outline_points
+= outline
->count
;
3472 nb_corners
++; /* first outline point always repeated as a corner */
3473 for (k
= 1; k
< outline
->count
; k
++)
3474 if (outline
->items
[k
].corner
)
3479 nb_vertices
= (nb_outline_points
+ nb_corners
) * 2 + textlen
;
3480 nb_faces
= nb_outline_points
* 2;
3482 if (!new_mesh(mesh
, nb_vertices
, nb_faces
))
3485 /* convert 2D vertices and faces into 3D mesh */
3486 vertex_ptr
= mesh
->vertices
;
3487 face_ptr
= mesh
->faces
;
3488 for (i
= 0; i
< textlen
; i
++)
3492 /* side vertices and faces */
3493 for (j
= 0; j
< glyphs
[i
].outlines
.count
; j
++)
3495 struct vertex
*outline_vertices
= vertex_ptr
;
3496 struct outline
*outline
= &glyphs
[i
].outlines
.items
[j
];
3498 struct point2d
*prevpt
= &outline
->items
[outline
->count
- 1];
3499 struct point2d
*pt
= &outline
->items
[0];
3501 for (k
= 1; k
<= outline
->count
; k
++)
3504 struct point2d
*nextpt
= &outline
->items
[k
% outline
->count
];
3505 WORD vtx_idx
= vertex_ptr
- mesh
->vertices
;
3508 if (pt
->corner
== POINTTYPE_CURVE_START
)
3509 D3DXVec2Subtract(&vec
, &pt
->pos
, &prevpt
->pos
);
3510 else if (pt
->corner
)
3511 D3DXVec2Subtract(&vec
, &nextpt
->pos
, &pt
->pos
);
3513 D3DXVec2Subtract(&vec
, &nextpt
->pos
, &prevpt
->pos
);
3514 D3DXVec2Normalize(&vec
, &vec
);
3515 vtx
.normal
.x
= -vec
.y
;
3516 vtx
.normal
.y
= vec
.x
;
3519 vtx
.position
.x
= pt
->pos
.x
+ glyphs
[i
].offset_x
;
3520 vtx
.position
.y
= pt
->pos
.y
;
3522 *vertex_ptr
++ = vtx
;
3524 vtx
.position
.z
= -extrusion
;
3525 *vertex_ptr
++ = vtx
;
3527 vtx
.position
.x
= nextpt
->pos
.x
+ glyphs
[i
].offset_x
;
3528 vtx
.position
.y
= nextpt
->pos
.y
;
3529 if (pt
->corner
&& nextpt
->corner
&& nextpt
->corner
!= POINTTYPE_CURVE_END
) {
3530 vtx
.position
.z
= -extrusion
;
3531 *vertex_ptr
++ = vtx
;
3533 *vertex_ptr
++ = vtx
;
3535 (*face_ptr
)[0] = vtx_idx
;
3536 (*face_ptr
)[1] = vtx_idx
+ 2;
3537 (*face_ptr
)[2] = vtx_idx
+ 1;
3540 (*face_ptr
)[0] = vtx_idx
;
3541 (*face_ptr
)[1] = vtx_idx
+ 3;
3542 (*face_ptr
)[2] = vtx_idx
+ 2;
3545 if (nextpt
->corner
) {
3546 if (nextpt
->corner
== POINTTYPE_CURVE_END
) {
3547 struct point2d
*nextpt2
= &outline
->items
[(k
+ 1) % outline
->count
];
3548 D3DXVec2Subtract(&vec
, &nextpt2
->pos
, &nextpt
->pos
);
3550 D3DXVec2Subtract(&vec
, &nextpt
->pos
, &pt
->pos
);
3552 D3DXVec2Normalize(&vec
, &vec
);
3553 vtx
.normal
.x
= -vec
.y
;
3554 vtx
.normal
.y
= vec
.x
;
3557 *vertex_ptr
++ = vtx
;
3558 vtx
.position
.z
= -extrusion
;
3559 *vertex_ptr
++ = vtx
;
3562 (*face_ptr
)[0] = vtx_idx
;
3563 (*face_ptr
)[1] = vtx_idx
+ 3;
3564 (*face_ptr
)[2] = vtx_idx
+ 1;
3567 (*face_ptr
)[0] = vtx_idx
;
3568 (*face_ptr
)[1] = vtx_idx
+ 2;
3569 (*face_ptr
)[2] = vtx_idx
+ 3;
3577 *vertex_ptr
++ = *outline_vertices
++;
3578 *vertex_ptr
++ = *outline_vertices
++;
3582 /* FIXME: compute expected faces */
3583 /* Add placeholder to separate glyph outlines */
3584 vertex_ptr
->position
.x
= 0;
3585 vertex_ptr
->position
.y
= 0;
3586 vertex_ptr
->position
.z
= 0;
3587 vertex_ptr
->normal
.x
= 0;
3588 vertex_ptr
->normal
.y
= 0;
3589 vertex_ptr
->normal
.z
= 1;
3596 for (i
= 0; i
< textlen
; i
++)
3599 for (j
= 0; j
< glyphs
[i
].outlines
.count
; j
++)
3600 HeapFree(GetProcessHeap(), 0, glyphs
[i
].outlines
.items
[j
].items
);
3601 HeapFree(GetProcessHeap(), 0, glyphs
[i
].outlines
.items
);
3603 HeapFree(GetProcessHeap(), 0, glyphs
);
3605 HeapFree(GetProcessHeap(), 0, raw_outline
);
3607 return hr
== D3D_OK
;
3610 static void compare_text_outline_mesh(const char *name
, ID3DXMesh
*d3dxmesh
, struct mesh
*mesh
, int textlen
, float extrusion
)
3613 DWORD number_of_vertices
, number_of_faces
;
3614 IDirect3DVertexBuffer9
*vertex_buffer
= NULL
;
3615 IDirect3DIndexBuffer9
*index_buffer
= NULL
;
3616 D3DVERTEXBUFFER_DESC vertex_buffer_description
;
3617 D3DINDEXBUFFER_DESC index_buffer_description
;
3618 struct vertex
*vertices
= NULL
;
3621 int vtx_idx1
, face_idx1
, vtx_idx2
, face_idx2
;
3623 number_of_vertices
= d3dxmesh
->lpVtbl
->GetNumVertices(d3dxmesh
);
3624 number_of_faces
= d3dxmesh
->lpVtbl
->GetNumFaces(d3dxmesh
);
3627 hr
= d3dxmesh
->lpVtbl
->GetVertexBuffer(d3dxmesh
, &vertex_buffer
);
3628 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
3631 skip("Couldn't get vertex buffers\n");
3635 hr
= IDirect3DVertexBuffer9_GetDesc(vertex_buffer
, &vertex_buffer_description
);
3636 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
3640 skip("Couldn't get vertex buffer description\n");
3644 ok(vertex_buffer_description
.Format
== D3DFMT_VERTEXDATA
, "Test %s, result %x, expected %x (D3DFMT_VERTEXDATA)\n",
3645 name
, vertex_buffer_description
.Format
, D3DFMT_VERTEXDATA
);
3646 ok(vertex_buffer_description
.Type
== D3DRTYPE_VERTEXBUFFER
, "Test %s, result %x, expected %x (D3DRTYPE_VERTEXBUFFER)\n",
3647 name
, vertex_buffer_description
.Type
, D3DRTYPE_VERTEXBUFFER
);
3648 ok(vertex_buffer_description
.Usage
== 0, "Test %s, result %x, expected %x\n", name
, vertex_buffer_description
.Usage
, 0);
3649 ok(vertex_buffer_description
.Pool
== D3DPOOL_MANAGED
, "Test %s, result %x, expected %x (D3DPOOL_MANAGED)\n",
3650 name
, vertex_buffer_description
.Pool
, D3DPOOL_MANAGED
);
3651 ok(vertex_buffer_description
.FVF
== mesh
->fvf
, "Test %s, result %x, expected %x\n",
3652 name
, vertex_buffer_description
.FVF
, mesh
->fvf
);
3655 expected
= number_of_vertices
* mesh
->vertex_size
;
3659 expected
= number_of_vertices
* D3DXGetFVFVertexSize(mesh
->fvf
);
3661 ok(vertex_buffer_description
.Size
== expected
, "Test %s, result %x, expected %x\n",
3662 name
, vertex_buffer_description
.Size
, expected
);
3665 hr
= d3dxmesh
->lpVtbl
->GetIndexBuffer(d3dxmesh
, &index_buffer
);
3666 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
3669 skip("Couldn't get index buffer\n");
3673 hr
= IDirect3DIndexBuffer9_GetDesc(index_buffer
, &index_buffer_description
);
3674 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
3678 skip("Couldn't get index buffer description\n");
3682 ok(index_buffer_description
.Format
== D3DFMT_INDEX16
, "Test %s, result %x, expected %x (D3DFMT_INDEX16)\n",
3683 name
, index_buffer_description
.Format
, D3DFMT_INDEX16
);
3684 ok(index_buffer_description
.Type
== D3DRTYPE_INDEXBUFFER
, "Test %s, result %x, expected %x (D3DRTYPE_INDEXBUFFER)\n",
3685 name
, index_buffer_description
.Type
, D3DRTYPE_INDEXBUFFER
);
3686 ok(index_buffer_description
.Usage
== 0, "Test %s, result %#x, expected %#x.\n",
3687 name
, index_buffer_description
.Usage
, 0);
3688 ok(index_buffer_description
.Pool
== D3DPOOL_MANAGED
, "Test %s, result %x, expected %x (D3DPOOL_MANAGED)\n",
3689 name
, index_buffer_description
.Pool
, D3DPOOL_MANAGED
);
3690 expected
= number_of_faces
* sizeof(WORD
) * 3;
3691 ok(index_buffer_description
.Size
== expected
, "Test %s, result %x, expected %x\n",
3692 name
, index_buffer_description
.Size
, expected
);
3695 /* specify offset and size to avoid potential overruns */
3696 hr
= IDirect3DVertexBuffer9_Lock(vertex_buffer
, 0, number_of_vertices
* sizeof(D3DXVECTOR3
) * 2,
3697 (void **)&vertices
, D3DLOCK_DISCARD
);
3698 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
3701 skip("Couldn't lock vertex buffer\n");
3704 hr
= IDirect3DIndexBuffer9_Lock(index_buffer
, 0, number_of_faces
* sizeof(WORD
) * 3,
3705 (void **)&faces
, D3DLOCK_DISCARD
);
3706 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
3709 skip("Couldn't lock index buffer\n");
3717 for (i
= 0; i
< textlen
; i
++)
3719 int nb_outline_vertices1
, nb_outline_faces1
;
3720 int nb_outline_vertices2
, nb_outline_faces2
;
3721 int nb_back_vertices
, nb_back_faces
;
3722 int first_vtx1
, first_vtx2
;
3723 int first_face1
, first_face2
;
3726 first_vtx1
= vtx_idx1
;
3727 first_vtx2
= vtx_idx2
;
3728 for (; vtx_idx1
< number_of_vertices
; vtx_idx1
++) {
3729 if (vertices
[vtx_idx1
].normal
.z
!= 0)
3732 for (; vtx_idx2
< mesh
->number_of_vertices
; vtx_idx2
++) {
3733 if (mesh
->vertices
[vtx_idx2
].normal
.z
!= 0)
3736 nb_outline_vertices1
= vtx_idx1
- first_vtx1
;
3737 nb_outline_vertices2
= vtx_idx2
- first_vtx2
;
3738 ok(nb_outline_vertices1
== nb_outline_vertices2
,
3739 "Test %s, glyph %d, outline vertex count result %d, expected %d\n", name
, i
,
3740 nb_outline_vertices1
, nb_outline_vertices2
);
3742 for (j
= 0; j
< min(nb_outline_vertices1
, nb_outline_vertices2
); j
++)
3744 vtx_idx1
= first_vtx1
+ j
;
3745 vtx_idx2
= first_vtx2
+ j
;
3746 ok(compare_vec3(vertices
[vtx_idx1
].position
, mesh
->vertices
[vtx_idx2
].position
),
3747 "Test %s, glyph %d, vertex position %d, result (%g, %g, %g), expected (%g, %g, %g)\n", name
, i
, vtx_idx1
,
3748 vertices
[vtx_idx1
].position
.x
, vertices
[vtx_idx1
].position
.y
, vertices
[vtx_idx1
].position
.z
,
3749 mesh
->vertices
[vtx_idx2
].position
.x
, mesh
->vertices
[vtx_idx2
].position
.y
, mesh
->vertices
[vtx_idx2
].position
.z
);
3750 ok(compare_vec3(vertices
[vtx_idx1
].normal
, mesh
->vertices
[first_vtx2
+ j
].normal
),
3751 "Test %s, glyph %d, vertex normal %d, result (%g, %g, %g), expected (%g, %g, %g)\n", name
, i
, vtx_idx1
,
3752 vertices
[vtx_idx1
].normal
.x
, vertices
[vtx_idx1
].normal
.y
, vertices
[vtx_idx1
].normal
.z
,
3753 mesh
->vertices
[vtx_idx2
].normal
.x
, mesh
->vertices
[vtx_idx2
].normal
.y
, mesh
->vertices
[vtx_idx2
].normal
.z
);
3755 vtx_idx1
= first_vtx1
+ nb_outline_vertices1
;
3756 vtx_idx2
= first_vtx2
+ nb_outline_vertices2
;
3758 first_face1
= face_idx1
;
3759 first_face2
= face_idx2
;
3760 for (; face_idx1
< number_of_faces
; face_idx1
++)
3762 if (faces
[face_idx1
][0] >= vtx_idx1
||
3763 faces
[face_idx1
][1] >= vtx_idx1
||
3764 faces
[face_idx1
][2] >= vtx_idx1
)
3767 for (; face_idx2
< mesh
->number_of_faces
; face_idx2
++)
3769 if (mesh
->faces
[face_idx2
][0] >= vtx_idx2
||
3770 mesh
->faces
[face_idx2
][1] >= vtx_idx2
||
3771 mesh
->faces
[face_idx2
][2] >= vtx_idx2
)
3774 nb_outline_faces1
= face_idx1
- first_face1
;
3775 nb_outline_faces2
= face_idx2
- first_face2
;
3776 ok(nb_outline_faces1
== nb_outline_faces2
,
3777 "Test %s, glyph %d, outline face count result %d, expected %d\n", name
, i
,
3778 nb_outline_faces1
, nb_outline_faces2
);
3780 for (j
= 0; j
< min(nb_outline_faces1
, nb_outline_faces2
); j
++)
3782 face_idx1
= first_face1
+ j
;
3783 face_idx2
= first_face2
+ j
;
3784 ok(faces
[face_idx1
][0] - first_vtx1
== mesh
->faces
[face_idx2
][0] - first_vtx2
&&
3785 faces
[face_idx1
][1] - first_vtx1
== mesh
->faces
[face_idx2
][1] - first_vtx2
&&
3786 faces
[face_idx1
][2] - first_vtx1
== mesh
->faces
[face_idx2
][2] - first_vtx2
,
3787 "Test %s, glyph %d, face %d, result (%d, %d, %d), expected (%d, %d, %d)\n", name
, i
, face_idx1
,
3788 faces
[face_idx1
][0], faces
[face_idx1
][1], faces
[face_idx1
][2],
3789 mesh
->faces
[face_idx2
][0] - first_vtx2
+ first_vtx1
,
3790 mesh
->faces
[face_idx2
][1] - first_vtx2
+ first_vtx1
,
3791 mesh
->faces
[face_idx2
][2] - first_vtx2
+ first_vtx1
);
3793 face_idx1
= first_face1
+ nb_outline_faces1
;
3794 face_idx2
= first_face2
+ nb_outline_faces2
;
3796 /* partial test on back vertices and faces */
3797 first_vtx1
= vtx_idx1
;
3798 for (; vtx_idx1
< number_of_vertices
; vtx_idx1
++) {
3801 if (vertices
[vtx_idx1
].normal
.z
!= 1.0f
)
3804 vtx
.position
.z
= 0.0f
;
3805 vtx
.normal
.x
= 0.0f
;
3806 vtx
.normal
.y
= 0.0f
;
3807 vtx
.normal
.z
= 1.0f
;
3808 ok(compare(vertices
[vtx_idx1
].position
.z
, vtx
.position
.z
),
3809 "Test %s, glyph %d, vertex position.z %d, result %g, expected %g\n", name
, i
, vtx_idx1
,
3810 vertices
[vtx_idx1
].position
.z
, vtx
.position
.z
);
3811 ok(compare_vec3(vertices
[vtx_idx1
].normal
, vtx
.normal
),
3812 "Test %s, glyph %d, vertex normal %d, result (%g, %g, %g), expected (%g, %g, %g)\n", name
, i
, vtx_idx1
,
3813 vertices
[vtx_idx1
].normal
.x
, vertices
[vtx_idx1
].normal
.y
, vertices
[vtx_idx1
].normal
.z
,
3814 vtx
.normal
.x
, vtx
.normal
.y
, vtx
.normal
.z
);
3816 nb_back_vertices
= vtx_idx1
- first_vtx1
;
3817 first_face1
= face_idx1
;
3818 for (; face_idx1
< number_of_faces
; face_idx1
++)
3820 const D3DXVECTOR3
*vtx1
, *vtx2
, *vtx3
;
3822 D3DXVECTOR3 v1
= {0, 0, 0};
3823 D3DXVECTOR3 v2
= {0, 0, 0};
3824 D3DXVECTOR3 forward
= {0.0f
, 0.0f
, 1.0f
};
3826 if (faces
[face_idx1
][0] >= vtx_idx1
||
3827 faces
[face_idx1
][1] >= vtx_idx1
||
3828 faces
[face_idx1
][2] >= vtx_idx1
)
3831 vtx1
= &vertices
[faces
[face_idx1
][0]].position
;
3832 vtx2
= &vertices
[faces
[face_idx1
][1]].position
;
3833 vtx3
= &vertices
[faces
[face_idx1
][2]].position
;
3835 D3DXVec3Subtract(&v1
, vtx2
, vtx1
);
3836 D3DXVec3Subtract(&v2
, vtx3
, vtx2
);
3837 D3DXVec3Cross(&normal
, &v1
, &v2
);
3838 D3DXVec3Normalize(&normal
, &normal
);
3839 ok(!D3DXVec3Length(&normal
) || compare_vec3(normal
, forward
),
3840 "Test %s, glyph %d, face %d normal, result (%g, %g, %g), expected (%g, %g, %g)\n", name
, i
, face_idx1
,
3841 normal
.x
, normal
.y
, normal
.z
, forward
.x
, forward
.y
, forward
.z
);
3843 nb_back_faces
= face_idx1
- first_face1
;
3845 /* compare front and back faces & vertices */
3846 if (extrusion
== 0.0f
) {
3847 /* Oddly there are only back faces in this case */
3848 nb_back_vertices
/= 2;
3850 face_idx1
-= nb_back_faces
;
3851 vtx_idx1
-= nb_back_vertices
;
3853 for (j
= 0; j
< nb_back_vertices
; j
++)
3855 struct vertex vtx
= vertices
[first_vtx1
];
3856 vtx
.position
.z
= -extrusion
;
3857 vtx
.normal
.x
= 0.0f
;
3858 vtx
.normal
.y
= 0.0f
;
3859 vtx
.normal
.z
= extrusion
== 0.0f
? 1.0f
: -1.0f
;
3860 ok(compare_vec3(vertices
[vtx_idx1
].position
, vtx
.position
),
3861 "Test %s, glyph %d, vertex position %d, result (%g, %g, %g), expected (%g, %g, %g)\n", name
, i
, vtx_idx1
,
3862 vertices
[vtx_idx1
].position
.x
, vertices
[vtx_idx1
].position
.y
, vertices
[vtx_idx1
].position
.z
,
3863 vtx
.position
.x
, vtx
.position
.y
, vtx
.position
.z
);
3864 ok(compare_vec3(vertices
[vtx_idx1
].normal
, vtx
.normal
),
3865 "Test %s, glyph %d, vertex normal %d, result (%g, %g, %g), expected (%g, %g, %g)\n", name
, i
, vtx_idx1
,
3866 vertices
[vtx_idx1
].normal
.x
, vertices
[vtx_idx1
].normal
.y
, vertices
[vtx_idx1
].normal
.z
,
3867 vtx
.normal
.x
, vtx
.normal
.y
, vtx
.normal
.z
);
3871 for (j
= 0; j
< nb_back_faces
; j
++)
3874 if (extrusion
== 0.0f
) {
3881 ok(faces
[face_idx1
][0] == faces
[first_face1
][0] + nb_back_vertices
&&
3882 faces
[face_idx1
][1] == faces
[first_face1
][f1
] + nb_back_vertices
&&
3883 faces
[face_idx1
][2] == faces
[first_face1
][f2
] + nb_back_vertices
,
3884 "Test %s, glyph %d, face %d, result (%d, %d, %d), expected (%d, %d, %d)\n", name
, i
, face_idx1
,
3885 faces
[face_idx1
][0], faces
[face_idx1
][1], faces
[face_idx1
][2],
3886 faces
[first_face1
][0] - nb_back_faces
,
3887 faces
[first_face1
][f1
] - nb_back_faces
,
3888 faces
[first_face1
][f2
] - nb_back_faces
);
3893 /* skip to the outline for the next glyph */
3894 for (; vtx_idx2
< mesh
->number_of_vertices
; vtx_idx2
++) {
3895 if (mesh
->vertices
[vtx_idx2
].normal
.z
== 0)
3898 for (; face_idx2
< mesh
->number_of_faces
; face_idx2
++)
3900 if (mesh
->faces
[face_idx2
][0] >= vtx_idx2
||
3901 mesh
->faces
[face_idx2
][1] >= vtx_idx2
||
3902 mesh
->faces
[face_idx2
][2] >= vtx_idx2
) break;
3907 if (vertices
) IDirect3DVertexBuffer9_Unlock(vertex_buffer
);
3908 if (faces
) IDirect3DIndexBuffer9_Unlock(index_buffer
);
3909 if (index_buffer
) IDirect3DIndexBuffer9_Release(index_buffer
);
3910 if (vertex_buffer
) IDirect3DVertexBuffer9_Release(vertex_buffer
);
3913 static void test_createtext(IDirect3DDevice9
*device
, HDC hdc
, const char *text
, float deviation
, float extrusion
)
3916 ID3DXMesh
*d3dxmesh
;
3919 OUTLINETEXTMETRICA otm
;
3921 GLYPHMETRICSFLOAT
*glyphmetrics_float
= HeapAlloc(GetProcessHeap(), 0, sizeof(GLYPHMETRICSFLOAT
) * strlen(text
));
3924 HFONT font
= NULL
, oldfont
= NULL
;
3926 sprintf(name
, "text ('%s', %f, %f)", text
, deviation
, extrusion
);
3928 hr
= D3DXCreateTextA(device
, hdc
, text
, deviation
, extrusion
, &d3dxmesh
, NULL
, glyphmetrics_float
);
3929 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n", hr
);
3932 skip("Couldn't create text with D3DXCreateText\n");
3936 /* must select a modified font having lfHeight = otm.otmEMSquare before
3937 * calling GetGlyphOutline to get the expected values */
3938 if (!GetObjectA(GetCurrentObject(hdc
, OBJ_FONT
), sizeof(lf
), &lf
)
3939 || !GetOutlineTextMetricsA(hdc
, sizeof(otm
), &otm
))
3941 d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
3942 skip("Couldn't get text outline\n");
3945 lf
.lfHeight
= otm
.otmEMSquare
;
3947 if (!(font
= CreateFontIndirectA(&lf
)))
3949 d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
3950 skip("Couldn't create the modified font\n");
3953 oldfont
= SelectObject(hdc
, font
);
3955 for (i
= 0; i
< strlen(text
); i
++)
3957 const MAT2 identity
= {{0, 1}, {0, 0}, {0, 0}, {0, 1}};
3958 GetGlyphOutlineA(hdc
, text
[i
], GGO_NATIVE
, &gm
, 0, NULL
, &identity
);
3959 compare_float(glyphmetrics_float
[i
].gmfBlackBoxX
, gm
.gmBlackBoxX
/ (float)otm
.otmEMSquare
);
3960 compare_float(glyphmetrics_float
[i
].gmfBlackBoxY
, gm
.gmBlackBoxY
/ (float)otm
.otmEMSquare
);
3961 compare_float(glyphmetrics_float
[i
].gmfptGlyphOrigin
.x
, gm
.gmptGlyphOrigin
.x
/ (float)otm
.otmEMSquare
);
3962 compare_float(glyphmetrics_float
[i
].gmfptGlyphOrigin
.y
, gm
.gmptGlyphOrigin
.y
/ (float)otm
.otmEMSquare
);
3963 compare_float(glyphmetrics_float
[i
].gmfCellIncX
, gm
.gmCellIncX
/ (float)otm
.otmEMSquare
);
3964 compare_float(glyphmetrics_float
[i
].gmfCellIncY
, gm
.gmCellIncY
/ (float)otm
.otmEMSquare
);
3967 ZeroMemory(&mesh
, sizeof(mesh
));
3968 if (!compute_text_mesh(&mesh
, hdc
, text
, deviation
, extrusion
, otm
.otmEMSquare
))
3970 skip("Couldn't create mesh\n");
3971 d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
3974 mesh
.fvf
= D3DFVF_XYZ
| D3DFVF_NORMAL
;
3976 compare_text_outline_mesh(name
, d3dxmesh
, &mesh
, strlen(text
), extrusion
);
3980 d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
3981 SelectObject(hdc
, oldfont
);
3982 HeapFree(GetProcessHeap(), 0, glyphmetrics_float
);
3985 static void D3DXCreateTextTest(void)
3991 IDirect3DDevice9
* device
;
3992 D3DPRESENT_PARAMETERS d3dpp
;
3993 ID3DXMesh
* d3dxmesh
= NULL
;
3995 OUTLINETEXTMETRICA otm
;
3996 int number_of_vertices
;
3997 int number_of_faces
;
3999 if (!(wnd
= CreateWindowA("static", "d3dx9_test", WS_POPUP
, 0, 0, 1000, 1000, NULL
, NULL
, NULL
, NULL
)))
4001 skip("Couldn't create application window\n");
4004 if (!(d3d
= Direct3DCreate9(D3D_SDK_VERSION
)))
4006 skip("Couldn't create IDirect3D9 object\n");
4011 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
4012 d3dpp
.Windowed
= TRUE
;
4013 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
4014 hr
= IDirect3D9_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, wnd
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &device
);
4017 skip("Failed to create IDirect3DDevice9 object %#x\n", hr
);
4018 IDirect3D9_Release(d3d
);
4023 hdc
= CreateCompatibleDC(NULL
);
4025 hFont
= CreateFontA(12, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, DEFAULT_CHARSET
, OUT_DEFAULT_PRECIS
,
4026 CLIP_DEFAULT_PRECIS
, DEFAULT_QUALITY
, DEFAULT_PITCH
| FF_DONTCARE
, "Arial");
4027 SelectObject(hdc
, hFont
);
4028 GetOutlineTextMetricsA(hdc
, sizeof(otm
), &otm
);
4030 hr
= D3DXCreateTextA(device
, hdc
, "wine", 0.001f
, 0.4f
, NULL
, NULL
, NULL
);
4031 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
4033 /* D3DXCreateTextA page faults from passing NULL text */
4035 hr
= D3DXCreateTextW(device
, hdc
, NULL
, 0.001f
, 0.4f
, &d3dxmesh
, NULL
, NULL
);
4036 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
4038 hr
= D3DXCreateTextA(device
, hdc
, "", 0.001f
, 0.4f
, &d3dxmesh
, NULL
, NULL
);
4039 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
4041 hr
= D3DXCreateTextA(device
, hdc
, " ", 0.001f
, 0.4f
, &d3dxmesh
, NULL
, NULL
);
4042 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
4044 hr
= D3DXCreateTextA(NULL
, hdc
, "wine", 0.001f
, 0.4f
, &d3dxmesh
, NULL
, NULL
);
4045 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
4047 hr
= D3DXCreateTextA(device
, NULL
, "wine", 0.001f
, 0.4f
, &d3dxmesh
, NULL
, NULL
);
4048 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
4050 hr
= D3DXCreateTextA(device
, hdc
, "wine", -FLT_MIN
, 0.4f
, &d3dxmesh
, NULL
, NULL
);
4051 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
4053 hr
= D3DXCreateTextA(device
, hdc
, "wine", 0.001f
, -FLT_MIN
, &d3dxmesh
, NULL
, NULL
);
4054 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
4056 /* deviation = 0.0f treated as if deviation = 1.0f / otm.otmEMSquare */
4057 hr
= D3DXCreateTextA(device
, hdc
, "wine", 1.0f
/ otm
.otmEMSquare
, 0.4f
, &d3dxmesh
, NULL
, NULL
);
4058 ok(hr
== D3D_OK
, "Got result %x, expected %x (D3D_OK)\n", hr
, D3D_OK
);
4059 number_of_vertices
= d3dxmesh
->lpVtbl
->GetNumVertices(d3dxmesh
);
4060 number_of_faces
= d3dxmesh
->lpVtbl
->GetNumFaces(d3dxmesh
);
4061 if (SUCCEEDED(hr
) && d3dxmesh
) d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
4063 hr
= D3DXCreateTextA(device
, hdc
, "wine", 0.0f
, 0.4f
, &d3dxmesh
, NULL
, NULL
);
4064 ok(hr
== D3D_OK
, "Got result %x, expected %x (D3D_OK)\n", hr
, D3D_OK
);
4065 ok(number_of_vertices
== d3dxmesh
->lpVtbl
->GetNumVertices(d3dxmesh
),
4066 "Got %d vertices, expected %d\n",
4067 d3dxmesh
->lpVtbl
->GetNumVertices(d3dxmesh
), number_of_vertices
);
4068 ok(number_of_faces
== d3dxmesh
->lpVtbl
->GetNumFaces(d3dxmesh
),
4069 "Got %d faces, expected %d\n",
4070 d3dxmesh
->lpVtbl
->GetNumVertices(d3dxmesh
), number_of_faces
);
4071 if (SUCCEEDED(hr
) && d3dxmesh
) d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
4075 /* too much detail requested, so will appear to hang */
4076 trace("Waiting for D3DXCreateText to finish with deviation = FLT_MIN ...\n");
4077 hr
= D3DXCreateTextA(device
, hdc
, "wine", FLT_MIN
, 0.4f
, &d3dxmesh
, NULL
, NULL
);
4078 ok(hr
== D3D_OK
, "Got result %x, expected %x (D3D_OK)\n", hr
, D3D_OK
);
4079 if (SUCCEEDED(hr
) && d3dxmesh
) d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
4080 trace("D3DXCreateText finish with deviation = FLT_MIN\n");
4083 hr
= D3DXCreateTextA(device
, hdc
, "wine", 0.001f
, 0.4f
, &d3dxmesh
, NULL
, NULL
);
4084 ok(hr
== D3D_OK
, "Got result %x, expected %x (D3D_OK)\n", hr
, D3D_OK
);
4085 if (SUCCEEDED(hr
) && d3dxmesh
) d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
4087 test_createtext(device
, hdc
, "wine", FLT_MAX
, 0.4f
);
4088 test_createtext(device
, hdc
, "wine", 0.001f
, FLT_MIN
);
4089 test_createtext(device
, hdc
, "wine", 0.001f
, 0.0f
);
4090 test_createtext(device
, hdc
, "wine", 0.001f
, FLT_MAX
);
4091 test_createtext(device
, hdc
, "wine", 0.0f
, 1.0f
);
4095 IDirect3DDevice9_Release(device
);
4096 IDirect3D9_Release(d3d
);
4100 static void test_get_decl_length(void)
4102 static const D3DVERTEXELEMENT9 declaration1
[] =
4104 {0, 0, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4105 {1, 0, D3DDECLTYPE_FLOAT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4106 {2, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4107 {3, 0, D3DDECLTYPE_FLOAT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4108 {4, 0, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4109 {5, 0, D3DDECLTYPE_UBYTE4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4110 {6, 0, D3DDECLTYPE_SHORT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4111 {7, 0, D3DDECLTYPE_SHORT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4112 {8, 0, D3DDECLTYPE_UBYTE4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4113 {9, 0, D3DDECLTYPE_SHORT2N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4114 {10, 0, D3DDECLTYPE_SHORT4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4115 {11, 0, D3DDECLTYPE_UDEC3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4116 {12, 0, D3DDECLTYPE_DEC3N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4117 {13, 0, D3DDECLTYPE_FLOAT16_2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4118 {14, 0, D3DDECLTYPE_FLOAT16_4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4121 static const D3DVERTEXELEMENT9 declaration2
[] =
4123 {0, 8, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4124 {1, 8, D3DDECLTYPE_FLOAT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4125 {2, 8, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4126 {3, 8, D3DDECLTYPE_FLOAT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4127 {4, 8, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4128 {5, 8, D3DDECLTYPE_UBYTE4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4129 {6, 8, D3DDECLTYPE_SHORT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4130 {7, 8, D3DDECLTYPE_SHORT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4131 {0, 8, D3DDECLTYPE_UBYTE4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4132 {1, 8, D3DDECLTYPE_SHORT2N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4133 {2, 8, D3DDECLTYPE_SHORT4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4134 {3, 8, D3DDECLTYPE_UDEC3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4135 {4, 8, D3DDECLTYPE_DEC3N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4136 {5, 8, D3DDECLTYPE_FLOAT16_2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4137 {6, 8, D3DDECLTYPE_FLOAT16_4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4138 {7, 8, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4143 size
= D3DXGetDeclLength(declaration1
);
4144 ok(size
== 15, "Got size %u, expected 15.\n", size
);
4146 size
= D3DXGetDeclLength(declaration2
);
4147 ok(size
== 16, "Got size %u, expected 16.\n", size
);
4150 static void test_get_decl_vertex_size(void)
4152 static const D3DVERTEXELEMENT9 declaration1
[] =
4154 {0, 0, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4155 {1, 0, D3DDECLTYPE_FLOAT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4156 {2, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4157 {3, 0, D3DDECLTYPE_FLOAT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4158 {4, 0, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4159 {5, 0, D3DDECLTYPE_UBYTE4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4160 {6, 0, D3DDECLTYPE_SHORT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4161 {7, 0, D3DDECLTYPE_SHORT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4162 {8, 0, D3DDECLTYPE_UBYTE4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4163 {9, 0, D3DDECLTYPE_SHORT2N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4164 {10, 0, D3DDECLTYPE_SHORT4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4165 {11, 0, D3DDECLTYPE_UDEC3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4166 {12, 0, D3DDECLTYPE_DEC3N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4167 {13, 0, D3DDECLTYPE_FLOAT16_2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4168 {14, 0, D3DDECLTYPE_FLOAT16_4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4171 static const D3DVERTEXELEMENT9 declaration2
[] =
4173 {0, 8, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4174 {1, 8, D3DDECLTYPE_FLOAT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4175 {2, 8, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4176 {3, 8, D3DDECLTYPE_FLOAT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4177 {4, 8, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4178 {5, 8, D3DDECLTYPE_UBYTE4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4179 {6, 8, D3DDECLTYPE_SHORT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4180 {7, 8, D3DDECLTYPE_SHORT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4181 {0, 8, D3DDECLTYPE_UBYTE4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4182 {1, 8, D3DDECLTYPE_SHORT2N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4183 {2, 8, D3DDECLTYPE_SHORT4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4184 {3, 8, D3DDECLTYPE_UDEC3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4185 {4, 8, D3DDECLTYPE_DEC3N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4186 {5, 8, D3DDECLTYPE_FLOAT16_2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4187 {6, 8, D3DDECLTYPE_FLOAT16_4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4188 {7, 8, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4191 static const UINT sizes1
[] =
4198 static const UINT sizes2
[] =
4206 size
= D3DXGetDeclVertexSize(NULL
, 0);
4207 ok(size
== 0, "Got size %#x, expected 0.\n", size
);
4209 for (i
= 0; i
< 16; ++i
)
4211 size
= D3DXGetDeclVertexSize(declaration1
, i
);
4212 ok(size
== sizes1
[i
], "Got size %u for stream %u, expected %u.\n", size
, i
, sizes1
[i
]);
4215 for (i
= 0; i
< 8; ++i
)
4217 size
= D3DXGetDeclVertexSize(declaration2
, i
);
4218 ok(size
== sizes2
[i
], "Got size %u for stream %u, expected %u.\n", size
, i
, sizes2
[i
]);
4222 static void D3DXGenerateAdjacencyTest(void)
4227 IDirect3DDevice9
*device
;
4228 D3DPRESENT_PARAMETERS d3dpp
;
4229 ID3DXMesh
*d3dxmesh
= NULL
;
4230 D3DXVECTOR3
*vertices
= NULL
;
4231 WORD
*indices
= NULL
;
4235 D3DXVECTOR3 vertices
[6];
4237 WORD indices
[3 * 3];
4239 DWORD adjacency
[3 * 3];
4241 { /* for epsilon < 0, indices must match for faces to be adjacent */
4242 4, {{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 1.0, 0.0}},
4243 2, {0, 1, 2, 0, 2, 3},
4245 {-1, -1, 1, 0, -1, -1},
4248 6, {{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 1.0, 0.0}},
4249 2, {0, 1, 2, 3, 4, 5},
4251 {-1, -1, -1, -1, -1, -1},
4253 { /* for epsilon == 0, indices or vertices must match for faces to be adjacent */
4254 6, {{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 1.0, 0.0}},
4255 2, {0, 1, 2, 3, 4, 5},
4257 {-1, -1, 1, 0, -1, -1},
4259 { /* for epsilon > 0, vertices must be less than (but NOT equal to) epsilon distance away */
4260 6, {{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 0.0, 0.25}, {1.0, 1.0, 0.25}, {0.0, 1.0, 0.25}},
4261 2, {0, 1, 2, 3, 4, 5},
4263 {-1, -1, -1, -1, -1, -1},
4265 { /* for epsilon > 0, vertices must be less than (but NOT equal to) epsilon distance away */
4266 6, {{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 0.0, 0.25}, {1.0, 1.0, 0.25}, {0.0, 1.0, 0.25}},
4267 2, {0, 1, 2, 3, 4, 5},
4269 {-1, -1, 1, 0, -1, -1},
4271 { /* length between vertices are compared to epsilon, not the individual dimension deltas */
4272 6, {{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 0.25, 0.25}, {1.0, 1.25, 0.25}, {0.0, 1.25, 0.25}},
4273 2, {0, 1, 2, 3, 4, 5},
4274 0.353, /* < sqrt(0.25*0.25 + 0.25*0.25) */
4275 {-1, -1, -1, -1, -1, -1},
4278 6, {{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 0.25, 0.25}, {1.0, 1.25, 0.25}, {0.0, 1.25, 0.25}},
4279 2, {0, 1, 2, 3, 4, 5},
4280 0.354, /* > sqrt(0.25*0.25 + 0.25*0.25) */
4281 {-1, -1, 1, 0, -1, -1},
4283 { /* adjacent faces must have opposite winding orders at the shared edge */
4284 4, {{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 1.0, 0.0}},
4285 2, {0, 1, 2, 0, 3, 2},
4287 {-1, -1, -1, -1, -1, -1},
4291 if (!(wnd
= CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW
, 0, 0,
4292 640, 480, NULL
, NULL
, NULL
, NULL
)))
4294 skip("Couldn't create application window\n");
4297 d3d
= Direct3DCreate9(D3D_SDK_VERSION
);
4300 skip("Couldn't create IDirect3D9 object\n");
4305 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
4306 d3dpp
.Windowed
= TRUE
;
4307 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
4308 hr
= IDirect3D9_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, wnd
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &device
);
4311 skip("Failed to create IDirect3DDevice9 object %#x\n", hr
);
4312 IDirect3D9_Release(d3d
);
4317 for (i
= 0; i
< ARRAY_SIZE(test_data
); i
++)
4319 DWORD adjacency
[ARRAY_SIZE(test_data
[0].adjacency
)];
4322 if (d3dxmesh
) d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
4325 hr
= D3DXCreateMeshFVF(test_data
[i
].num_faces
, test_data
[i
].num_vertices
, 0, D3DFVF_XYZ
, device
, &d3dxmesh
);
4326 ok(hr
== D3D_OK
, "Got result %x, expected %x (D3D_OK)\n", hr
, D3D_OK
);
4328 hr
= d3dxmesh
->lpVtbl
->LockVertexBuffer(d3dxmesh
, D3DLOCK_DISCARD
, (void**)&vertices
);
4329 ok(hr
== D3D_OK
, "test %d: Got result %x, expected %x (D3D_OK)\n", i
, hr
, D3D_OK
);
4330 if (FAILED(hr
)) continue;
4331 CopyMemory(vertices
, test_data
[i
].vertices
, test_data
[i
].num_vertices
* sizeof(test_data
[0].vertices
[0]));
4332 d3dxmesh
->lpVtbl
->UnlockVertexBuffer(d3dxmesh
);
4334 hr
= d3dxmesh
->lpVtbl
->LockIndexBuffer(d3dxmesh
, D3DLOCK_DISCARD
, (void**)&indices
);
4335 ok(hr
== D3D_OK
, "test %d: Got result %x, expected %x (D3D_OK)\n", i
, hr
, D3D_OK
);
4336 if (FAILED(hr
)) continue;
4337 CopyMemory(indices
, test_data
[i
].indices
, test_data
[i
].num_faces
* 3 * sizeof(test_data
[0].indices
[0]));
4338 d3dxmesh
->lpVtbl
->UnlockIndexBuffer(d3dxmesh
);
4341 hr
= d3dxmesh
->lpVtbl
->GenerateAdjacency(d3dxmesh
, 0.0f
, NULL
);
4342 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
4345 hr
= d3dxmesh
->lpVtbl
->GenerateAdjacency(d3dxmesh
, test_data
[i
].epsilon
, adjacency
);
4346 ok(hr
== D3D_OK
, "Got result %x, expected %x (D3D_OK)\n", hr
, D3D_OK
);
4347 if (FAILED(hr
)) continue;
4349 for (j
= 0; j
< test_data
[i
].num_faces
* 3; j
++)
4350 ok(adjacency
[j
] == test_data
[i
].adjacency
[j
],
4351 "Test %d adjacency %d: Got result %u, expected %u\n", i
, j
,
4352 adjacency
[j
], test_data
[i
].adjacency
[j
]);
4354 if (d3dxmesh
) d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
4357 static void test_update_semantics(void)
4360 struct test_context
*test_context
= NULL
;
4361 ID3DXMesh
*mesh
= NULL
;
4362 D3DVERTEXELEMENT9 declaration0
[] =
4364 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4365 {0, 24, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
4366 {0, 36, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 0},
4369 D3DVERTEXELEMENT9 declaration_pos_type_color
[] =
4371 {0, 0, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4372 {0, 24, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
4373 {0, 36, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 0},
4376 D3DVERTEXELEMENT9 declaration_smaller
[] =
4378 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4379 {0, 24, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
4382 D3DVERTEXELEMENT9 declaration_larger
[] =
4384 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4385 {0, 24, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
4386 {0, 36, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 0},
4387 {0, 40, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TANGENT
, 0},
4390 D3DVERTEXELEMENT9 declaration_multiple_streams
[] =
4392 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4393 {1, 12, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TANGENT
, 0},
4394 {0, 24, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
4395 {0, 36, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 0},
4399 D3DVERTEXELEMENT9 declaration_double_usage
[] =
4401 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4402 {0, 12, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4403 {0, 24, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
4404 {0, 36, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 0},
4407 D3DVERTEXELEMENT9 declaration_undefined_type
[] =
4409 {0, 0, D3DDECLTYPE_UNUSED
+1, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4410 {0, 24, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
4411 {0, 36, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 0},
4414 D3DVERTEXELEMENT9 declaration_not_4_byte_aligned_offset
[] =
4416 {0, 3, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4417 {0, 24, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
4418 {0, 36, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 0},
4423 D3DXVECTOR3 position0
;
4424 D3DXVECTOR3 position1
;
4430 { { 0.0f
, 1.0f
, 0.f
}, { 1.0f
, 0.0f
, 0.f
}, {0.0f
, 0.0f
, 1.0f
}, 0xffff0000 },
4431 { { 1.0f
, -1.0f
, 0.f
}, {-1.0f
, -1.0f
, 0.f
}, {0.0f
, 0.0f
, 1.0f
}, 0xff00ff00 },
4432 { {-1.0f
, -1.0f
, 0.f
}, {-1.0f
, 1.0f
, 0.f
}, {0.0f
, 0.0f
, 1.0f
}, 0xff0000ff },
4434 unsigned int faces
[] = {0, 1, 2};
4435 unsigned int attributes
[] = {0};
4436 unsigned int num_faces
= ARRAY_SIZE(faces
) / 3;
4437 unsigned int num_vertices
= ARRAY_SIZE(vertices
);
4438 int offset
= sizeof(D3DXVECTOR3
);
4439 DWORD options
= D3DXMESH_32BIT
| D3DXMESH_SYSTEMMEM
;
4440 void *vertex_buffer
;
4442 DWORD
*attributes_buffer
;
4443 D3DVERTEXELEMENT9 declaration
[MAX_FVF_DECL_SIZE
];
4444 D3DVERTEXELEMENT9
*decl_ptr
;
4445 DWORD exp_vertex_size
= sizeof(*vertices
);
4446 DWORD vertex_size
= 0;
4450 int filler_a
= 0xaaaaaaaa;
4451 int filler_b
= 0xbbbbbbbb;
4453 test_context
= new_test_context();
4456 skip("Couldn't create a test_context\n");
4460 hr
= D3DXCreateMesh(num_faces
, num_vertices
, options
, declaration0
,
4461 test_context
->device
, &mesh
);
4464 skip("Couldn't create test mesh %#x\n", hr
);
4468 mesh
->lpVtbl
->LockVertexBuffer(mesh
, 0, &vertex_buffer
);
4469 memcpy(vertex_buffer
, vertices
, sizeof(vertices
));
4470 mesh
->lpVtbl
->UnlockVertexBuffer(mesh
);
4472 mesh
->lpVtbl
->LockIndexBuffer(mesh
, 0, &index_buffer
);
4473 memcpy(index_buffer
, faces
, sizeof(faces
));
4474 mesh
->lpVtbl
->UnlockIndexBuffer(mesh
);
4476 mesh
->lpVtbl
->LockAttributeBuffer(mesh
, 0, &attributes_buffer
);
4477 memcpy(attributes_buffer
, attributes
, sizeof(attributes
));
4478 mesh
->lpVtbl
->UnlockAttributeBuffer(mesh
);
4480 /* Get the declaration and try to change it */
4481 hr
= mesh
->lpVtbl
->GetDeclaration(mesh
, declaration
);
4484 skip("Couldn't get vertex declaration %#x\n", hr
);
4487 equal
= memcmp(declaration
, declaration0
, sizeof(declaration0
));
4488 ok(equal
== 0, "Vertex declarations were not equal\n");
4490 for (decl_ptr
= declaration
; decl_ptr
->Stream
!= 0xFF; decl_ptr
++)
4492 if (decl_ptr
->Usage
== D3DDECLUSAGE_POSITION
)
4494 /* Use second vertex position instead of first */
4495 decl_ptr
->Offset
= offset
;
4499 hr
= mesh
->lpVtbl
->UpdateSemantics(mesh
, declaration
);
4500 ok(hr
== D3D_OK
, "Test UpdateSematics, got %#x expected %#x\n", hr
, D3D_OK
);
4502 /* Check that declaration was written by getting it again */
4503 memset(declaration
, 0, sizeof(declaration
));
4504 hr
= mesh
->lpVtbl
->GetDeclaration(mesh
, declaration
);
4507 skip("Couldn't get vertex declaration %#x\n", hr
);
4511 for (decl_ptr
= declaration
; decl_ptr
->Stream
!= 0xFF; decl_ptr
++)
4513 if (decl_ptr
->Usage
== D3DDECLUSAGE_POSITION
)
4515 ok(decl_ptr
->Offset
== offset
, "Test UpdateSematics, got offset %d expected %d\n",
4516 decl_ptr
->Offset
, offset
);
4520 /* Check that GetDeclaration only writes up to the D3DDECL_END() marker and
4521 * not the full MAX_FVF_DECL_SIZE elements.
4523 memset(declaration
, filler_a
, sizeof(declaration
));
4524 memcpy(declaration
, declaration0
, sizeof(declaration0
));
4525 hr
= mesh
->lpVtbl
->UpdateSemantics(mesh
, declaration
);
4526 ok(hr
== D3D_OK
, "Test UpdateSematics, "
4527 "got %#x expected D3D_OK\n", hr
);
4528 memset(declaration
, filler_b
, sizeof(declaration
));
4529 hr
= mesh
->lpVtbl
->GetDeclaration(mesh
, declaration
);
4530 ok(hr
== D3D_OK
, "Couldn't get vertex declaration. Got %#x, expected D3D_OK\n", hr
);
4531 decl_mem
= (int*)declaration
;
4532 for (i
= sizeof(declaration0
)/sizeof(*decl_mem
); i
< sizeof(declaration
)/sizeof(*decl_mem
); i
++)
4534 equal
= memcmp(&decl_mem
[i
], &filler_b
, sizeof(filler_b
));
4536 "GetDeclaration wrote past the D3DDECL_END() marker. "
4537 "Got %#x, expected %#x\n", decl_mem
[i
], filler_b
);
4538 if (equal
!= 0) break;
4541 /* UpdateSemantics does not check for overlapping fields */
4542 memset(declaration
, 0, sizeof(declaration
));
4543 hr
= mesh
->lpVtbl
->GetDeclaration(mesh
, declaration
);
4546 skip("Couldn't get vertex declaration %#x\n", hr
);
4550 for (decl_ptr
= declaration
; decl_ptr
->Stream
!= 0xFF; decl_ptr
++)
4552 if (decl_ptr
->Type
== D3DDECLTYPE_FLOAT3
)
4554 decl_ptr
->Type
= D3DDECLTYPE_FLOAT4
;
4558 hr
= mesh
->lpVtbl
->UpdateSemantics(mesh
, declaration
);
4559 ok(hr
== D3D_OK
, "Test UpdateSematics for overlapping fields, "
4560 "got %#x expected D3D_OK\n", hr
);
4562 /* Set the position type to color instead of float3 */
4563 hr
= mesh
->lpVtbl
->UpdateSemantics(mesh
, declaration_pos_type_color
);
4564 ok(hr
== D3D_OK
, "Test UpdateSematics position type color, "
4565 "got %#x expected D3D_OK\n", hr
);
4567 /* The following test cases show that NULL, smaller or larger declarations,
4568 * and declarations with non-zero Stream values are not accepted.
4569 * UpdateSemantics returns D3DERR_INVALIDCALL and the previously set
4570 * declaration will be used by DrawSubset, GetNumBytesPerVertex, and
4574 /* Null declaration (invalid declaration) */
4575 mesh
->lpVtbl
->UpdateSemantics(mesh
, declaration0
); /* Set a valid declaration */
4576 hr
= mesh
->lpVtbl
->UpdateSemantics(mesh
, NULL
);
4577 ok(hr
== D3DERR_INVALIDCALL
, "Test UpdateSematics null pointer declaration, "
4578 "got %#x expected D3DERR_INVALIDCALL\n", hr
);
4579 vertex_size
= mesh
->lpVtbl
->GetNumBytesPerVertex(mesh
);
4580 ok(vertex_size
== exp_vertex_size
, "Got vertex declaration size %u, expected %u\n",
4581 vertex_size
, exp_vertex_size
);
4582 memset(declaration
, 0, sizeof(declaration
));
4583 hr
= mesh
->lpVtbl
->GetDeclaration(mesh
, declaration
);
4584 ok(hr
== D3D_OK
, "Couldn't get vertex declaration. Got %#x, expected D3D_OK\n", hr
);
4585 equal
= memcmp(declaration
, declaration0
, sizeof(declaration0
));
4586 ok(equal
== 0, "Vertex declarations were not equal\n");
4588 /* Smaller vertex declaration (invalid declaration) */
4589 mesh
->lpVtbl
->UpdateSemantics(mesh
, declaration0
); /* Set a valid declaration */
4590 hr
= mesh
->lpVtbl
->UpdateSemantics(mesh
, declaration_smaller
);
4591 ok(hr
== D3DERR_INVALIDCALL
, "Test UpdateSematics for smaller vertex declaration, "
4592 "got %#x expected D3DERR_INVALIDCALL\n", hr
);
4593 vertex_size
= mesh
->lpVtbl
->GetNumBytesPerVertex(mesh
);
4594 ok(vertex_size
== exp_vertex_size
, "Got vertex declaration size %u, expected %u\n",
4595 vertex_size
, exp_vertex_size
);
4596 memset(declaration
, 0, sizeof(declaration
));
4597 hr
= mesh
->lpVtbl
->GetDeclaration(mesh
, declaration
);
4598 ok(hr
== D3D_OK
, "Couldn't get vertex declaration. Got %#x, expected D3D_OK\n", hr
);
4599 equal
= memcmp(declaration
, declaration0
, sizeof(declaration0
));
4600 ok(equal
== 0, "Vertex declarations were not equal\n");
4602 /* Larger vertex declaration (invalid declaration) */
4603 mesh
->lpVtbl
->UpdateSemantics(mesh
, declaration0
); /* Set a valid declaration */
4604 hr
= mesh
->lpVtbl
->UpdateSemantics(mesh
, declaration_larger
);
4605 ok(hr
== D3DERR_INVALIDCALL
, "Test UpdateSematics for larger vertex declaration, "
4606 "got %#x expected D3DERR_INVALIDCALL\n", hr
);
4607 vertex_size
= mesh
->lpVtbl
->GetNumBytesPerVertex(mesh
);
4608 ok(vertex_size
== exp_vertex_size
, "Got vertex declaration size %u, expected %u\n",
4609 vertex_size
, exp_vertex_size
);
4610 memset(declaration
, 0, sizeof(declaration
));
4611 hr
= mesh
->lpVtbl
->GetDeclaration(mesh
, declaration
);
4612 ok(hr
== D3D_OK
, "Couldn't get vertex declaration. Got %#x, expected D3D_OK\n", hr
);
4613 equal
= memcmp(declaration
, declaration0
, sizeof(declaration0
));
4614 ok(equal
== 0, "Vertex declarations were not equal\n");
4616 /* Use multiple streams and keep the same vertex size (invalid declaration) */
4617 mesh
->lpVtbl
->UpdateSemantics(mesh
, declaration0
); /* Set a valid declaration */
4618 hr
= mesh
->lpVtbl
->UpdateSemantics(mesh
, declaration_multiple_streams
);
4619 ok(hr
== D3DERR_INVALIDCALL
, "Test UpdateSematics using multiple streams, "
4620 "got %#x expected D3DERR_INVALIDCALL\n", hr
);
4621 vertex_size
= mesh
->lpVtbl
->GetNumBytesPerVertex(mesh
);
4622 ok(vertex_size
== exp_vertex_size
, "Got vertex declaration size %u, expected %u\n",
4623 vertex_size
, exp_vertex_size
);
4624 memset(declaration
, 0, sizeof(declaration
));
4625 hr
= mesh
->lpVtbl
->GetDeclaration(mesh
, declaration
);
4626 ok(hr
== D3D_OK
, "Couldn't get vertex declaration. Got %#x, expected D3D_OK\n", hr
);
4627 equal
= memcmp(declaration
, declaration0
, sizeof(declaration0
));
4628 ok(equal
== 0, "Vertex declarations were not equal\n");
4630 /* The next following test cases show that some invalid declarations are
4631 * accepted with a D3D_OK. An access violation is thrown on Windows if
4632 * DrawSubset is called. The methods GetNumBytesPerVertex and GetDeclaration
4633 * are not affected, which indicates that the declaration is cached.
4636 /* Double usage (invalid declaration) */
4637 mesh
->lpVtbl
->UpdateSemantics(mesh
, declaration0
); /* Set a valid declaration */
4638 hr
= mesh
->lpVtbl
->UpdateSemantics(mesh
, declaration_double_usage
);
4639 ok(hr
== D3D_OK
, "Test UpdateSematics double usage, "
4640 "got %#x expected D3D_OK\n", hr
);
4641 vertex_size
= mesh
->lpVtbl
->GetNumBytesPerVertex(mesh
);
4642 ok(vertex_size
== exp_vertex_size
, "Got vertex declaration size %u, expected %u\n",
4643 vertex_size
, exp_vertex_size
);
4644 memset(declaration
, 0, sizeof(declaration
));
4645 hr
= mesh
->lpVtbl
->GetDeclaration(mesh
, declaration
);
4646 ok(hr
== D3D_OK
, "Couldn't get vertex declaration. Got %#x, expected D3D_OK\n", hr
);
4647 equal
= memcmp(declaration
, declaration_double_usage
, sizeof(declaration_double_usage
));
4648 ok(equal
== 0, "Vertex declarations were not equal\n");
4650 /* Set the position to an undefined type (invalid declaration) */
4651 mesh
->lpVtbl
->UpdateSemantics(mesh
, declaration0
); /* Set a valid declaration */
4652 hr
= mesh
->lpVtbl
->UpdateSemantics(mesh
, declaration_undefined_type
);
4653 ok(hr
== D3D_OK
, "Test UpdateSematics undefined type, "
4654 "got %#x expected D3D_OK\n", hr
);
4655 vertex_size
= mesh
->lpVtbl
->GetNumBytesPerVertex(mesh
);
4656 ok(vertex_size
== exp_vertex_size
, "Got vertex declaration size %u, expected %u\n",
4657 vertex_size
, exp_vertex_size
);
4658 memset(declaration
, 0, sizeof(declaration
));
4659 hr
= mesh
->lpVtbl
->GetDeclaration(mesh
, declaration
);
4660 ok(hr
== D3D_OK
, "Couldn't get vertex declaration. Got %#x, expected D3D_OK\n", hr
);
4661 equal
= memcmp(declaration
, declaration_undefined_type
, sizeof(declaration_undefined_type
));
4662 ok(equal
== 0, "Vertex declarations were not equal\n");
4664 /* Use a not 4 byte aligned offset (invalid declaration) */
4665 mesh
->lpVtbl
->UpdateSemantics(mesh
, declaration0
); /* Set a valid declaration */
4666 hr
= mesh
->lpVtbl
->UpdateSemantics(mesh
, declaration_not_4_byte_aligned_offset
);
4667 ok(hr
== D3D_OK
, "Test UpdateSematics not 4 byte aligned offset, "
4668 "got %#x expected D3D_OK\n", hr
);
4669 vertex_size
= mesh
->lpVtbl
->GetNumBytesPerVertex(mesh
);
4670 ok(vertex_size
== exp_vertex_size
, "Got vertex declaration size %u, expected %u\n",
4671 vertex_size
, exp_vertex_size
);
4672 memset(declaration
, 0, sizeof(declaration
));
4673 hr
= mesh
->lpVtbl
->GetDeclaration(mesh
, declaration
);
4674 ok(hr
== D3D_OK
, "Couldn't get vertex declaration. Got %#x, expected D3D_OK\n", hr
);
4675 equal
= memcmp(declaration
, declaration_not_4_byte_aligned_offset
,
4676 sizeof(declaration_not_4_byte_aligned_offset
));
4677 ok(equal
== 0, "Vertex declarations were not equal\n");
4681 mesh
->lpVtbl
->Release(mesh
);
4683 free_test_context(test_context
);
4686 static void test_create_skin_info(void)
4689 ID3DXSkinInfo
*skininfo
= NULL
;
4690 D3DVERTEXELEMENT9 empty_declaration
[] = { D3DDECL_END() };
4691 D3DVERTEXELEMENT9 declaration_out
[MAX_FVF_DECL_SIZE
];
4692 const D3DVERTEXELEMENT9 declaration_with_nonzero_stream
[] = {
4693 {1, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
4697 hr
= D3DXCreateSkinInfo(0, empty_declaration
, 0, &skininfo
);
4698 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
4699 if (skininfo
) IUnknown_Release(skininfo
);
4702 hr
= D3DXCreateSkinInfo(1, NULL
, 1, &skininfo
);
4703 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
4705 hr
= D3DXCreateSkinInfo(1, declaration_with_nonzero_stream
, 1, &skininfo
);
4706 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
4708 hr
= D3DXCreateSkinInfoFVF(1, 0, 1, &skininfo
);
4709 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
4714 const char *string_result
;
4715 D3DXMATRIX
*transform
;
4716 D3DXMATRIX identity_matrix
;
4718 /* test initial values */
4719 hr
= skininfo
->lpVtbl
->GetDeclaration(skininfo
, declaration_out
);
4720 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
4722 compare_elements(declaration_out
, empty_declaration
, __LINE__
, 0);
4724 dword_result
= skininfo
->lpVtbl
->GetNumBones(skininfo
);
4725 ok(dword_result
== 1, "Expected 1, got %u\n", dword_result
);
4727 flt_result
= skininfo
->lpVtbl
->GetMinBoneInfluence(skininfo
);
4728 ok(flt_result
== 0.0f
, "Expected 0.0, got %g\n", flt_result
);
4730 string_result
= skininfo
->lpVtbl
->GetBoneName(skininfo
, 0);
4731 ok(string_result
== NULL
, "Expected NULL, got %p\n", string_result
);
4733 dword_result
= skininfo
->lpVtbl
->GetFVF(skininfo
);
4734 ok(dword_result
== 0, "Expected 0, got %u\n", dword_result
);
4736 dword_result
= skininfo
->lpVtbl
->GetNumBoneInfluences(skininfo
, 0);
4737 ok(dword_result
== 0, "Expected 0, got %u\n", dword_result
);
4739 dword_result
= skininfo
->lpVtbl
->GetNumBoneInfluences(skininfo
, 1);
4740 ok(dword_result
== 0, "Expected 0, got %u\n", dword_result
);
4742 transform
= skininfo
->lpVtbl
->GetBoneOffsetMatrix(skininfo
, -1);
4743 ok(transform
== NULL
, "Expected NULL, got %p\n", transform
);
4746 /* test [GS]etBoneOffsetMatrix */
4747 hr
= skininfo
->lpVtbl
->SetBoneOffsetMatrix(skininfo
, 1, &identity_matrix
);
4748 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
4750 hr
= skininfo
->lpVtbl
->SetBoneOffsetMatrix(skininfo
, 0, NULL
);
4751 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
4753 D3DXMatrixIdentity(&identity_matrix
);
4754 hr
= skininfo
->lpVtbl
->SetBoneOffsetMatrix(skininfo
, 0, &identity_matrix
);
4755 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
4757 transform
= skininfo
->lpVtbl
->GetBoneOffsetMatrix(skininfo
, 0);
4758 check_matrix(transform
, &identity_matrix
);
4762 /* test [GS]etBoneName */
4763 const char *name_in
= "testBoneName";
4764 const char *string_result2
;
4766 hr
= skininfo
->lpVtbl
->SetBoneName(skininfo
, 1, name_in
);
4767 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
4769 hr
= skininfo
->lpVtbl
->SetBoneName(skininfo
, 0, NULL
);
4770 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
4772 hr
= skininfo
->lpVtbl
->SetBoneName(skininfo
, 0, name_in
);
4773 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
4775 string_result
= skininfo
->lpVtbl
->GetBoneName(skininfo
, 0);
4776 ok(string_result
!= NULL
, "Expected non-NULL string, got %p\n", string_result
);
4777 ok(!strcmp(string_result
, name_in
), "Expected '%s', got '%s'\n", name_in
, string_result
);
4779 string_result2
= skininfo
->lpVtbl
->GetBoneName(skininfo
, 0);
4780 ok(string_result
== string_result2
, "Expected %p, got %p\n", string_result
, string_result2
);
4782 string_result
= skininfo
->lpVtbl
->GetBoneName(skininfo
, 1);
4783 ok(string_result
== NULL
, "Expected NULL, got %p\n", string_result
);
4787 /* test [GS]etBoneInfluence */
4791 DWORD num_influences
;
4792 DWORD exp_vertices
[2];
4793 FLOAT exp_weights
[2];
4795 /* vertex and weight arrays untouched when num_influences is 0 */
4796 vertices
[0] = 0xdeadbeef;
4797 weights
[0] = FLT_MAX
;
4798 hr
= skininfo
->lpVtbl
->GetBoneInfluence(skininfo
, 0, vertices
, weights
);
4799 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
4800 ok(vertices
[0] == 0xdeadbeef, "expected 0xdeadbeef, got %#x\n", vertices
[0]);
4801 ok(weights
[0] == FLT_MAX
, "expected %g, got %g\n", FLT_MAX
, weights
[0]);
4803 hr
= skininfo
->lpVtbl
->GetBoneInfluence(skininfo
, 1, vertices
, weights
);
4804 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
4806 hr
= skininfo
->lpVtbl
->GetBoneInfluence(skininfo
, 0, NULL
, NULL
);
4807 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
4809 hr
= skininfo
->lpVtbl
->GetBoneInfluence(skininfo
, 0, vertices
, NULL
);
4810 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
4812 hr
= skininfo
->lpVtbl
->GetBoneInfluence(skininfo
, 0, NULL
, weights
);
4813 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
4816 /* no vertex or weight value checking */
4817 exp_vertices
[0] = 0;
4818 exp_vertices
[1] = 0x87654321;
4819 exp_weights
[0] = 0.5;
4820 exp_weights
[1] = NAN
;
4823 hr
= skininfo
->lpVtbl
->SetBoneInfluence(skininfo
, 1, num_influences
, vertices
, weights
);
4824 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
4826 hr
= skininfo
->lpVtbl
->SetBoneInfluence(skininfo
, 0, num_influences
, NULL
, weights
);
4827 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
4829 hr
= skininfo
->lpVtbl
->SetBoneInfluence(skininfo
, 0, num_influences
, vertices
, NULL
);
4830 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
4832 hr
= skininfo
->lpVtbl
->SetBoneInfluence(skininfo
, 0, num_influences
, NULL
, NULL
);
4833 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
4835 hr
= skininfo
->lpVtbl
->SetBoneInfluence(skininfo
, 0, num_influences
, exp_vertices
, exp_weights
);
4836 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
4838 memset(vertices
, 0, sizeof(vertices
));
4839 memset(weights
, 0, sizeof(weights
));
4840 hr
= skininfo
->lpVtbl
->GetBoneInfluence(skininfo
, 0, vertices
, weights
);
4841 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
4842 for (i
= 0; i
< num_influences
; i
++) {
4843 ok(exp_vertices
[i
] == vertices
[i
],
4844 "influence[%d]: expected vertex %u, got %u\n", i
, exp_vertices
[i
], vertices
[i
]);
4845 ok((isnan(exp_weights
[i
]) && isnan(weights
[i
])) || exp_weights
[i
] == weights
[i
],
4846 "influence[%d]: expected weights %g, got %g\n", i
, exp_weights
[i
], weights
[i
]);
4849 /* vertices and weights aren't returned after setting num_influences to 0 */
4850 memset(vertices
, 0, sizeof(vertices
));
4851 memset(weights
, 0, sizeof(weights
));
4852 hr
= skininfo
->lpVtbl
->SetBoneInfluence(skininfo
, 0, 0, vertices
, weights
);
4853 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
4855 vertices
[0] = 0xdeadbeef;
4856 weights
[0] = FLT_MAX
;
4857 hr
= skininfo
->lpVtbl
->GetBoneInfluence(skininfo
, 0, vertices
, weights
);
4858 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
4859 ok(vertices
[0] == 0xdeadbeef, "expected vertex 0xdeadbeef, got %u\n", vertices
[0]);
4860 ok(weights
[0] == FLT_MAX
, "expected weight %g, got %g\n", FLT_MAX
, weights
[0]);
4864 /* test [GS]etFVF and [GS]etDeclaration */
4865 D3DVERTEXELEMENT9 declaration_in
[MAX_FVF_DECL_SIZE
];
4866 DWORD fvf
= D3DFVF_XYZ
;
4869 hr
= skininfo
->lpVtbl
->SetDeclaration(skininfo
, NULL
);
4870 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
4872 hr
= skininfo
->lpVtbl
->SetDeclaration(skininfo
, declaration_with_nonzero_stream
);
4873 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
4875 hr
= skininfo
->lpVtbl
->SetFVF(skininfo
, 0);
4876 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
4878 hr
= D3DXDeclaratorFromFVF(fvf
, declaration_in
);
4879 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
4880 hr
= skininfo
->lpVtbl
->SetDeclaration(skininfo
, declaration_in
);
4881 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
4882 got_fvf
= skininfo
->lpVtbl
->GetFVF(skininfo
);
4883 ok(fvf
== got_fvf
, "Expected %#x, got %#x\n", fvf
, got_fvf
);
4884 hr
= skininfo
->lpVtbl
->GetDeclaration(skininfo
, declaration_out
);
4885 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
4886 compare_elements(declaration_out
, declaration_in
, __LINE__
, 0);
4888 hr
= skininfo
->lpVtbl
->SetDeclaration(skininfo
, empty_declaration
);
4889 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
4890 got_fvf
= skininfo
->lpVtbl
->GetFVF(skininfo
);
4891 ok(got_fvf
== 0, "Expected 0, got %#x\n", got_fvf
);
4892 hr
= skininfo
->lpVtbl
->GetDeclaration(skininfo
, declaration_out
);
4893 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
4894 compare_elements(declaration_out
, empty_declaration
, __LINE__
, 0);
4896 hr
= skininfo
->lpVtbl
->SetFVF(skininfo
, fvf
);
4897 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
4898 got_fvf
= skininfo
->lpVtbl
->GetFVF(skininfo
);
4899 ok(fvf
== got_fvf
, "Expected %#x, got %#x\n", fvf
, got_fvf
);
4900 hr
= skininfo
->lpVtbl
->GetDeclaration(skininfo
, declaration_out
);
4901 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
4902 compare_elements(declaration_out
, declaration_in
, __LINE__
, 0);
4905 if (skininfo
) IUnknown_Release(skininfo
);
4908 hr
= D3DXCreateSkinInfoFVF(1, D3DFVF_XYZ
, 1, NULL
);
4909 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
4911 hr
= D3DXCreateSkinInfo(1, NULL
, 1, &skininfo
);
4912 ok(hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
4915 static void test_convert_adjacency_to_point_reps(void)
4918 struct test_context
*test_context
= NULL
;
4919 const DWORD options
= D3DXMESH_32BIT
| D3DXMESH_SYSTEMMEM
;
4920 const DWORD options_16bit
= D3DXMESH_SYSTEMMEM
;
4921 const D3DVERTEXELEMENT9 declaration
[] =
4923 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
4924 {0, 12, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
4925 {0, 24, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 0},
4928 const unsigned int VERTS_PER_FACE
= 3;
4929 void *vertex_buffer
;
4931 DWORD
*attributes_buffer
;
4933 enum color
{ RED
= 0xffff0000, GREEN
= 0xff00ff00, BLUE
= 0xff0000ff};
4936 D3DXVECTOR3 position
;
4938 enum color color
; /* In case of manual visual inspection */
4940 D3DXVECTOR3 up
= {0.0f
, 0.0f
, 1.0f
};
4948 const struct vertex_pnc vertices0
[] =
4950 {{ 0.0f
, 3.0f
, 0.f
}, up
, RED
},
4951 {{ 2.0f
, 3.0f
, 0.f
}, up
, GREEN
},
4952 {{ 0.0f
, 0.0f
, 0.f
}, up
, BLUE
},
4954 const DWORD indices0
[] = {0, 1, 2};
4955 const unsigned int num_vertices0
= ARRAY_SIZE(vertices0
);
4956 const unsigned int num_faces0
= ARRAY_SIZE(indices0
) / VERTS_PER_FACE
;
4957 const DWORD adjacency0
[] = {-1, -1, -1};
4958 const DWORD exp_point_rep0
[] = {0, 1, 2};
4966 const struct vertex_pnc vertices1
[] =
4968 {{ 0.0f
, 3.0f
, 0.f
}, up
, RED
},
4969 {{ 2.0f
, 3.0f
, 0.f
}, up
, GREEN
},
4970 {{ 0.0f
, 0.0f
, 0.f
}, up
, BLUE
},
4972 {{ 3.0f
, 3.0f
, 0.f
}, up
, GREEN
},
4973 {{ 3.0f
, 0.0f
, 0.f
}, up
, RED
},
4974 {{ 1.0f
, 0.0f
, 0.f
}, up
, BLUE
},
4976 const DWORD indices1
[] = {0, 1, 2, 3, 4, 5};
4977 const unsigned int num_vertices1
= ARRAY_SIZE(vertices1
);
4978 const unsigned int num_faces1
= ARRAY_SIZE(indices1
) / VERTS_PER_FACE
;
4979 const DWORD adjacency1
[] = {-1, 1, -1, -1, -1, 0};
4980 const DWORD exp_point_rep1
[] = {0, 1, 2, 1, 4, 2};
4988 const struct vertex_pnc vertices2
[] =
4990 {{ 0.0f
, 3.0f
, 0.f
}, up
, RED
},
4991 {{ 2.0f
, 3.0f
, 0.f
}, up
, GREEN
},
4992 {{ 0.0f
, 0.0f
, 0.f
}, up
, BLUE
},
4994 {{-1.0f
, 3.0f
, 0.f
}, up
, RED
},
4995 {{-1.0f
, 0.0f
, 0.f
}, up
, GREEN
},
4996 {{-3.0f
, 0.0f
, 0.f
}, up
, BLUE
},
4998 const DWORD indices2
[] = {0, 1, 2, 3, 4, 5};
4999 const unsigned int num_vertices2
= ARRAY_SIZE(vertices2
);
5000 const unsigned int num_faces2
= ARRAY_SIZE(indices2
) / VERTS_PER_FACE
;
5001 const DWORD adjacency2
[] = {-1, -1, 1, 0, -1, -1};
5002 const DWORD exp_point_rep2
[] = {0, 1, 2, 0, 2, 5};
5014 struct vertex_pnc vertices3
[] =
5016 {{ 0.0f
, 3.0f
, 0.f
}, up
, RED
},
5017 {{ 2.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5018 {{ 0.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5020 {{ 2.0f
, 7.0f
, 0.f
}, up
, BLUE
},
5021 {{ 2.0f
, 4.0f
, 0.f
}, up
, GREEN
},
5022 {{ 0.0f
, 4.0f
, 0.f
}, up
, RED
},
5024 const DWORD indices3
[] = {0, 1, 2, 3, 4, 5};
5025 const unsigned int num_vertices3
= ARRAY_SIZE(vertices3
);
5026 const unsigned int num_faces3
= ARRAY_SIZE(indices3
) / VERTS_PER_FACE
;
5027 const DWORD adjacency3
[] = {1, -1, -1, -1, 0, -1};
5028 const DWORD exp_point_rep3
[] = {0, 1, 2, 3, 1, 0};
5029 /* mesh4 (below, tip against tip)
5040 struct vertex_pnc vertices4
[] =
5042 {{ 0.0f
, 3.0f
, 0.f
}, up
, RED
},
5043 {{ 2.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5044 {{ 0.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5046 {{ 0.0f
, -4.0f
, 0.f
}, up
, BLUE
},
5047 {{ 2.0f
, -7.0f
, 0.f
}, up
, GREEN
},
5048 {{ 0.0f
, -7.0f
, 0.f
}, up
, RED
},
5050 const DWORD indices4
[] = {0, 1, 2, 3, 4, 5};
5051 const unsigned int num_vertices4
= ARRAY_SIZE(vertices4
);
5052 const unsigned int num_faces4
= ARRAY_SIZE(indices4
) / VERTS_PER_FACE
;
5053 const DWORD adjacency4
[] = {-1, -1, -1, -1, -1, -1};
5054 const DWORD exp_point_rep4
[] = {0, 1, 2, 3, 4, 5};
5055 /* mesh5 (gap in mesh)
5060 * 2-----1 5 17-----16
5061 * 6-----7 9 12-----13
5067 const struct vertex_pnc vertices5
[] =
5069 {{ 0.0f
, 1.0f
, 0.f
}, up
, RED
},
5070 {{ 1.0f
, -1.0f
, 0.f
}, up
, GREEN
},
5071 {{-1.0f
, -1.0f
, 0.f
}, up
, BLUE
},
5073 {{ 0.1f
, 1.0f
, 0.f
}, up
, RED
},
5074 {{ 2.1f
, 1.0f
, 0.f
}, up
, BLUE
},
5075 {{ 1.1f
, -1.0f
, 0.f
}, up
, GREEN
},
5077 {{-1.0f
, -1.1f
, 0.f
}, up
, BLUE
},
5078 {{ 1.0f
, -1.1f
, 0.f
}, up
, GREEN
},
5079 {{ 0.0f
, -3.1f
, 0.f
}, up
, RED
},
5081 {{ 1.1f
, -1.1f
, 0.f
}, up
, GREEN
},
5082 {{ 2.1f
, -3.1f
, 0.f
}, up
, BLUE
},
5083 {{ 0.1f
, -3.1f
, 0.f
}, up
, RED
},
5085 {{ 1.2f
, -1.1f
, 0.f
}, up
, GREEN
},
5086 {{ 3.2f
, -1.1f
, 0.f
}, up
, RED
},
5087 {{ 2.2f
, -3.1f
, 0.f
}, up
, BLUE
},
5089 {{ 2.2f
, 1.0f
, 0.f
}, up
, BLUE
},
5090 {{ 3.2f
, -1.0f
, 0.f
}, up
, RED
},
5091 {{ 1.2f
, -1.0f
, 0.f
}, up
, GREEN
},
5093 const DWORD indices5
[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
5094 const unsigned int num_vertices5
= ARRAY_SIZE(vertices5
);
5095 const unsigned int num_faces5
= ARRAY_SIZE(indices5
) / VERTS_PER_FACE
;
5096 const DWORD adjacency5
[] = {-1, 2, -1, -1, 5, -1, 0, -1, -1, 4, -1, -1, 5, -1, 3, -1, 4, 1};
5097 const DWORD exp_point_rep5
[] = {0, 1, 2, 3, 4, 5, 2, 1, 8, 5, 10, 11, 5, 13, 10, 4, 13, 5};
5098 const WORD indices5_16bit
[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
5099 /* mesh6 (indices re-ordering)
5106 const struct vertex_pnc vertices6
[] =
5108 {{ 0.0f
, 3.0f
, 0.f
}, up
, RED
},
5109 {{ 2.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5110 {{ 0.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5112 {{ 3.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5113 {{ 3.0f
, 0.0f
, 0.f
}, up
, RED
},
5114 {{ 1.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5116 {{ 4.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5117 {{ 6.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5118 {{ 4.0f
, 0.0f
, 0.f
}, up
, RED
},
5120 const DWORD indices6
[] = {0, 1, 2, 6, 7, 8, 3, 4, 5};
5121 const unsigned int num_vertices6
= ARRAY_SIZE(vertices6
);
5122 const unsigned int num_faces6
= ARRAY_SIZE(indices6
) / VERTS_PER_FACE
;
5123 const DWORD adjacency6
[] = {-1, 1, -1, 2, -1, 0, -1, -1, 1};
5124 const DWORD exp_point_rep6
[] = {0, 1, 2, 1, 4, 5, 1, 5, 2};
5125 /* mesh7 (expands collapsed triangle)
5132 const struct vertex_pnc vertices7
[] =
5134 {{ 0.0f
, 3.0f
, 0.f
}, up
, RED
},
5135 {{ 2.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5136 {{ 0.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5138 {{ 3.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5139 {{ 3.0f
, 0.0f
, 0.f
}, up
, RED
},
5140 {{ 1.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5142 const DWORD indices7
[] = {0, 1, 2, 3, 3, 3}; /* Face 1 is collapsed*/
5143 const unsigned int num_vertices7
= ARRAY_SIZE(vertices7
);
5144 const unsigned int num_faces7
= ARRAY_SIZE(indices7
) / VERTS_PER_FACE
;
5145 const DWORD adjacency7
[] = {-1, -1, -1, -1, -1, -1};
5146 const DWORD exp_point_rep7
[] = {0, 1, 2, 3, 4, 5};
5147 /* mesh8 (indices re-ordering and double replacement)
5158 const struct vertex_pnc vertices8
[] =
5160 {{ 0.0f
, 3.0f
, 0.f
}, up
, RED
},
5161 {{ 2.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5162 {{ 0.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5164 {{ 4.0, -4.0, 0.f
}, up
, RED
},
5165 {{ 6.0, -4.0, 0.f
}, up
, BLUE
},
5166 {{ 4.0, -7.0, 0.f
}, up
, GREEN
},
5168 {{ 4.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5169 {{ 6.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5170 {{ 4.0f
, 0.0f
, 0.f
}, up
, RED
},
5172 {{ 3.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5173 {{ 3.0f
, 0.0f
, 0.f
}, up
, RED
},
5174 {{ 1.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5176 const DWORD indices8
[] = {0, 1, 2, 9, 10, 11, 6, 7, 8, 3, 4, 5};
5177 const unsigned int num_vertices8
= ARRAY_SIZE(vertices8
);
5178 const unsigned int num_faces8
= ARRAY_SIZE(indices8
) / VERTS_PER_FACE
;
5179 const DWORD adjacency8
[] = {-1, 1, -1, 2, -1, 0, -1, 3, 1, 2, -1, -1};
5180 const DWORD exp_point_rep8
[] = {0, 1, 2, 3, 4, 5, 1, 4, 3, 1, 3, 2};
5181 /* mesh9 (right, shared vertices)
5188 const struct vertex_pnc vertices9
[] =
5190 {{ 0.0f
, 3.0f
, 0.f
}, up
, RED
},
5191 {{ 2.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5192 {{ 0.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5194 {{ 2.0f
, 0.0f
, 0.f
}, up
, RED
},
5196 const DWORD indices9
[] = {0, 1, 2, 1, 3, 2};
5197 const unsigned int num_vertices9
= ARRAY_SIZE(vertices9
);
5198 const unsigned int num_faces9
= ARRAY_SIZE(indices9
) / VERTS_PER_FACE
;
5199 const DWORD adjacency9
[] = {-1, 1, -1, -1, -1, 0};
5200 const DWORD exp_point_rep9
[] = {0, 1, 2, 3};
5202 ID3DXMesh
*mesh
= NULL
;
5203 ID3DXMesh
*mesh_null_check
= NULL
;
5204 unsigned int attributes
[] = {0};
5207 const struct vertex_pnc
*vertices
;
5208 const DWORD
*indices
;
5209 const DWORD num_vertices
;
5210 const DWORD num_faces
;
5211 const DWORD
*adjacency
;
5212 const DWORD
*exp_point_reps
;
5213 const DWORD options
;
5309 (DWORD
*)indices5_16bit
,
5317 DWORD
*point_reps
= NULL
;
5319 test_context
= new_test_context();
5322 skip("Couldn't create test context\n");
5326 for (i
= 0; i
< ARRAY_SIZE(tc
); i
++)
5328 hr
= D3DXCreateMesh(tc
[i
].num_faces
, tc
[i
].num_vertices
, tc
[i
].options
, declaration
,
5329 test_context
->device
, &mesh
);
5332 skip("Couldn't create mesh %d. Got %x expected D3D_OK\n", i
, hr
);
5336 if (i
== 0) /* Save first mesh for later NULL checks */
5337 mesh_null_check
= mesh
;
5339 point_reps
= HeapAlloc(GetProcessHeap(), 0, tc
[i
].num_vertices
* sizeof(*point_reps
));
5342 skip("Couldn't allocate point reps array.\n");
5346 hr
= mesh
->lpVtbl
->LockVertexBuffer(mesh
, 0, &vertex_buffer
);
5349 skip("Couldn't lock vertex buffer.\n");
5352 memcpy(vertex_buffer
, tc
[i
].vertices
, tc
[i
].num_vertices
* sizeof(*tc
[i
].vertices
));
5353 hr
= mesh
->lpVtbl
->UnlockVertexBuffer(mesh
);
5356 skip("Couldn't unlock vertex buffer.\n");
5360 hr
= mesh
->lpVtbl
->LockIndexBuffer(mesh
, 0, &index_buffer
);
5363 skip("Couldn't lock index buffer.\n");
5366 if (tc
[i
].options
& D3DXMESH_32BIT
)
5368 memcpy(index_buffer
, tc
[i
].indices
, VERTS_PER_FACE
* tc
[i
].num_faces
* sizeof(DWORD
));
5372 memcpy(index_buffer
, tc
[i
].indices
, VERTS_PER_FACE
* tc
[i
].num_faces
* sizeof(WORD
));
5374 hr
= mesh
->lpVtbl
->UnlockIndexBuffer(mesh
);
5376 skip("Couldn't unlock index buffer.\n");
5380 hr
= mesh
->lpVtbl
->LockAttributeBuffer(mesh
, 0, &attributes_buffer
);
5383 skip("Couldn't lock attributes buffer.\n");
5386 memcpy(attributes_buffer
, attributes
, sizeof(attributes
));
5387 hr
= mesh
->lpVtbl
->UnlockAttributeBuffer(mesh
);
5390 skip("Couldn't unlock attributes buffer.\n");
5394 /* Convert adjacency to point representation */
5395 for (j
= 0; j
< tc
[i
].num_vertices
; j
++) point_reps
[j
] = -1;
5396 hr
= mesh
->lpVtbl
->ConvertAdjacencyToPointReps(mesh
, tc
[i
].adjacency
, point_reps
);
5397 ok(hr
== D3D_OK
, "ConvertAdjacencyToPointReps failed case %d. "
5398 "Got %x expected D3D_OK\n", i
, hr
);
5400 /* Check point representation */
5401 for (j
= 0; j
< tc
[i
].num_vertices
; j
++)
5403 ok(point_reps
[j
] == tc
[i
].exp_point_reps
[j
],
5404 "Unexpected point representation at (%d, %d)."
5405 " Got %d expected %d\n",
5406 i
, j
, point_reps
[j
], tc
[i
].exp_point_reps
[j
]);
5409 HeapFree(GetProcessHeap(), 0, point_reps
);
5412 if (i
!= 0) /* First mesh will be freed during cleanup */
5413 mesh
->lpVtbl
->Release(mesh
);
5417 hr
= mesh_null_check
->lpVtbl
->ConvertAdjacencyToPointReps(mesh_null_check
, tc
[0].adjacency
, NULL
);
5418 ok(hr
== D3DERR_INVALIDCALL
, "ConvertAdjacencyToPointReps point_reps NULL. "
5419 "Got %x expected D3DERR_INVALIDCALL\n", hr
);
5420 hr
= mesh_null_check
->lpVtbl
->ConvertAdjacencyToPointReps(mesh_null_check
, NULL
, NULL
);
5421 ok(hr
== D3DERR_INVALIDCALL
, "ConvertAdjacencyToPointReps adjacency and point_reps NULL. "
5422 "Got %x expected D3DERR_INVALIDCALL\n", hr
);
5425 if (mesh_null_check
)
5426 mesh_null_check
->lpVtbl
->Release(mesh_null_check
);
5427 HeapFree(GetProcessHeap(), 0, point_reps
);
5428 free_test_context(test_context
);
5431 static void test_convert_point_reps_to_adjacency(void)
5434 struct test_context
*test_context
= NULL
;
5435 const DWORD options
= D3DXMESH_32BIT
| D3DXMESH_SYSTEMMEM
;
5436 const DWORD options_16bit
= D3DXMESH_SYSTEMMEM
;
5437 const D3DVERTEXELEMENT9 declaration
[] =
5439 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
5440 {0, 12, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
5441 {0, 24, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 0},
5444 const unsigned int VERTS_PER_FACE
= 3;
5445 void *vertex_buffer
;
5447 DWORD
*attributes_buffer
;
5449 enum color
{ RED
= 0xffff0000, GREEN
= 0xff00ff00, BLUE
= 0xff0000ff};
5452 D3DXVECTOR3 position
;
5454 enum color color
; /* In case of manual visual inspection */
5456 D3DXVECTOR3 up
= {0.0f
, 0.0f
, 1.0f
};
5464 const struct vertex_pnc vertices0
[] =
5466 {{ 0.0f
, 3.0f
, 0.f
}, up
, RED
},
5467 {{ 2.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5468 {{ 0.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5470 const DWORD indices0
[] = {0, 1, 2};
5471 const unsigned int num_vertices0
= ARRAY_SIZE(vertices0
);
5472 const unsigned int num_faces0
= num_vertices0
/ VERTS_PER_FACE
;
5473 const DWORD exp_adjacency0
[] = {-1, -1, -1};
5474 const DWORD exp_id_adjacency0
[] = {-1, -1, -1};
5475 const DWORD point_rep0
[] = {0, 1, 2};
5483 const struct vertex_pnc vertices1
[] =
5485 {{ 0.0f
, 3.0f
, 0.f
}, up
, RED
},
5486 {{ 2.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5487 {{ 0.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5489 {{ 3.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5490 {{ 3.0f
, 0.0f
, 0.f
}, up
, RED
},
5491 {{ 1.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5493 const DWORD indices1
[] = {0, 1, 2, 3, 4, 5};
5494 const unsigned int num_vertices1
= ARRAY_SIZE(vertices1
);
5495 const unsigned int num_faces1
= num_vertices1
/ VERTS_PER_FACE
;
5496 const DWORD exp_adjacency1
[] = {-1, 1, -1, -1, -1, 0};
5497 const DWORD exp_id_adjacency1
[] = {-1, -1, -1, -1, -1, -1};
5498 const DWORD point_rep1
[] = {0, 1, 2, 1, 4, 2};
5506 const struct vertex_pnc vertices2
[] =
5508 {{ 0.0f
, 3.0f
, 0.f
}, up
, RED
},
5509 {{ 2.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5510 {{ 0.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5512 {{-1.0f
, 3.0f
, 0.f
}, up
, RED
},
5513 {{-1.0f
, 0.0f
, 0.f
}, up
, GREEN
},
5514 {{-3.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5516 const DWORD indices2
[] = {0, 1, 2, 3, 4, 5};
5517 const unsigned int num_vertices2
= ARRAY_SIZE(vertices2
);
5518 const unsigned int num_faces2
= num_vertices2
/ VERTS_PER_FACE
;
5519 const DWORD exp_adjacency2
[] = {-1, -1, 1, 0, -1, -1};
5520 const DWORD exp_id_adjacency2
[] = {-1, -1, -1, -1, -1, -1};
5521 const DWORD point_rep2
[] = {0, 1, 2, 0, 2, 5};
5533 struct vertex_pnc vertices3
[] =
5535 {{ 0.0f
, 3.0f
, 0.f
}, up
, RED
},
5536 {{ 2.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5537 {{ 0.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5539 {{ 2.0f
, 7.0f
, 0.f
}, up
, BLUE
},
5540 {{ 2.0f
, 4.0f
, 0.f
}, up
, GREEN
},
5541 {{ 0.0f
, 4.0f
, 0.f
}, up
, RED
},
5543 const DWORD indices3
[] = {0, 1, 2, 3, 4, 5};
5544 const unsigned int num_vertices3
= ARRAY_SIZE(vertices3
);
5545 const unsigned int num_faces3
= num_vertices3
/ VERTS_PER_FACE
;
5546 const DWORD exp_adjacency3
[] = {1, -1, -1, -1, 0, -1};
5547 const DWORD exp_id_adjacency3
[] = {-1, -1, -1, -1, -1, -1};
5548 const DWORD point_rep3
[] = {0, 1, 2, 3, 1, 0};
5549 /* mesh4 (below, tip against tip)
5560 struct vertex_pnc vertices4
[] =
5562 {{ 0.0f
, 3.0f
, 0.f
}, up
, RED
},
5563 {{ 2.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5564 {{ 0.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5566 {{ 0.0f
, -4.0f
, 0.f
}, up
, BLUE
},
5567 {{ 2.0f
, -7.0f
, 0.f
}, up
, GREEN
},
5568 {{ 0.0f
, -7.0f
, 0.f
}, up
, RED
},
5570 const DWORD indices4
[] = {0, 1, 2, 3, 4, 5};
5571 const unsigned int num_vertices4
= ARRAY_SIZE(vertices4
);
5572 const unsigned int num_faces4
= num_vertices4
/ VERTS_PER_FACE
;
5573 const DWORD exp_adjacency4
[] = {-1, -1, -1, -1, -1, -1};
5574 const DWORD exp_id_adjacency4
[] = {-1, -1, -1, -1, -1, -1};
5575 const DWORD point_rep4
[] = {0, 1, 2, 3, 4, 5};
5576 /* mesh5 (gap in mesh)
5581 * 2-----1 5 17-----16
5582 * 6-----7 9 12-----13
5588 const struct vertex_pnc vertices5
[] =
5590 {{ 0.0f
, 1.0f
, 0.f
}, up
, RED
},
5591 {{ 1.0f
, -1.0f
, 0.f
}, up
, GREEN
},
5592 {{-1.0f
, -1.0f
, 0.f
}, up
, BLUE
},
5594 {{ 0.1f
, 1.0f
, 0.f
}, up
, RED
},
5595 {{ 2.1f
, 1.0f
, 0.f
}, up
, BLUE
},
5596 {{ 1.1f
, -1.0f
, 0.f
}, up
, GREEN
},
5598 {{-1.0f
, -1.1f
, 0.f
}, up
, BLUE
},
5599 {{ 1.0f
, -1.1f
, 0.f
}, up
, GREEN
},
5600 {{ 0.0f
, -3.1f
, 0.f
}, up
, RED
},
5602 {{ 1.1f
, -1.1f
, 0.f
}, up
, GREEN
},
5603 {{ 2.1f
, -3.1f
, 0.f
}, up
, BLUE
},
5604 {{ 0.1f
, -3.1f
, 0.f
}, up
, RED
},
5606 {{ 1.2f
, -1.1f
, 0.f
}, up
, GREEN
},
5607 {{ 3.2f
, -1.1f
, 0.f
}, up
, RED
},
5608 {{ 2.2f
, -3.1f
, 0.f
}, up
, BLUE
},
5610 {{ 2.2f
, 1.0f
, 0.f
}, up
, BLUE
},
5611 {{ 3.2f
, -1.0f
, 0.f
}, up
, RED
},
5612 {{ 1.2f
, -1.0f
, 0.f
}, up
, GREEN
},
5614 const DWORD indices5
[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
5615 const unsigned int num_vertices5
= ARRAY_SIZE(vertices5
);
5616 const unsigned int num_faces5
= num_vertices5
/ VERTS_PER_FACE
;
5617 const DWORD exp_adjacency5
[] = {-1, 2, -1, -1, 5, -1, 0, -1, -1, 4, -1, -1, 5, -1, 3, -1, 4, 1};
5618 const DWORD exp_id_adjacency5
[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
5619 const DWORD point_rep5
[] = {0, 1, 2, 3, 4, 5, 2, 1, 8, 5, 10, 11, 5, 13, 10, 4, 13, 5};
5620 /* mesh6 (indices re-ordering)
5627 const struct vertex_pnc vertices6
[] =
5629 {{ 0.0f
, 3.0f
, 0.f
}, up
, RED
},
5630 {{ 2.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5631 {{ 0.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5633 {{ 3.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5634 {{ 3.0f
, 0.0f
, 0.f
}, up
, RED
},
5635 {{ 1.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5637 {{ 4.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5638 {{ 6.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5639 {{ 4.0f
, 0.0f
, 0.f
}, up
, RED
},
5641 const DWORD indices6
[] = {0, 1, 2, 6, 7, 8, 3, 4, 5};
5642 const unsigned int num_vertices6
= ARRAY_SIZE(vertices6
);
5643 const unsigned int num_faces6
= num_vertices6
/ VERTS_PER_FACE
;
5644 const DWORD exp_adjacency6
[] = {-1, 1, -1, 2, -1, 0, -1, -1, 1};
5645 const DWORD exp_id_adjacency6
[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1};
5646 const DWORD point_rep6
[] = {0, 1, 2, 1, 4, 5, 1, 5, 2};
5647 /* mesh7 (expands collapsed triangle)
5654 const struct vertex_pnc vertices7
[] =
5656 {{ 0.0f
, 3.0f
, 0.f
}, up
, RED
},
5657 {{ 2.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5658 {{ 0.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5660 {{ 3.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5661 {{ 3.0f
, 0.0f
, 0.f
}, up
, RED
},
5662 {{ 1.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5664 const DWORD indices7
[] = {0, 1, 2, 3, 3, 3}; /* Face 1 is collapsed*/
5665 const unsigned int num_vertices7
= ARRAY_SIZE(vertices7
);
5666 const unsigned int num_faces7
= num_vertices7
/ VERTS_PER_FACE
;
5667 const DWORD exp_adjacency7
[] = {-1, -1, -1, -1, -1, -1};
5668 const DWORD exp_id_adjacency7
[] = {-1, -1, -1, -1, -1, -1};
5669 const DWORD point_rep7
[] = {0, 1, 2, 3, 4, 5};
5670 /* mesh8 (indices re-ordering and double replacement)
5681 const struct vertex_pnc vertices8
[] =
5683 {{ 0.0f
, 3.0f
, 0.f
}, up
, RED
},
5684 {{ 2.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5685 {{ 0.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5687 {{ 4.0, -4.0, 0.f
}, up
, RED
},
5688 {{ 6.0, -4.0, 0.f
}, up
, BLUE
},
5689 {{ 4.0, -7.0, 0.f
}, up
, GREEN
},
5691 {{ 4.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5692 {{ 6.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5693 {{ 4.0f
, 0.0f
, 0.f
}, up
, RED
},
5695 {{ 3.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5696 {{ 3.0f
, 0.0f
, 0.f
}, up
, RED
},
5697 {{ 1.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5699 const DWORD indices8
[] = {0, 1, 2, 9, 10, 11, 6, 7, 8, 3, 4, 5};
5700 const WORD indices8_16bit
[] = {0, 1, 2, 9, 10, 11, 6, 7, 8, 3, 4, 5};
5701 const unsigned int num_vertices8
= ARRAY_SIZE(vertices8
);
5702 const unsigned int num_faces8
= num_vertices8
/ VERTS_PER_FACE
;
5703 const DWORD exp_adjacency8
[] = {-1, 1, -1, 2, -1, 0, -1, 3, 1, 2, -1, -1};
5704 const DWORD exp_id_adjacency8
[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
5705 const DWORD point_rep8
[] = {0, 1, 2, 3, 4, 5, 1, 4, 3, 1, 3, 2};
5706 /* mesh9 (right, shared vertices)
5713 const struct vertex_pnc vertices9
[] =
5715 {{ 0.0f
, 3.0f
, 0.f
}, up
, RED
},
5716 {{ 2.0f
, 3.0f
, 0.f
}, up
, GREEN
},
5717 {{ 0.0f
, 0.0f
, 0.f
}, up
, BLUE
},
5719 {{ 2.0f
, 0.0f
, 0.f
}, up
, RED
},
5721 const DWORD indices9
[] = {0, 1, 2, 1, 3, 2};
5722 const unsigned int num_vertices9
= ARRAY_SIZE(vertices9
);
5723 const unsigned int num_faces9
= 2;
5724 const DWORD exp_adjacency9
[] = {-1, 1, -1, -1, -1, 0};
5725 const DWORD exp_id_adjacency9
[] = {-1, 1, -1, -1, -1, 0};
5726 const DWORD point_rep9
[] = {0, 1, 2, 3};
5728 ID3DXMesh
*mesh
= NULL
;
5729 ID3DXMesh
*mesh_null_check
= NULL
;
5730 unsigned int attributes
[] = {0};
5733 const struct vertex_pnc
*vertices
;
5734 const DWORD
*indices
;
5735 const DWORD num_vertices
;
5736 const DWORD num_faces
;
5737 const DWORD
*point_reps
;
5738 const DWORD
*exp_adjacency
;
5739 const DWORD
*exp_id_adjacency
;
5740 const DWORD options
;
5846 (DWORD
*)indices8_16bit
,
5855 DWORD
*adjacency
= NULL
;
5857 test_context
= new_test_context();
5860 skip("Couldn't create test context\n");
5864 for (i
= 0; i
< ARRAY_SIZE(tc
); i
++)
5866 hr
= D3DXCreateMesh(tc
[i
].num_faces
, tc
[i
].num_vertices
, tc
[i
].options
,
5867 declaration
, test_context
->device
, &mesh
);
5870 skip("Couldn't create mesh %d. Got %x expected D3D_OK\n", i
, hr
);
5874 if (i
== 0) /* Save first mesh for later NULL checks */
5875 mesh_null_check
= mesh
;
5877 adjacency
= HeapAlloc(GetProcessHeap(), 0, VERTS_PER_FACE
* tc
[i
].num_faces
* sizeof(*adjacency
));
5880 skip("Couldn't allocate adjacency array.\n");
5884 hr
= mesh
->lpVtbl
->LockVertexBuffer(mesh
, 0, &vertex_buffer
);
5887 skip("Couldn't lock vertex buffer.\n");
5890 memcpy(vertex_buffer
, tc
[i
].vertices
, tc
[i
].num_vertices
* sizeof(*tc
[i
].vertices
));
5891 hr
= mesh
->lpVtbl
->UnlockVertexBuffer(mesh
);
5894 skip("Couldn't unlock vertex buffer.\n");
5897 hr
= mesh
->lpVtbl
->LockIndexBuffer(mesh
, 0, &index_buffer
);
5900 skip("Couldn't lock index buffer.\n");
5903 if (tc
[i
].options
& D3DXMESH_32BIT
)
5905 memcpy(index_buffer
, tc
[i
].indices
, VERTS_PER_FACE
* tc
[i
].num_faces
* sizeof(DWORD
));
5909 memcpy(index_buffer
, tc
[i
].indices
, VERTS_PER_FACE
* tc
[i
].num_faces
* sizeof(WORD
));
5911 hr
= mesh
->lpVtbl
->UnlockIndexBuffer(mesh
);
5913 skip("Couldn't unlock index buffer.\n");
5917 hr
= mesh
->lpVtbl
->LockAttributeBuffer(mesh
, 0, &attributes_buffer
);
5920 skip("Couldn't lock attributes buffer.\n");
5923 memcpy(attributes_buffer
, attributes
, sizeof(attributes
));
5924 hr
= mesh
->lpVtbl
->UnlockAttributeBuffer(mesh
);
5927 skip("Couldn't unlock attributes buffer.\n");
5931 /* Convert point representation to adjacency*/
5932 for (j
= 0; j
< VERTS_PER_FACE
* tc
[i
].num_faces
; j
++) adjacency
[j
] = -2;
5934 hr
= mesh
->lpVtbl
->ConvertPointRepsToAdjacency(mesh
, tc
[i
].point_reps
, adjacency
);
5935 ok(hr
== D3D_OK
, "ConvertPointRepsToAdjacency failed case %d. "
5936 "Got %x expected D3D_OK\n", i
, hr
);
5937 /* Check adjacency */
5938 for (j
= 0; j
< VERTS_PER_FACE
* tc
[i
].num_faces
; j
++)
5940 ok(adjacency
[j
] == tc
[i
].exp_adjacency
[j
],
5941 "Unexpected adjacency information at (%d, %d)."
5942 " Got %d expected %d\n",
5943 i
, j
, adjacency
[j
], tc
[i
].exp_adjacency
[j
]);
5946 /* NULL point representation is considered identity. */
5947 for (j
= 0; j
< VERTS_PER_FACE
* tc
[i
].num_faces
; j
++) adjacency
[j
] = -2;
5948 hr
= mesh_null_check
->lpVtbl
->ConvertPointRepsToAdjacency(mesh
, NULL
, adjacency
);
5949 ok(hr
== D3D_OK
, "ConvertPointRepsToAdjacency NULL point_reps. "
5950 "Got %x expected D3D_OK\n", hr
);
5951 for (j
= 0; j
< VERTS_PER_FACE
* tc
[i
].num_faces
; j
++)
5953 ok(adjacency
[j
] == tc
[i
].exp_id_adjacency
[j
],
5954 "Unexpected adjacency information (id) at (%d, %d)."
5955 " Got %d expected %d\n",
5956 i
, j
, adjacency
[j
], tc
[i
].exp_id_adjacency
[j
]);
5959 HeapFree(GetProcessHeap(), 0, adjacency
);
5961 if (i
!= 0) /* First mesh will be freed during cleanup */
5962 mesh
->lpVtbl
->Release(mesh
);
5966 hr
= mesh_null_check
->lpVtbl
->ConvertPointRepsToAdjacency(mesh_null_check
, tc
[0].point_reps
, NULL
);
5967 ok(hr
== D3DERR_INVALIDCALL
, "ConvertPointRepsToAdjacency NULL adjacency. "
5968 "Got %x expected D3DERR_INVALIDCALL\n", hr
);
5969 hr
= mesh_null_check
->lpVtbl
->ConvertPointRepsToAdjacency(mesh_null_check
, NULL
, NULL
);
5970 ok(hr
== D3DERR_INVALIDCALL
, "ConvertPointRepsToAdjacency NULL point_reps and adjacency. "
5971 "Got %x expected D3DERR_INVALIDCALL\n", hr
);
5974 if (mesh_null_check
)
5975 mesh_null_check
->lpVtbl
->Release(mesh_null_check
);
5976 HeapFree(GetProcessHeap(), 0, adjacency
);
5977 free_test_context(test_context
);
5980 static HRESULT
init_test_mesh(const DWORD num_faces
, const DWORD num_vertices
,
5981 const DWORD options
,
5982 const D3DVERTEXELEMENT9
*declaration
,
5983 IDirect3DDevice9
*device
, ID3DXMesh
**mesh_ptr
,
5984 const void *vertices
, const DWORD vertex_size
,
5985 const DWORD
*indices
, const DWORD
*attributes
)
5988 void *vertex_buffer
;
5990 DWORD
*attributes_buffer
;
5991 ID3DXMesh
*mesh
= NULL
;
5993 hr
= D3DXCreateMesh(num_faces
, num_vertices
, options
, declaration
, device
, mesh_ptr
);
5996 skip("Couldn't create mesh. Got %x expected D3D_OK\n", hr
);
6001 hr
= mesh
->lpVtbl
->LockVertexBuffer(mesh
, 0, &vertex_buffer
);
6004 skip("Couldn't lock vertex buffer.\n");
6007 memcpy(vertex_buffer
, vertices
, num_vertices
* vertex_size
);
6008 hr
= mesh
->lpVtbl
->UnlockVertexBuffer(mesh
);
6011 skip("Couldn't unlock vertex buffer.\n");
6015 hr
= mesh
->lpVtbl
->LockIndexBuffer(mesh
, 0, &index_buffer
);
6018 skip("Couldn't lock index buffer.\n");
6021 if (options
& D3DXMESH_32BIT
)
6024 memcpy(index_buffer
, indices
, 3 * num_faces
* sizeof(DWORD
));
6027 /* Fill index buffer with 0, 1, 2, ...*/
6028 DWORD
*indices_32bit
= (DWORD
*)index_buffer
;
6030 for (i
= 0; i
< 3 * num_faces
; i
++)
6031 indices_32bit
[i
] = i
;
6037 memcpy(index_buffer
, indices
, 3 * num_faces
* sizeof(WORD
));
6040 /* Fill index buffer with 0, 1, 2, ...*/
6041 WORD
*indices_16bit
= (WORD
*)index_buffer
;
6043 for (i
= 0; i
< 3 * num_faces
; i
++)
6044 indices_16bit
[i
] = i
;
6047 hr
= mesh
->lpVtbl
->UnlockIndexBuffer(mesh
);
6049 skip("Couldn't unlock index buffer.\n");
6053 hr
= mesh
->lpVtbl
->LockAttributeBuffer(mesh
, 0, &attributes_buffer
);
6056 skip("Couldn't lock attributes buffer.\n");
6061 memcpy(attributes_buffer
, attributes
, num_faces
* sizeof(*attributes
));
6063 memset(attributes_buffer
, 0, num_faces
* sizeof(*attributes
));
6065 hr
= mesh
->lpVtbl
->UnlockAttributeBuffer(mesh
);
6068 skip("Couldn't unlock attributes buffer.\n");
6077 /* Using structs instead of bit-fields in order to avoid compiler issues. */
6094 static DWORD
init_udec3_dword(UINT x
, UINT y
, UINT z
, UINT w
)
6099 d
|= (y
<< 10) & 0xffc00;
6100 d
|= (z
<< 20) & 0x3ff00000;
6101 d
|= (w
<< 30) & 0xc0000000;
6106 static DWORD
init_dec3n_dword(INT x
, INT y
, INT z
, INT w
)
6111 d
|= (y
<< 10) & 0xffc00;
6112 d
|= (z
<< 20) & 0x3ff00000;
6113 d
|= (w
<< 30) & 0xc0000000;
6118 static struct udec3
dword_to_udec3(DWORD d
)
6123 v
.y
= (d
& 0xffc00) >> 10;
6124 v
.z
= (d
& 0x3ff00000) >> 20;
6125 v
.w
= (d
& 0xc0000000) >> 30;
6130 static struct dec3n
dword_to_dec3n(DWORD d
)
6135 v
.y
= (d
& 0xffc00) >> 10;
6136 v
.z
= (d
& 0x3ff00000) >> 20;
6137 v
.w
= (d
& 0xc0000000) >> 30;
6142 static void check_vertex_components(int line
, int mesh_number
, int vertex_number
, BYTE
*got_ptr
, const BYTE
*exp_ptr
, D3DVERTEXELEMENT9
*declaration
)
6144 const char *usage_strings
[] =
6151 "texture coordinates",
6154 "tessellation factor",
6155 "position transformed",
6161 D3DVERTEXELEMENT9
*decl_ptr
;
6162 const float PRECISION
= 1e-5f
;
6164 for (decl_ptr
= declaration
; decl_ptr
->Stream
!= 0xFF; decl_ptr
++)
6166 switch (decl_ptr
->Type
)
6168 case D3DDECLTYPE_FLOAT1
:
6170 FLOAT
*got
= (FLOAT
*)(got_ptr
+ decl_ptr
->Offset
);
6171 FLOAT
*exp
= (FLOAT
*)(exp_ptr
+ decl_ptr
->Offset
);
6172 FLOAT diff
= fabsf(*got
- *exp
);
6173 ok_(__FILE__
,line
)(diff
<= PRECISION
, "Mesh %d: Got %f for vertex %d %s, expected %f.\n",
6174 mesh_number
, *got
, vertex_number
, usage_strings
[decl_ptr
->Usage
], *exp
);
6177 case D3DDECLTYPE_FLOAT2
:
6179 D3DXVECTOR2
*got
= (D3DXVECTOR2
*)(got_ptr
+ decl_ptr
->Offset
);
6180 D3DXVECTOR2
*exp
= (D3DXVECTOR2
*)(exp_ptr
+ decl_ptr
->Offset
);
6181 FLOAT diff
= max(fabsf(got
->x
- exp
->x
), fabsf(got
->y
- exp
->y
));
6182 ok_(__FILE__
,line
)(diff
<= PRECISION
, "Mesh %d: Got (%f, %f) for vertex %d %s, expected (%f, %f).\n",
6183 mesh_number
, got
->x
, got
->y
, vertex_number
, usage_strings
[decl_ptr
->Usage
], exp
->x
, exp
->y
);
6186 case D3DDECLTYPE_FLOAT3
:
6188 D3DXVECTOR3
*got
= (D3DXVECTOR3
*)(got_ptr
+ decl_ptr
->Offset
);
6189 D3DXVECTOR3
*exp
= (D3DXVECTOR3
*)(exp_ptr
+ decl_ptr
->Offset
);
6190 FLOAT diff
= max(fabsf(got
->x
- exp
->x
), fabsf(got
->y
- exp
->y
));
6191 diff
= max(diff
, fabsf(got
->z
- exp
->z
));
6192 ok_(__FILE__
,line
)(diff
<= PRECISION
, "Mesh %d: Got (%f, %f, %f) for vertex %d %s, expected (%f, %f, %f).\n",
6193 mesh_number
, got
->x
, got
->y
, got
->z
, vertex_number
, usage_strings
[decl_ptr
->Usage
], exp
->x
, exp
->y
, exp
->z
);
6196 case D3DDECLTYPE_FLOAT4
:
6198 D3DXVECTOR4
*got
= (D3DXVECTOR4
*)(got_ptr
+ decl_ptr
->Offset
);
6199 D3DXVECTOR4
*exp
= (D3DXVECTOR4
*)(exp_ptr
+ decl_ptr
->Offset
);
6200 FLOAT diff
= max(fabsf(got
->x
- exp
->x
), fabsf(got
->y
- exp
->y
));
6201 diff
= max(diff
, fabsf(got
->z
- exp
->z
));
6202 diff
= max(diff
, fabsf(got
->w
- exp
->w
));
6203 ok_(__FILE__
,line
)(diff
<= PRECISION
, "Mesh %d: Got (%f, %f, %f, %f) for vertex %d %s, expected (%f, %f, %f, %f).\n",
6204 mesh_number
, got
->x
, got
->y
, got
->z
, got
->w
, vertex_number
, usage_strings
[decl_ptr
->Usage
], exp
->x
, exp
->y
, exp
->z
, got
->w
);
6207 case D3DDECLTYPE_D3DCOLOR
:
6209 BYTE
*got
= got_ptr
+ decl_ptr
->Offset
;
6210 const BYTE
*exp
= exp_ptr
+ decl_ptr
->Offset
;
6211 BOOL same_color
= got
[0] == exp
[0] && got
[1] == exp
[1]
6212 && got
[2] == exp
[2] && got
[3] == exp
[3];
6213 const char *color_types
[] = {"diffuse", "specular", "undefined color"};
6214 BYTE usage_index
= decl_ptr
->UsageIndex
;
6215 if (usage_index
> 1) usage_index
= 2;
6216 ok_(__FILE__
,line
)(same_color
, "Mesh %d: Got (%u, %u, %u, %u) for vertex %d %s, expected (%u, %u, %u, %u).\n",
6217 mesh_number
, got
[0], got
[1], got
[2], got
[3], vertex_number
, color_types
[usage_index
], exp
[0], exp
[1], exp
[2], exp
[3]);
6220 case D3DDECLTYPE_UBYTE4
:
6221 case D3DDECLTYPE_UBYTE4N
:
6223 BYTE
*got
= got_ptr
+ decl_ptr
->Offset
;
6224 const BYTE
*exp
= exp_ptr
+ decl_ptr
->Offset
;
6225 BOOL same
= got
[0] == exp
[0] && got
[1] == exp
[1]
6226 && got
[2] == exp
[2] && got
[3] == exp
[3];
6227 ok_(__FILE__
,line
)(same
, "Mesh %d: Got (%u, %u, %u, %u) for vertex %d %s, expected (%u, %u, %u, %u).\n",
6228 mesh_number
, got
[0], got
[1], got
[2], got
[3], vertex_number
, usage_strings
[decl_ptr
->Usage
], exp
[0], exp
[1], exp
[2], exp
[3]);
6231 case D3DDECLTYPE_SHORT2
:
6232 case D3DDECLTYPE_SHORT2N
:
6234 SHORT
*got
= (SHORT
*)(got_ptr
+ decl_ptr
->Offset
);
6235 SHORT
*exp
= (SHORT
*)(exp_ptr
+ decl_ptr
->Offset
);
6236 BOOL same
= got
[0] == exp
[0] && got
[1] == exp
[1];
6237 ok_(__FILE__
,line
)(same
, "Mesh %d: Got (%hd, %hd) for vertex %d %s, expected (%hd, %hd).\n",
6238 mesh_number
, got
[0], got
[1], vertex_number
, usage_strings
[decl_ptr
->Usage
], exp
[0], exp
[1]);
6241 case D3DDECLTYPE_SHORT4
:
6242 case D3DDECLTYPE_SHORT4N
:
6244 SHORT
*got
= (SHORT
*)(got_ptr
+ decl_ptr
->Offset
);
6245 SHORT
*exp
= (SHORT
*)(exp_ptr
+ decl_ptr
->Offset
);
6246 BOOL same
= got
[0] == exp
[0] && got
[1] == exp
[1]
6247 && got
[2] == exp
[2] && got
[3] == exp
[3];
6248 ok_(__FILE__
,line
)(same
, "Mesh %d: Got (%hd, %hd, %hd, %hd) for vertex %d %s, expected (%hd, %hd, %hd, %hd).\n",
6249 mesh_number
, got
[0], got
[1], got
[2], got
[3], vertex_number
, usage_strings
[decl_ptr
->Usage
], exp
[0], exp
[1], exp
[2], exp
[3]);
6252 case D3DDECLTYPE_USHORT2N
:
6254 USHORT
*got
= (USHORT
*)(got_ptr
+ decl_ptr
->Offset
);
6255 USHORT
*exp
= (USHORT
*)(exp_ptr
+ decl_ptr
->Offset
);
6256 BOOL same
= got
[0] == exp
[0] && got
[1] == exp
[1];
6257 ok_(__FILE__
,line
)(same
, "Mesh %d: Got (%hu, %hu) for vertex %d %s, expected (%hu, %hu).\n",
6258 mesh_number
, got
[0], got
[1], vertex_number
, usage_strings
[decl_ptr
->Usage
], exp
[0], exp
[1]);
6261 case D3DDECLTYPE_USHORT4N
:
6263 USHORT
*got
= (USHORT
*)(got_ptr
+ decl_ptr
->Offset
);
6264 USHORT
*exp
= (USHORT
*)(exp_ptr
+ decl_ptr
->Offset
);
6265 BOOL same
= got
[0] == exp
[0] && got
[1] == exp
[1]
6266 && got
[2] == exp
[2] && got
[3] == exp
[3];
6267 ok_(__FILE__
,line
)(same
, "Mesh %d: Got (%hu, %hu, %hu, %hu) for vertex %d %s, expected (%hu, %hu, %hu, %hu).\n",
6268 mesh_number
, got
[0], got
[1], got
[2], got
[3], vertex_number
, usage_strings
[decl_ptr
->Usage
], exp
[0], exp
[1], exp
[2], exp
[3]);
6271 case D3DDECLTYPE_UDEC3
:
6273 DWORD
*got
= (DWORD
*)(got_ptr
+ decl_ptr
->Offset
);
6274 DWORD
*exp
= (DWORD
*)(exp_ptr
+ decl_ptr
->Offset
);
6275 BOOL same
= memcmp(got
, exp
, sizeof(*got
)) == 0;
6276 struct udec3 got_udec3
= dword_to_udec3(*got
);
6277 struct udec3 exp_udec3
= dword_to_udec3(*exp
);
6278 ok_(__FILE__
,line
)(same
, "Mesh %d: Got (%u, %u, %u, %u) for vertex %d %s, expected (%u, %u, %u, %u).\n",
6279 mesh_number
, got_udec3
.x
, got_udec3
.y
, got_udec3
.z
, got_udec3
.w
, vertex_number
, usage_strings
[decl_ptr
->Usage
], exp_udec3
.x
, exp_udec3
.y
, exp_udec3
.z
, exp_udec3
.w
);
6283 case D3DDECLTYPE_DEC3N
:
6285 DWORD
*got
= (DWORD
*)(got_ptr
+ decl_ptr
->Offset
);
6286 DWORD
*exp
= (DWORD
*)(exp_ptr
+ decl_ptr
->Offset
);
6287 BOOL same
= memcmp(got
, exp
, sizeof(*got
)) == 0;
6288 struct dec3n got_dec3n
= dword_to_dec3n(*got
);
6289 struct dec3n exp_dec3n
= dword_to_dec3n(*exp
);
6290 ok_(__FILE__
,line
)(same
, "Mesh %d: Got (%d, %d, %d, %d) for vertex %d %s, expected (%d, %d, %d, %d).\n",
6291 mesh_number
, got_dec3n
.x
, got_dec3n
.y
, got_dec3n
.z
, got_dec3n
.w
, vertex_number
, usage_strings
[decl_ptr
->Usage
], exp_dec3n
.x
, exp_dec3n
.y
, exp_dec3n
.z
, exp_dec3n
.w
);
6294 case D3DDECLTYPE_FLOAT16_2
:
6296 WORD
*got
= (WORD
*)(got_ptr
+ decl_ptr
->Offset
);
6297 WORD
*exp
= (WORD
*)(exp_ptr
+ decl_ptr
->Offset
);
6298 BOOL same
= got
[0] == exp
[0] && got
[1] == exp
[1];
6299 ok_(__FILE__
,line
)(same
, "Mesh %d: Got (%hx, %hx) for vertex %d %s, expected (%hx, %hx).\n",
6300 mesh_number
, got
[0], got
[1], vertex_number
, usage_strings
[decl_ptr
->Usage
], exp
[0], exp
[1]);
6303 case D3DDECLTYPE_FLOAT16_4
:
6305 WORD
*got
= (WORD
*)(got_ptr
+ decl_ptr
->Offset
);
6306 WORD
*exp
= (WORD
*)(exp_ptr
+ decl_ptr
->Offset
);
6307 BOOL same
= got
[0] == exp
[0] && got
[1] == exp
[1]
6308 && got
[2] == exp
[2] && got
[3] == exp
[3];
6309 ok_(__FILE__
,line
)(same
, "Mesh %d: Got (%hx, %hx, %hx, %hx) for vertex %d %s, expected (%hx, %hx, %hx, %hx).\n",
6310 mesh_number
, got
[0], got
[1], got
[2], got
[3], vertex_number
, usage_strings
[decl_ptr
->Usage
], exp
[0], exp
[1], exp
[3], exp
[4]);
6319 static void test_weld_vertices(void)
6322 struct test_context
*test_context
= NULL
;
6324 const DWORD options
= D3DXMESH_32BIT
| D3DXMESH_SYSTEMMEM
;
6325 const DWORD options_16bit
= D3DXMESH_SYSTEMMEM
;
6326 BYTE
*vertices
= NULL
;
6327 DWORD
*indices
= NULL
;
6328 WORD
*indices_16bit
= NULL
;
6329 const UINT VERTS_PER_FACE
= 3;
6330 const D3DXVECTOR3 up
= {0.0f
, 0.0f
, 1.0f
};
6331 struct vertex_normal
6333 D3DXVECTOR3 position
;
6336 struct vertex_blendweight
6338 D3DXVECTOR3 position
;
6341 struct vertex_texcoord
6343 D3DXVECTOR3 position
;
6344 D3DXVECTOR2 texcoord
;
6348 D3DXVECTOR3 position
;
6351 struct vertex_color_ubyte4
6353 D3DXVECTOR3 position
;
6356 struct vertex_texcoord_short2
6358 D3DXVECTOR3 position
;
6361 struct vertex_texcoord_ushort2n
6363 D3DXVECTOR3 position
;
6366 struct vertex_normal_short4
6368 D3DXVECTOR3 position
;
6371 struct vertex_color_float4
6373 D3DXVECTOR3 position
;
6376 struct vertex_texcoord_float16_2
6378 D3DXVECTOR3 position
;
6381 struct vertex_texcoord_float16_4
6383 D3DXVECTOR3 position
;
6386 struct vertex_normal_udec3
6388 D3DXVECTOR3 position
;
6391 struct vertex_normal_dec3n
6393 D3DXVECTOR3 position
;
6396 UINT vertex_size_normal
= sizeof(struct vertex_normal
);
6397 UINT vertex_size_blendweight
= sizeof(struct vertex_blendweight
);
6398 UINT vertex_size_texcoord
= sizeof(struct vertex_texcoord
);
6399 UINT vertex_size_color
= sizeof(struct vertex_color
);
6400 UINT vertex_size_color_ubyte4
= sizeof(struct vertex_color_ubyte4
);
6401 UINT vertex_size_texcoord_short2
= sizeof(struct vertex_texcoord_short2
);
6402 UINT vertex_size_normal_short4
= sizeof(struct vertex_normal_short4
);
6403 UINT vertex_size_color_float4
= sizeof(struct vertex_color_float4
);
6404 UINT vertex_size_texcoord_float16_2
= sizeof(struct vertex_texcoord_float16_2
);
6405 UINT vertex_size_texcoord_float16_4
= sizeof(struct vertex_texcoord_float16_4
);
6406 UINT vertex_size_normal_udec3
= sizeof(struct vertex_normal_udec3
);
6407 UINT vertex_size_normal_dec3n
= sizeof(struct vertex_normal_dec3n
);
6408 D3DVERTEXELEMENT9 declaration_normal
[] =
6410 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
6411 {0, 12, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
6414 D3DVERTEXELEMENT9 declaration_normal3
[] =
6416 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 3},
6417 {0, 12, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
6420 D3DVERTEXELEMENT9 declaration_blendweight
[] =
6422 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
6423 {0, 12, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_BLENDWEIGHT
, 0},
6426 D3DVERTEXELEMENT9 declaration_texcoord
[] =
6428 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
6429 {0, 12, D3DDECLTYPE_FLOAT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
6432 D3DVERTEXELEMENT9 declaration_color
[] =
6434 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
6435 {0, 12, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 0},
6438 D3DVERTEXELEMENT9 declaration_color_ubyte4n
[] =
6440 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
6441 {0, 12, D3DDECLTYPE_UBYTE4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 0},
6444 D3DVERTEXELEMENT9 declaration_color_ubyte4
[] =
6446 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
6447 {0, 12, D3DDECLTYPE_UBYTE4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 0},
6450 D3DVERTEXELEMENT9 declaration_texcoord_short2
[] =
6452 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
6453 {0, 12, D3DDECLTYPE_SHORT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
6456 D3DVERTEXELEMENT9 declaration_texcoord_short2n
[] =
6458 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
6459 {0, 12, D3DDECLTYPE_SHORT2N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
6462 D3DVERTEXELEMENT9 declaration_texcoord_ushort2n
[] =
6464 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
6465 {0, 12, D3DDECLTYPE_USHORT2N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
6468 D3DVERTEXELEMENT9 declaration_normal_short4
[] =
6470 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
6471 {0, 12, D3DDECLTYPE_SHORT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
6474 D3DVERTEXELEMENT9 declaration_normal_short4n
[] =
6476 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
6477 {0, 12, D3DDECLTYPE_SHORT4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
6480 D3DVERTEXELEMENT9 declaration_normal_ushort4n
[] =
6482 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
6483 {0, 12, D3DDECLTYPE_USHORT4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
6486 D3DVERTEXELEMENT9 declaration_texcoord10
[] =
6488 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
6489 {0, 12, D3DDECLTYPE_FLOAT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 10},
6492 D3DVERTEXELEMENT9 declaration_color2
[] =
6494 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
6495 {0, 12, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 2},
6498 D3DVERTEXELEMENT9 declaration_color2_float4
[] =
6500 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
6501 {0, 12, D3DDECLTYPE_FLOAT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 2},
6504 D3DVERTEXELEMENT9 declaration_texcoord_float16_2
[] =
6506 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
6507 {0, 12, D3DDECLTYPE_FLOAT16_2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
6510 D3DVERTEXELEMENT9 declaration_texcoord_float16_4
[] =
6512 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
6513 {0, 12, D3DDECLTYPE_FLOAT16_4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
6516 D3DVERTEXELEMENT9 declaration_normal_udec3
[] =
6518 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
6519 {0, 12, D3DDECLTYPE_UDEC3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
6522 D3DVERTEXELEMENT9 declaration_normal_dec3n
[] =
6524 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
6525 {0, 12, D3DDECLTYPE_DEC3N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
6528 /* Test 0. One face and no welding.
6535 const struct vertex vertices0
[] =
6537 {{ 0.0f
, 3.0f
, 0.f
}, up
},
6538 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6539 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6541 const DWORD indices0
[] = {0, 1, 2};
6542 const DWORD attributes0
[] = {0};
6543 const DWORD exp_indices0
[] = {0, 1, 2};
6544 const UINT num_vertices0
= ARRAY_SIZE(vertices0
);
6545 const UINT num_faces0
= ARRAY_SIZE(indices0
) / VERTS_PER_FACE
;
6546 const DWORD flags0
= D3DXWELDEPSILONS_WELDALL
;
6547 /* epsilons0 is NULL */
6548 const DWORD adjacency0
[] = {-1, -1, -1};
6549 const struct vertex exp_vertices0
[] =
6551 {{ 0.0f
, 3.0f
, 0.f
}, up
},
6552 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6553 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6555 const DWORD exp_face_remap0
[] = {0};
6556 const DWORD exp_vertex_remap0
[] = {0, 1, 2};
6557 const DWORD exp_new_num_vertices0
= ARRAY_SIZE(exp_vertices0
);
6558 /* Test 1. Two vertices should be removed without regard to epsilon.
6565 const struct vertex_normal vertices1
[] =
6567 {{ 0.0f
, 3.0f
, 0.f
}, up
},
6568 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6569 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6571 {{ 3.0f
, 3.0f
, 0.f
}, up
},
6572 {{ 3.0f
, 0.0f
, 0.f
}, up
},
6573 {{ 1.0f
, 0.0f
, 0.f
}, up
},
6575 const DWORD indices1
[] = {0, 1, 2, 3, 4, 5};
6576 const DWORD attributes1
[] = {0, 0};
6577 const UINT num_vertices1
= ARRAY_SIZE(vertices1
);
6578 const UINT num_faces1
= ARRAY_SIZE(indices1
) / VERTS_PER_FACE
;
6579 const DWORD flags1
= D3DXWELDEPSILONS_WELDALL
;
6580 /* epsilons1 is NULL */
6581 const DWORD adjacency1
[] = {-1, 1, -1, -1, -1, 0};
6582 const struct vertex_normal exp_vertices1
[] =
6584 {{ 0.0f
, 3.0f
, 0.f
}, up
},
6585 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6586 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6588 {{ 3.0f
, 0.0f
, 0.f
}, up
}
6590 const DWORD exp_indices1
[] = {0, 1, 2, 1, 3, 2};
6591 const DWORD exp_face_remap1
[] = {0, 1};
6592 const DWORD exp_vertex_remap1
[] = {0, 1, 2, 4, -1, -1};
6593 const DWORD exp_new_num_vertices1
= ARRAY_SIZE(exp_vertices1
);
6594 /* Test 2. Two faces. No vertices should be removed because of normal
6595 * epsilon, but the positions should be replaced. */
6596 const struct vertex_normal vertices2
[] =
6598 {{ 0.0f
, 3.0f
, 0.f
}, up
},
6599 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6600 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6602 {{ 3.0f
, 3.0f
, 0.f
}, {0.0f
, 0.5f
, 0.5f
}},
6603 {{ 3.0f
, 0.0f
, 0.f
}, up
},
6604 {{ 1.0f
, 0.0f
, 0.f
}, {0.2f
, 0.4f
, 0.4f
}},
6606 const DWORD indices2
[] = {0, 1, 2, 3, 4, 5};
6607 const DWORD attributes2
[] = {0, 0};
6608 const UINT num_vertices2
= ARRAY_SIZE(vertices2
);
6609 const UINT num_faces2
= ARRAY_SIZE(indices2
) / VERTS_PER_FACE
;
6610 DWORD flags2
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
6611 const D3DXWELDEPSILONS epsilons2
= {1.0f
, 0.0f
, 0.499999f
, 0.0f
, 0.0f
, 0.0f
, {0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
6612 const DWORD adjacency2
[] = {-1, 1, -1, -1, -1, 0};
6613 const struct vertex_normal exp_vertices2
[] =
6615 {{ 0.0f
, 3.0f
, 0.f
}, up
},
6616 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6617 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6619 {{ 2.0f
, 3.0f
, 0.f
}, {0.0f
, 0.5f
, 0.5f
}},
6620 {{ 3.0f
, 0.0f
, 0.f
}, up
},
6621 {{ 0.0f
, 0.0f
, 0.f
}, {0.2f
, 0.4f
, 0.4f
}},
6623 const DWORD exp_indices2
[] = {0, 1, 2, 3, 4, 5};
6624 const DWORD exp_face_remap2
[] = {0, 1};
6625 const DWORD exp_vertex_remap2
[] = {0, 1, 2, 3, 4, 5};
6626 const DWORD exp_new_num_vertices2
= ARRAY_SIZE(exp_vertices2
);
6627 /* Test 3. Two faces. One vertex should be removed because of normal epsilon. */
6628 const struct vertex_normal vertices3
[] =
6630 {{ 0.0f
, 3.0f
, 0.f
}, up
},
6631 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6632 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6634 {{ 3.0f
, 3.0f
, 0.f
}, {0.0f
, 0.5f
, 0.5f
}},
6635 {{ 3.0f
, 0.0f
, 0.f
}, up
},
6636 {{ 1.0f
, 0.0f
, 0.f
}, {0.2f
, 0.4f
, 0.4f
}},
6638 const DWORD indices3
[] = {0, 1, 2, 3, 4, 5};
6639 const DWORD attributes3
[] = {0, 0};
6640 const UINT num_vertices3
= ARRAY_SIZE(vertices3
);
6641 const UINT num_faces3
= ARRAY_SIZE(indices3
) / VERTS_PER_FACE
;
6642 DWORD flags3
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
6643 const D3DXWELDEPSILONS epsilons3
= {1.0f
, 0.0f
, 0.5f
, 0.0f
, 0.0f
, 0.0f
, {0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
6644 const DWORD adjacency3
[] = {-1, 1, -1, -1, -1, 0};
6645 const struct vertex_normal exp_vertices3
[] =
6647 {{ 0.0f
, 3.0f
, 0.f
}, up
},
6648 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6649 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6651 {{ 3.0f
, 0.0f
, 0.f
}, up
},
6652 {{ 0.0f
, 0.0f
, 0.f
}, {0.2f
, 0.4f
, 0.4f
}},
6654 const DWORD exp_indices3
[] = {0, 1, 2, 1, 3, 4};
6655 const DWORD exp_face_remap3
[] = {0, 1};
6656 const DWORD exp_vertex_remap3
[] = {0, 1, 2, 4, 5, -1};
6657 const DWORD exp_new_num_vertices3
= ARRAY_SIZE(exp_vertices3
);
6658 /* Test 4 Two faces. Two vertices should be removed. */
6659 const struct vertex_normal vertices4
[] =
6661 {{ 0.0f
, 3.0f
, 0.f
}, up
},
6662 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6663 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6665 {{ 3.0f
, 3.0f
, 0.f
}, {0.0f
, 0.5f
, 0.5f
}},
6666 {{ 3.0f
, 0.0f
, 0.f
}, up
},
6667 {{ 1.0f
, 0.0f
, 0.f
}, {0.2f
, 0.4f
, 0.4f
}},
6669 const DWORD indices4
[] = {0, 1, 2, 3, 4, 5};
6670 const DWORD attributes4
[] = {0, 0};
6671 const UINT num_vertices4
= ARRAY_SIZE(vertices4
);
6672 const UINT num_faces4
= ARRAY_SIZE(indices4
) / VERTS_PER_FACE
;
6673 DWORD flags4
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
6674 const D3DXWELDEPSILONS epsilons4
= {1.0f
, 0.0f
, 0.6f
, 0.0f
, 0.0f
, 0.0f
, {0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
6675 const DWORD adjacency4
[] = {-1, 1, -1, -1, -1, 0};
6676 const struct vertex_normal exp_vertices4
[] =
6678 {{ 0.0f
, 3.0f
, 0.f
}, up
},
6679 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6680 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6682 {{ 3.0f
, 0.0f
, 0.f
}, up
},
6684 const DWORD exp_indices4
[] = {0, 1, 2, 1, 3, 2};
6685 const DWORD exp_face_remap4
[] = {0, 1};
6686 const DWORD exp_vertex_remap4
[] = {0, 1, 2, 4, -1, -1};
6687 const DWORD exp_new_num_vertices4
= ARRAY_SIZE(exp_vertices4
);
6688 /* Test 5. Odd face ordering.
6695 const struct vertex_normal vertices5
[] =
6697 {{ 0.0f
, 3.0f
, 0.f
}, up
},
6698 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6699 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6701 {{ 3.0f
, 3.0f
, 0.f
}, up
},
6702 {{ 3.0f
, 0.0f
, 0.f
}, up
},
6703 {{ 1.0f
, 0.0f
, 0.f
}, up
},
6705 {{ 4.0f
, 3.0f
, 0.f
}, up
},
6706 {{ 6.0f
, 0.0f
, 0.f
}, up
},
6707 {{ 4.0f
, 0.0f
, 0.f
}, up
},
6709 const DWORD indices5
[] = {0, 1, 2, 6, 7, 8, 3, 4, 5};
6710 const DWORD exp_indices5
[] = {0, 1, 2, 1, 4, 2, 1, 3, 4};
6711 const DWORD attributes5
[] = {0, 0, 0};
6712 const UINT num_vertices5
= ARRAY_SIZE(vertices5
);
6713 const UINT num_faces5
= ARRAY_SIZE(indices5
) / VERTS_PER_FACE
;
6714 DWORD flags5
= D3DXWELDEPSILONS_WELDALL
;
6715 const DWORD adjacency5
[] = {-1, 1, -1, 2, -1, 0, -1, -1, 1};
6716 const struct vertex_normal exp_vertices5
[] =
6718 {{ 0.0f
, 3.0f
, 0.f
}, up
},
6719 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6720 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6722 {{ 3.0f
, 0.0f
, 0.f
}, up
},
6723 {{ 1.0f
, 0.0f
, 0.f
}, up
},
6725 const DWORD exp_face_remap5
[] = {0, 1, 2};
6726 const DWORD exp_vertex_remap5
[] = {0, 1, 2, 4, 5, -1, -1, -1, -1};
6727 const DWORD exp_new_num_vertices5
= ARRAY_SIZE(exp_vertices5
);
6728 /* Test 6. Two faces. Do not remove flag is used, so no vertices should be
6730 const struct vertex_normal vertices6
[] =
6732 {{ 0.0f
, 3.0f
, 0.f
}, up
},
6733 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6734 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6736 {{ 3.0f
, 3.0f
, 0.f
}, {0.0f
, 0.5f
, 0.5f
}},
6737 {{ 3.0f
, 0.0f
, 0.f
}, up
},
6738 {{ 1.0f
, 0.0f
, 0.f
}, {0.2f
, 0.4f
, 0.4f
}},
6740 const DWORD indices6
[] = {0, 1, 2, 3, 4, 5};
6741 const DWORD attributes6
[] = {0, 0};
6742 const UINT num_vertices6
= ARRAY_SIZE(vertices6
);
6743 const UINT num_faces6
= ARRAY_SIZE(indices6
) / VERTS_PER_FACE
;
6744 DWORD flags6
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
| D3DXWELDEPSILONS_DONOTREMOVEVERTICES
;
6745 const D3DXWELDEPSILONS epsilons6
= {1.0f
, 0.0f
, 0.6f
, 0.0f
, 0.0f
, 0.0f
, {0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
6746 const DWORD adjacency6
[] = {-1, 1, -1, -1, -1, 0};
6747 const struct vertex_normal exp_vertices6
[] =
6749 {{ 0.0f
, 3.0f
, 0.f
}, up
},
6750 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6751 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6753 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6754 {{ 3.0f
, 0.0f
, 0.f
}, up
},
6755 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6758 const DWORD exp_indices6
[] = {0, 1, 2, 3, 4, 5};
6759 const DWORD exp_face_remap6
[] = {0, 1};
6760 const DWORD exp_vertex_remap6
[] = {0, 1, 2, 3, 4, 5};
6761 const DWORD exp_new_num_vertices6
= ARRAY_SIZE(exp_vertices6
);
6762 /* Test 7. Same as test 6 but with 16 bit indices. */
6763 const WORD indices6_16bit
[] = {0, 1, 2, 3, 4, 5};
6764 /* Test 8. No flags. Same result as D3DXWELDEPSILONS_WELDPARTIALMATCHES. */
6765 const struct vertex_normal vertices8
[] =
6767 {{ 0.0f
, 3.0f
, 0.f
}, up
},
6768 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6769 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6771 {{ 3.0f
, 3.0f
, 0.f
}, {0.0f
, 0.5f
, 0.5f
}},
6772 {{ 3.0f
, 0.0f
, 0.f
}, up
},
6773 {{ 1.0f
, 0.0f
, 0.f
}, {0.2f
, 0.4f
, 0.4f
}},
6775 const DWORD indices8
[] = {0, 1, 2, 1, 3, 4};
6776 const DWORD attributes8
[] = {0, 0};
6777 const UINT num_vertices8
= ARRAY_SIZE(vertices8
);
6778 const UINT num_faces8
= ARRAY_SIZE(indices8
) / VERTS_PER_FACE
;
6780 const D3DXWELDEPSILONS epsilons8
= {1.0f
, 0.0f
, 0.5f
, 0.0f
, 0.0f
, 0.0f
, {0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
6781 const DWORD adjacency8
[] = {-1, 1, -1, -1, -1, 0};
6782 const struct vertex_normal exp_vertices8
[] =
6784 {{ 0.0f
, 3.0f
, 0.f
}, up
},
6785 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6786 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6788 {{ 3.0f
, 3.0f
, 0.f
}, {0.0f
, 0.5f
, 0.5f
}},
6789 {{ 3.0f
, 0.0f
, 0.f
}, up
},
6791 const DWORD exp_indices8
[] = {0, 1, 2, 1, 3, 4};
6792 const DWORD exp_face_remap8
[] = {0, 1};
6793 const DWORD exp_vertex_remap8
[] = {0, 1, 2, 3, 4, -1};
6794 const DWORD exp_new_num_vertices8
= ARRAY_SIZE(exp_vertices8
);
6795 /* Test 9. Vertices are removed even though they belong to separate
6796 * attribute groups if D3DXWELDEPSILONS_DONOTSPLIT is set. */
6797 const struct vertex_normal vertices9
[] =
6799 {{ 0.0f
, 3.0f
, 0.f
}, up
},
6800 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6801 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6803 {{ 3.0f
, 3.0f
, 0.f
}, {0.0f
, 0.5f
, 0.5f
}},
6804 {{ 3.0f
, 0.0f
, 0.f
}, up
},
6805 {{ 1.0f
, 0.0f
, 0.f
}, {0.2f
, 0.4f
, 0.4f
}},
6807 const DWORD indices9
[] = {0, 1, 2, 3, 4, 5};
6808 const DWORD attributes9
[] = {0, 1};
6809 const UINT num_vertices9
= ARRAY_SIZE(vertices9
);
6810 const UINT num_faces9
= ARRAY_SIZE(indices9
) / VERTS_PER_FACE
;
6811 DWORD flags9
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
| D3DXWELDEPSILONS_DONOTSPLIT
;
6812 const D3DXWELDEPSILONS epsilons9
= {1.0f
, 0.0f
, 0.6f
, 0.0f
, 0.0f
, 0.0f
, {0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
6813 const DWORD adjacency9
[] = {-1, 1, -1, -1, -1, 0};
6814 const struct vertex_normal exp_vertices9
[] =
6816 {{ 0.0f
, 3.0f
, 0.f
}, up
},
6817 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6818 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6820 {{ 3.0f
, 0.0f
, 0.f
}, up
},
6822 const DWORD exp_indices9
[] = {0, 1, 2, 1, 3, 2};
6823 const DWORD exp_face_remap9
[] = {0, 1};
6824 const DWORD exp_vertex_remap9
[] = {0, 1, 2, 4, -1, -1};
6825 const DWORD exp_new_num_vertices9
= ARRAY_SIZE(exp_vertices9
);
6826 /* Test 10. Weld blendweight (FLOAT1). */
6827 const struct vertex_blendweight vertices10
[] =
6829 {{ 0.0f
, 3.0f
, 0.f
}, 1.0f
},
6830 {{ 2.0f
, 3.0f
, 0.f
}, 1.0f
},
6831 {{ 0.0f
, 0.0f
, 0.f
}, 1.0f
},
6833 {{ 3.0f
, 3.0f
, 0.f
}, 0.9},
6834 {{ 3.0f
, 0.0f
, 0.f
}, 1.0},
6835 {{ 1.0f
, 0.0f
, 0.f
}, 0.4},
6837 const DWORD indices10
[] = {0, 1, 2, 3, 4, 5};
6838 const DWORD attributes10
[] = {0, 0};
6839 const UINT num_vertices10
= ARRAY_SIZE(vertices10
);
6840 const UINT num_faces10
= ARRAY_SIZE(indices10
) / VERTS_PER_FACE
;
6841 DWORD flags10
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
6842 const D3DXWELDEPSILONS epsilons10
= {1.0f
, 0.1f
+ FLT_EPSILON
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, {0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
6843 const DWORD adjacency10
[] = {-1, 1, -1, -1, -1, 0};
6844 const struct vertex_blendweight exp_vertices10
[] =
6846 {{ 0.0f
, 3.0f
, 0.f
}, 1.0f
},
6847 {{ 2.0f
, 3.0f
, 0.f
}, 1.0f
},
6848 {{ 0.0f
, 0.0f
, 0.f
}, 1.0f
},
6850 {{ 3.0f
, 0.0f
, 0.f
}, 1.0},
6851 {{ 0.0f
, 0.0f
, 0.f
}, 0.4},
6853 const DWORD exp_indices10
[] = {0, 1, 2, 1, 3, 4};
6854 const DWORD exp_face_remap10
[] = {0, 1};
6855 const DWORD exp_vertex_remap10
[] = {0, 1, 2, 4, 5, -1};
6856 const DWORD exp_new_num_vertices10
= ARRAY_SIZE(exp_vertices10
);
6857 /* Test 11. Weld texture coordinates. */
6858 const struct vertex_texcoord vertices11
[] =
6860 {{ 0.0f
, 3.0f
, 0.f
}, {1.0f
, 1.0f
}},
6861 {{ 2.0f
, 3.0f
, 0.f
}, {0.5f
, 0.7f
}},
6862 {{ 0.0f
, 0.0f
, 0.f
}, {-0.2f
, -0.3f
}},
6864 {{ 3.0f
, 3.0f
, 0.f
}, {0.2f
, 0.3f
}},
6865 {{ 3.0f
, 0.0f
, 0.f
}, {1.0f
, 1.0f
}},
6866 {{ 1.0f
, 0.0f
, 0.f
}, {0.1f
, 0.2f
}}
6868 const DWORD indices11
[] = {0, 1, 2, 3, 4, 5};
6869 const DWORD attributes11
[] = {0, 0};
6870 const UINT num_vertices11
= ARRAY_SIZE(vertices11
);
6871 const UINT num_faces11
= ARRAY_SIZE(indices11
) / VERTS_PER_FACE
;
6872 DWORD flags11
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
6873 const D3DXWELDEPSILONS epsilons11
= {1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, {0.4f
+ FLT_EPSILON
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
6874 const DWORD adjacency11
[] = {-1, 1, -1, -1, -1, 0};
6875 const struct vertex_texcoord exp_vertices11
[] =
6877 {{ 0.0f
, 3.0f
, 0.f
}, {1.0f
, 1.0f
}},
6878 {{ 2.0f
, 3.0f
, 0.f
}, {0.5f
, 0.7f
}},
6879 {{ 0.0f
, 0.0f
, 0.f
}, {-0.2f
, -0.3f
}},
6881 {{ 3.0f
, 0.0f
, 0.f
}, {1.0f
, 1.0f
}},
6882 {{ 0.0f
, 0.0f
, 0.f
}, {0.1f
, 0.2f
}},
6884 const DWORD exp_indices11
[] = {0, 1, 2, 1, 3, 4};
6885 const DWORD exp_face_remap11
[] = {0, 1};
6886 const DWORD exp_vertex_remap11
[] = {0, 1, 2, 4, 5, -1};
6887 const DWORD exp_new_num_vertices11
= ARRAY_SIZE(exp_vertices11
);
6888 /* Test 12. Weld with color. */
6889 const struct vertex_color vertices12
[] =
6891 {{ 0.0f
, 3.0f
, 0.f
}, 0xFFFFFFFF},
6892 {{ 2.0f
, 3.0f
, 0.f
}, 0xFFFFFFFF},
6893 {{ 0.0f
, 0.0f
, 0.f
}, 0xFFFFFFFF},
6895 {{ 3.0f
, 3.0f
, 0.f
}, 0x00000000},
6896 {{ 3.0f
, 0.0f
, 0.f
}, 0xFFFFFFFF},
6897 {{ 1.0f
, 0.0f
, 0.f
}, 0x88888888},
6899 const DWORD indices12
[] = {0, 1, 2, 3, 4, 5};
6900 const DWORD attributes12
[] = {0, 0};
6901 const UINT num_vertices12
= ARRAY_SIZE(vertices12
);
6902 const UINT num_faces12
= ARRAY_SIZE(indices12
) / VERTS_PER_FACE
;
6903 DWORD flags12
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
6904 const D3DXWELDEPSILONS epsilons12
= {1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.5f
, {0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
6905 const DWORD adjacency12
[] = {-1, 1, -1, -1, -1, 0};
6906 const struct vertex_color exp_vertices12
[] =
6908 {{ 0.0f
, 3.0f
, 0.f
}, 0xFFFFFFFF},
6909 {{ 2.0f
, 3.0f
, 0.f
}, 0xFFFFFFFF},
6910 {{ 0.0f
, 0.0f
, 0.f
}, 0xFFFFFFFF},
6912 {{ 2.0f
, 3.0f
, 0.f
}, 0x00000000},
6913 {{ 3.0f
, 0.0f
, 0.f
}, 0xFFFFFFFF},
6915 const DWORD exp_indices12
[] = {0, 1, 2, 3, 4, 2};
6916 const DWORD exp_face_remap12
[] = {0, 1};
6917 const DWORD exp_vertex_remap12
[] = {0, 1, 2, 3, 4, -1};
6918 const DWORD exp_new_num_vertices12
= ARRAY_SIZE(exp_vertices12
);
6919 /* Test 13. Two faces. One vertex should be removed because of normal epsilon.
6920 * This is similar to test 3, but the declaration has been changed to NORMAL3.
6922 const struct vertex_normal vertices13
[] =
6924 {{ 0.0f
, 3.0f
, 0.f
}, up
},
6925 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6926 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6928 {{ 3.0f
, 3.0f
, 0.f
}, {0.0f
, 0.5f
, 0.5f
}},
6929 {{ 3.0f
, 0.0f
, 0.f
}, up
},
6930 {{ 1.0f
, 0.0f
, 0.f
}, {0.2f
, 0.4f
, 0.4f
}},
6932 const DWORD indices13
[] = {0, 1, 2, 3, 4, 5};
6933 const DWORD attributes13
[] = {0, 0};
6934 const UINT num_vertices13
= ARRAY_SIZE(vertices3
);
6935 const UINT num_faces13
= ARRAY_SIZE(indices3
) / VERTS_PER_FACE
;
6936 DWORD flags13
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
6937 const D3DXWELDEPSILONS epsilons13
= {1.0f
, 0.0f
, 0.5f
, 0.0f
, 0.0f
, 0.0f
, {0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
6938 const DWORD adjacency13
[] = {-1, 1, -1, -1, -1, 0};
6939 const struct vertex_normal exp_vertices13
[] =
6941 {{ 0.0f
, 3.0f
, 0.f
}, up
},
6942 {{ 2.0f
, 3.0f
, 0.f
}, up
},
6943 {{ 0.0f
, 0.0f
, 0.f
}, up
},
6945 {{ 3.0f
, 0.0f
, 0.f
}, up
},
6946 {{ 0.0f
, 0.0f
, 0.f
}, {0.2f
, 0.4f
, 0.4f
}},
6948 const DWORD exp_indices13
[] = {0, 1, 2, 1, 3, 4};
6949 const DWORD exp_face_remap13
[] = {0, 1};
6950 const DWORD exp_vertex_remap13
[] = {0, 1, 2, 4, 5, -1};
6951 const DWORD exp_new_num_vertices13
= ARRAY_SIZE(exp_vertices13
);
6952 /* Test 14. Another test for welding with color. */
6953 const struct vertex_color vertices14
[] =
6955 {{ 0.0f
, 3.0f
, 0.f
}, 0xFFFFFFFF},
6956 {{ 2.0f
, 3.0f
, 0.f
}, 0xFFFFFFFF},
6957 {{ 0.0f
, 0.0f
, 0.f
}, 0xFFFFFFFF},
6959 {{ 3.0f
, 3.0f
, 0.f
}, 0x00000000},
6960 {{ 3.0f
, 0.0f
, 0.f
}, 0xFFFFFFFF},
6961 {{ 1.0f
, 0.0f
, 0.f
}, 0x01010101},
6963 const DWORD indices14
[] = {0, 1, 2, 3, 4, 5};
6964 const DWORD attributes14
[] = {0, 0};
6965 const UINT num_vertices14
= ARRAY_SIZE(vertices14
);
6966 const UINT num_faces14
= ARRAY_SIZE(indices14
) / VERTS_PER_FACE
;
6967 DWORD flags14
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
6968 const D3DXWELDEPSILONS epsilons14
= {1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 254.0f
/255.0f
, {0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
6969 const DWORD adjacency14
[] = {-1, 1, -1, -1, -1, 0};
6970 const struct vertex_color exp_vertices14
[] =
6972 {{ 0.0f
, 3.0f
, 0.f
}, 0xFFFFFFFF},
6973 {{ 2.0f
, 3.0f
, 0.f
}, 0xFFFFFFFF},
6974 {{ 0.0f
, 0.0f
, 0.f
}, 0xFFFFFFFF},
6976 {{ 2.0f
, 3.0f
, 0.f
}, 0x00000000},
6977 {{ 3.0f
, 0.0f
, 0.f
}, 0xFFFFFFFF},
6979 const DWORD exp_indices14
[] = {0, 1, 2, 3, 4, 2};
6980 const DWORD exp_face_remap14
[] = {0, 1};
6981 const DWORD exp_vertex_remap14
[] = {0, 1, 2, 3, 4, -1};
6982 const DWORD exp_new_num_vertices14
= ARRAY_SIZE(exp_vertices14
);
6983 /* Test 15. Weld with color, but as UBYTE4N instead of D3DCOLOR. It shows
6984 * that UBYTE4N and D3DCOLOR are compared the same way.
6986 const struct vertex_color_ubyte4 vertices15
[] =
6988 {{ 0.0f
, 3.0f
, 0.f
}, {255, 255, 255, 255}},
6989 {{ 2.0f
, 3.0f
, 0.f
}, {255, 255, 255, 255}},
6990 {{ 0.0f
, 0.0f
, 0.f
}, {255, 255, 255, 255}},
6992 {{ 3.0f
, 3.0f
, 0.f
}, { 0, 0, 0, 0}},
6993 {{ 3.0f
, 0.0f
, 0.f
}, {255, 255, 255, 255}},
6994 {{ 1.0f
, 0.0f
, 0.f
}, { 1, 1, 1, 1}},
6996 const DWORD indices15
[] = {0, 1, 2, 3, 4, 5};
6997 const DWORD attributes15
[] = {0, 0};
6998 const UINT num_vertices15
= ARRAY_SIZE(vertices15
);
6999 const UINT num_faces15
= ARRAY_SIZE(indices15
) / VERTS_PER_FACE
;
7000 DWORD flags15
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
7001 const D3DXWELDEPSILONS epsilons15
= {1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 254.0f
/255.0f
, {0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
7002 const DWORD adjacency15
[] = {-1, 1, -1, -1, -1, 0};
7003 const struct vertex_color_ubyte4 exp_vertices15
[] =
7005 {{ 0.0f
, 3.0f
, 0.f
}, {255, 255, 255, 255}},
7006 {{ 2.0f
, 3.0f
, 0.f
}, {255, 255, 255, 255}},
7007 {{ 0.0f
, 0.0f
, 0.f
}, {255, 255, 255, 255}},
7009 {{ 2.0f
, 3.0f
, 0.f
}, { 0, 0, 0, 0}},
7010 {{ 3.0f
, 0.0f
, 0.f
}, {255, 255, 255, 255}},
7012 const DWORD exp_indices15
[] = {0, 1, 2, 3, 4, 2};
7013 const DWORD exp_face_remap15
[] = {0, 1};
7014 const DWORD exp_vertex_remap15
[] = {0, 1, 2, 3, 4, -1};
7015 const DWORD exp_new_num_vertices15
= ARRAY_SIZE(exp_vertices15
);
7016 /* Test 16. Weld with color, but as UBYTE4 instead of D3DCOLOR. It shows
7017 * that UBYTE4 is not normalized and that epsilon is truncated and compared
7018 * directly to each of the four bytes.
7020 const struct vertex_color_ubyte4 vertices16
[] =
7022 {{ 0.0f
, 3.0f
, 0.f
}, {255, 255, 255, 255}},
7023 {{ 2.0f
, 3.0f
, 0.f
}, {255, 255, 255, 255}},
7024 {{ 0.0f
, 0.0f
, 0.f
}, {255, 255, 255, 255}},
7026 {{ 3.0f
, 3.0f
, 0.f
}, { 0, 0, 0, 0}},
7027 {{ 3.0f
, 0.0f
, 0.f
}, {255, 255, 255, 255}},
7028 {{ 1.0f
, 0.0f
, 0.f
}, { 1, 1, 1, 1}},
7030 const DWORD indices16
[] = {0, 1, 2, 3, 4, 5};
7031 const DWORD attributes16
[] = {0, 0};
7032 const UINT num_vertices16
= ARRAY_SIZE(vertices16
);
7033 const UINT num_faces16
= ARRAY_SIZE(indices16
) / VERTS_PER_FACE
;
7034 DWORD flags16
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
7035 const D3DXWELDEPSILONS epsilons16
= {1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 254.9f
, {0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
7036 const DWORD adjacency16
[] = {-1, 1, -1, -1, -1, 0};
7037 const struct vertex_color_ubyte4 exp_vertices16
[] =
7039 {{ 0.0f
, 3.0f
, 0.f
}, {255, 255, 255, 255}},
7040 {{ 2.0f
, 3.0f
, 0.f
}, {255, 255, 255, 255}},
7041 {{ 0.0f
, 0.0f
, 0.f
}, {255, 255, 255, 255}},
7043 {{ 2.0f
, 3.0f
, 0.f
}, { 0, 0, 0, 0}},
7044 {{ 3.0f
, 0.0f
, 0.f
}, {255, 255, 255, 255}},
7046 const DWORD exp_indices16
[] = {0, 1, 2, 3, 4, 2};
7047 const DWORD exp_face_remap16
[] = {0, 1};
7048 const DWORD exp_vertex_remap16
[] = {0, 1, 2, 3, 4, -1};
7049 const DWORD exp_new_num_vertices16
= ARRAY_SIZE(exp_vertices16
);
7050 /* Test 17. Weld texture coordinates but as SHORT2 instead of D3DXVECTOR2.*/
7051 const struct vertex_texcoord_short2 vertices17
[] =
7053 {{ 0.0f
, 3.0f
, 0.f
}, { 0, 0}},
7054 {{ 2.0f
, 3.0f
, 0.f
}, { 0, 0}},
7055 {{ 0.0f
, 0.0f
, 0.f
}, { 0, 0}},
7057 {{ 3.0f
, 3.0f
, 0.f
}, {32767, 32767}},
7058 {{ 3.0f
, 0.0f
, 0.f
}, {0, 0}},
7059 {{ 1.0f
, 0.0f
, 0.f
}, {32766, 32766}},
7061 const DWORD indices17
[] = {0, 1, 2, 3, 4, 5};
7062 const DWORD attributes17
[] = {0, 0};
7063 const UINT num_vertices17
= ARRAY_SIZE(vertices17
);
7064 const UINT num_faces17
= ARRAY_SIZE(indices17
) / VERTS_PER_FACE
;
7065 DWORD flags17
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
7066 const D3DXWELDEPSILONS epsilons17
= {1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, {32766.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
7067 const DWORD adjacency17
[] = {-1, 1, -1, -1, -1, 0};
7068 const struct vertex_texcoord_short2 exp_vertices17
[] =
7070 {{ 0.0f
, 3.0f
, 0.f
}, { 0, 0}},
7071 {{ 2.0f
, 3.0f
, 0.f
}, { 0, 0}},
7072 {{ 0.0f
, 0.0f
, 0.f
}, { 0, 0}},
7074 {{ 2.0f
, 3.0f
, 0.f
}, {32767, 32767}},
7075 {{ 3.0f
, 0.0f
, 0.f
}, {0, 0}},
7077 const DWORD exp_indices17
[] = {0, 1, 2, 3, 4, 2};
7078 const DWORD exp_face_remap17
[] = {0, 1};
7079 const DWORD exp_vertex_remap17
[] = {0, 1, 2, 3, 4, -1};
7080 const DWORD exp_new_num_vertices17
= ARRAY_SIZE(exp_vertices17
);
7081 /* Test 18. Weld texture coordinates but as SHORT2N instead of D3DXVECTOR2. */
7082 const struct vertex_texcoord_short2 vertices18
[] =
7084 {{ 0.0f
, 3.0f
, 0.f
}, { 0, 0}},
7085 {{ 2.0f
, 3.0f
, 0.f
}, { 0, 0}},
7086 {{ 0.0f
, 0.0f
, 0.f
}, { 0, 0}},
7088 {{ 3.0f
, 3.0f
, 0.f
}, {32767, 32767}},
7089 {{ 3.0f
, 0.0f
, 0.f
}, {0, 0}},
7090 {{ 1.0f
, 0.0f
, 0.f
}, {32766, 32766}},
7092 const DWORD indices18
[] = {0, 1, 2, 3, 4, 5};
7093 const DWORD attributes18
[] = {0, 0};
7094 const UINT num_vertices18
= ARRAY_SIZE(vertices18
);
7095 const UINT num_faces18
= ARRAY_SIZE(indices18
) / VERTS_PER_FACE
;
7096 DWORD flags18
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
7097 const D3DXWELDEPSILONS epsilons18
= {1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, {32766.0f
/32767.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
7098 const DWORD adjacency18
[] = {-1, 1, -1, -1, -1, 0};
7099 const struct vertex_texcoord_short2 exp_vertices18
[] =
7101 {{ 0.0f
, 3.0f
, 0.f
}, { 0, 0}},
7102 {{ 2.0f
, 3.0f
, 0.f
}, { 0, 0}},
7103 {{ 0.0f
, 0.0f
, 0.f
}, { 0, 0}},
7105 {{ 2.0f
, 3.0f
, 0.f
}, {32767, 32767}},
7106 {{ 3.0f
, 0.0f
, 0.f
}, {0, 0}},
7108 const DWORD exp_indices18
[] = {0, 1, 2, 3, 4, 2};
7109 const DWORD exp_face_remap18
[] = {0, 1};
7110 const DWORD exp_vertex_remap18
[] = {0, 1, 2, 3, 4, -1};
7111 const DWORD exp_new_num_vertices18
= ARRAY_SIZE(exp_vertices18
);
7112 /* Test 19. Weld texture coordinates but as USHORT2N instead of D3DXVECTOR2. */
7113 const struct vertex_texcoord_ushort2n vertices19
[] =
7115 {{ 0.0f
, 3.0f
, 0.f
}, { 0, 0}},
7116 {{ 2.0f
, 3.0f
, 0.f
}, { 0, 0}},
7117 {{ 0.0f
, 0.0f
, 0.f
}, { 0, 0}},
7119 {{ 3.0f
, 3.0f
, 0.f
}, {65535, 65535}},
7120 {{ 3.0f
, 0.0f
, 0.f
}, {0, 0}},
7121 {{ 1.0f
, 0.0f
, 0.f
}, {65534, 65534}},
7123 const DWORD indices19
[] = {0, 1, 2, 3, 4, 5};
7124 const DWORD attributes19
[] = {0, 0};
7125 const UINT num_vertices19
= ARRAY_SIZE(vertices19
);
7126 const UINT num_faces19
= ARRAY_SIZE(indices19
) / VERTS_PER_FACE
;
7127 DWORD flags19
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
7128 const D3DXWELDEPSILONS epsilons19
= {1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, {65534.0f
/65535.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
7129 const DWORD adjacency19
[] = {-1, 1, -1, -1, -1, 0};
7130 const struct vertex_texcoord_ushort2n exp_vertices19
[] =
7132 {{ 0.0f
, 3.0f
, 0.f
}, { 0, 0}},
7133 {{ 2.0f
, 3.0f
, 0.f
}, { 0, 0}},
7134 {{ 0.0f
, 0.0f
, 0.f
}, { 0, 0}},
7136 {{ 2.0f
, 3.0f
, 0.f
}, {65535, 65535}},
7137 {{ 3.0f
, 0.0f
, 0.f
}, {0, 0}},
7139 const DWORD exp_indices19
[] = {0, 1, 2, 3, 4, 2};
7140 const DWORD exp_face_remap19
[] = {0, 1};
7141 const DWORD exp_vertex_remap19
[] = {0, 1, 2, 3, 4, -1};
7142 const DWORD exp_new_num_vertices19
= ARRAY_SIZE(exp_vertices19
);
7143 /* Test 20. Weld normal as SHORT4 instead of D3DXVECTOR3. */
7144 const struct vertex_normal_short4 vertices20
[] =
7146 {{ 0.0f
, 3.0f
, 0.f
}, {0, 0, 0, 0}},
7147 {{ 2.0f
, 3.0f
, 0.f
}, {0, 0, 0, 0}},
7148 {{ 0.0f
, 0.0f
, 0.f
}, {0, 0, 0, 0}},
7150 {{ 3.0f
, 3.0f
, 0.f
}, {32767, 32767, 32767, 32767}},
7151 {{ 3.0f
, 0.0f
, 0.f
}, {0, 0, 0, 0}},
7152 {{ 1.0f
, 0.0f
, 0.f
}, {32766, 32766, 32766, 32766}},
7154 const DWORD indices20
[] = {0, 1, 2, 3, 4, 5};
7155 const DWORD attributes20
[] = {0, 0};
7156 const UINT num_vertices20
= ARRAY_SIZE(vertices20
);
7157 const UINT num_faces20
= ARRAY_SIZE(indices20
) / VERTS_PER_FACE
;
7158 DWORD flags20
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
7159 const D3DXWELDEPSILONS epsilons20
= {1.0f
, 0.0f
, 32766.0f
, 0.0f
, 0.0f
, 0.0f
, {0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
7160 const DWORD adjacency20
[] = {-1, 1, -1, -1, -1, 0};
7161 const struct vertex_normal_short4 exp_vertices20
[] =
7163 {{ 0.0f
, 3.0f
, 0.f
}, {0, 0, 0, 0}},
7164 {{ 2.0f
, 3.0f
, 0.f
}, {0, 0, 0, 0}},
7165 {{ 0.0f
, 0.0f
, 0.f
}, {0, 0, 0, 0}},
7167 {{ 2.0f
, 3.0f
, 0.f
}, {32767, 32767, 32767, 32767}},
7168 {{ 3.0f
, 0.0f
, 0.f
}, {0, 0, 0, 0}},
7170 const DWORD exp_indices20
[] = {0, 1, 2, 3, 4, 2};
7171 const DWORD exp_face_remap20
[] = {0, 1};
7172 const DWORD exp_vertex_remap20
[] = {0, 1, 2, 3, 4, -1};
7173 const DWORD exp_new_num_vertices20
= ARRAY_SIZE(exp_vertices20
);
7174 /* Test 21. Weld normal as SHORT4N instead of D3DXVECTOR3. */
7175 const struct vertex_normal_short4 vertices21
[] =
7177 {{ 0.0f
, 3.0f
, 0.f
}, {0, 0, 0, 0}},
7178 {{ 2.0f
, 3.0f
, 0.f
}, {0, 0, 0, 0}},
7179 {{ 0.0f
, 0.0f
, 0.f
}, {0, 0, 0, 0}},
7181 {{ 3.0f
, 3.0f
, 0.f
}, {32767, 32767, 32767, 32767}},
7182 {{ 3.0f
, 0.0f
, 0.f
}, {0, 0, 0, 0}},
7183 {{ 1.0f
, 0.0f
, 0.f
}, {32766, 32766, 32766, 32766}},
7185 const DWORD indices21
[] = {0, 1, 2, 3, 4, 5};
7186 const DWORD attributes21
[] = {0, 0};
7187 const UINT num_vertices21
= ARRAY_SIZE(vertices21
);
7188 const UINT num_faces21
= ARRAY_SIZE(indices21
) / VERTS_PER_FACE
;
7189 DWORD flags21
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
7190 const D3DXWELDEPSILONS epsilons21
= {1.0f
, 0.0f
, 32766.0f
/32767.0f
, 0.0f
, 0.0f
, 0.0f
, {0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
7191 const DWORD adjacency21
[] = {-1, 1, -1, -1, -1, 0};
7192 const struct vertex_normal_short4 exp_vertices21
[] =
7194 {{ 0.0f
, 3.0f
, 0.f
}, {0, 0, 0, 0}},
7195 {{ 2.0f
, 3.0f
, 0.f
}, {0, 0, 0, 0}},
7196 {{ 0.0f
, 0.0f
, 0.f
}, {0, 0, 0, 0}},
7198 {{ 2.0f
, 3.0f
, 0.f
}, {32767, 32767, 32767, 32767}},
7199 {{ 3.0f
, 0.0f
, 0.f
}, {0, 0, 0, 0}},
7201 const DWORD exp_indices21
[] = {0, 1, 2, 3, 4, 2};
7202 const DWORD exp_face_remap21
[] = {0, 1};
7203 const DWORD exp_vertex_remap21
[] = {0, 1, 2, 3, 4, -1};
7204 const DWORD exp_new_num_vertices21
= ARRAY_SIZE(exp_vertices21
);
7205 /* Test 22. Weld normal as USHORT4N instead of D3DXVECTOR3. */
7206 const struct vertex_normal_short4 vertices22
[] =
7208 {{ 0.0f
, 3.0f
, 0.f
}, {0, 0, 0, 0}},
7209 {{ 2.0f
, 3.0f
, 0.f
}, {0, 0, 0, 0}},
7210 {{ 0.0f
, 0.0f
, 0.f
}, {0, 0, 0, 0}},
7212 {{ 3.0f
, 3.0f
, 0.f
}, {65535, 65535, 65535, 65535}},
7213 {{ 3.0f
, 0.0f
, 0.f
}, {0, 0, 0, 0}},
7214 {{ 1.0f
, 0.0f
, 0.f
}, {65534, 65534, 65534, 65534}},
7216 const DWORD indices22
[] = {0, 1, 2, 3, 4, 5};
7217 const DWORD attributes22
[] = {0, 0};
7218 const UINT num_vertices22
= ARRAY_SIZE(vertices22
);
7219 const UINT num_faces22
= ARRAY_SIZE(indices22
) / VERTS_PER_FACE
;
7220 DWORD flags22
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
7221 const D3DXWELDEPSILONS epsilons22
= {1.0f
, 0.0f
, 65534.0f
/65535.0f
, 0.0f
, 0.0f
, 0.0f
, {0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
7222 const DWORD adjacency22
[] = {-1, 1, -1, -1, -1, 0};
7223 const struct vertex_normal_short4 exp_vertices22
[] =
7225 {{ 0.0f
, 3.0f
, 0.f
}, {0, 0, 0, 0}},
7226 {{ 2.0f
, 3.0f
, 0.f
}, {0, 0, 0, 0}},
7227 {{ 0.0f
, 0.0f
, 0.f
}, {0, 0, 0, 0}},
7229 {{ 2.0f
, 3.0f
, 0.f
}, {65535, 65535, 65535, 65535}},
7230 {{ 3.0f
, 0.0f
, 0.f
}, {0, 0, 0, 0}},
7232 const DWORD exp_indices22
[] = {0, 1, 2, 3, 4, 2};
7233 const DWORD exp_face_remap22
[] = {0, 1};
7234 const DWORD exp_vertex_remap22
[] = {0, 1, 2, 3, 4, -1};
7235 const DWORD exp_new_num_vertices22
= ARRAY_SIZE(exp_vertices22
);
7236 /* Test 23. Weld texture coordinates as FLOAT16_2. Similar to test 11, but
7237 * with texture coordinates converted to float16 in hex. */
7238 const struct vertex_texcoord_float16_2 vertices23
[] =
7240 {{ 0.0f
, 3.0f
, 0.f
}, {0x3c00, 0x3c00}}, /* {1.0f, 1.0f} */
7241 {{ 2.0f
, 3.0f
, 0.f
}, {0x3800, 0x399a}}, /* {0.5f, 0.7f} */
7242 {{ 0.0f
, 0.0f
, 0.f
}, {0xb266, 0xb4cd}}, /* {-0.2f, -0.3f} */
7244 {{ 3.0f
, 3.0f
, 0.f
}, {0x3266, 0x34cd}}, /* {0.2f, 0.3f} */
7245 {{ 3.0f
, 0.0f
, 0.f
}, {0x3c00, 0x3c00}}, /* {1.0f, 1.0f} */
7246 {{ 1.0f
, 0.0f
, 0.f
}, {0x2e66, 0x3266}}, /* {0.1f, 0.2f} */
7248 const DWORD indices23
[] = {0, 1, 2, 3, 4, 5};
7249 const DWORD attributes23
[] = {0, 0};
7250 const UINT num_vertices23
= ARRAY_SIZE(vertices23
);
7251 const UINT num_faces23
= ARRAY_SIZE(indices23
) / VERTS_PER_FACE
;
7252 DWORD flags23
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
7253 const D3DXWELDEPSILONS epsilons23
= {1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, {0.41f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
7254 const DWORD adjacency23
[] = {-1, 1, -1, -1, -1, 0};
7255 const struct vertex_texcoord_float16_2 exp_vertices23
[] =
7257 {{ 0.0f
, 3.0f
, 0.f
}, {0x3c00, 0x3c00}}, /* {1.0f, 1.0f} */
7258 {{ 2.0f
, 3.0f
, 0.f
}, {0x3800, 0x399a}}, /* {0.5f, 0.7f} */
7259 {{ 0.0f
, 0.0f
, 0.f
}, {0xb266, 0xb4cd}}, /* {-0.2f, -0.3f} */
7261 {{ 3.0f
, 0.0f
, 0.f
}, {0x3c00, 0x3c00}}, /* {1.0f, 1.0f} */
7262 {{ 0.0f
, 0.0f
, 0.f
}, {0x2e66, 0x3266}}, /* {0.1f, 0.2f} */
7264 const DWORD exp_indices23
[] = {0, 1, 2, 1, 3, 4};
7265 const DWORD exp_face_remap23
[] = {0, 1};
7266 const DWORD exp_vertex_remap23
[] = {0, 1, 2, 4, 5, -1};
7267 const DWORD exp_new_num_vertices23
= ARRAY_SIZE(exp_vertices23
);
7268 /* Test 24. Weld texture coordinates as FLOAT16_4. Similar to test 24. */
7269 const struct vertex_texcoord_float16_4 vertices24
[] =
7271 {{ 0.0f
, 3.0f
, 0.f
}, {0x3c00, 0x3c00, 0x3c00, 0x3c00}},
7272 {{ 2.0f
, 3.0f
, 0.f
}, {0x3800, 0x399a, 0x3800, 0x399a}},
7273 {{ 0.0f
, 0.0f
, 0.f
}, {0xb266, 0xb4cd, 0xb266, 0xb4cd}},
7275 {{ 3.0f
, 3.0f
, 0.f
}, {0x3266, 0x34cd, 0x3266, 0x34cd}},
7276 {{ 3.0f
, 0.0f
, 0.f
}, {0x3c00, 0x3c00, 0x3c00, 0x3c00}},
7277 {{ 1.0f
, 0.0f
, 0.f
}, {0x2e66, 0x3266, 0x2e66, 0x3266}},
7279 const DWORD indices24
[] = {0, 1, 2, 3, 4, 5};
7280 const DWORD attributes24
[] = {0, 0};
7281 const UINT num_vertices24
= ARRAY_SIZE(vertices24
);
7282 const UINT num_faces24
= ARRAY_SIZE(indices24
) / VERTS_PER_FACE
;
7283 DWORD flags24
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
7284 const D3DXWELDEPSILONS epsilons24
= {1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, {0.41f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
7285 const DWORD adjacency24
[] = {-1, 1, -1, -1, -1, 0};
7286 const struct vertex_texcoord_float16_4 exp_vertices24
[] =
7288 {{ 0.0f
, 3.0f
, 0.f
}, {0x3c00, 0x3c00, 0x3c00, 0x3c00}},
7289 {{ 2.0f
, 3.0f
, 0.f
}, {0x3800, 0x399a, 0x3800, 0x399a}},
7290 {{ 0.0f
, 0.0f
, 0.f
}, {0xb266, 0xb4cd, 0xb266, 0xb4cd}},
7292 {{ 3.0f
, 0.0f
, 0.f
}, {0x3c00, 0x3c00, 0x3c00, 0x3c00}},
7293 {{ 0.0f
, 0.0f
, 0.f
}, {0x2e66, 0x3266, 0x2e66, 0x3266}},
7295 const DWORD exp_indices24
[] = {0, 1, 2, 1, 3, 4};
7296 const DWORD exp_face_remap24
[] = {0, 1};
7297 const DWORD exp_vertex_remap24
[] = {0, 1, 2, 4, 5, -1};
7298 const DWORD exp_new_num_vertices24
= ARRAY_SIZE(exp_vertices24
);
7299 /* Test 25. Weld texture coordinates with usage index 10 (TEXCOORD10). The
7300 * usage index is capped at 7, so the epsilon for TEXCOORD7 is used instead.
7302 const struct vertex_texcoord vertices25
[] =
7304 {{ 0.0f
, 3.0f
, 0.f
}, {1.0f
, 1.0f
}},
7305 {{ 2.0f
, 3.0f
, 0.f
}, {0.5f
, 0.7f
}},
7306 {{ 0.0f
, 0.0f
, 0.f
}, {-0.2f
, -0.3f
}},
7308 {{ 3.0f
, 3.0f
, 0.f
}, {0.2f
, 0.3f
}},
7309 {{ 3.0f
, 0.0f
, 0.f
}, {1.0f
, 1.0f
}},
7310 {{ 1.0f
, 0.0f
, 0.f
}, {0.1f
, 0.2f
}}
7312 const DWORD indices25
[] = {0, 1, 2, 3, 4, 5};
7313 const DWORD attributes25
[] = {0, 0};
7314 const UINT num_vertices25
= ARRAY_SIZE(vertices25
);
7315 const UINT num_faces25
= ARRAY_SIZE(indices25
) / VERTS_PER_FACE
;
7316 DWORD flags25
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
7317 const D3DXWELDEPSILONS epsilons25
= {1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, {0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.4f
+ FLT_EPSILON
}, 0.0f
, 0.0f
, 0.0f
};
7318 const DWORD adjacency25
[] = {-1, 1, -1, -1, -1, 0};
7319 const struct vertex_texcoord exp_vertices25
[] =
7321 {{ 0.0f
, 3.0f
, 0.f
}, {1.0f
, 1.0f
}},
7322 {{ 2.0f
, 3.0f
, 0.f
}, {0.5f
, 0.7f
}},
7323 {{ 0.0f
, 0.0f
, 0.f
}, {-0.2f
, -0.3f
}},
7325 {{ 3.0f
, 0.0f
, 0.f
}, {1.0f
, 1.0f
}},
7326 {{ 0.0f
, 0.0f
, 0.f
}, {0.1f
, 0.2f
}},
7328 const DWORD exp_indices25
[] = {0, 1, 2, 1, 3, 4};
7329 const DWORD exp_face_remap25
[] = {0, 1};
7330 const DWORD exp_vertex_remap25
[] = {0, 1, 2, 4, 5, -1};
7331 const DWORD exp_new_num_vertices25
= ARRAY_SIZE(exp_vertices25
);
7332 /* Test 26. Weld color with usage index larger than 1. Shows that none of
7333 * the epsilon values are used. */
7334 const struct vertex_color vertices26
[] =
7336 {{ 0.0f
, 3.0f
, 0.f
}, 0xFFFFFFFF},
7337 {{ 2.0f
, 3.0f
, 0.f
}, 0xFFFFFFFF},
7338 {{ 0.0f
, 0.0f
, 0.f
}, 0xFFFFFFFF},
7340 {{ 3.0f
, 3.0f
, 0.f
}, 0x00000000},
7341 {{ 3.0f
, 0.0f
, 0.f
}, 0xFFFFFFFF},
7342 {{ 1.0f
, 0.0f
, 0.f
}, 0x01010101},
7344 const DWORD indices26
[] = {0, 1, 2, 3, 4, 5};
7345 const DWORD attributes26
[] = {0, 0};
7346 const UINT num_vertices26
= ARRAY_SIZE(vertices26
);
7347 const UINT num_faces26
= ARRAY_SIZE(indices26
) / VERTS_PER_FACE
;
7348 DWORD flags26
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
7349 const D3DXWELDEPSILONS epsilons26
= {1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, {1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
}, 1.0f
, 1.0f
, 1.0f
};
7350 const DWORD adjacency26
[] = {-1, 1, -1, -1, -1, 0};
7351 const struct vertex_color exp_vertices26
[] =
7353 {{ 0.0f
, 3.0f
, 0.f
}, 0xFFFFFFFF},
7354 {{ 2.0f
, 3.0f
, 0.f
}, 0xFFFFFFFF},
7355 {{ 0.0f
, 0.0f
, 0.f
}, 0xFFFFFFFF},
7357 {{ 2.0f
, 3.0f
, 0.f
}, 0x00000000},
7358 {{ 3.0f
, 0.0f
, 0.f
}, 0xFFFFFFFF},
7359 {{ 0.0f
, 0.0f
, 0.f
}, 0x01010101},
7361 const DWORD exp_indices26
[] = {0, 1, 2, 3, 4, 5};
7362 const DWORD exp_face_remap26
[] = {0, 1};
7363 const DWORD exp_vertex_remap26
[] = {0, 1, 2, 3, 4, 5};
7364 const DWORD exp_new_num_vertices26
= ARRAY_SIZE(exp_vertices26
);
7365 /* Test 27. Weld color with usage index larger than 1. Check that the
7366 * default epsilon of 1e-6f is used. */
7367 D3DXVECTOR4 zero_float4
= {0.0f
, 0.0f
, 0.0f
, 0.0f
};
7368 D3DXVECTOR4 almost_zero_float4
= {0.0f
+ FLT_EPSILON
, 0.0f
+ FLT_EPSILON
, 0.0f
+ FLT_EPSILON
, 0.0f
+ FLT_EPSILON
};
7369 const struct vertex_color_float4 vertices27
[] =
7371 {{ 0.0f
, 3.0f
, 0.f
}, zero_float4
},
7372 {{ 2.0f
, 3.0f
, 0.f
}, zero_float4
},
7373 {{ 0.0f
, 0.0f
, 0.f
}, zero_float4
},
7375 {{ 3.0f
, 3.0f
, 0.f
}, almost_zero_float4
},
7376 {{ 3.0f
, 0.0f
, 0.f
}, zero_float4
},
7377 {{ 1.0f
, 0.0f
, 0.f
}, almost_zero_float4
},
7379 const DWORD indices27
[] = {0, 1, 2, 3, 4, 5};
7380 const DWORD attributes27
[] = {0, 0};
7381 const UINT num_vertices27
= ARRAY_SIZE(vertices27
);
7382 const UINT num_faces27
= ARRAY_SIZE(indices27
) / VERTS_PER_FACE
;
7383 DWORD flags27
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
7384 const D3DXWELDEPSILONS epsilons27
= {1.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, {0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
7385 const DWORD adjacency27
[] = {-1, 1, -1, -1, -1, 0};
7386 const struct vertex_color_float4 exp_vertices27
[] =
7388 {{ 0.0f
, 3.0f
, 0.f
}, zero_float4
},
7389 {{ 2.0f
, 3.0f
, 0.f
}, zero_float4
},
7390 {{ 0.0f
, 0.0f
, 0.f
}, zero_float4
},
7392 {{ 3.0f
, 0.0f
, 0.f
}, zero_float4
},
7394 const DWORD exp_indices27
[] = {0, 1, 2, 1, 3, 2};
7395 const DWORD exp_face_remap27
[] = {0, 1};
7396 const DWORD exp_vertex_remap27
[] = {0, 1, 2, 4, -1, -1};
7397 const DWORD exp_new_num_vertices27
= ARRAY_SIZE(exp_vertices27
);
7398 /* Test 28. Weld one normal with UDEC3. */
7399 const DWORD dword_udec3_zero
= init_udec3_dword(0, 0, 0, 1);
7400 const DWORD dword_udec3_1023
= init_udec3_dword(1023, 1023, 1023, 1);
7401 const DWORD dword_udec3_1022
= init_udec3_dword(1022, 1022, 1022, 1);
7402 const struct vertex_normal_udec3 vertices28
[] =
7404 {{ 0.0f
, 3.0f
, 0.f
}, dword_udec3_zero
},
7405 {{ 2.0f
, 3.0f
, 0.f
}, dword_udec3_zero
},
7406 {{ 0.0f
, 0.0f
, 0.f
}, dword_udec3_zero
},
7408 {{ 3.0f
, 3.0f
, 0.f
}, dword_udec3_1023
},
7409 {{ 3.0f
, 0.0f
, 0.f
}, dword_udec3_zero
},
7410 {{ 1.0f
, 0.0f
, 0.f
}, dword_udec3_1022
},
7412 const DWORD indices28
[] = {0, 1, 2, 3, 4, 5};
7413 const DWORD attributes28
[] = {0, 0};
7414 const UINT num_vertices28
= ARRAY_SIZE(vertices28
);
7415 const UINT num_faces28
= ARRAY_SIZE(indices28
) / VERTS_PER_FACE
;
7416 DWORD flags28
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
7417 const D3DXWELDEPSILONS epsilons28
= {1.0f
, 0.0f
, 1022.0f
, 0.0f
, 0.0f
, 0.0f
, {0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0.0f
, 0.0f
, 0.0f
};
7418 const DWORD adjacency28
[] = {-1, 1, -1, -1, -1, 0};
7419 const struct vertex_normal_udec3 exp_vertices28
[] =
7421 {{ 0.0f
, 3.0f
, 0.f
}, dword_udec3_zero
},
7422 {{ 2.0f
, 3.0f
, 0.f
}, dword_udec3_zero
},
7423 {{ 0.0f
, 0.0f
, 0.f
}, dword_udec3_zero
},
7425 {{ 2.0f
, 3.0f
, 0.f
}, dword_udec3_1023
},
7426 {{ 3.0f
, 0.0f
, 0.f
}, dword_udec3_zero
},
7428 const DWORD exp_indices28
[] = {0, 1, 2, 3, 4, 2};
7429 const DWORD exp_face_remap28
[] = {0, 1};
7430 const DWORD exp_vertex_remap28
[] = {0, 1, 2, 3, 4, -1};
7431 const DWORD exp_new_num_vertices28
= ARRAY_SIZE(exp_vertices28
);
7432 /* Test 29. Weld one normal with DEC3N. */
7433 const DWORD dword_dec3n_zero
= init_dec3n_dword(0, 0, 0, 1);
7434 const DWORD dword_dec3n_511
= init_dec3n_dword(511, 511, 511, 1);
7435 const DWORD dword_dec3n_510
= init_dec3n_dword(510, 510, 510, 1);
7436 const struct vertex_normal_dec3n vertices29
[] =
7438 {{ 0.0f
, 3.0f
, 0.f
}, dword_dec3n_zero
},
7439 {{ 2.0f
, 3.0f
, 0.f
}, dword_dec3n_zero
},
7440 {{ 0.0f
, 0.0f
, 0.f
}, dword_dec3n_zero
},
7442 {{ 3.0f
, 3.0f
, 0.f
}, dword_dec3n_511
},
7443 {{ 3.0f
, 0.0f
, 0.f
}, dword_dec3n_zero
},
7444 {{ 1.0f
, 0.0f
, 0.f
}, dword_dec3n_510
},
7446 const DWORD indices29
[] = {0, 1, 2, 3, 4, 5};
7447 const DWORD attributes29
[] = {0, 0};
7448 const UINT num_vertices29
= ARRAY_SIZE(vertices29
);
7449 const UINT num_faces29
= ARRAY_SIZE(indices29
) / VERTS_PER_FACE
;
7450 DWORD flags29
= D3DXWELDEPSILONS_WELDPARTIALMATCHES
;
7451 const D3DXWELDEPSILONS epsilons29
= {1.0f
, 0.0f
, 510.0f
/511.0f
, 0.0f
, 0.0f
, 0.0f
, {0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, .0f
}, 0.0f
, 0.0f
, 0.0f
};
7452 const DWORD adjacency29
[] = {-1, 1, -1, -1, -1, 0};
7453 const struct vertex_normal_dec3n exp_vertices29
[] =
7455 {{ 0.0f
, 3.0f
, 0.f
}, dword_dec3n_zero
},
7456 {{ 2.0f
, 3.0f
, 0.f
}, dword_dec3n_zero
},
7457 {{ 0.0f
, 0.0f
, 0.f
}, dword_dec3n_zero
},
7459 {{ 2.0f
, 3.0f
, 0.f
}, dword_dec3n_511
},
7460 {{ 3.0f
, 0.0f
, 0.f
}, dword_dec3n_zero
},
7462 const DWORD exp_indices29
[] = {0, 1, 2, 3, 4, 2};
7463 const DWORD exp_face_remap29
[] = {0, 1};
7464 const DWORD exp_vertex_remap29
[] = {0, 1, 2, 3, 4, -1};
7465 const DWORD exp_new_num_vertices29
= ARRAY_SIZE(exp_vertices29
);
7467 DWORD
*adjacency_out
= NULL
;
7468 DWORD
*face_remap
= NULL
;
7469 ID3DXMesh
*mesh
= NULL
;
7470 ID3DXBuffer
*vertex_remap
= NULL
;
7473 const BYTE
*vertices
;
7474 const DWORD
*indices
;
7475 const DWORD
*attributes
;
7476 const DWORD num_vertices
;
7477 const DWORD num_faces
;
7478 const DWORD options
;
7479 D3DVERTEXELEMENT9
*declaration
;
7480 const UINT vertex_size
;
7482 const D3DXWELDEPSILONS
*epsilons
;
7483 const DWORD
*adjacency
;
7484 const BYTE
*exp_vertices
;
7485 const DWORD
*exp_indices
;
7486 const DWORD
*exp_face_remap
;
7487 const DWORD
*exp_vertex_remap
;
7488 const DWORD exp_new_num_vertices
;
7504 (BYTE
*)exp_vertices0
,
7508 exp_new_num_vertices0
7522 (BYTE
*)exp_vertices1
,
7526 exp_new_num_vertices1
7540 (BYTE
*)exp_vertices2
,
7544 exp_new_num_vertices2
7558 (BYTE
*)exp_vertices3
,
7562 exp_new_num_vertices3
7576 (BYTE
*)exp_vertices4
,
7580 exp_new_num_vertices4
7582 /* Unusual ordering. */
7595 (BYTE
*)exp_vertices5
,
7599 exp_new_num_vertices5
7613 (BYTE
*)exp_vertices6
,
7617 exp_new_num_vertices6
7621 (DWORD
*)indices6_16bit
,
7631 (BYTE
*)exp_vertices6
,
7635 exp_new_num_vertices6
7649 (BYTE
*)exp_vertices8
,
7653 exp_new_num_vertices8
7667 (BYTE
*)exp_vertices9
,
7671 exp_new_num_vertices9
7680 declaration_blendweight
,
7681 vertex_size_blendweight
,
7685 (BYTE
*)exp_vertices10
,
7689 exp_new_num_vertices10
7698 declaration_texcoord
,
7699 vertex_size_texcoord
,
7703 (BYTE
*)exp_vertices11
,
7707 exp_new_num_vertices11
7721 (BYTE
*)exp_vertices12
,
7725 exp_new_num_vertices12
7734 declaration_normal3
,
7739 (BYTE
*)exp_vertices13
,
7743 exp_new_num_vertices13
7757 (BYTE
*)exp_vertices14
,
7761 exp_new_num_vertices14
7770 declaration_color_ubyte4n
,
7771 vertex_size_color_ubyte4
, /* UBYTE4 same size as UBYTE4N */
7775 (BYTE
*)exp_vertices15
,
7779 exp_new_num_vertices15
7788 declaration_color_ubyte4
,
7789 vertex_size_color_ubyte4
,
7793 (BYTE
*)exp_vertices16
,
7797 exp_new_num_vertices16
7806 declaration_texcoord_short2
,
7807 vertex_size_texcoord_short2
,
7811 (BYTE
*)exp_vertices17
,
7815 exp_new_num_vertices17
7824 declaration_texcoord_short2n
,
7825 vertex_size_texcoord_short2
, /* SHORT2 same size as SHORT2N */
7829 (BYTE
*)exp_vertices18
,
7833 exp_new_num_vertices18
7842 declaration_texcoord_ushort2n
,
7843 vertex_size_texcoord_short2
, /* SHORT2 same size as USHORT2N */
7847 (BYTE
*)exp_vertices19
,
7851 exp_new_num_vertices19
7860 declaration_normal_short4
,
7861 vertex_size_normal_short4
,
7865 (BYTE
*)exp_vertices20
,
7869 exp_new_num_vertices20
7878 declaration_normal_short4n
,
7879 vertex_size_normal_short4
, /* SHORT4 same size as SHORT4N */
7883 (BYTE
*)exp_vertices21
,
7887 exp_new_num_vertices21
7896 declaration_normal_ushort4n
,
7897 vertex_size_normal_short4
, /* SHORT4 same size as USHORT4N */
7901 (BYTE
*)exp_vertices22
,
7905 exp_new_num_vertices22
7914 declaration_texcoord_float16_2
,
7915 vertex_size_texcoord_float16_2
,
7919 (BYTE
*)exp_vertices23
,
7923 exp_new_num_vertices23
7932 declaration_texcoord_float16_4
,
7933 vertex_size_texcoord_float16_4
,
7937 (BYTE
*)exp_vertices24
,
7941 exp_new_num_vertices24
7950 declaration_texcoord10
,
7951 vertex_size_texcoord
,
7955 (BYTE
*)exp_vertices25
,
7959 exp_new_num_vertices25
7973 (BYTE
*)exp_vertices26
,
7977 exp_new_num_vertices26
7986 declaration_color2_float4
,
7987 vertex_size_color_float4
,
7991 (BYTE
*)exp_vertices27
,
7995 exp_new_num_vertices27
8004 declaration_normal_udec3
,
8005 vertex_size_normal_udec3
,
8009 (BYTE
*)exp_vertices28
,
8013 exp_new_num_vertices28
8022 declaration_normal_dec3n
,
8023 vertex_size_normal_dec3n
,
8027 (BYTE
*)exp_vertices29
,
8031 exp_new_num_vertices29
8035 test_context
= new_test_context();
8038 skip("Couldn't create test context\n");
8042 for (i
= 0; i
< ARRAY_SIZE(tc
); i
++)
8045 DWORD
*vertex_remap_ptr
;
8046 DWORD new_num_vertices
;
8048 hr
= init_test_mesh(tc
[i
].num_faces
, tc
[i
].num_vertices
, tc
[i
].options
,
8049 tc
[i
].declaration
, test_context
->device
, &mesh
,
8050 tc
[i
].vertices
, tc
[i
].vertex_size
,
8051 tc
[i
].indices
, tc
[i
].attributes
);
8054 skip("Couldn't initialize test mesh %d.\n", i
);
8058 /* Allocate out parameters */
8059 adjacency_out
= HeapAlloc(GetProcessHeap(), 0, VERTS_PER_FACE
* tc
[i
].num_faces
* sizeof(*adjacency_out
));
8062 skip("Couldn't allocate adjacency_out array.\n");
8065 face_remap
= HeapAlloc(GetProcessHeap(), 0, tc
[i
].num_faces
* sizeof(*face_remap
));
8068 skip("Couldn't allocate face_remap array.\n");
8072 hr
= D3DXWeldVertices(mesh
, tc
[i
].flags
, tc
[i
].epsilons
, tc
[i
].adjacency
,
8073 adjacency_out
, face_remap
, &vertex_remap
);
8074 ok(hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
8075 /* Check number of vertices*/
8076 new_num_vertices
= mesh
->lpVtbl
->GetNumVertices(mesh
);
8077 ok(new_num_vertices
== tc
[i
].exp_new_num_vertices
,
8078 "Mesh %d: new_num_vertices == %d, expected %d.\n",
8079 i
, new_num_vertices
, tc
[i
].exp_new_num_vertices
);
8080 /* Check index buffer */
8081 if (tc
[i
].options
& D3DXMESH_32BIT
)
8083 hr
= mesh
->lpVtbl
->LockIndexBuffer(mesh
, 0, (void**)&indices
);
8086 skip("Couldn't lock index buffer.\n");
8089 for (j
= 0; j
< VERTS_PER_FACE
* tc
[i
].num_faces
; j
++)
8091 ok(indices
[j
] == tc
[i
].exp_indices
[j
],
8092 "Mesh %d: indices[%d] == %d, expected %d\n",
8093 i
, j
, indices
[j
], tc
[i
].exp_indices
[j
]);
8098 hr
= mesh
->lpVtbl
->LockIndexBuffer(mesh
, 0, (void**)&indices_16bit
);
8101 skip("Couldn't lock index buffer.\n");
8104 for (j
= 0; j
< VERTS_PER_FACE
* tc
[i
].num_faces
; j
++)
8106 ok(indices_16bit
[j
] == tc
[i
].exp_indices
[j
],
8107 "Mesh %d: indices_16bit[%d] == %d, expected %d\n",
8108 i
, j
, indices_16bit
[j
], tc
[i
].exp_indices
[j
]);
8111 mesh
->lpVtbl
->UnlockIndexBuffer(mesh
);
8113 indices_16bit
= NULL
;
8114 /* Check adjacency_out */
8115 for (j
= 0; j
< VERTS_PER_FACE
* tc
[i
].num_faces
; j
++)
8117 ok(adjacency_out
[j
] == tc
[i
].adjacency
[j
],
8118 "Mesh %d: adjacency_out[%d] == %d, expected %d\n",
8119 i
, j
, adjacency_out
[j
], tc
[i
].adjacency
[j
]);
8121 /* Check face_remap */
8122 for (j
= 0; j
< tc
[i
].num_faces
; j
++)
8124 ok(face_remap
[j
] == tc
[i
].exp_face_remap
[j
],
8125 "Mesh %d: face_remap[%d] == %d, expected %d\n",
8126 i
, j
, face_remap
[j
], tc
[i
].exp_face_remap
[j
]);
8128 /* Check vertex_remap */
8129 vertex_remap_ptr
= vertex_remap
->lpVtbl
->GetBufferPointer(vertex_remap
);
8130 for (j
= 0; j
< VERTS_PER_FACE
* tc
[i
].num_faces
; j
++)
8132 ok(vertex_remap_ptr
[j
] == tc
[i
].exp_vertex_remap
[j
],
8133 "Mesh %d: vertex_remap_ptr[%d] == %d, expected %d\n",
8134 i
, j
, vertex_remap_ptr
[j
], tc
[i
].exp_vertex_remap
[j
]);
8136 /* Check vertex buffer */
8137 hr
= mesh
->lpVtbl
->LockVertexBuffer(mesh
, 0, (void*)&vertices
);
8140 skip("Couldn't lock vertex buffer.\n");
8143 /* Check contents of re-ordered vertex buffer */
8144 for (j
= 0; j
< tc
[i
].exp_new_num_vertices
; j
++)
8146 int index
= tc
[i
].vertex_size
*j
;
8147 check_vertex_components(__LINE__
, i
, j
, &vertices
[index
], &tc
[i
].exp_vertices
[index
], tc
[i
].declaration
);
8149 mesh
->lpVtbl
->UnlockVertexBuffer(mesh
);
8152 /* Free mesh and output data */
8153 HeapFree(GetProcessHeap(), 0, adjacency_out
);
8154 adjacency_out
= NULL
;
8155 HeapFree(GetProcessHeap(), 0, face_remap
);
8157 vertex_remap
->lpVtbl
->Release(vertex_remap
);
8158 vertex_remap
= NULL
;
8159 mesh
->lpVtbl
->Release(mesh
);
8164 HeapFree(GetProcessHeap(), 0, adjacency_out
);
8165 HeapFree(GetProcessHeap(), 0, face_remap
);
8166 if (indices
) mesh
->lpVtbl
->UnlockIndexBuffer(mesh
);
8167 if (indices_16bit
) mesh
->lpVtbl
->UnlockIndexBuffer(mesh
);
8168 if (mesh
) mesh
->lpVtbl
->Release(mesh
);
8169 if (vertex_remap
) vertex_remap
->lpVtbl
->Release(vertex_remap
);
8170 if (vertices
) mesh
->lpVtbl
->UnlockVertexBuffer(mesh
);
8171 free_test_context(test_context
);
8174 static void test_clone_mesh(void)
8177 struct test_context
*test_context
= NULL
;
8178 const DWORD options
= D3DXMESH_32BIT
| D3DXMESH_SYSTEMMEM
;
8179 D3DVERTEXELEMENT9 declaration_pn
[] =
8181 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
8182 {0, 12, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
8185 D3DVERTEXELEMENT9 declaration_pntc
[] =
8187 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
8188 {0, 12, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
8189 {0, 24, D3DDECLTYPE_FLOAT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
8192 D3DVERTEXELEMENT9 declaration_ptcn
[] =
8194 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
8195 {0, 12, D3DDECLTYPE_FLOAT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
8196 {0, 20, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
8199 D3DVERTEXELEMENT9 declaration_ptc
[] =
8201 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
8202 {0, 12, D3DDECLTYPE_FLOAT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
8205 D3DVERTEXELEMENT9 declaration_ptc_float16_2
[] =
8207 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
8208 {0, 12, D3DDECLTYPE_FLOAT16_2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
8211 D3DVERTEXELEMENT9 declaration_ptc_float16_4
[] =
8213 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
8214 {0, 12, D3DDECLTYPE_FLOAT16_4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
8217 D3DVERTEXELEMENT9 declaration_ptc_float1
[] =
8219 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
8220 {0, 12, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
8223 D3DVERTEXELEMENT9 declaration_ptc_float3
[] =
8225 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
8226 {0, 12, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
8229 D3DVERTEXELEMENT9 declaration_ptc_float4
[] =
8231 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
8232 {0, 12, D3DDECLTYPE_FLOAT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
8235 D3DVERTEXELEMENT9 declaration_ptc_d3dcolor
[] =
8237 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
8238 {0, 12, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
8241 D3DVERTEXELEMENT9 declaration_ptc_ubyte4
[] =
8243 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
8244 {0, 12, D3DDECLTYPE_UBYTE4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
8247 D3DVERTEXELEMENT9 declaration_ptc_ubyte4n
[] =
8249 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
8250 {0, 12, D3DDECLTYPE_UBYTE4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
8253 D3DVERTEXELEMENT9 declaration_ptc_short2
[] =
8255 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
8256 {0, 12, D3DDECLTYPE_SHORT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
8259 D3DVERTEXELEMENT9 declaration_ptc_short4
[] =
8261 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
8262 {0, 12, D3DDECLTYPE_SHORT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
8265 D3DVERTEXELEMENT9 declaration_ptc_short2n
[] =
8267 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
8268 {0, 12, D3DDECLTYPE_SHORT2N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
8271 D3DVERTEXELEMENT9 declaration_ptc_short4n
[] =
8273 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
8274 {0, 12, D3DDECLTYPE_SHORT4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
8277 D3DVERTEXELEMENT9 declaration_ptc_ushort2n
[] =
8279 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
8280 {0, 12, D3DDECLTYPE_USHORT2N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
8283 D3DVERTEXELEMENT9 declaration_ptc_ushort4n
[] =
8285 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
8286 {0, 12, D3DDECLTYPE_USHORT4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
8289 D3DVERTEXELEMENT9 declaration_ptc_float16_2_partialu
[] =
8291 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
8292 {0, 12, D3DDECLTYPE_FLOAT16_2
, D3DDECLMETHOD_PARTIALU
, D3DDECLUSAGE_TEXCOORD
, 0},
8295 D3DVERTEXELEMENT9 declaration_pntc1
[] =
8297 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
8298 {0, 12, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
8299 {0, 24, D3DDECLTYPE_FLOAT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 1},
8302 const unsigned int VERTS_PER_FACE
= 3;
8303 BYTE
*vertices
= NULL
;
8307 D3DXVECTOR3 position
;
8312 D3DXVECTOR3 position
;
8314 D3DXVECTOR2 texcoords
;
8318 D3DXVECTOR3 position
;
8319 D3DXVECTOR2 texcoords
;
8324 D3DXVECTOR3 position
;
8325 D3DXVECTOR2 texcoords
;
8327 struct vertex_ptc_float16_2
8329 D3DXVECTOR3 position
;
8330 WORD texcoords
[2]; /* float16_2 */
8332 struct vertex_ptc_float16_4
8334 D3DXVECTOR3 position
;
8335 WORD texcoords
[4]; /* float16_4 */
8337 struct vertex_ptc_float1
8339 D3DXVECTOR3 position
;
8342 struct vertex_ptc_float3
8344 D3DXVECTOR3 position
;
8347 struct vertex_ptc_float4
8349 D3DXVECTOR3 position
;
8352 struct vertex_ptc_d3dcolor
8354 D3DXVECTOR3 position
;
8357 struct vertex_ptc_ubyte4
8359 D3DXVECTOR3 position
;
8362 struct vertex_ptc_ubyte4n
8364 D3DXVECTOR3 position
;
8367 struct vertex_ptc_short2
8369 D3DXVECTOR3 position
;
8372 struct vertex_ptc_short4
8374 D3DXVECTOR3 position
;
8377 struct vertex_ptc_ushort2n
8379 D3DXVECTOR3 position
;
8380 USHORT texcoords
[2];
8382 struct vertex_ptc_ushort4n
8384 D3DXVECTOR3 position
;
8385 USHORT texcoords
[4];
8387 struct vertex_ptc_udec3
8389 D3DXVECTOR3 position
;
8392 struct vertex_ptc_dec3n
8394 D3DXVECTOR3 position
;
8397 D3DXVECTOR3 up
= {0.0f
, 0.0f
, 1.0f
};
8398 D3DXVECTOR2 zero_vec2
= {0.0f
, 0.0f
};
8399 /* Test 0. Check that a mesh can be cloned if the new declaration is the
8400 * same as the one used to create the mesh.
8407 const struct vertex_pn vertices0
[] =
8409 {{ 0.0f
, 3.0f
, 0.f
}, up
},
8410 {{ 2.0f
, 3.0f
, 0.f
}, up
},
8411 {{ 0.0f
, 0.0f
, 0.f
}, up
},
8413 {{ 3.0f
, 3.0f
, 0.f
}, up
},
8414 {{ 3.0f
, 0.0f
, 0.f
}, up
},
8415 {{ 1.0f
, 0.0f
, 0.f
}, up
},
8417 const UINT num_vertices0
= ARRAY_SIZE(vertices0
);
8418 const UINT num_faces0
= ARRAY_SIZE(vertices0
) / VERTS_PER_FACE
;
8419 const UINT vertex_size0
= sizeof(*vertices0
);
8420 /* Test 1. Check that 16-bit indices are handled. */
8421 const DWORD options_16bit
= D3DXMESH_SYSTEMMEM
;
8422 /* Test 2. Check that the size of each vertex is increased and the data
8423 * moved if the new declaration adds an element after the original elements.
8425 const struct vertex_pntc exp_vertices2
[] =
8427 {{ 0.0f
, 3.0f
, 0.f
}, up
, zero_vec2
},
8428 {{ 2.0f
, 3.0f
, 0.f
}, up
, zero_vec2
},
8429 {{ 0.0f
, 0.0f
, 0.f
}, up
, zero_vec2
},
8431 {{ 3.0f
, 3.0f
, 0.f
}, up
, zero_vec2
},
8432 {{ 3.0f
, 0.0f
, 0.f
}, up
, zero_vec2
},
8433 {{ 1.0f
, 0.0f
, 0.f
}, up
, zero_vec2
},
8435 const UINT exp_vertex_size2
= sizeof(*exp_vertices2
);
8436 /* Test 3. Check that the size of each vertex is increased and the data
8437 * moved if the new declaration adds an element between the original
8440 const struct vertex_ptcn exp_vertices3
[] =
8442 {{ 0.0f
, 3.0f
, 0.f
}, zero_vec2
, up
},
8443 {{ 2.0f
, 3.0f
, 0.f
}, zero_vec2
, up
},
8444 {{ 0.0f
, 0.0f
, 0.f
}, zero_vec2
, up
},
8446 {{ 3.0f
, 3.0f
, 0.f
}, zero_vec2
, up
},
8447 {{ 3.0f
, 0.0f
, 0.f
}, zero_vec2
, up
},
8448 {{ 1.0f
, 0.0f
, 0.f
}, zero_vec2
, up
},
8450 const UINT exp_vertex_size3
= sizeof(*exp_vertices3
);
8451 /* Test 4. Test that data types can be converted, e.g. FLOAT2 to FLOAT16_2. */
8452 const struct vertex_ptc vertices4
[] =
8454 {{ 0.0f
, 3.0f
, 0.f
}, { 1.0f
, 1.0f
}},
8455 {{ 2.0f
, 3.0f
, 0.f
}, { 0.5f
, 0.7f
}},
8456 {{ 0.0f
, 0.0f
, 0.f
}, {-0.2f
, -0.3f
}},
8458 {{ 3.0f
, 3.0f
, 0.f
}, { 0.2f
, 0.3f
}},
8459 {{ 3.0f
, 0.0f
, 0.f
}, { 1.0f
, 1.0f
}},
8460 {{ 1.0f
, 0.0f
, 0.f
}, { 0.1f
, 0.2f
}},
8462 const UINT num_vertices4
= ARRAY_SIZE(vertices4
);
8463 const UINT num_faces4
= ARRAY_SIZE(vertices4
) / VERTS_PER_FACE
;
8464 const UINT vertex_size4
= sizeof(*vertices4
);
8465 const struct vertex_ptc_float16_2 exp_vertices4
[] =
8467 {{ 0.0f
, 3.0f
, 0.f
}, {0x3c00, 0x3c00}}, /* {1.0f, 1.0f} */
8468 {{ 2.0f
, 3.0f
, 0.f
}, {0x3800, 0x399a}}, /* {0.5f, 0.7f} */
8469 {{ 0.0f
, 0.0f
, 0.f
}, {0xb266, 0xb4cd}}, /* {-0.2f, -0.3f} */
8471 {{ 3.0f
, 3.0f
, 0.f
}, {0x3266, 0x34cd}}, /* {0.2f, 0.3f} */
8472 {{ 3.0f
, 0.0f
, 0.f
}, {0x3c00, 0x3c00}}, /* {1.0f, 1.0f} */
8473 {{ 1.0f
, 0.0f
, 0.f
}, {0x2e66, 0x3266}}, /* {0.1f, 0.2f} */
8475 const UINT exp_vertex_size4
= sizeof(*exp_vertices4
);
8476 /* Test 5. Convert FLOAT2 to FLOAT16_4. */
8477 const struct vertex_ptc vertices5
[] =
8479 {{ 0.0f
, 3.0f
, 0.f
}, { 1.0f
, 1.0f
}},
8480 {{ 2.0f
, 3.0f
, 0.f
}, { 0.5f
, 0.7f
}},
8481 {{ 0.0f
, 0.0f
, 0.f
}, {-0.2f
, -0.3f
}},
8483 {{ 3.0f
, 3.0f
, 0.f
}, { 0.2f
, 0.3f
}},
8484 {{ 3.0f
, 0.0f
, 0.f
}, { 1.0f
, 1.0f
}},
8485 {{ 1.0f
, 0.0f
, 0.f
}, { 0.1f
, 0.2f
}},
8487 const UINT num_vertices5
= ARRAY_SIZE(vertices5
);
8488 const UINT num_faces5
= ARRAY_SIZE(vertices5
) / VERTS_PER_FACE
;
8489 const UINT vertex_size5
= sizeof(*vertices5
);
8490 const struct vertex_ptc_float16_4 exp_vertices5
[] =
8492 {{ 0.0f
, 3.0f
, 0.f
}, {0x3c00, 0x3c00, 0, 0x3c00}}, /* {1.0f, 1.0f, 0.0f, 1.0f} */
8493 {{ 2.0f
, 3.0f
, 0.f
}, {0x3800, 0x399a, 0, 0x3c00}}, /* {0.5f, 0.7f, 0.0f, 1.0f} */
8494 {{ 0.0f
, 0.0f
, 0.f
}, {0xb266, 0xb4cd, 0, 0x3c00}}, /* {-0.2f, -0.3f, 0.0f, 1.0f} */
8496 {{ 3.0f
, 3.0f
, 0.f
}, {0x3266, 0x34cd, 0, 0x3c00}}, /* {0.2f, 0.3f, 0.0f, 1.0f} */
8497 {{ 3.0f
, 0.0f
, 0.f
}, {0x3c00, 0x3c00, 0, 0x3c00}}, /* {1.0f, 1.0f, 0.0f, 1.0f} */
8498 {{ 1.0f
, 0.0f
, 0.f
}, {0x2e66, 0x3266, 0, 0x3c00}}, /* {0.1f, 0.2f, 0.0f, 1.0f} */
8500 const UINT exp_vertex_size5
= sizeof(*exp_vertices5
);
8501 /* Test 6. Convert FLOAT2 to FLOAT1. */
8502 const struct vertex_ptc vertices6
[] =
8504 {{ 0.0f
, 3.0f
, 0.f
}, { 1.0f
, 1.0f
}},
8505 {{ 2.0f
, 3.0f
, 0.f
}, { 0.5f
, 0.7f
}},
8506 {{ 0.0f
, 0.0f
, 0.f
}, {-0.2f
, -0.3f
}},
8508 {{ 3.0f
, 3.0f
, 0.f
}, { 0.2f
, 0.3f
}},
8509 {{ 3.0f
, 0.0f
, 0.f
}, { 1.0f
, 1.0f
}},
8510 {{ 1.0f
, 0.0f
, 0.f
}, { 0.1f
, 0.2f
}},
8512 const UINT num_vertices6
= ARRAY_SIZE(vertices6
);
8513 const UINT num_faces6
= ARRAY_SIZE(vertices6
) / VERTS_PER_FACE
;
8514 const UINT vertex_size6
= sizeof(*vertices6
);
8515 const struct vertex_ptc_float1 exp_vertices6
[] =
8517 {{ 0.0f
, 3.0f
, 0.f
}, 1.0f
},
8518 {{ 2.0f
, 3.0f
, 0.f
}, 0.5f
},
8519 {{ 0.0f
, 0.0f
, 0.f
}, -0.2f
},
8521 {{ 3.0f
, 3.0f
, 0.f
}, 0.2f
},
8522 {{ 3.0f
, 0.0f
, 0.f
}, 1.0f
},
8523 {{ 1.0f
, 0.0f
, 0.f
}, 0.1f
},
8525 const UINT exp_vertex_size6
= sizeof(*exp_vertices6
);
8526 /* Test 7. Convert FLOAT2 to FLOAT3. */
8527 const struct vertex_ptc vertices7
[] =
8529 {{ 0.0f
, 3.0f
, 0.f
}, { 1.0f
, 1.0f
}},
8530 {{ 2.0f
, 3.0f
, 0.f
}, { 0.5f
, 0.7f
}},
8531 {{ 0.0f
, 0.0f
, 0.f
}, {-0.2f
, -0.3f
}},
8533 {{ 3.0f
, 3.0f
, 0.f
}, { 0.2f
, 0.3f
}},
8534 {{ 3.0f
, 0.0f
, 0.f
}, { 1.0f
, 1.0f
}},
8535 {{ 1.0f
, 0.0f
, 0.f
}, { 0.1f
, 0.2f
}},
8537 const UINT num_vertices7
= ARRAY_SIZE(vertices7
);
8538 const UINT num_faces7
= ARRAY_SIZE(vertices7
) / VERTS_PER_FACE
;
8539 const UINT vertex_size7
= sizeof(*vertices7
);
8540 const struct vertex_ptc_float3 exp_vertices7
[] =
8542 {{ 0.0f
, 3.0f
, 0.f
}, { 1.0f
, 1.0f
, 0.0f
}},
8543 {{ 2.0f
, 3.0f
, 0.f
}, { 0.5f
, 0.7f
, 0.0f
}},
8544 {{ 0.0f
, 0.0f
, 0.f
}, {-0.2f
, -0.3f
, 0.0f
}},
8546 {{ 3.0f
, 3.0f
, 0.f
}, { 0.2f
, 0.3f
, 0.0f
}},
8547 {{ 3.0f
, 0.0f
, 0.f
}, { 1.0f
, 1.0f
, 0.0f
}},
8548 {{ 1.0f
, 0.0f
, 0.f
}, { 0.1f
, 0.2f
, 0.0f
}},
8550 const UINT exp_vertex_size7
= sizeof(*exp_vertices7
);
8551 /* Test 8. Convert FLOAT2 to FLOAT4. */
8552 const struct vertex_ptc vertices8
[] =
8554 {{ 0.0f
, 3.0f
, 0.f
}, { 1.0f
, 1.0f
}},
8555 {{ 2.0f
, 3.0f
, 0.f
}, { 0.5f
, 0.7f
}},
8556 {{ 0.0f
, 0.0f
, 0.f
}, {-0.2f
, -0.3f
}},
8558 {{ 3.0f
, 3.0f
, 0.f
}, { 0.2f
, 0.3f
}},
8559 {{ 3.0f
, 0.0f
, 0.f
}, { 1.0f
, 1.0f
}},
8560 {{ 1.0f
, 0.0f
, 0.f
}, { 0.1f
, 0.2f
}},
8562 const UINT num_vertices8
= ARRAY_SIZE(vertices8
);
8563 const UINT num_faces8
= ARRAY_SIZE(vertices8
) / VERTS_PER_FACE
;
8564 const UINT vertex_size8
= sizeof(*vertices8
);
8565 const struct vertex_ptc_float4 exp_vertices8
[] =
8567 {{ 0.0f
, 3.0f
, 0.f
}, { 1.0f
, 1.0f
, 0.0f
, 1.0f
}},
8568 {{ 2.0f
, 3.0f
, 0.f
}, { 0.5f
, 0.7f
, 0.0f
, 1.0f
}},
8569 {{ 0.0f
, 0.0f
, 0.f
}, {-0.2f
, -0.3f
, 0.0f
, 1.0f
}},
8571 {{ 3.0f
, 3.0f
, 0.f
}, { 0.2f
, 0.3f
, 0.0f
, 1.0f
}},
8572 {{ 3.0f
, 0.0f
, 0.f
}, { 1.0f
, 1.0f
, 0.0f
, 1.0f
}},
8573 {{ 1.0f
, 0.0f
, 0.f
}, { 0.1f
, 0.2f
, 0.0f
, 1.0f
}},
8575 const UINT exp_vertex_size8
= sizeof(*exp_vertices8
);
8576 /* Test 9. Convert FLOAT2 to D3DCOLOR. */
8577 const struct vertex_ptc vertices9
[] =
8579 {{ 0.0f
, 3.0f
, 0.f
}, { 1.0f
, 1.0f
}},
8580 {{ 2.0f
, 3.0f
, 0.f
}, { 0.5f
, 0.7f
}},
8581 {{ 0.0f
, 0.0f
, 0.f
}, {-0.4f
, -0.6f
}},
8583 {{ 3.0f
, 3.0f
, 0.f
}, { 0.2f
, 0.3f
}},
8584 {{ 3.0f
, 0.0f
, 0.f
}, { 2.0f
, 256.0f
}},
8585 {{ 1.0f
, 0.0f
, 0.f
}, { 0.11f
, 0.2f
}},
8587 const UINT num_vertices9
= ARRAY_SIZE(vertices9
);
8588 const UINT num_faces9
= ARRAY_SIZE(vertices9
) / VERTS_PER_FACE
;
8589 const UINT vertex_size9
= sizeof(*vertices9
);
8590 const struct vertex_ptc_d3dcolor exp_vertices9
[] =
8592 {{ 0.0f
, 3.0f
, 0.f
}, {0, 255, 255, 255}},
8593 {{ 2.0f
, 3.0f
, 0.f
}, {0, 179, 128, 255}},
8594 {{ 0.0f
, 0.0f
, 0.f
}, {0, 0, 0, 255}},
8596 {{ 3.0f
, 3.0f
, 0.f
}, {0, 77, 51, 255}},
8597 {{ 3.0f
, 0.0f
, 0.f
}, {0, 255, 255, 255}},
8598 {{ 1.0f
, 0.0f
, 0.f
}, {0, 51, 28, 255}},
8600 const UINT exp_vertex_size9
= sizeof(*exp_vertices9
);
8601 /* Test 10. Convert FLOAT2 to UBYTE4. */
8602 const struct vertex_ptc vertices10
[] =
8604 {{ 0.0f
, 3.0f
, 0.f
}, { 0.0f
, 1.0f
}},
8605 {{ 2.0f
, 3.0f
, 0.f
}, { 2.0f
, 3.0f
}},
8606 {{ 0.0f
, 0.0f
, 0.f
}, { 254.0f
, 255.0f
}},
8608 {{ 3.0f
, 3.0f
, 0.f
}, { 256.0f
, 257.0f
}},
8609 {{ 3.0f
, 0.0f
, 0.f
}, { 1.4f
, 1.5f
}},
8610 {{ 1.0f
, 0.0f
, 0.f
}, {-4.0f
, -5.0f
}},
8612 const UINT num_vertices10
= ARRAY_SIZE(vertices10
);
8613 const UINT num_faces10
= ARRAY_SIZE(vertices10
) / VERTS_PER_FACE
;
8614 const UINT vertex_size10
= sizeof(*vertices10
);
8615 const struct vertex_ptc_ubyte4 exp_vertices10
[] =
8617 {{ 0.0f
, 3.0f
, 0.f
}, {0, 1, 0, 1}},
8618 {{ 2.0f
, 3.0f
, 0.f
}, {2, 3, 0, 1}},
8619 {{ 0.0f
, 0.0f
, 0.f
}, {254, 255, 0, 1}},
8621 {{ 3.0f
, 3.0f
, 0.f
}, {0, 1, 0, 1}},
8622 {{ 3.0f
, 0.0f
, 0.f
}, {1, 2, 0, 1}},
8623 {{ 1.0f
, 0.0f
, 0.f
}, {0, 0, 0, 1}},
8625 const UINT exp_vertex_size10
= sizeof(*exp_vertices10
);
8626 /* Test 11. Convert FLOAT2 to SHORT2. */
8627 const struct vertex_ptc vertices11
[] =
8629 {{ 0.0f
, 3.0f
, 0.f
}, { 1.0f
, -1.0f
}},
8630 {{ 2.0f
, 3.0f
, 0.f
}, { 0.4f
, 0.5f
}},
8631 {{ 0.0f
, 0.0f
, 0.f
}, {-0.5f
, -5.0f
}},
8633 {{ 3.0f
, 3.0f
, 0.f
}, {SHRT_MAX
, SHRT_MIN
}},
8634 {{ 3.0f
, 0.0f
, 0.f
}, {SHRT_MAX
+ 1.0f
, SHRT_MIN
- 1.0f
}},
8635 {{ 1.0f
, 0.0f
, 0.f
}, {SHRT_MAX
+ 2.0f
, SHRT_MIN
- 2.0f
}},
8637 {{ 4.0f
, 3.0f
, 0.f
}, {2 * SHRT_MAX
, 2 * SHRT_MIN
}},
8638 {{ 6.0f
, 0.0f
, 0.f
}, {3 * SHRT_MAX
, 3 * SHRT_MIN
}},
8639 {{ 4.0f
, 0.0f
, 0.f
}, {4 * SHRT_MAX
, 4 * SHRT_MIN
}},
8641 const UINT num_vertices11
= ARRAY_SIZE(vertices11
);
8642 const UINT num_faces11
= ARRAY_SIZE(vertices11
) / VERTS_PER_FACE
;
8643 const UINT vertex_size11
= sizeof(*vertices11
);
8644 const struct vertex_ptc_short2 exp_vertices11
[] =
8646 {{ 0.0f
, 3.0f
, 0.f
}, {1, 0}},
8647 {{ 2.0f
, 3.0f
, 0.f
}, {0, 1}},
8648 {{ 0.0f
, 0.0f
, 0.f
}, {0, -4}},
8650 {{ 3.0f
, 3.0f
, 0.f
}, {SHRT_MAX
, SHRT_MIN
+ 1}},
8651 {{ 3.0f
, 0.0f
, 0.f
}, {SHRT_MIN
, SHRT_MIN
}},
8652 {{ 1.0f
, 0.0f
, 0.f
}, {SHRT_MIN
+ 1, SHRT_MAX
}},
8654 {{ 4.0f
, 3.0f
, 0.f
}, {-2, 1}},
8655 {{ 6.0f
, 0.0f
, 0.f
}, {32765, -32767}},
8656 {{ 4.0f
, 0.0f
, 0.f
}, {-4, 1}},
8658 const UINT exp_vertex_size11
= sizeof(*exp_vertices11
);
8659 /* Test 12. Convert FLOAT2 to SHORT4. */
8660 const struct vertex_ptc vertices12
[] =
8662 {{ 0.0f
, 3.0f
, 0.f
}, { 1.0f
, -1.0f
}},
8663 {{ 2.0f
, 3.0f
, 0.f
}, { 0.4f
, 0.5f
}},
8664 {{ 0.0f
, 0.0f
, 0.f
}, {-0.5f
, -5.0f
}},
8666 {{ 3.0f
, 3.0f
, 0.f
}, {SHRT_MAX
, SHRT_MIN
}},
8667 {{ 3.0f
, 0.0f
, 0.f
}, {SHRT_MAX
+ 1.0f
, SHRT_MIN
- 1.0f
}},
8668 {{ 1.0f
, 0.0f
, 0.f
}, {SHRT_MAX
+ 2.0f
, SHRT_MIN
- 2.0f
}},
8670 {{ 4.0f
, 3.0f
, 0.f
}, {2 * SHRT_MAX
, 2 * SHRT_MIN
}},
8671 {{ 6.0f
, 0.0f
, 0.f
}, {3 * SHRT_MAX
, 3 * SHRT_MIN
}},
8672 {{ 4.0f
, 0.0f
, 0.f
}, {4 * SHRT_MAX
, 4 * SHRT_MIN
}},
8674 const UINT num_vertices12
= ARRAY_SIZE(vertices12
);
8675 const UINT num_faces12
= ARRAY_SIZE(vertices12
) / VERTS_PER_FACE
;
8676 const UINT vertex_size12
= sizeof(*vertices12
);
8677 const struct vertex_ptc_short4 exp_vertices12
[] =
8679 {{ 0.0f
, 3.0f
, 0.f
}, {1, 0, 0, 1}},
8680 {{ 2.0f
, 3.0f
, 0.f
}, {0, 1, 0, 1}},
8681 {{ 0.0f
, 0.0f
, 0.f
}, {0, -4, 0, 1}},
8683 {{ 3.0f
, 3.0f
, 0.f
}, {SHRT_MAX
, SHRT_MIN
+ 1, 0, 1}},
8684 {{ 3.0f
, 0.0f
, 0.f
}, {SHRT_MIN
, SHRT_MIN
, 0, 1}},
8685 {{ 1.0f
, 0.0f
, 0.f
}, {SHRT_MIN
+ 1, SHRT_MAX
, 0, 1}},
8687 {{ 4.0f
, 3.0f
, 0.f
}, {-2, 1, 0, 1}},
8688 {{ 6.0f
, 0.0f
, 0.f
}, {32765, -32767, 0, 1}},
8689 {{ 4.0f
, 0.0f
, 0.f
}, {-4, 1, 0, 1}},
8691 const UINT exp_vertex_size12
= sizeof(*exp_vertices12
);
8692 /* Test 13. Convert FLOAT2 to UBYTE4N. */
8693 const struct vertex_ptc vertices13
[] =
8695 {{ 0.0f
, 3.0f
, 0.f
}, { 1.0f
, 2.0f
}},
8696 {{ 2.0f
, 3.0f
, 0.f
}, { 0.5f
, 0.7f
}},
8697 {{ 0.0f
, 0.0f
, 0.f
}, {-0.4f
, -0.5f
}},
8699 {{ 3.0f
, 3.0f
, 0.f
}, {-0.6f
, -1.0f
}},
8700 {{ 3.0f
, 0.0f
, 0.f
}, {UCHAR_MAX
, UCHAR_MAX
+ 1}},
8701 {{ 1.0f
, 0.0f
, 0.f
}, {2 * UCHAR_MAX
, -UCHAR_MAX
}},
8703 const UINT num_vertices13
= ARRAY_SIZE(vertices13
);
8704 const UINT num_faces13
= ARRAY_SIZE(vertices13
) / VERTS_PER_FACE
;
8705 const UINT vertex_size13
= sizeof(*vertices13
);
8706 const struct vertex_ptc_ubyte4n exp_vertices13
[] =
8708 {{ 0.0f
, 3.0f
, 0.f
}, {255, 255, 0, 255}},
8709 {{ 2.0f
, 3.0f
, 0.f
}, {128, 179, 0, 255}},
8710 {{ 0.0f
, 0.0f
, 0.f
}, {0, 0, 0, 255}},
8712 {{ 3.0f
, 3.0f
, 0.f
}, {0, 0, 0, 255}},
8713 {{ 3.0f
, 0.0f
, 0.f
}, {255, 255, 0, 255}},
8714 {{ 1.0f
, 0.0f
, 0.f
}, {255, 0, 0, 255}},
8716 const UINT exp_vertex_size13
= sizeof(*exp_vertices13
);
8717 /* Test 14. Convert FLOAT2 to SHORT2N. */
8718 const struct vertex_ptc vertices14
[] =
8720 {{ 0.0f
, 3.0f
, 0.f
}, {1.0f
, 2.0f
}},
8721 {{ 2.0f
, 3.0f
, 0.f
}, {0.4f
, 0.5f
}},
8722 {{ 0.0f
, 0.0f
, 0.f
}, {0.6f
, -1.0f
}},
8724 {{ 3.0f
, 3.0f
, 0.f
}, {-0.4f
, -0.5f
}},
8725 {{ 3.0f
, 0.0f
, 0.f
}, {-0.9f
, -0.99997}},
8726 {{ 1.0f
, 0.0f
, 0.f
}, {SHRT_MAX
, SHRT_MIN
}},
8728 const UINT num_vertices14
= ARRAY_SIZE(vertices14
);
8729 const UINT num_faces14
= ARRAY_SIZE(vertices14
) / VERTS_PER_FACE
;
8730 const UINT vertex_size14
= sizeof(*vertices14
);
8731 const struct vertex_ptc_short2 exp_vertices14
[] =
8733 {{ 0.0f
, 3.0f
, 0.f
}, {SHRT_MAX
, SHRT_MAX
}},
8734 {{ 2.0f
, 3.0f
, 0.f
}, {13107, 16384}},
8735 {{ 0.0f
, 0.0f
, 0.f
}, {19660, SHRT_MIN
+ 2}},
8737 {{ 3.0f
, 3.0f
, 0.f
}, {-13106, -16383}},
8738 {{ 3.0f
, 0.0f
, 0.f
}, {-29489, SHRT_MIN
+ 3}},
8739 {{ 1.0f
, 0.0f
, 0.f
}, {SHRT_MAX
, SHRT_MIN
+ 2}},
8741 const UINT exp_vertex_size14
= sizeof(*exp_vertices14
);
8742 /* Test 15. Convert FLOAT2 to SHORT4N. */
8743 const struct vertex_ptc vertices15
[] =
8745 {{ 0.0f
, 3.0f
, 0.f
}, {1.0f
, 2.0f
}},
8746 {{ 2.0f
, 3.0f
, 0.f
}, {0.4f
, 0.5f
}},
8747 {{ 0.0f
, 0.0f
, 0.f
}, {0.6f
, -1.0f
}},
8749 {{ 3.0f
, 3.0f
, 0.f
}, {-0.4f
, -0.5f
}},
8750 {{ 3.0f
, 0.0f
, 0.f
}, {-0.9f
, -0.99997}},
8751 {{ 1.0f
, 0.0f
, 0.f
}, {SHRT_MAX
, SHRT_MIN
}},
8753 const UINT num_vertices15
= ARRAY_SIZE(vertices15
);
8754 const UINT num_faces15
= ARRAY_SIZE(vertices15
) / VERTS_PER_FACE
;
8755 const UINT vertex_size15
= sizeof(*vertices15
);
8756 const struct vertex_ptc_short4 exp_vertices15
[] =
8758 {{ 0.0f
, 3.0f
, 0.f
}, {SHRT_MAX
, SHRT_MAX
, 0, SHRT_MAX
}},
8759 {{ 2.0f
, 3.0f
, 0.f
}, {13107, 16384, 0, SHRT_MAX
}},
8760 {{ 0.0f
, 0.0f
, 0.f
}, {19660, SHRT_MIN
+ 2, 0, SHRT_MAX
}},
8762 {{ 3.0f
, 3.0f
, 0.f
}, {-13106, -16383, 0, SHRT_MAX
}},
8763 {{ 3.0f
, 0.0f
, 0.f
}, {-29489, SHRT_MIN
+ 3, 0, SHRT_MAX
}},
8764 {{ 1.0f
, 0.0f
, 0.f
}, {SHRT_MAX
, SHRT_MIN
+ 2, 0, SHRT_MAX
}},
8766 const UINT exp_vertex_size15
= sizeof(*exp_vertices15
);
8767 /* Test 16. Convert FLOAT2 to USHORT2N. */
8768 const struct vertex_ptc vertices16
[] =
8770 {{ 0.0f
, 3.0f
, 0.f
}, {1.0f
, 2.0f
}},
8771 {{ 2.0f
, 3.0f
, 0.f
}, {0.4f
, 0.5f
}},
8772 {{ 0.0f
, 0.0f
, 0.f
}, {0.6f
, -1.0f
}},
8774 {{ 3.0f
, 3.0f
, 0.f
}, {-0.4f
, -0.5f
}},
8775 {{ 3.0f
, 0.0f
, 0.f
}, {-0.9f
, 0.99998f
}},
8776 {{ 1.0f
, 0.0f
, 0.f
}, {USHRT_MAX
, 0.0f
}},
8778 const UINT num_vertices16
= ARRAY_SIZE(vertices16
);
8779 const UINT num_faces16
= ARRAY_SIZE(vertices16
) / VERTS_PER_FACE
;
8780 const UINT vertex_size16
= sizeof(*vertices16
);
8781 const struct vertex_ptc_ushort2n exp_vertices16
[] =
8783 {{ 0.0f
, 3.0f
, 0.f
}, {USHRT_MAX
, USHRT_MAX
}},
8784 {{ 2.0f
, 3.0f
, 0.f
}, {26214, 32768}},
8785 {{ 0.0f
, 0.0f
, 0.f
}, {39321, 0}},
8787 {{ 3.0f
, 3.0f
, 0.f
}, {0, 0}},
8788 {{ 3.0f
, 0.0f
, 0.f
}, {0, USHRT_MAX
- 1}},
8789 {{ 1.0f
, 0.0f
, 0.f
}, {USHRT_MAX
, 0}},
8791 const UINT exp_vertex_size16
= sizeof(*exp_vertices16
);
8792 /* Test 17. Convert FLOAT2 to USHORT4N. */
8793 const struct vertex_ptc vertices17
[] =
8795 {{ 0.0f
, 3.0f
, 0.f
}, {1.0f
, 2.0f
}},
8796 {{ 2.0f
, 3.0f
, 0.f
}, {0.4f
, 0.5f
}},
8797 {{ 0.0f
, 0.0f
, 0.f
}, {0.6f
, -1.0f
}},
8799 {{ 3.0f
, 3.0f
, 0.f
}, {-0.4f
, -0.5f
}},
8800 {{ 3.0f
, 0.0f
, 0.f
}, {-0.9f
, 0.99998f
}},
8801 {{ 1.0f
, 0.0f
, 0.f
}, {USHRT_MAX
, 0.0f
}},
8803 const UINT num_vertices17
= ARRAY_SIZE(vertices17
);
8804 const UINT num_faces17
= ARRAY_SIZE(vertices17
) / VERTS_PER_FACE
;
8805 const UINT vertex_size17
= sizeof(*vertices17
);
8806 const struct vertex_ptc_ushort4n exp_vertices17
[] =
8808 {{ 0.0f
, 3.0f
, 0.f
}, {USHRT_MAX
, USHRT_MAX
, 0, USHRT_MAX
}},
8809 {{ 2.0f
, 3.0f
, 0.f
}, {26214, 32768, 0, USHRT_MAX
}},
8810 {{ 0.0f
, 0.0f
, 0.f
}, {39321, 0, 0, USHRT_MAX
}},
8812 {{ 3.0f
, 3.0f
, 0.f
}, {0, 0, 0, USHRT_MAX
}},
8813 {{ 3.0f
, 0.0f
, 0.f
}, {0, USHRT_MAX
- 1, 0, USHRT_MAX
}},
8814 {{ 1.0f
, 0.0f
, 0.f
}, {USHRT_MAX
, 0, 0, USHRT_MAX
}},
8816 const UINT exp_vertex_size17
= sizeof(*exp_vertices17
);
8817 /* Test 18. Test that the method field is compared by converting a FLOAT2 to
8818 * FLOAT16_2. where the method field has been change from
8819 * D3DDECLMETHOD_DEFAULT to D3DDECLMETHOD_PARTIALU. */
8820 const struct vertex_ptc vertices18
[] =
8822 {{ 0.0f
, 3.0f
, 0.f
}, { 1.0f
, 1.0f
}},
8823 {{ 2.0f
, 3.0f
, 0.f
}, { 0.5f
, 0.7f
}},
8824 {{ 0.0f
, 0.0f
, 0.f
}, {-0.2f
, -0.3f
}},
8826 {{ 3.0f
, 3.0f
, 0.f
}, { 0.2f
, 0.3f
}},
8827 {{ 3.0f
, 0.0f
, 0.f
}, { 1.0f
, 1.0f
}},
8828 {{ 1.0f
, 0.0f
, 0.f
}, { 0.1f
, 0.2f
}},
8830 const UINT num_vertices18
= ARRAY_SIZE(vertices18
);
8831 const UINT num_faces18
= ARRAY_SIZE(vertices18
) / VERTS_PER_FACE
;
8832 const UINT vertex_size18
= sizeof(*vertices18
);
8833 const struct vertex_ptc_float16_2 exp_vertices18
[] =
8835 {{ 0.0f
, 3.0f
, 0.f
}, {0x3c00, 0x3c00}}, /* {1.0f, 1.0f} */
8836 {{ 2.0f
, 3.0f
, 0.f
}, {0x3800, 0x399a}}, /* {0.5f, 0.7f} */
8837 {{ 0.0f
, 0.0f
, 0.f
}, {0xb266, 0xb4cd}}, /* {-0.2f, -0.3f} */
8839 {{ 3.0f
, 3.0f
, 0.f
}, {0x3266, 0x34cd}}, /* {0.2f, 0.3f} */
8840 {{ 3.0f
, 0.0f
, 0.f
}, {0x3c00, 0x3c00}}, /* {1.0f, 1.0f} */
8841 {{ 1.0f
, 0.0f
, 0.f
}, {0x2e66, 0x3266}}, /* {0.1f, 0.2f} */
8843 const UINT exp_vertex_size18
= sizeof(*exp_vertices18
);
8844 /* Test 19. Test that data is lost if usage index changes, e.g. TEXCOORD0
8846 const struct vertex_pntc vertices19
[] =
8848 {{ 0.0f
, 3.0f
, 0.f
}, up
, { 1.0f
, 1.0f
}},
8849 {{ 2.0f
, 3.0f
, 0.f
}, up
, { 0.5f
, 0.7f
}},
8850 {{ 0.0f
, 0.0f
, 0.f
}, up
, {-0.2f
, -0.3f
}},
8852 {{ 3.0f
, 3.0f
, 0.f
}, up
, { 0.2f
, 0.3f
}},
8853 {{ 3.0f
, 0.0f
, 0.f
}, up
, { 1.0f
, 1.0f
}},
8854 {{ 1.0f
, 0.0f
, 0.f
}, up
, { 0.1f
, 0.2f
}},
8856 const UINT num_vertices19
= ARRAY_SIZE(vertices19
);
8857 const UINT num_faces19
= ARRAY_SIZE(vertices19
) / VERTS_PER_FACE
;
8858 const UINT vertex_size19
= sizeof(*vertices19
);
8859 const struct vertex_pntc exp_vertices19
[] =
8861 {{ 0.0f
, 3.0f
, 0.f
}, up
, zero_vec2
},
8862 {{ 2.0f
, 3.0f
, 0.f
}, up
, zero_vec2
},
8863 {{ 0.0f
, 0.0f
, 0.f
}, up
, zero_vec2
},
8865 {{ 3.0f
, 3.0f
, 0.f
}, up
, zero_vec2
},
8866 {{ 3.0f
, 0.0f
, 0.f
}, up
, zero_vec2
},
8867 {{ 1.0f
, 0.0f
, 0.f
}, up
, zero_vec2
},
8869 const UINT exp_vertex_size19
= sizeof(*exp_vertices19
);
8870 /* Test 20. Another test that data is lost if usage index changes, e.g.
8871 * TEXCOORD1 to TEXCOORD0. */
8872 const struct vertex_pntc vertices20
[] =
8874 {{ 0.0f
, 3.0f
, 0.f
}, up
, { 1.0f
, 1.0f
}},
8875 {{ 2.0f
, 3.0f
, 0.f
}, up
, { 0.5f
, 0.7f
}},
8876 {{ 0.0f
, 0.0f
, 0.f
}, up
, {-0.2f
, -0.3f
}},
8878 {{ 3.0f
, 3.0f
, 0.f
}, up
, { 0.2f
, 0.3f
}},
8879 {{ 3.0f
, 0.0f
, 0.f
}, up
, { 1.0f
, 1.0f
}},
8880 {{ 1.0f
, 0.0f
, 0.f
}, up
, { 0.1f
, 0.2f
}},
8882 const UINT num_vertices20
= ARRAY_SIZE(vertices20
);
8883 const UINT num_faces20
= ARRAY_SIZE(vertices20
) / VERTS_PER_FACE
;
8884 const UINT vertex_size20
= sizeof(*vertices20
);
8885 const struct vertex_pntc exp_vertices20
[] =
8887 {{ 0.0f
, 3.0f
, 0.f
}, up
, zero_vec2
},
8888 {{ 2.0f
, 3.0f
, 0.f
}, up
, zero_vec2
},
8889 {{ 0.0f
, 0.0f
, 0.f
}, up
, zero_vec2
},
8891 {{ 3.0f
, 3.0f
, 0.f
}, up
, zero_vec2
},
8892 {{ 3.0f
, 0.0f
, 0.f
}, up
, zero_vec2
},
8893 {{ 1.0f
, 0.0f
, 0.f
}, up
, zero_vec2
},
8895 const UINT exp_vertex_size20
= sizeof(*exp_vertices20
);
8896 /* Test 21. Convert FLOAT1 to FLOAT2. */
8897 const struct vertex_ptc_float1 vertices21
[] =
8899 {{ 0.0f
, 3.0f
, 0.f
}, 1.0f
},
8900 {{ 2.0f
, 3.0f
, 0.f
}, 0.5f
},
8901 {{ 0.0f
, 0.0f
, 0.f
}, -0.2f
},
8903 {{ 3.0f
, 3.0f
, 0.f
}, 0.2f
},
8904 {{ 3.0f
, 0.0f
, 0.f
}, 1.0f
},
8905 {{ 1.0f
, 0.0f
, 0.f
}, 0.1f
},
8907 const UINT num_vertices21
= ARRAY_SIZE(vertices21
);
8908 const UINT num_faces21
= ARRAY_SIZE(vertices21
) / VERTS_PER_FACE
;
8909 const UINT vertex_size21
= sizeof(*vertices21
);
8910 const struct vertex_ptc exp_vertices21
[] =
8912 {{ 0.0f
, 3.0f
, 0.f
}, { 1.0f
, 0.0f
}},
8913 {{ 2.0f
, 3.0f
, 0.f
}, { 0.5f
, 0.0f
}},
8914 {{ 0.0f
, 0.0f
, 0.f
}, {-0.2f
, 0.0f
}},
8916 {{ 3.0f
, 3.0f
, 0.f
}, { 0.2f
, 0.0f
}},
8917 {{ 3.0f
, 0.0f
, 0.f
}, { 1.0f
, 0.0f
}},
8918 {{ 1.0f
, 0.0f
, 0.f
}, { 0.1f
, 0.0f
}},
8920 const UINT exp_vertex_size21
= sizeof(*exp_vertices21
);
8921 /* Test 22. Convert FLOAT1 to FLOAT3. */
8922 const struct vertex_ptc_float1 vertices22
[] =
8924 {{ 0.0f
, 3.0f
, 0.f
}, 1.0f
},
8925 {{ 2.0f
, 3.0f
, 0.f
}, 0.5f
},
8926 {{ 0.0f
, 0.0f
, 0.f
}, -0.2f
},
8928 {{ 3.0f
, 3.0f
, 0.f
}, 0.2f
},
8929 {{ 3.0f
, 0.0f
, 0.f
}, 1.0f
},
8930 {{ 1.0f
, 0.0f
, 0.f
}, 0.1f
},
8932 const UINT num_vertices22
= ARRAY_SIZE(vertices22
);
8933 const UINT num_faces22
= ARRAY_SIZE(vertices22
) / VERTS_PER_FACE
;
8934 const UINT vertex_size22
= sizeof(*vertices22
);
8935 const struct vertex_ptc_float3 exp_vertices22
[] =
8937 {{ 0.0f
, 3.0f
, 0.f
}, { 1.0f
, 0.0f
, 0.0f
}},
8938 {{ 2.0f
, 3.0f
, 0.f
}, { 0.5f
, 0.0f
, 0.0f
}},
8939 {{ 0.0f
, 0.0f
, 0.f
}, {-0.2f
, 0.0f
, 0.0f
}},
8941 {{ 3.0f
, 3.0f
, 0.f
}, { 0.2f
, 0.0f
, 0.0f
}},
8942 {{ 3.0f
, 0.0f
, 0.f
}, { 1.0f
, 0.0f
, 0.0f
}},
8943 {{ 1.0f
, 0.0f
, 0.f
}, { 0.1f
, 0.0f
, 0.0f
}},
8945 const UINT exp_vertex_size22
= sizeof(*exp_vertices22
);
8946 /* Test 23. Convert FLOAT1 to FLOAT4. */
8947 const struct vertex_ptc_float1 vertices23
[] =
8949 {{ 0.0f
, 3.0f
, 0.f
}, 1.0f
},
8950 {{ 2.0f
, 3.0f
, 0.f
}, 0.5f
},
8951 {{ 0.0f
, 0.0f
, 0.f
}, -0.2f
},
8953 {{ 3.0f
, 3.0f
, 0.f
}, 0.2f
},
8954 {{ 3.0f
, 0.0f
, 0.f
}, 1.0f
},
8955 {{ 1.0f
, 0.0f
, 0.f
}, 0.1f
},
8957 const UINT num_vertices23
= ARRAY_SIZE(vertices23
);
8958 const UINT num_faces23
= ARRAY_SIZE(vertices23
) / VERTS_PER_FACE
;
8959 const UINT vertex_size23
= sizeof(*vertices23
);
8960 const struct vertex_ptc_float4 exp_vertices23
[] =
8962 {{ 0.0f
, 3.0f
, 0.f
}, { 1.0f
, 0.0f
, 0.0f
, 1.0f
}},
8963 {{ 2.0f
, 3.0f
, 0.f
}, { 0.5f
, 0.0f
, 0.0f
, 1.0f
}},
8964 {{ 0.0f
, 0.0f
, 0.f
}, {-0.2f
, 0.0f
, 0.0f
, 1.0f
}},
8966 {{ 3.0f
, 3.0f
, 0.f
}, { 0.2f
, 0.0f
, 0.0f
, 1.0f
}},
8967 {{ 3.0f
, 0.0f
, 0.f
}, { 1.0f
, 0.0f
, 0.0f
, 1.0f
}},
8968 {{ 1.0f
, 0.0f
, 0.f
}, { 0.1f
, 0.0f
, 0.0f
, 1.0f
}},
8970 const UINT exp_vertex_size23
= sizeof(*exp_vertices23
);
8971 /* Test 24. Convert FLOAT1 to D3DCOLOR. */
8972 const struct vertex_ptc_float1 vertices24
[] =
8974 {{ 0.0f
, 3.0f
, 0.f
}, 1.0f
},
8975 {{ 2.0f
, 3.0f
, 0.f
}, 0.5f
},
8976 {{ 0.0f
, 0.0f
, 0.f
}, -0.2f
},
8978 {{ 3.0f
, 3.0f
, 0.f
}, 0.2f
},
8979 {{ 3.0f
, 0.0f
, 0.f
}, 1.0f
},
8980 {{ 1.0f
, 0.0f
, 0.f
}, 0.11f
},
8982 const UINT num_vertices24
= ARRAY_SIZE(vertices24
);
8983 const UINT num_faces24
= ARRAY_SIZE(vertices24
) / VERTS_PER_FACE
;
8984 const UINT vertex_size24
= sizeof(*vertices24
);
8985 const struct vertex_ptc_d3dcolor exp_vertices24
[] =
8987 {{ 0.0f
, 3.0f
, 0.f
}, {0, 0, 255, 255}},
8988 {{ 2.0f
, 3.0f
, 0.f
}, {0, 0, 128, 255}},
8989 {{ 0.0f
, 0.0f
, 0.f
}, {0, 0, 0, 255}},
8991 {{ 3.0f
, 3.0f
, 0.f
}, {0, 0, 51, 255}},
8992 {{ 3.0f
, 0.0f
, 0.f
}, {0, 0, 255, 255}},
8993 {{ 1.0f
, 0.0f
, 0.f
}, {0, 0, 28, 255}},
8995 const UINT exp_vertex_size24
= sizeof(*exp_vertices24
);
8996 /* Test 25. Convert FLOAT1 to ubyte4. */
8997 const struct vertex_ptc_float1 vertices25
[] =
8999 {{ 0.0f
, 3.0f
, 0.f
}, 0.0f
},
9000 {{ 2.0f
, 3.0f
, 0.f
}, 1.4f
},
9001 {{ 0.0f
, 0.0f
, 0.f
}, 1.5f
},
9003 {{ 3.0f
, 3.0f
, 0.f
}, 255.0f
},
9004 {{ 3.0f
, 0.0f
, 0.f
}, 256.0f
},
9005 {{ 1.0f
, 0.0f
, 0.f
}, -1.0f
},
9007 const UINT num_vertices25
= ARRAY_SIZE(vertices25
);
9008 const UINT num_faces25
= ARRAY_SIZE(vertices25
) / VERTS_PER_FACE
;
9009 const UINT vertex_size25
= sizeof(*vertices25
);
9010 const struct vertex_ptc_ubyte4 exp_vertices25
[] =
9012 {{ 0.0f
, 3.0f
, 0.f
}, {0, 0, 0, 1}},
9013 {{ 2.0f
, 3.0f
, 0.f
}, {1, 0, 0, 1}},
9014 {{ 0.0f
, 0.0f
, 0.f
}, {2, 0, 0, 1}},
9016 {{ 3.0f
, 3.0f
, 0.f
}, {255, 0, 0, 1}},
9017 {{ 3.0f
, 0.0f
, 0.f
}, {0, 0, 0, 1}},
9018 {{ 1.0f
, 0.0f
, 0.f
}, {0, 0, 0, 1}},
9020 const UINT exp_vertex_size25
= sizeof(*exp_vertices25
);
9021 /* Test 26. Convert FLOAT4 to D3DCOLOR. */
9022 const struct vertex_ptc_float4 vertices26
[] =
9024 {{ 0.0f
, 3.0f
, 0.f
}, {0.0f
, 1.0f
, 0.4f
, 0.5f
}},
9025 {{ 2.0f
, 3.0f
, 0.f
}, {-0.4f
, -0.5f
, -1.0f
, -2.0f
}},
9026 {{ 0.0f
, 0.0f
, 0.f
}, {254.0f
, 255.0f
, 256.0f
, 257.0f
}},
9028 {{ 3.0f
, 3.0f
, 0.f
}, {0.1f
, 0.2f
, 0.3f
, 0.4f
}},
9029 {{ 3.0f
, 0.0f
, 0.f
}, {0.5f
, 0.6f
, 0.7f
, 0.8f
}},
9030 {{ 1.0f
, 0.0f
, 0.f
}, {0.9f
, 0.99f
, 0.995f
, 0.999f
}},
9032 const UINT num_vertices26
= ARRAY_SIZE(vertices26
);
9033 const UINT num_faces26
= ARRAY_SIZE(vertices26
) / VERTS_PER_FACE
;
9034 const UINT vertex_size26
= sizeof(*vertices26
);
9035 const struct vertex_ptc_d3dcolor exp_vertices26
[] =
9037 {{ 0.0f
, 3.0f
, 0.f
}, {102, 255, 0, 128}},
9038 {{ 2.0f
, 3.0f
, 0.f
}, {0, 0, 0, 0}},
9039 {{ 0.0f
, 0.0f
, 0.f
}, {255, 255, 255, 255}},
9041 {{ 3.0f
, 3.0f
, 0.f
}, {77, 51, 26, 102}},
9042 {{ 3.0f
, 0.0f
, 0.f
}, {179, 153, 128, 204}},
9043 {{ 1.0f
, 0.0f
, 0.f
}, {254, 252, 230, 255}},
9045 const UINT exp_vertex_size26
= sizeof(*exp_vertices26
);
9046 /* Test 27. Convert D3DCOLOR to FLOAT4. */
9047 const struct vertex_ptc_d3dcolor vertices27
[] =
9049 {{ 0.0f
, 3.0f
, 0.f
}, {102, 255, 0, 128}},
9050 {{ 2.0f
, 3.0f
, 0.f
}, {0, 0, 0, 0}},
9051 {{ 0.0f
, 0.0f
, 0.f
}, {255, 255, 255, 255}},
9053 {{ 3.0f
, 3.0f
, 0.f
}, {77, 51, 26, 102}},
9054 {{ 3.0f
, 0.0f
, 0.f
}, {179, 153, 128, 204}},
9055 {{ 1.0f
, 0.0f
, 0.f
}, {254, 252, 230, 255}},
9057 const UINT num_vertices27
= ARRAY_SIZE(vertices27
);
9058 const UINT num_faces27
= ARRAY_SIZE(vertices27
) / VERTS_PER_FACE
;
9059 const UINT vertex_size27
= sizeof(*vertices27
);
9060 const struct vertex_ptc_float4 exp_vertices27
[] =
9062 {{ 0.0f
, 3.0f
, 0.f
}, {0.0f
, 1.0f
, 0.4f
, 0.501961f
}},
9063 {{ 2.0f
, 3.0f
, 0.f
}, {0.0f
, 0.0f
, 0.0f
, 0.0f
}},
9064 {{ 0.0f
, 0.0f
, 0.f
}, {1.0f
, 1.0f
, 1.0f
, 1.0f
}},
9066 {{ 3.0f
, 3.0f
, 0.f
}, {0.101961f
, 0.2f
, 0.301961f
, 0.4f
}},
9067 {{ 3.0f
, 0.0f
, 0.f
}, {0.501961f
, 0.6f
, 0.701961f
, 0.8f
}},
9068 {{ 1.0f
, 0.0f
, 0.f
}, {0.901961f
, 0.988235f
, 0.996078f
, 1.0f
}},
9070 const UINT exp_vertex_size27
= sizeof(*exp_vertices27
);
9071 /* Test 28. Convert UBYTE4 to FLOAT4. */
9072 const struct vertex_ptc_ubyte4 vertices28
[] =
9074 {{ 0.0f
, 3.0f
, 0.f
}, {0, 0, 0, 0}},
9075 {{ 2.0f
, 3.0f
, 0.f
}, {1, 1, 1, 1}},
9076 {{ 0.0f
, 0.0f
, 0.f
}, {1, 0, 1, 0}},
9078 {{ 3.0f
, 3.0f
, 0.f
}, {0, 1, 0, 1}},
9079 {{ 3.0f
, 0.0f
, 0.f
}, {10, 20, 30, 40}},
9080 {{ 1.0f
, 0.0f
, 0.f
}, {50, 60, 127, 255}},
9082 const UINT num_vertices28
= ARRAY_SIZE(vertices28
);
9083 const UINT num_faces28
= ARRAY_SIZE(vertices28
) / VERTS_PER_FACE
;
9084 const UINT vertex_size28
= sizeof(*vertices28
);
9085 const struct vertex_ptc_float4 exp_vertices28
[] =
9087 {{ 0.0f
, 3.0f
, 0.f
}, {0.0f
, 0.0f
, 0.0f
, 0.0f
}},
9088 {{ 2.0f
, 3.0f
, 0.f
}, {1.0f
, 1.0f
, 1.0f
, 1.0f
}},
9089 {{ 0.0f
, 0.0f
, 0.f
}, {1.0f
, 0.0f
, 1.0f
, 0.0f
}},
9091 {{ 3.0f
, 3.0f
, 0.f
}, {0.0f
, 1.0f
, 0.0f
, 1.0f
}},
9092 {{ 3.0f
, 0.0f
, 0.f
}, {10.0f
, 20.0f
, 30.0f
, 40.0f
}},
9093 {{ 1.0f
, 0.0f
, 0.f
}, {50.0f
, 60.0f
, 127.0f
, 255.0f
}},
9095 const UINT exp_vertex_size28
= sizeof(*exp_vertices28
);
9096 /* Test 29. Convert SHORT2 to FLOAT4. */
9097 const struct vertex_ptc_short2 vertices29
[] =
9099 {{ 0.0f
, 3.0f
, 0.f
}, {0, 0}},
9100 {{ 2.0f
, 3.0f
, 0.f
}, {0, 1}},
9101 {{ 0.0f
, 0.0f
, 0.f
}, {1, 0}},
9103 {{ 3.0f
, 3.0f
, 0.f
}, {1, 1}},
9104 {{ 3.0f
, 0.0f
, 0.f
}, {SHRT_MIN
, SHRT_MAX
}},
9105 {{ 1.0f
, 0.0f
, 0.f
}, {-42, 42}},
9107 const UINT num_vertices29
= ARRAY_SIZE(vertices29
);
9108 const UINT num_faces29
= ARRAY_SIZE(vertices29
) / VERTS_PER_FACE
;
9109 const UINT vertex_size29
= sizeof(*vertices29
);
9110 const struct vertex_ptc_float4 exp_vertices29
[] =
9112 {{ 0.0f
, 3.0f
, 0.f
}, {0.0f
, 0.0f
, 0.0f
, 1.0f
}},
9113 {{ 2.0f
, 3.0f
, 0.f
}, {0.0f
, 1.0f
, 0.0f
, 1.0f
}},
9114 {{ 0.0f
, 0.0f
, 0.f
}, {1.0f
, 0.0f
, 0.0f
, 1.0f
}},
9116 {{ 3.0f
, 3.0f
, 0.f
}, {1.0f
, 1.0f
, 0.0f
, 1.0f
}},
9117 {{ 3.0f
, 0.0f
, 0.f
}, {SHRT_MIN
, SHRT_MAX
, 0.0f
, 1.0f
}},
9118 {{ 1.0f
, 0.0f
, 0.f
}, {-42.0f
, 42.0f
, 0.0f
, 1.0f
}},
9120 const UINT exp_vertex_size29
= sizeof(*exp_vertices29
);
9121 /* Test 29. Convert SHORT4 to FLOAT4. */
9122 const struct vertex_ptc_short4 vertices30
[] =
9124 {{ 0.0f
, 3.0f
, 0.f
}, {0, 0, 0, 0}},
9125 {{ 2.0f
, 3.0f
, 0.f
}, {0, 1, 0, 1}},
9126 {{ 0.0f
, 0.0f
, 0.f
}, {1, 0, 1, 0}},
9128 {{ 3.0f
, 3.0f
, 0.f
}, {1, 1, 1, 1}},
9129 {{ 3.0f
, 0.0f
, 0.f
}, {SHRT_MIN
, SHRT_MAX
, 1, 0}},
9130 {{ 1.0f
, 0.0f
, 0.f
}, {-42, 42, SHRT_MAX
, SHRT_MIN
}},
9132 const UINT num_vertices30
= ARRAY_SIZE(vertices30
);
9133 const UINT num_faces30
= ARRAY_SIZE(vertices30
) / VERTS_PER_FACE
;
9134 const UINT vertex_size30
= sizeof(*vertices30
);
9135 const struct vertex_ptc_float4 exp_vertices30
[] =
9137 {{ 0.0f
, 3.0f
, 0.f
}, {0.0f
, 0.0f
, 0.0f
, 0.0f
}},
9138 {{ 2.0f
, 3.0f
, 0.f
}, {0.0f
, 1.0f
, 0.0f
, 1.0f
}},
9139 {{ 0.0f
, 0.0f
, 0.f
}, {1.0f
, 0.0f
, 1.0f
, 0.0f
}},
9141 {{ 3.0f
, 3.0f
, 0.f
}, {1.0f
, 1.0f
, 1.0f
, 1.0f
}},
9142 {{ 3.0f
, 0.0f
, 0.f
}, {SHRT_MIN
, SHRT_MAX
, 1.0f
, 0.0f
}},
9143 {{ 1.0f
, 0.0f
, 0.f
}, {-42.0f
, 42.0f
, SHRT_MAX
, SHRT_MIN
}},
9145 const UINT exp_vertex_size30
= sizeof(*exp_vertices30
);
9146 /* Test 31. Convert UBYTE4N to FLOAT4. */
9147 const struct vertex_ptc_ubyte4n vertices31
[] =
9149 {{ 0.0f
, 3.0f
, 0.f
}, {0, 0, 0, 0}},
9150 {{ 2.0f
, 3.0f
, 0.f
}, {1, 1, 1, 1}},
9151 {{ 0.0f
, 0.0f
, 0.f
}, {1, 0, 1, 0}},
9153 {{ 3.0f
, 3.0f
, 0.f
}, {0, 1, 0, 1}},
9154 {{ 3.0f
, 0.0f
, 0.f
}, {10, 20, 30, 40}},
9155 {{ 1.0f
, 0.0f
, 0.f
}, {50, 60, 70, UCHAR_MAX
}},
9157 const UINT num_vertices31
= ARRAY_SIZE(vertices31
);
9158 const UINT num_faces31
= ARRAY_SIZE(vertices31
) / VERTS_PER_FACE
;
9159 const UINT vertex_size31
= sizeof(*vertices31
);
9160 const struct vertex_ptc_float4 exp_vertices31
[] =
9162 {{ 0.0f
, 3.0f
, 0.f
}, {0.0f
, 0.0f
, 0.0f
, 0.0f
}},
9163 {{ 2.0f
, 3.0f
, 0.f
}, {(FLOAT
)1/UCHAR_MAX
, (FLOAT
)1/UCHAR_MAX
, (FLOAT
)1/UCHAR_MAX
, (FLOAT
)1/UCHAR_MAX
}},
9164 {{ 0.0f
, 0.0f
, 0.f
}, {(FLOAT
)1/UCHAR_MAX
, 0.0f
, (FLOAT
)1/UCHAR_MAX
, 0.0f
}},
9166 {{ 3.0f
, 3.0f
, 0.f
}, {0.0f
, (FLOAT
)1/UCHAR_MAX
, 0.0f
, (FLOAT
)1/UCHAR_MAX
}},
9167 {{ 3.0f
, 0.0f
, 0.f
}, {(FLOAT
)10/UCHAR_MAX
, (FLOAT
)20/UCHAR_MAX
, (FLOAT
)30/UCHAR_MAX
, (FLOAT
)40/UCHAR_MAX
}},
9168 {{ 1.0f
, 0.0f
, 0.f
}, {(FLOAT
)50/UCHAR_MAX
, (FLOAT
)60/UCHAR_MAX
, (FLOAT
)70/UCHAR_MAX
, 1.0f
}},
9170 const UINT exp_vertex_size31
= sizeof(*exp_vertices31
);
9171 /* Test 32. Convert SHORT2N to FLOAT4. */
9172 const struct vertex_ptc_short2 vertices32
[] =
9174 {{ 0.0f
, 3.0f
, 0.f
}, {0, 0}},
9175 {{ 2.0f
, 3.0f
, 0.f
}, {0, 1}},
9176 {{ 0.0f
, 0.0f
, 0.f
}, {1, 0}},
9178 {{ 3.0f
, 3.0f
, 0.f
}, {1, 1}},
9179 {{ 3.0f
, 0.0f
, 0.f
}, {SHRT_MIN
+ 1, SHRT_MAX
}},
9180 {{ 1.0f
, 0.0f
, 0.f
}, {-42, 42}},
9182 const UINT num_vertices32
= ARRAY_SIZE(vertices32
);
9183 const UINT num_faces32
= ARRAY_SIZE(vertices32
) / VERTS_PER_FACE
;
9184 const UINT vertex_size32
= sizeof(*vertices32
);
9185 const struct vertex_ptc_float4 exp_vertices32
[] =
9187 {{ 0.0f
, 3.0f
, 0.f
}, {0.0f
, 0.0f
, 0.0f
, 1.0f
}},
9188 {{ 2.0f
, 3.0f
, 0.f
}, {0.0f
, 1.0f
/SHRT_MAX
, 0.0f
, 1.0f
}},
9189 {{ 0.0f
, 0.0f
, 0.f
}, {1.0f
/SHRT_MAX
, 0.0f
, 0.0f
, 1.0f
}},
9191 {{ 3.0f
, 3.0f
, 0.f
}, {1.0f
/SHRT_MAX
, 1.0f
/SHRT_MAX
, 0.0f
, 1.0f
}},
9192 {{ 3.0f
, 0.0f
, 0.f
}, {-1.0f
, 1.0f
, 0.0f
, 1.0f
}},
9193 {{ 1.0f
, 0.0f
, 0.f
}, {-42.0f
/SHRT_MAX
, 42.0f
/SHRT_MAX
, 0.0f
, 1.0f
}},
9195 const UINT exp_vertex_size32
= sizeof(*exp_vertices32
);
9196 /* Test 33. Convert SHORT4N to FLOAT4. */
9197 const struct vertex_ptc_short4 vertices33
[] =
9199 {{ 0.0f
, 3.0f
, 0.f
}, {0, 0, 0, 0}},
9200 {{ 2.0f
, 3.0f
, 0.f
}, {0, 1, 0, 1}},
9201 {{ 0.0f
, 0.0f
, 0.f
}, {1, 0, 1, 0}},
9203 {{ 3.0f
, 3.0f
, 0.f
}, {1, 1, 1, 1}},
9204 {{ 3.0f
, 0.0f
, 0.f
}, {SHRT_MIN
+ 1, SHRT_MAX
, SHRT_MIN
+ 1, SHRT_MAX
}},
9205 {{ 1.0f
, 0.0f
, 0.f
}, {-42, 42, 1, 1}},
9207 const UINT num_vertices33
= ARRAY_SIZE(vertices33
);
9208 const UINT num_faces33
= ARRAY_SIZE(vertices33
) / VERTS_PER_FACE
;
9209 const UINT vertex_size33
= sizeof(*vertices33
);
9210 const struct vertex_ptc_float4 exp_vertices33
[] =
9212 {{ 0.0f
, 3.0f
, 0.f
}, {0.0f
, 0.0f
, 0.0f
, 0.0f
}},
9213 {{ 2.0f
, 3.0f
, 0.f
}, {0.0f
, 1.0f
/SHRT_MAX
, 0.0f
, 1.0f
/SHRT_MAX
}},
9214 {{ 0.0f
, 0.0f
, 0.f
}, {1.0f
/SHRT_MAX
, 0.0f
, 1.0f
/SHRT_MAX
, 0.0f
}},
9216 {{ 3.0f
, 3.0f
, 0.f
}, {1.0f
/SHRT_MAX
, 1.0f
/SHRT_MAX
, 1.0f
/SHRT_MAX
, 1.0f
/SHRT_MAX
}},
9217 {{ 3.0f
, 0.0f
, 0.f
}, {-1.0f
, 1.0f
, -1.0f
, 1.0f
}},
9218 {{ 1.0f
, 0.0f
, 0.f
}, {-42.0f
/SHRT_MAX
, 42.0f
/SHRT_MAX
, 1.0f
/SHRT_MAX
, 1.0f
/SHRT_MAX
}},
9220 const UINT exp_vertex_size33
= sizeof(*exp_vertices33
);
9221 /* Test 34. Convert FLOAT16_2 to FLOAT4. */
9222 const struct vertex_ptc_float16_2 vertices34
[] =
9224 {{ 0.0f
, 3.0f
, 0.f
}, {0x3c00, 0x3c00}}, /* {1.0f, 1.0f} */
9225 {{ 2.0f
, 3.0f
, 0.f
}, {0x3800, 0x399a}}, /* {0.5f, 0.7f} */
9226 {{ 0.0f
, 0.0f
, 0.f
}, {0xb266, 0xb4cd}}, /* {-0.2f, -0.3f} */
9228 {{ 3.0f
, 3.0f
, 0.f
}, {0x3266, 0x34cd}}, /* {0.2f, 0.3f} */
9229 {{ 3.0f
, 0.0f
, 0.f
}, {0x3c00, 0x3c00}}, /* {1.0f, 1.0f} */
9230 {{ 1.0f
, 0.0f
, 0.f
}, {0x2e66, 0x3266}}, /* {0.1f, 0.2f} */
9232 const UINT num_vertices34
= ARRAY_SIZE(vertices34
);
9233 const UINT num_faces34
= ARRAY_SIZE(vertices34
) / VERTS_PER_FACE
;
9234 const UINT vertex_size34
= sizeof(*vertices34
);
9235 const struct vertex_ptc_float4 exp_vertices34
[] =
9237 {{ 0.0f
, 3.0f
, 0.f
}, {1.0f
, 1.0f
, 0.0f
, 1.0f
}},
9238 {{ 2.0f
, 3.0f
, 0.f
}, {0.5f
, 0.700195f
, 0.0f
, 1.0f
}},
9239 {{ 0.0f
, 0.0f
, 0.f
}, {-0.199951f
, -0.300049f
, 0.0f
, 1.0f
}},
9241 {{ 3.0f
, 3.0f
, 0.f
}, {0.199951f
, 0.300049f
, 0.0f
, 1.0f
}},
9242 {{ 3.0f
, 0.0f
, 0.f
}, {1.0f
, 1.0f
, 0.0f
, 1.0f
}},
9243 {{ 1.0f
, 0.0f
, 0.f
}, {0.099976f
, 0.199951f
, 0.0f
, 1.0f
}},
9245 const UINT exp_vertex_size34
= sizeof(*exp_vertices34
);
9246 /* Test 35. Convert FLOAT16_4 to FLOAT4. */
9247 const struct vertex_ptc_float16_4 vertices35
[] =
9249 {{ 0.0f
, 3.0f
, 0.f
}, {0x0000, 0x0000, 0x0000, 0x0000}},
9250 {{ 2.0f
, 3.0f
, 0.f
}, {0x3c00, 0x3c00, 0x3c00, 0x3c00}},
9251 {{ 0.0f
, 0.0f
, 0.f
}, {0x3c00, 0x0000, 0x3c00, 0x0000}},
9253 {{ 3.0f
, 3.0f
, 0.f
}, {0x0000, 0x3c00, 0x0000, 0x3c00}},
9254 {{ 3.0f
, 0.0f
, 0.f
}, {0x3800, 0x399a, 0xb266, 0xb4cd}},
9255 {{ 1.0f
, 0.0f
, 0.f
}, {0x2e66, 0x3266, 0x2e66, 0x3266}},
9257 const UINT num_vertices35
= ARRAY_SIZE(vertices35
);
9258 const UINT num_faces35
= ARRAY_SIZE(vertices35
) / VERTS_PER_FACE
;
9259 const UINT vertex_size35
= sizeof(*vertices35
);
9260 const struct vertex_ptc_float4 exp_vertices35
[] =
9262 {{ 0.0f
, 3.0f
, 0.f
}, {0.0f
, 0.0f
, 0.0f
, 0.0f
}},
9263 {{ 2.0f
, 3.0f
, 0.f
}, {1.0f
, 1.0f
, 1.0f
, 1.0f
}},
9264 {{ 0.0f
, 0.0f
, 0.f
}, {1.0f
, 0.0f
, 1.0f
, 0.0f
}},
9266 {{ 3.0f
, 3.0f
, 0.f
}, {0.0f
, 1.0f
, 0.0f
, 1.0f
}},
9267 {{ 3.0f
, 0.0f
, 0.f
}, {0.5f
, 0.700195f
, -0.199951f
, -0.300049f
}},
9268 {{ 1.0f
, 0.0f
, 0.f
}, {0.099976f
, 0.199951f
, 0.099976f
, 0.199951f
}},
9270 const UINT exp_vertex_size35
= sizeof(*exp_vertices35
);
9271 /* Test 36. Check that vertex buffer sharing is ok. */
9272 const struct vertex_pn vertices36
[] =
9274 {{ 0.0f
, 3.0f
, 0.f
}, up
},
9275 {{ 2.0f
, 3.0f
, 0.f
}, up
},
9276 {{ 0.0f
, 0.0f
, 0.f
}, up
},
9278 const UINT num_vertices36
= ARRAY_SIZE(vertices36
);
9279 const UINT num_faces36
= ARRAY_SIZE(vertices36
) / VERTS_PER_FACE
;
9280 const UINT vertex_size36
= sizeof(*vertices36
);
9281 const DWORD clone_options36
= options
| D3DXMESH_VB_SHARE
;
9282 /* Common mesh data */
9283 ID3DXMesh
*mesh
= NULL
;
9284 ID3DXMesh
*mesh_clone
= NULL
;
9287 const BYTE
*vertices
;
9288 const DWORD
*indices
;
9289 const DWORD
*attributes
;
9290 const UINT num_vertices
;
9291 const UINT num_faces
;
9292 const UINT vertex_size
;
9293 const DWORD create_options
;
9294 const DWORD clone_options
;
9295 D3DVERTEXELEMENT9
*declaration
;
9296 D3DVERTEXELEMENT9
*new_declaration
;
9297 const BYTE
*exp_vertices
;
9298 const UINT exp_vertex_size
;
9341 (BYTE
*)exp_vertices2
,
9355 (BYTE
*)exp_vertices3
,
9368 declaration_ptc_float16_2
,
9369 (BYTE
*)exp_vertices4
,
9382 declaration_ptc_float16_4
,
9383 (BYTE
*)exp_vertices5
,
9396 declaration_ptc_float1
,
9397 (BYTE
*)exp_vertices6
,
9410 declaration_ptc_float3
,
9411 (BYTE
*)exp_vertices7
,
9424 declaration_ptc_float4
,
9425 (BYTE
*)exp_vertices8
,
9438 declaration_ptc_d3dcolor
,
9439 (BYTE
*)exp_vertices9
,
9452 declaration_ptc_ubyte4
,
9453 (BYTE
*)exp_vertices10
,
9466 declaration_ptc_short2
,
9467 (BYTE
*)exp_vertices11
,
9480 declaration_ptc_short4
,
9481 (BYTE
*)exp_vertices12
,
9494 declaration_ptc_ubyte4n
,
9495 (BYTE
*)exp_vertices13
,
9508 declaration_ptc_short2n
,
9509 (BYTE
*)exp_vertices14
,
9522 declaration_ptc_short4n
,
9523 (BYTE
*)exp_vertices15
,
9536 declaration_ptc_ushort2n
,
9537 (BYTE
*)exp_vertices16
,
9550 declaration_ptc_ushort4n
,
9551 (BYTE
*)exp_vertices17
,
9564 declaration_ptc_float16_2_partialu
,
9565 (BYTE
*)exp_vertices18
,
9579 (BYTE
*)exp_vertices19
,
9593 (BYTE
*)exp_vertices20
,
9605 declaration_ptc_float1
,
9607 (BYTE
*)exp_vertices21
,
9619 declaration_ptc_float1
,
9620 declaration_ptc_float3
,
9621 (BYTE
*)exp_vertices22
,
9633 declaration_ptc_float1
,
9634 declaration_ptc_float4
,
9635 (BYTE
*)exp_vertices23
,
9647 declaration_ptc_float1
,
9648 declaration_ptc_d3dcolor
,
9649 (BYTE
*)exp_vertices24
,
9661 declaration_ptc_float1
,
9662 declaration_ptc_ubyte4
,
9663 (BYTE
*)exp_vertices25
,
9675 declaration_ptc_float4
,
9676 declaration_ptc_d3dcolor
,
9677 (BYTE
*)exp_vertices26
,
9689 declaration_ptc_d3dcolor
,
9690 declaration_ptc_float4
,
9691 (BYTE
*)exp_vertices27
,
9703 declaration_ptc_ubyte4
,
9704 declaration_ptc_float4
,
9705 (BYTE
*)exp_vertices28
,
9717 declaration_ptc_short2
,
9718 declaration_ptc_float4
,
9719 (BYTE
*)exp_vertices29
,
9731 declaration_ptc_short4
,
9732 declaration_ptc_float4
,
9733 (BYTE
*)exp_vertices30
,
9745 declaration_ptc_ubyte4n
,
9746 declaration_ptc_float4
,
9747 (BYTE
*)exp_vertices31
,
9759 declaration_ptc_short2n
,
9760 declaration_ptc_float4
,
9761 (BYTE
*)exp_vertices32
,
9773 declaration_ptc_short4n
,
9774 declaration_ptc_float4
,
9775 (BYTE
*)exp_vertices33
,
9787 declaration_ptc_float16_2
,
9788 declaration_ptc_float4
,
9789 (BYTE
*)exp_vertices34
,
9801 declaration_ptc_float16_4
,
9802 declaration_ptc_float4
,
9803 (BYTE
*)exp_vertices35
,
9822 test_context
= new_test_context();
9825 skip("Couldn't create test context\n");
9829 for (i
= 0; i
< ARRAY_SIZE(tc
); i
++)
9832 D3DVERTEXELEMENT9 new_declaration
[MAX_FVF_DECL_SIZE
];
9833 UINT exp_new_decl_length
, new_decl_length
;
9834 UINT exp_new_decl_size
, new_decl_size
;
9836 hr
= init_test_mesh(tc
[i
].num_faces
, tc
[i
].num_vertices
,
9837 tc
[i
].create_options
,
9839 test_context
->device
, &mesh
,
9840 tc
[i
].vertices
, tc
[i
].vertex_size
,
9841 tc
[i
].indices
, tc
[i
].attributes
);
9844 skip("Couldn't initialize test mesh %d. Got %x expected D3D_OK\n", i
, hr
);
9848 hr
= mesh
->lpVtbl
->CloneMesh(mesh
, tc
[i
].clone_options
, tc
[i
].new_declaration
,
9849 test_context
->device
, &mesh_clone
);
9850 ok(hr
== D3D_OK
, "CloneMesh test case %d failed. Got %x\n, expected D3D_OK\n", i
, hr
);
9852 hr
= mesh_clone
->lpVtbl
->GetDeclaration(mesh_clone
, new_declaration
);
9853 ok(hr
== D3D_OK
, "GetDeclaration test case %d failed. Got %x\n, expected D3D_OK\n", i
, hr
);
9854 /* Check declaration elements */
9855 for (j
= 0; tc
[i
].new_declaration
[j
].Stream
!= 0xFF; j
++)
9857 ok(memcmp(&tc
[i
].new_declaration
[j
], &new_declaration
[j
], sizeof(*new_declaration
)) == 0,
9858 "Test case %d failed. Declaration element %d did not match.\n", i
, j
);
9861 /* Check declaration length */
9862 exp_new_decl_length
= D3DXGetDeclLength(tc
[i
].new_declaration
);
9863 new_decl_length
= D3DXGetDeclLength(new_declaration
);
9864 ok(new_decl_length
== exp_new_decl_length
,
9865 "Test case %d failed. Got new declaration length %d, expected %d\n",
9866 i
, new_decl_length
, exp_new_decl_length
);
9868 /* Check declaration size */
9869 exp_new_decl_size
= D3DXGetDeclVertexSize(tc
[i
].new_declaration
, 0);
9870 new_decl_size
= D3DXGetDeclVertexSize(new_declaration
, 0);
9871 ok(new_decl_size
== exp_new_decl_size
,
9872 "Test case %d failed. Got new declaration size %d, expected %d\n",
9873 i
, new_decl_size
, exp_new_decl_size
);
9875 /* Check vertex data in cloned mesh */
9876 hr
= mesh_clone
->lpVtbl
->LockVertexBuffer(mesh_clone
, 0, (void**)&vertices
);
9879 skip("Couldn't lock cloned vertex buffer.\n");
9882 for (j
= 0; j
< tc
[i
].num_vertices
; j
++)
9884 UINT index
= tc
[i
].exp_vertex_size
* j
;
9885 check_vertex_components(__LINE__
, i
, j
, &vertices
[index
], &tc
[i
].exp_vertices
[index
], tc
[i
].new_declaration
);
9887 hr
= mesh_clone
->lpVtbl
->UnlockVertexBuffer(mesh_clone
);
9890 skip("Couldn't unlock vertex buffer.\n");
9894 mesh
->lpVtbl
->Release(mesh
);
9896 mesh_clone
->lpVtbl
->Release(mesh_clone
);
9900 /* The following test shows that it is not possible to share a vertex buffer
9901 * with D3DXMESH_VB_SHARE and change the vertex declaration at the same
9902 * time. It reuses the test data from test 2.
9904 hr
= init_test_mesh(tc
[2].num_faces
, tc
[2].num_vertices
,
9905 tc
[2].create_options
,
9907 test_context
->device
, &mesh
,
9908 tc
[2].vertices
, tc
[2].vertex_size
,
9909 tc
[2].indices
, tc
[2].attributes
);
9912 skip("Couldn't initialize test mesh for D3DXMESH_VB_SHARE case."
9913 " Got %x expected D3D_OK\n", hr
);
9917 hr
= mesh
->lpVtbl
->CloneMesh(mesh
, tc
[2].create_options
| D3DXMESH_VB_SHARE
,
9918 tc
[2].new_declaration
, test_context
->device
,
9920 ok(hr
== D3DERR_INVALIDCALL
, "CloneMesh D3DXMESH_VB_SHARE with new"
9921 " declaration. Got %x, expected D3DERR_INVALIDCALL\n",
9923 mesh
->lpVtbl
->Release(mesh
);
9928 if (vertices
) mesh
->lpVtbl
->UnlockVertexBuffer(mesh
);
9929 if (mesh
) mesh
->lpVtbl
->Release(mesh
);
9930 if (mesh_clone
) mesh_clone
->lpVtbl
->Release(mesh_clone
);
9931 free_test_context(test_context
);
9934 static void test_valid_mesh(void)
9937 struct test_context
*test_context
= NULL
;
9939 const DWORD options
= D3DXMESH_32BIT
| D3DXMESH_SYSTEMMEM
;
9940 const D3DVERTEXELEMENT9 declaration
[] =
9942 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
9945 const unsigned int VERTS_PER_FACE
= 3;
9953 const D3DXVECTOR3 vertices0
[] =
9959 const DWORD indices0
[] = {0, 1, 2};
9960 const unsigned int num_vertices0
= ARRAY_SIZE(vertices0
);
9961 const unsigned int num_faces0
= ARRAY_SIZE(indices0
) / VERTS_PER_FACE
;
9962 const DWORD adjacency0
[] = {-1, -1, -1};
9963 const HRESULT exp_hr0
= D3D_OK
;
9964 /* mesh1 (Simple bow-tie)
9971 const D3DXVECTOR3 vertices1
[] =
9980 const DWORD indices1
[] = {0, 1, 2, 1, 3, 4};
9981 const unsigned int num_vertices1
= ARRAY_SIZE(vertices1
);
9982 const unsigned int num_faces1
= ARRAY_SIZE(indices1
) / VERTS_PER_FACE
;
9983 const DWORD adjacency1
[] = {-1, -1, -1, -1, -1, -1};
9984 const HRESULT exp_hr1
= D3DXERR_INVALIDMESH
;
9985 /* Common mesh data */
9986 ID3DXMesh
*mesh
= NULL
;
9987 UINT vertex_size
= sizeof(D3DXVECTOR3
);
9988 ID3DXBuffer
*errors_and_warnings
= NULL
;
9991 const D3DXVECTOR3
*vertices
;
9992 const DWORD
*indices
;
9993 const UINT num_vertices
;
9994 const UINT num_faces
;
9995 const DWORD
*adjacency
;
9996 const HRESULT exp_hr
;
10018 test_context
= new_test_context();
10021 skip("Couldn't create test context\n");
10025 for (i
= 0; i
< ARRAY_SIZE(tc
); i
++)
10027 hr
= init_test_mesh(tc
[i
].num_faces
, tc
[i
].num_vertices
,
10028 options
, declaration
,
10029 test_context
->device
, &mesh
,
10030 tc
[i
].vertices
, vertex_size
,
10031 tc
[i
].indices
, NULL
);
10034 skip("Couldn't initialize test mesh %d. Got %x expected D3D_OK\n", i
, hr
);
10038 hr
= D3DXValidMesh(mesh
, tc
[i
].adjacency
, &errors_and_warnings
);
10039 todo_wine
ok(hr
== tc
[i
].exp_hr
, "D3DXValidMesh test case %d failed. "
10040 "Got %x\n, expected %x\n", i
, hr
, tc
[i
].exp_hr
);
10042 /* Note errors_and_warnings is deliberately not checked because that
10043 * would require copying wast amounts of the text output. */
10044 if (errors_and_warnings
)
10046 ID3DXBuffer_Release(errors_and_warnings
);
10047 errors_and_warnings
= NULL
;
10049 mesh
->lpVtbl
->Release(mesh
);
10054 if (mesh
) mesh
->lpVtbl
->Release(mesh
);
10055 free_test_context(test_context
);
10058 static void test_optimize_faces(void)
10062 DWORD smallest_face_remap
;
10070 const DWORD indices0
[] = {0, 1, 2};
10071 const UINT num_faces0
= 1;
10072 const UINT num_vertices0
= 3;
10073 const DWORD exp_face_remap0
[] = {0};
10081 const DWORD indices1
[] = {0, 1, 2, 3, 4, 5};
10082 const UINT num_faces1
= 2;
10083 const UINT num_vertices1
= 6;
10084 const DWORD exp_face_remap1
[] = {1, 0};
10092 const DWORD indices2
[] = {0, 1, 2, 1, 3, 2};
10093 const UINT num_faces2
= 2;
10094 const UINT num_vertices2
= 4;
10095 const DWORD exp_face_remap2
[] = {1, 0};
10106 const DWORD indices3
[] = {0, 1, 2, 1, 3, 2, 2, 3, 4, 3, 4, 5};
10107 const UINT num_faces3
= 4;
10108 const UINT num_vertices3
= 6;
10109 const DWORD exp_face_remap3
[] = {3, 2, 1, 0};
10120 const WORD indices4
[] = {0, 1, 2, 1, 3, 2, 2, 3, 4, 3, 4, 5};
10121 const UINT num_faces4
= 4;
10122 const UINT num_vertices4
= 6;
10123 const DWORD exp_face_remap4
[] = {3, 2, 1, 0};
10124 /* Test cases are stored in the tc array */
10127 const VOID
*indices
;
10128 const UINT num_faces
;
10129 const UINT num_vertices
;
10130 const BOOL indices_are_32bit
;
10131 const DWORD
*exp_face_remap
;
10172 /* Go through all test cases */
10173 for (i
= 0; i
< ARRAY_SIZE(tc
); i
++)
10177 face_remap
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
10178 tc
[i
].num_faces
*sizeof(*face_remap
));
10180 hr
= D3DXOptimizeFaces(tc
[i
].indices
, tc
[i
].num_faces
,
10181 tc
[i
].num_vertices
, tc
[i
].indices_are_32bit
,
10183 ok(hr
== D3D_OK
, "D3DXOptimizeFaces test case %d failed. "
10184 "Got %x\n, expected D3D_OK\n", i
, hr
);
10186 /* Compare face remap with expected face remap */
10187 for (j
= 0; j
< tc
[i
].num_faces
; j
++)
10189 ok(tc
[i
].exp_face_remap
[j
] == face_remap
[j
],
10190 "Test case %d: Got face %d at %d, expected %d\n", i
,
10191 face_remap
[j
], j
, tc
[i
].exp_face_remap
[j
]);
10194 HeapFree(GetProcessHeap(), 0, face_remap
);
10197 /* face_remap must not be NULL */
10198 hr
= D3DXOptimizeFaces(tc
[0].indices
, tc
[0].num_faces
,
10199 tc
[0].num_vertices
, tc
[0].indices_are_32bit
,
10201 ok(hr
== D3DERR_INVALIDCALL
, "D3DXOptimizeFaces passed NULL face_remap "
10202 "pointer. Got %x\n, expected D3DERR_INVALIDCALL\n", hr
);
10204 /* Number of faces must be smaller than 2^15 */
10205 hr
= D3DXOptimizeFaces(tc
[0].indices
, 2 << 15,
10206 tc
[0].num_vertices
, FALSE
,
10207 &smallest_face_remap
);
10208 ok(hr
== D3DERR_INVALIDCALL
, "D3DXOptimizeFaces should not accept 2^15 "
10209 "faces when using 16-bit indices. Got %x\n, expected D3DERR_INVALIDCALL\n", hr
);
10214 D3DXBoundProbeTest();
10215 D3DXComputeBoundingBoxTest();
10216 D3DXComputeBoundingSphereTest();
10217 D3DXGetFVFVertexSizeTest();
10218 D3DXIntersectTriTest();
10219 D3DXCreateMeshTest();
10220 D3DXCreateMeshFVFTest();
10221 D3DXLoadMeshTest();
10222 D3DXCreateBoxTest();
10223 D3DXCreateSphereTest();
10224 D3DXCreateCylinderTest();
10225 D3DXCreateTextTest();
10226 test_get_decl_length();
10227 test_get_decl_vertex_size();
10228 test_fvf_decl_conversion();
10229 D3DXGenerateAdjacencyTest();
10230 test_update_semantics();
10231 test_create_skin_info();
10232 test_convert_adjacency_to_point_reps();
10233 test_convert_point_reps_to_adjacency();
10234 test_weld_vertices();
10237 test_optimize_faces();