2 * Copyright 2008 David Adam
3 * Copyright 2008 Luis Busquets
4 * Copyright 2009 Henri Verbeet for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/test.h"
25 #define admitted_error 0.0001f
27 #define compare_vertex_sizes(type, exp) \
28 got=D3DXGetFVFVertexSize(type); \
29 ok(got==exp, "Expected: %d, Got: %d\n", exp, got);
31 static BOOL
compare(FLOAT u
, FLOAT v
)
33 return (fabs(u
-v
) < admitted_error
);
36 static BOOL
compare_vec3(D3DXVECTOR3 u
, D3DXVECTOR3 v
)
38 return ( compare(u
.x
, v
.x
) && compare(u
.y
, v
.y
) && compare(u
.z
, v
.z
) );
49 static BOOL
compare_face(face a
, face b
)
51 return (a
[0]==b
[0] && a
[1] == b
[1] && a
[2] == b
[2]);
56 DWORD number_of_vertices
;
57 struct vertex
*vertices
;
59 DWORD number_of_faces
;
66 static void free_mesh(struct mesh
*mesh
)
68 HeapFree(GetProcessHeap(), 0, mesh
->faces
);
69 HeapFree(GetProcessHeap(), 0, mesh
->vertices
);
72 static BOOL
new_mesh(struct mesh
*mesh
, DWORD number_of_vertices
, DWORD number_of_faces
)
74 mesh
->vertices
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, number_of_vertices
* sizeof(*mesh
->vertices
));
79 mesh
->number_of_vertices
= number_of_vertices
;
81 mesh
->faces
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, number_of_faces
* sizeof(*mesh
->faces
));
84 HeapFree(GetProcessHeap(), 0, mesh
->vertices
);
87 mesh
->number_of_faces
= number_of_faces
;
92 static void compare_mesh(const char *name
, ID3DXMesh
*d3dxmesh
, struct mesh
*mesh
)
95 DWORD number_of_vertices
, number_of_faces
;
96 IDirect3DVertexBuffer9
*vertex_buffer
;
97 IDirect3DIndexBuffer9
*index_buffer
;
98 D3DVERTEXBUFFER_DESC vertex_buffer_description
;
99 D3DINDEXBUFFER_DESC index_buffer_description
;
100 struct vertex
*vertices
;
104 number_of_vertices
= d3dxmesh
->lpVtbl
->GetNumVertices(d3dxmesh
);
105 ok(number_of_vertices
== mesh
->number_of_vertices
, "Test %s, result %u, expected %d\n",
106 name
, number_of_vertices
, mesh
->number_of_vertices
);
108 number_of_faces
= d3dxmesh
->lpVtbl
->GetNumFaces(d3dxmesh
);
109 ok(number_of_faces
== mesh
->number_of_faces
, "Test %s, result %u, expected %d\n",
110 name
, number_of_faces
, mesh
->number_of_faces
);
113 hr
= d3dxmesh
->lpVtbl
->GetVertexBuffer(d3dxmesh
, &vertex_buffer
);
114 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
118 skip("Couldn't get vertex buffer\n");
122 hr
= IDirect3DVertexBuffer9_GetDesc(vertex_buffer
, &vertex_buffer_description
);
123 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
127 skip("Couldn't get vertex buffer description\n");
131 ok(vertex_buffer_description
.Format
== D3DFMT_VERTEXDATA
, "Test %s, result %x, expected %x (D3DFMT_VERTEXDATA)\n",
132 name
, vertex_buffer_description
.Format
, D3DFMT_VERTEXDATA
);
133 ok(vertex_buffer_description
.Type
== D3DRTYPE_VERTEXBUFFER
, "Test %s, result %x, expected %x (D3DRTYPE_VERTEXBUFFER)\n",
134 name
, vertex_buffer_description
.Type
, D3DRTYPE_VERTEXBUFFER
);
135 ok(vertex_buffer_description
.Usage
== 0, "Test %s, result %x, expected %x\n", name
, vertex_buffer_description
.Usage
, 0);
136 ok(vertex_buffer_description
.Pool
== D3DPOOL_MANAGED
, "Test %s, result %x, expected %x (D3DPOOL_DEFAULT)\n",
137 name
, vertex_buffer_description
.Pool
, D3DPOOL_DEFAULT
);
138 ok(vertex_buffer_description
.FVF
== mesh
->fvf
, "Test %s, result %x, expected %x\n",
139 name
, vertex_buffer_description
.FVF
, mesh
->fvf
);
142 expected
= number_of_vertices
* mesh
->vertex_size
;
146 expected
= number_of_vertices
* D3DXGetFVFVertexSize(mesh
->fvf
);
148 ok(vertex_buffer_description
.Size
== expected
, "Test %s, result %x, expected %x\n",
149 name
, vertex_buffer_description
.Size
, expected
);
152 /* specify offset and size to avoid potential overruns */
153 hr
= IDirect3DVertexBuffer9_Lock(vertex_buffer
, 0, number_of_vertices
* sizeof(D3DXVECTOR3
) * 2,
154 (LPVOID
*)&vertices
, D3DLOCK_DISCARD
);
155 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
159 skip("Couldn't lock vertex buffer\n");
163 for (i
= 0; i
< number_of_vertices
; i
++)
165 ok(compare_vec3(vertices
[i
].position
, mesh
->vertices
[i
].position
),
166 "Test %s, vertex position %d, result (%g, %g, %g), expected (%g, %g, %g)\n", name
, i
,
167 vertices
[i
].position
.x
, vertices
[i
].position
.y
, vertices
[i
].position
.z
,
168 mesh
->vertices
[i
].position
.x
, mesh
->vertices
[i
].position
.y
, mesh
->vertices
[i
].position
.z
);
169 ok(compare_vec3(vertices
[i
].normal
, mesh
->vertices
[i
].normal
),
170 "Test %s, vertex normal %d, result (%g, %g, %g), expected (%g, %g, %g)\n", name
, i
,
171 vertices
[i
].normal
.x
, vertices
[i
].normal
.y
, vertices
[i
].normal
.z
,
172 mesh
->vertices
[i
].normal
.x
, mesh
->vertices
[i
].normal
.y
, mesh
->vertices
[i
].normal
.z
);
175 IDirect3DVertexBuffer9_Unlock(vertex_buffer
);
178 IDirect3DVertexBuffer9_Release(vertex_buffer
);
182 hr
= d3dxmesh
->lpVtbl
->GetIndexBuffer(d3dxmesh
, &index_buffer
);
183 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
187 skip("Couldn't get index buffer\n");
191 hr
= IDirect3DIndexBuffer9_GetDesc(index_buffer
, &index_buffer_description
);
192 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
196 skip("Couldn't get index buffer description\n");
200 ok(index_buffer_description
.Format
== D3DFMT_INDEX16
, "Test %s, result %x, expected %x (D3DFMT_INDEX16)\n",
201 name
, index_buffer_description
.Format
, D3DFMT_INDEX16
);
202 ok(index_buffer_description
.Type
== D3DRTYPE_INDEXBUFFER
, "Test %s, result %x, expected %x (D3DRTYPE_INDEXBUFFER)\n",
203 name
, index_buffer_description
.Type
, D3DRTYPE_INDEXBUFFER
);
204 todo_wine
ok(index_buffer_description
.Usage
== 0, "Test %s, result %x, expected %x\n", name
, index_buffer_description
.Usage
, 0);
205 ok(index_buffer_description
.Pool
== D3DPOOL_MANAGED
, "Test %s, result %x, expected %x (D3DPOOL_DEFAULT)\n",
206 name
, index_buffer_description
.Pool
, D3DPOOL_DEFAULT
);
207 expected
= number_of_faces
* sizeof(WORD
) * 3;
208 ok(index_buffer_description
.Size
== expected
, "Test %s, result %x, expected %x\n",
209 name
, index_buffer_description
.Size
, expected
);
212 /* specify offset and size to avoid potential overruns */
213 hr
= IDirect3DIndexBuffer9_Lock(index_buffer
, 0, number_of_faces
* sizeof(WORD
) * 3,
214 (LPVOID
*)&faces
, D3DLOCK_DISCARD
);
215 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
219 skip("Couldn't lock index buffer\n");
223 for (i
= 0; i
< number_of_faces
; i
++)
225 ok(compare_face(faces
[i
], mesh
->faces
[i
]),
226 "Test %s, face %d, result (%u, %u, %u), expected (%u, %u, %u)\n", name
, i
,
227 faces
[i
][0], faces
[i
][1], faces
[i
][2],
228 mesh
->faces
[i
][0], mesh
->faces
[i
][1], mesh
->faces
[i
][2]);
231 IDirect3DIndexBuffer9_Unlock(index_buffer
);
234 IDirect3DIndexBuffer9_Release(index_buffer
);
238 static void D3DXBoundProbeTest(void)
241 D3DXVECTOR3 bottom_point
, center
, top_point
, raydirection
, rayposition
;
244 /*____________Test the Box case___________________________*/
245 bottom_point
.x
= -3.0f
; bottom_point
.y
= -2.0f
; bottom_point
.z
= -1.0f
;
246 top_point
.x
= 7.0f
; top_point
.y
= 8.0f
; top_point
.z
= 9.0f
;
248 raydirection
.x
= -4.0f
; raydirection
.y
= -5.0f
; raydirection
.z
= -6.0f
;
249 rayposition
.x
= 5.0f
; rayposition
.y
= 5.0f
; rayposition
.z
= 11.0f
;
250 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
251 ok(result
== TRUE
, "expected TRUE, received FALSE\n");
253 raydirection
.x
= 4.0f
; raydirection
.y
= 5.0f
; raydirection
.z
= 6.0f
;
254 rayposition
.x
= 5.0f
; rayposition
.y
= 5.0f
; rayposition
.z
= 11.0f
;
255 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
256 ok(result
== FALSE
, "expected FALSE, received TRUE\n");
258 rayposition
.x
= -4.0f
; rayposition
.y
= 1.0f
; rayposition
.z
= -2.0f
;
259 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
260 ok(result
== TRUE
, "expected TRUE, received FALSE\n");
262 bottom_point
.x
= 1.0f
; bottom_point
.y
= 0.0f
; bottom_point
.z
= 0.0f
;
263 top_point
.x
= 1.0f
; top_point
.y
= 0.0f
; top_point
.z
= 0.0f
;
264 rayposition
.x
= 0.0f
; rayposition
.y
= 1.0f
; rayposition
.z
= 0.0f
;
265 raydirection
.x
= 0.0f
; raydirection
.y
= 3.0f
; raydirection
.z
= 0.0f
;
266 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
267 ok(result
== FALSE
, "expected FALSE, received TRUE\n");
269 bottom_point
.x
= 1.0f
; bottom_point
.y
= 2.0f
; bottom_point
.z
= 3.0f
;
270 top_point
.x
= 10.0f
; top_point
.y
= 15.0f
; top_point
.z
= 20.0f
;
272 raydirection
.x
= 7.0f
; raydirection
.y
= 8.0f
; raydirection
.z
= 9.0f
;
273 rayposition
.x
= 3.0f
; rayposition
.y
= 7.0f
; rayposition
.z
= -6.0f
;
274 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
275 ok(result
== TRUE
, "expected TRUE, received FALSE\n");
277 bottom_point
.x
= 0.0f
; bottom_point
.y
= 0.0f
; bottom_point
.z
= 0.0f
;
278 top_point
.x
= 1.0f
; top_point
.y
= 1.0f
; top_point
.z
= 1.0f
;
280 raydirection
.x
= 0.0f
; raydirection
.y
= 1.0f
; raydirection
.z
= .0f
;
281 rayposition
.x
= -3.0f
; rayposition
.y
= 0.0f
; rayposition
.z
= 0.0f
;
282 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
283 ok(result
== FALSE
, "expected FALSE, received TRUE\n");
285 raydirection
.x
= 1.0f
; raydirection
.y
= 0.0f
; raydirection
.z
= .0f
;
286 rayposition
.x
= -3.0f
; rayposition
.y
= 0.0f
; rayposition
.z
= 0.0f
;
287 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
288 ok(result
== TRUE
, "expected TRUE, received FALSE\n");
290 /*____________Test the Sphere case________________________*/
291 radius
= sqrt(77.0f
);
292 center
.x
= 1.0f
; center
.y
= 2.0f
; center
.z
= 3.0f
;
293 raydirection
.x
= 2.0f
; raydirection
.y
= -4.0f
; raydirection
.z
= 2.0f
;
295 rayposition
.x
= 5.0f
; rayposition
.y
= 5.0f
; rayposition
.z
= 9.0f
;
296 result
= D3DXSphereBoundProbe(¢er
, radius
, &rayposition
, &raydirection
);
297 ok(result
== TRUE
, "expected TRUE, received FALSE\n");
299 rayposition
.x
= 45.0f
; rayposition
.y
= -75.0f
; rayposition
.z
= 49.0f
;
300 result
= D3DXSphereBoundProbe(¢er
, radius
, &rayposition
, &raydirection
);
301 ok(result
== FALSE
, "expected FALSE, received TRUE\n");
303 rayposition
.x
= 5.0f
; rayposition
.y
= 11.0f
; rayposition
.z
= 9.0f
;
304 result
= D3DXSphereBoundProbe(¢er
, radius
, &rayposition
, &raydirection
);
305 ok(result
== FALSE
, "expected FALSE, received TRUE\n");
308 static void D3DXComputeBoundingBoxTest(void)
310 D3DXVECTOR3 exp_max
, exp_min
, got_max
, got_min
, vertex
[5];
313 vertex
[0].x
= 1.0f
; vertex
[0].y
= 1.0f
; vertex
[0].z
= 1.0f
;
314 vertex
[1].x
= 1.0f
; vertex
[1].y
= 1.0f
; vertex
[1].z
= 1.0f
;
315 vertex
[2].x
= 1.0f
; vertex
[2].y
= 1.0f
; vertex
[2].z
= 1.0f
;
316 vertex
[3].x
= 1.0f
; vertex
[3].y
= 1.0f
; vertex
[3].z
= 1.0f
;
317 vertex
[4].x
= 9.0f
; vertex
[4].y
= 9.0f
; vertex
[4].z
= 9.0f
;
319 exp_min
.x
= 1.0f
; exp_min
.y
= 1.0f
; exp_min
.z
= 1.0f
;
320 exp_max
.x
= 9.0f
; exp_max
.y
= 9.0f
; exp_max
.z
= 9.0f
;
322 hr
= D3DXComputeBoundingBox(&vertex
[3],2,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_min
,&got_max
);
324 ok( hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
325 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
);
326 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
);
328 /*________________________*/
330 vertex
[0].x
= 2.0f
; vertex
[0].y
= 5.9f
; vertex
[0].z
= -1.2f
;
331 vertex
[1].x
= -1.87f
; vertex
[1].y
= 7.9f
; vertex
[1].z
= 7.4f
;
332 vertex
[2].x
= 7.43f
; vertex
[2].y
= -0.9f
; vertex
[2].z
= 11.9f
;
333 vertex
[3].x
= -6.92f
; vertex
[3].y
= 6.3f
; vertex
[3].z
= -3.8f
;
334 vertex
[4].x
= 11.4f
; vertex
[4].y
= -8.1f
; vertex
[4].z
= 4.5f
;
336 exp_min
.x
= -6.92f
; exp_min
.y
= -8.1f
; exp_min
.z
= -3.80f
;
337 exp_max
.x
= 11.4f
; exp_max
.y
= 7.90f
; exp_max
.z
= 11.9f
;
339 hr
= D3DXComputeBoundingBox(&vertex
[0],5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_min
,&got_max
);
341 ok( hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
342 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
);
343 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
);
345 /*________________________*/
347 vertex
[0].x
= 2.0f
; vertex
[0].y
= 5.9f
; vertex
[0].z
= -1.2f
;
348 vertex
[1].x
= -1.87f
; vertex
[1].y
= 7.9f
; vertex
[1].z
= 7.4f
;
349 vertex
[2].x
= 7.43f
; vertex
[2].y
= -0.9f
; vertex
[2].z
= 11.9f
;
350 vertex
[3].x
= -6.92f
; vertex
[3].y
= 6.3f
; vertex
[3].z
= -3.8f
;
351 vertex
[4].x
= 11.4f
; vertex
[4].y
= -8.1f
; vertex
[4].z
= 4.5f
;
353 exp_min
.x
= -6.92f
; exp_min
.y
= -0.9f
; exp_min
.z
= -3.8f
;
354 exp_max
.x
= 7.43f
; exp_max
.y
= 7.90f
; exp_max
.z
= 11.9f
;
356 hr
= D3DXComputeBoundingBox(&vertex
[0],4,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_min
,&got_max
);
358 ok( hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
359 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
);
360 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
);
362 /*________________________*/
363 hr
= D3DXComputeBoundingBox(NULL
,5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_min
,&got_max
);
364 ok( hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
366 /*________________________*/
367 hr
= D3DXComputeBoundingBox(&vertex
[3],5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),NULL
,&got_max
);
368 ok( hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
370 /*________________________*/
371 hr
= D3DXComputeBoundingBox(&vertex
[3],5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_min
,NULL
);
372 ok( hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
375 static void D3DXComputeBoundingSphereTest(void)
377 D3DXVECTOR3 exp_cen
, got_cen
, vertex
[5];
378 FLOAT exp_rad
, got_rad
;
381 vertex
[0].x
= 1.0f
; vertex
[0].y
= 1.0f
; vertex
[0].z
= 1.0f
;
382 vertex
[1].x
= 1.0f
; vertex
[1].y
= 1.0f
; vertex
[1].z
= 1.0f
;
383 vertex
[2].x
= 1.0f
; vertex
[2].y
= 1.0f
; vertex
[2].z
= 1.0f
;
384 vertex
[3].x
= 1.0f
; vertex
[3].y
= 1.0f
; vertex
[3].z
= 1.0f
;
385 vertex
[4].x
= 9.0f
; vertex
[4].y
= 9.0f
; vertex
[4].z
= 9.0f
;
388 exp_cen
.x
= 5.0; exp_cen
.y
= 5.0; exp_cen
.z
= 5.0;
390 hr
= D3DXComputeBoundingSphere(&vertex
[3],2,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_cen
,&got_rad
);
392 ok( hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
393 ok( compare(exp_rad
, got_rad
), "Expected radius: %f, got radius: %f\n", exp_rad
, got_rad
);
394 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
);
396 /*________________________*/
398 vertex
[0].x
= 2.0f
; vertex
[0].y
= 5.9f
; vertex
[0].z
= -1.2f
;
399 vertex
[1].x
= -1.87f
; vertex
[1].y
= 7.9f
; vertex
[1].z
= 7.4f
;
400 vertex
[2].x
= 7.43f
; vertex
[2].y
= -0.9f
; vertex
[2].z
= 11.9f
;
401 vertex
[3].x
= -6.92f
; vertex
[3].y
= 6.3f
; vertex
[3].z
= -3.8f
;
402 vertex
[4].x
= 11.4f
; vertex
[4].y
= -8.1f
; vertex
[4].z
= 4.5f
;
404 exp_rad
= 13.707883f
;
405 exp_cen
.x
= 2.408f
; exp_cen
.y
= 2.22f
; exp_cen
.z
= 3.76f
;
407 hr
= D3DXComputeBoundingSphere(&vertex
[0],5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_cen
,&got_rad
);
409 ok( hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
410 ok( compare(exp_rad
, got_rad
), "Expected radius: %f, got radius: %f\n", exp_rad
, got_rad
);
411 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
);
413 /*________________________*/
414 hr
= D3DXComputeBoundingSphere(NULL
,5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_cen
,&got_rad
);
415 ok( hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
417 /*________________________*/
418 hr
= D3DXComputeBoundingSphere(&vertex
[3],5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),NULL
,&got_rad
);
419 ok( hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
421 /*________________________*/
422 hr
= D3DXComputeBoundingSphere(&vertex
[3],5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_cen
,NULL
);
423 ok( hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
426 static void print_elements(const D3DVERTEXELEMENT9
*elements
)
428 D3DVERTEXELEMENT9 last
= D3DDECL_END();
429 const D3DVERTEXELEMENT9
*ptr
= elements
;
432 while (memcmp(ptr
, &last
, sizeof(D3DVERTEXELEMENT9
)))
435 "[Element %d] Stream = %d, Offset = %d, Type = %d, Method = %d, Usage = %d, UsageIndex = %d\n",
436 count
, ptr
->Stream
, ptr
->Offset
, ptr
->Type
, ptr
->Method
, ptr
->Usage
, ptr
->UsageIndex
);
442 static void compare_elements(const D3DVERTEXELEMENT9
*elements
, const D3DVERTEXELEMENT9
*expected_elements
,
443 unsigned int line
, unsigned int test_id
)
445 D3DVERTEXELEMENT9 last
= D3DDECL_END();
448 for (i
= 0; i
< MAX_FVF_DECL_SIZE
; i
++)
450 int end1
= memcmp(&elements
[i
], &last
, sizeof(last
));
451 int end2
= memcmp(&expected_elements
[i
], &last
, sizeof(last
));
454 if (!end1
&& !end2
) break;
456 status
= !end1
^ !end2
;
457 ok(!status
, "Line %u, test %u: Mismatch in size, test declaration is %s than expected.\n",
458 line
, test_id
, end1
? "shorter" : "longer");
461 print_elements(elements
);
465 status
= memcmp(&elements
[i
], &expected_elements
[i
], sizeof(D3DVERTEXELEMENT9
));
466 ok(!status
, "Line %u, test %u: Mismatch in element %u.\n", line
, test_id
, i
);
469 print_elements(elements
);
475 static void test_fvf_to_decl(DWORD test_fvf
, const D3DVERTEXELEMENT9 expected_elements
[],
476 HRESULT expected_hr
, unsigned int line
, unsigned int test_id
)
479 D3DVERTEXELEMENT9 decl
[MAX_FVF_DECL_SIZE
];
481 hr
= D3DXDeclaratorFromFVF(test_fvf
, decl
);
482 ok(hr
== expected_hr
,
483 "Line %u, test %u: D3DXDeclaratorFromFVF returned %#x, expected %#x.\n",
484 line
, test_id
, hr
, expected_hr
);
485 if (SUCCEEDED(hr
)) compare_elements(decl
, expected_elements
, line
, test_id
);
488 static void test_decl_to_fvf(const D3DVERTEXELEMENT9
*decl
, DWORD expected_fvf
,
489 HRESULT expected_hr
, unsigned int line
, unsigned int test_id
)
492 DWORD result_fvf
= 0xdeadbeef;
494 hr
= D3DXFVFFromDeclarator(decl
, &result_fvf
);
495 ok(hr
== expected_hr
,
496 "Line %u, test %u: D3DXFVFFromDeclarator returned %#x, expected %#x.\n",
497 line
, test_id
, hr
, expected_hr
);
500 ok(expected_fvf
== result_fvf
, "Line %u, test %u: Got FVF %#x, expected %#x.\n",
501 line
, test_id
, result_fvf
, expected_fvf
);
505 static void test_fvf_decl_conversion(void)
509 D3DVERTEXELEMENT9 decl
[MAXD3DDECLLENGTH
+ 1];
518 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
522 {0, 0, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_POSITIONT
, 0},
526 {0, 0, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_POSITIONT
, 0},
530 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
531 {0, 12, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
535 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
536 {0, 12, D3DDECLTYPE_UBYTE4
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
538 }, D3DFVF_XYZB1
| D3DFVF_LASTBETA_UBYTE4
},
540 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
541 {0, 12, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
543 }, D3DFVF_XYZB1
| D3DFVF_LASTBETA_D3DCOLOR
},
545 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
546 {0, 12, D3DDECLTYPE_FLOAT2
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
550 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
551 {0, 12, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
552 {0, 16, D3DDECLTYPE_UBYTE4
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
554 }, D3DFVF_XYZB2
| D3DFVF_LASTBETA_UBYTE4
},
556 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
557 {0, 12, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
558 {0, 16, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
560 }, D3DFVF_XYZB2
| D3DFVF_LASTBETA_D3DCOLOR
},
562 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
563 {0, 12, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
567 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
568 {0, 12, D3DDECLTYPE_FLOAT2
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
569 {0, 20, D3DDECLTYPE_UBYTE4
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
571 }, D3DFVF_XYZB3
| D3DFVF_LASTBETA_UBYTE4
},
573 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
574 {0, 12, D3DDECLTYPE_FLOAT2
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
575 {0, 20, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
577 }, D3DFVF_XYZB3
| D3DFVF_LASTBETA_D3DCOLOR
},
579 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
580 {0, 12, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
584 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
585 {0, 12, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
586 {0, 24, D3DDECLTYPE_UBYTE4
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
588 }, D3DFVF_XYZB4
| D3DFVF_LASTBETA_UBYTE4
},
590 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
591 {0, 12, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
592 {0, 24, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
594 }, D3DFVF_XYZB4
| D3DFVF_LASTBETA_D3DCOLOR
},
596 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
597 {0, 12, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
598 {0, 28, D3DDECLTYPE_UBYTE4
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
600 }, D3DFVF_XYZB5
| D3DFVF_LASTBETA_UBYTE4
},
602 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
603 {0, 12, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
604 {0, 28, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
606 }, D3DFVF_XYZB5
| D3DFVF_LASTBETA_D3DCOLOR
},
608 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_NORMAL
, 0},
612 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_NORMAL
, 0},
613 {0, 12, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 0},
615 }, D3DFVF_NORMAL
| D3DFVF_DIFFUSE
},
617 {0, 0, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_PSIZE
, 0},
621 {0, 0, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 0},
625 {0, 0, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 1},
628 /* Make sure textures of different sizes work. */
630 {0, 0, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_TEXCOORD
, 0},
632 }, D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEX1
},
634 {0, 0, D3DDECLTYPE_FLOAT2
, 0, D3DDECLUSAGE_TEXCOORD
, 0},
636 }, D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEX1
},
638 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_TEXCOORD
, 0},
640 }, D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1
},
642 {0, 0, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_TEXCOORD
, 0},
644 }, D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1
},
645 /* Make sure the TEXCOORD index works correctly - try several textures. */
647 {0, 0, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_TEXCOORD
, 0},
648 {0, 4, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_TEXCOORD
, 1},
649 {0, 16, D3DDECLTYPE_FLOAT2
, 0, D3DDECLUSAGE_TEXCOORD
, 2},
650 {0, 24, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_TEXCOORD
, 3},
652 }, D3DFVF_TEX4
| D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEXCOORDSIZE3(1)
653 | D3DFVF_TEXCOORDSIZE2(2) | D3DFVF_TEXCOORDSIZE4(3)},
654 /* Now try some combination tests. */
656 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
657 {0, 12, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
658 {0, 28, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 0},
659 {0, 32, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 1},
660 {0, 36, D3DDECLTYPE_FLOAT2
, 0, D3DDECLUSAGE_TEXCOORD
, 0},
661 {0, 44, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_TEXCOORD
, 1},
663 }, D3DFVF_XYZB4
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
| D3DFVF_TEX2
664 | D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE3(1)},
666 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
667 {0, 12, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_NORMAL
, 0},
668 {0, 24, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_PSIZE
, 0},
669 {0, 28, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 1},
670 {0, 32, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_TEXCOORD
, 0},
671 {0, 36, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_TEXCOORD
, 1},
673 }, D3DFVF_XYZ
| D3DFVF_NORMAL
| D3DFVF_PSIZE
| D3DFVF_SPECULAR
| D3DFVF_TEX2
674 | D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEXCOORDSIZE4(1)},
678 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
680 test_decl_to_fvf(test_data
[i
].decl
, test_data
[i
].fvf
, D3D_OK
, __LINE__
, i
);
681 test_fvf_to_decl(test_data
[i
].fvf
, test_data
[i
].decl
, D3D_OK
, __LINE__
, i
);
684 /* Usage indices for position and normal are apparently ignored. */
686 const D3DVERTEXELEMENT9 decl
[] =
688 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 1},
691 test_decl_to_fvf(decl
, D3DFVF_XYZ
, D3D_OK
, __LINE__
, 0);
694 const D3DVERTEXELEMENT9 decl
[] =
696 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_NORMAL
, 1},
699 test_decl_to_fvf(decl
, D3DFVF_NORMAL
, D3D_OK
, __LINE__
, 0);
701 /* D3DFVF_LASTBETA_UBYTE4 and D3DFVF_LASTBETA_D3DCOLOR are ignored if
702 * there are no blend matrices. */
704 const D3DVERTEXELEMENT9 decl
[] =
706 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
709 test_fvf_to_decl(D3DFVF_XYZ
| D3DFVF_LASTBETA_UBYTE4
, decl
, D3D_OK
, __LINE__
, 0);
712 const D3DVERTEXELEMENT9 decl
[] =
714 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
717 test_fvf_to_decl(D3DFVF_XYZ
| D3DFVF_LASTBETA_D3DCOLOR
, decl
, D3D_OK
, __LINE__
, 0);
719 /* D3DFVF_LASTBETA_UBYTE4 takes precedence over D3DFVF_LASTBETA_D3DCOLOR. */
721 const D3DVERTEXELEMENT9 decl
[] =
723 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
724 {0, 12, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
725 {0, 28, D3DDECLTYPE_UBYTE4
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
728 test_fvf_to_decl(D3DFVF_XYZB5
| D3DFVF_LASTBETA_D3DCOLOR
| D3DFVF_LASTBETA_UBYTE4
,
729 decl
, D3D_OK
, __LINE__
, 0);
731 /* These are supposed to fail, both ways. */
733 const D3DVERTEXELEMENT9 decl
[] =
735 {0, 0, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_POSITION
, 0},
738 test_decl_to_fvf(decl
, D3DFVF_XYZW
, D3DERR_INVALIDCALL
, __LINE__
, 0);
739 test_fvf_to_decl(D3DFVF_XYZW
, decl
, D3DERR_INVALIDCALL
, __LINE__
, 0);
742 const D3DVERTEXELEMENT9 decl
[] =
744 {0, 0, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_POSITION
, 0},
745 {0, 16, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_NORMAL
, 0},
748 test_decl_to_fvf(decl
, D3DFVF_XYZW
| D3DFVF_NORMAL
, D3DERR_INVALIDCALL
, __LINE__
, 0);
749 test_fvf_to_decl(D3DFVF_XYZW
| D3DFVF_NORMAL
, decl
, D3DERR_INVALIDCALL
, __LINE__
, 0);
752 const D3DVERTEXELEMENT9 decl
[] =
754 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
755 {0, 12, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_BLENDWEIGHT
, 0},
756 {0, 28, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_BLENDINDICES
, 0},
759 test_decl_to_fvf(decl
, D3DFVF_XYZB5
, D3DERR_INVALIDCALL
, __LINE__
, 0);
760 test_fvf_to_decl(D3DFVF_XYZB5
, decl
, D3DERR_INVALIDCALL
, __LINE__
, 0);
762 /* Test a declaration that can't be converted to an FVF. */
764 const D3DVERTEXELEMENT9 decl
[] =
766 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
767 {0, 12, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_NORMAL
, 0},
768 {0, 24, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_PSIZE
, 0},
769 {0, 28, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 1},
770 {0, 32, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_TEXCOORD
, 0},
771 /* 8 bytes padding */
772 {0, 44, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_TEXCOORD
, 1},
775 test_decl_to_fvf(decl
, 0, D3DERR_INVALIDCALL
, __LINE__
, 0);
777 /* Elements must be ordered by offset. */
779 const D3DVERTEXELEMENT9 decl
[] =
781 {0, 12, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 0},
782 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
785 test_decl_to_fvf(decl
, 0, D3DERR_INVALIDCALL
, __LINE__
, 0);
787 /* Basic tests for element order. */
789 const D3DVERTEXELEMENT9 decl
[] =
791 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
792 {0, 12, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 0},
793 {0, 16, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_NORMAL
, 0},
796 test_decl_to_fvf(decl
, 0, D3DERR_INVALIDCALL
, __LINE__
, 0);
799 const D3DVERTEXELEMENT9 decl
[] =
801 {0, 0, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 0},
802 {0, 4, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
805 test_decl_to_fvf(decl
, 0, D3DERR_INVALIDCALL
, __LINE__
, 0);
808 const D3DVERTEXELEMENT9 decl
[] =
810 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_NORMAL
, 0},
811 {0, 12, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
814 test_decl_to_fvf(decl
, 0, D3DERR_INVALIDCALL
, __LINE__
, 0);
816 /* Textures must be ordered by texcoords. */
818 const D3DVERTEXELEMENT9 decl
[] =
820 {0, 0, D3DDECLTYPE_FLOAT1
, 0, D3DDECLUSAGE_TEXCOORD
, 0},
821 {0, 4, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_TEXCOORD
, 2},
822 {0, 16, D3DDECLTYPE_FLOAT2
, 0, D3DDECLUSAGE_TEXCOORD
, 1},
823 {0, 24, D3DDECLTYPE_FLOAT4
, 0, D3DDECLUSAGE_TEXCOORD
, 3},
826 test_decl_to_fvf(decl
, 0, D3DERR_INVALIDCALL
, __LINE__
, 0);
828 /* Duplicate elements are not allowed. */
830 const D3DVERTEXELEMENT9 decl
[] =
832 {0, 0, D3DDECLTYPE_FLOAT3
, 0, D3DDECLUSAGE_POSITION
, 0},
833 {0, 12, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 0},
834 {0, 16, D3DDECLTYPE_D3DCOLOR
, 0, D3DDECLUSAGE_COLOR
, 0},
837 test_decl_to_fvf(decl
, 0, D3DERR_INVALIDCALL
, __LINE__
, 0);
839 /* Invalid FVFs cannot be converted to a declarator. */
840 test_fvf_to_decl(0xdeadbeef, NULL
, D3DERR_INVALIDCALL
, __LINE__
, 0);
843 static void D3DXGetFVFVertexSizeTest(void)
847 compare_vertex_sizes (D3DFVF_XYZ
, 12);
849 compare_vertex_sizes (D3DFVF_XYZB3
, 24);
851 compare_vertex_sizes (D3DFVF_XYZB5
, 32);
853 compare_vertex_sizes (D3DFVF_XYZ
| D3DFVF_NORMAL
, 24);
855 compare_vertex_sizes (D3DFVF_XYZ
| D3DFVF_DIFFUSE
, 16);
857 compare_vertex_sizes (
860 D3DFVF_TEXCOORDSIZE1(0), 16);
861 compare_vertex_sizes (
864 D3DFVF_TEXCOORDSIZE1(0) |
865 D3DFVF_TEXCOORDSIZE1(1), 20);
867 compare_vertex_sizes (
870 D3DFVF_TEXCOORDSIZE2(0), 20);
872 compare_vertex_sizes (
875 D3DFVF_TEXCOORDSIZE2(0) |
876 D3DFVF_TEXCOORDSIZE2(1), 28);
878 compare_vertex_sizes (
881 D3DFVF_TEXCOORDSIZE2(0) |
882 D3DFVF_TEXCOORDSIZE2(1) |
883 D3DFVF_TEXCOORDSIZE2(2) |
884 D3DFVF_TEXCOORDSIZE2(3) |
885 D3DFVF_TEXCOORDSIZE2(4) |
886 D3DFVF_TEXCOORDSIZE2(5), 60);
888 compare_vertex_sizes (
891 D3DFVF_TEXCOORDSIZE2(0) |
892 D3DFVF_TEXCOORDSIZE2(1) |
893 D3DFVF_TEXCOORDSIZE2(2) |
894 D3DFVF_TEXCOORDSIZE2(3) |
895 D3DFVF_TEXCOORDSIZE2(4) |
896 D3DFVF_TEXCOORDSIZE2(5) |
897 D3DFVF_TEXCOORDSIZE2(6) |
898 D3DFVF_TEXCOORDSIZE2(7), 76);
900 compare_vertex_sizes (
903 D3DFVF_TEXCOORDSIZE3(0), 24);
905 compare_vertex_sizes (
908 D3DFVF_TEXCOORDSIZE3(0) |
909 D3DFVF_TEXCOORDSIZE3(1) |
910 D3DFVF_TEXCOORDSIZE3(2) |
911 D3DFVF_TEXCOORDSIZE3(3), 60);
913 compare_vertex_sizes (
916 D3DFVF_TEXCOORDSIZE4(0), 28);
918 compare_vertex_sizes (
921 D3DFVF_TEXCOORDSIZE4(0) |
922 D3DFVF_TEXCOORDSIZE4(1), 44);
924 compare_vertex_sizes (
927 D3DFVF_TEXCOORDSIZE4(0) |
928 D3DFVF_TEXCOORDSIZE4(1) |
929 D3DFVF_TEXCOORDSIZE4(2), 60);
931 compare_vertex_sizes (
937 D3DFVF_TEXCOORDSIZE4(0) |
938 D3DFVF_TEXCOORDSIZE4(1) |
939 D3DFVF_TEXCOORDSIZE4(2) |
940 D3DFVF_TEXCOORDSIZE4(3) |
941 D3DFVF_TEXCOORDSIZE4(4) |
942 D3DFVF_TEXCOORDSIZE4(5) |
943 D3DFVF_TEXCOORDSIZE4(6) |
944 D3DFVF_TEXCOORDSIZE4(7), 180);
947 static void D3DXIntersectTriTest(void)
949 BOOL exp_res
, got_res
;
950 D3DXVECTOR3 position
, ray
, vertex
[3];
951 FLOAT exp_dist
, got_dist
, exp_u
, got_u
, exp_v
, got_v
;
953 vertex
[0].x
= 1.0f
; vertex
[0].y
= 0.0f
; vertex
[0].z
= 0.0f
;
954 vertex
[1].x
= 2.0f
; vertex
[1].y
= 0.0f
; vertex
[1].z
= 0.0f
;
955 vertex
[2].x
= 1.0f
; vertex
[2].y
= 1.0f
; vertex
[2].z
= 0.0f
;
957 position
.x
= -14.5f
; position
.y
= -23.75f
; position
.z
= -32.0f
;
959 ray
.x
= 2.0f
; ray
.y
= 3.0f
; ray
.z
= 4.0f
;
961 exp_res
= TRUE
; exp_u
= 0.5f
; exp_v
= 0.25f
; exp_dist
= 8.0f
;
963 got_res
= D3DXIntersectTri(&vertex
[0],&vertex
[1],&vertex
[2],&position
,&ray
,&got_u
,&got_v
,&got_dist
);
964 ok( got_res
== exp_res
, "Expected result = %d, got %d\n",exp_res
,got_res
);
965 ok( compare(exp_u
,got_u
), "Expected u = %f, got %f\n",exp_u
,got_u
);
966 ok( compare(exp_v
,got_v
), "Expected v = %f, got %f\n",exp_v
,got_v
);
967 ok( compare(exp_dist
,got_dist
), "Expected distance = %f, got %f\n",exp_dist
,got_dist
);
969 /*Only positive ray is taken in account*/
971 vertex
[0].x
= 1.0f
; vertex
[0].y
= 0.0f
; vertex
[0].z
= 0.0f
;
972 vertex
[1].x
= 2.0f
; vertex
[1].y
= 0.0f
; vertex
[1].z
= 0.0f
;
973 vertex
[2].x
= 1.0f
; vertex
[2].y
= 1.0f
; vertex
[2].z
= 0.0f
;
975 position
.x
= 17.5f
; position
.y
= 24.25f
; position
.z
= 32.0f
;
977 ray
.x
= 2.0f
; ray
.y
= 3.0f
; ray
.z
= 4.0f
;
981 got_res
= D3DXIntersectTri(&vertex
[0],&vertex
[1],&vertex
[2],&position
,&ray
,&got_u
,&got_v
,&got_dist
);
982 ok( got_res
== exp_res
, "Expected result = %d, got %d\n",exp_res
,got_res
);
984 /*Intersection between ray and triangle in a same plane is considered as empty*/
986 vertex
[0].x
= 4.0f
; vertex
[0].y
= 0.0f
; vertex
[0].z
= 0.0f
;
987 vertex
[1].x
= 6.0f
; vertex
[1].y
= 0.0f
; vertex
[1].z
= 0.0f
;
988 vertex
[2].x
= 4.0f
; vertex
[2].y
= 2.0f
; vertex
[2].z
= 0.0f
;
990 position
.x
= 1.0f
; position
.y
= 1.0f
; position
.z
= 0.0f
;
992 ray
.x
= 1.0f
; ray
.y
= 0.0f
; ray
.z
= 0.0f
;
996 got_res
= D3DXIntersectTri(&vertex
[0],&vertex
[1],&vertex
[2],&position
,&ray
,&got_u
,&got_v
,&got_dist
);
997 ok( got_res
== exp_res
, "Expected result = %d, got %d\n",exp_res
,got_res
);
1000 static void D3DXCreateMeshTest(void)
1005 IDirect3DDevice9
*device
, *test_device
;
1006 D3DPRESENT_PARAMETERS d3dpp
;
1007 ID3DXMesh
*d3dxmesh
;
1009 D3DVERTEXELEMENT9 test_decl
[MAX_FVF_DECL_SIZE
];
1013 static const D3DVERTEXELEMENT9 decl1
[3] = {
1014 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1015 {0, 12, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
1018 static const D3DVERTEXELEMENT9 decl2
[] = {
1019 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1020 {0, 12, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
1021 {0, 24, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_PSIZE
, 0},
1022 {0, 28, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 1},
1023 {0, 32, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 0},
1024 /* 8 bytes padding */
1025 {0, 44, D3DDECLTYPE_FLOAT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_TEXCOORD
, 1},
1029 hr
= D3DXCreateMesh(0, 0, 0, NULL
, NULL
, NULL
);
1030 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1032 hr
= D3DXCreateMesh(1, 3, D3DXMESH_MANAGED
, decl1
, NULL
, &d3dxmesh
);
1033 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1035 wnd
= CreateWindow("static", "d3dx9_test", 0, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
);
1038 skip("Couldn't create application window\n");
1041 d3d
= Direct3DCreate9(D3D_SDK_VERSION
);
1044 skip("Couldn't create IDirect3D9 object\n");
1049 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
1050 d3dpp
.Windowed
= TRUE
;
1051 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1052 hr
= IDirect3D9_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, wnd
, D3DCREATE_MIXED_VERTEXPROCESSING
, &d3dpp
, &device
);
1055 skip("Failed to create IDirect3DDevice9 object %#x\n", hr
);
1056 IDirect3D9_Release(d3d
);
1061 hr
= D3DXCreateMesh(0, 3, D3DXMESH_MANAGED
, decl1
, device
, &d3dxmesh
);
1062 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1064 hr
= D3DXCreateMesh(1, 0, D3DXMESH_MANAGED
, decl1
, device
, &d3dxmesh
);
1065 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1067 hr
= D3DXCreateMesh(1, 3, 0, decl1
, device
, &d3dxmesh
);
1068 ok(hr
== D3D_OK
, "Got result %x, expected %x (D3D_OK)\n", hr
, D3D_OK
);
1072 d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
1075 hr
= D3DXCreateMesh(1, 3, D3DXMESH_MANAGED
, 0, device
, &d3dxmesh
);
1076 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1078 hr
= D3DXCreateMesh(1, 3, D3DXMESH_MANAGED
, decl1
, device
, NULL
);
1079 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1081 hr
= D3DXCreateMesh(1, 3, D3DXMESH_MANAGED
, decl1
, device
, &d3dxmesh
);
1082 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n", hr
);
1087 hr
= d3dxmesh
->lpVtbl
->GetDevice(d3dxmesh
, NULL
);
1088 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1090 hr
= d3dxmesh
->lpVtbl
->GetDevice(d3dxmesh
, &test_device
);
1091 ok(hr
== D3D_OK
, "Got result %x, expected %x (D3D_OK)\n", hr
, D3D_OK
);
1092 ok(test_device
== device
, "Got result %p, expected %p\n", test_device
, device
);
1096 IDirect3DDevice9_Release(device
);
1100 hr
= d3dxmesh
->lpVtbl
->GetDeclaration(d3dxmesh
, NULL
);
1101 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1103 hr
= d3dxmesh
->lpVtbl
->GetDeclaration(d3dxmesh
, test_decl
);
1104 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n", hr
);
1108 size
= sizeof(decl1
) / sizeof(decl1
[0]);
1109 for (i
= 0; i
< size
- 1; i
++)
1111 ok(test_decl
[i
].Stream
== decl1
[i
].Stream
, "Returned stream %d, expected %d\n", test_decl
[i
].Stream
, decl1
[i
].Stream
);
1112 ok(test_decl
[i
].Type
== decl1
[i
].Type
, "Returned type %d, expected %d\n", test_decl
[i
].Type
, decl1
[i
].Type
);
1113 ok(test_decl
[i
].Method
== decl1
[i
].Method
, "Returned method %d, expected %d\n", test_decl
[i
].Method
, decl1
[i
].Method
);
1114 ok(test_decl
[i
].Usage
== decl1
[i
].Usage
, "Returned usage %d, expected %d\n", test_decl
[i
].Usage
, decl1
[i
].Usage
);
1115 ok(test_decl
[i
].UsageIndex
== decl1
[i
].UsageIndex
, "Returned usage index %d, expected %d\n", test_decl
[i
].UsageIndex
, decl1
[i
].UsageIndex
);
1116 ok(test_decl
[i
].Offset
== decl1
[i
].Offset
, "Returned offset %d, expected %d\n", test_decl
[i
].Offset
, decl1
[i
].Offset
);
1118 ok(decl1
[size
-1].Stream
== 0xFF, "Returned too long vertex declaration\n"); /* end element */
1122 options
= d3dxmesh
->lpVtbl
->GetOptions(d3dxmesh
);
1123 ok(options
== D3DXMESH_MANAGED
, "Got result %x, expected %x (D3DXMESH_MANAGED)\n", options
, D3DXMESH_MANAGED
);
1126 if (!new_mesh(&mesh
, 3, 1))
1128 skip("Couldn't create mesh\n");
1132 memset(mesh
.vertices
, 0, mesh
.number_of_vertices
* sizeof(*mesh
.vertices
));
1133 memset(mesh
.faces
, 0, mesh
.number_of_faces
* sizeof(*mesh
.faces
));
1134 mesh
.fvf
= D3DFVF_XYZ
| D3DFVF_NORMAL
;
1136 compare_mesh("createmesh1", d3dxmesh
, &mesh
);
1141 d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
1144 /* Test a declaration that can't be converted to an FVF. */
1145 hr
= D3DXCreateMesh(1, 3, D3DXMESH_MANAGED
, decl2
, device
, &d3dxmesh
);
1146 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n", hr
);
1151 hr
= d3dxmesh
->lpVtbl
->GetDevice(d3dxmesh
, NULL
);
1152 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1154 hr
= d3dxmesh
->lpVtbl
->GetDevice(d3dxmesh
, &test_device
);
1155 ok(hr
== D3D_OK
, "Got result %x, expected %x (D3D_OK)\n", hr
, D3D_OK
);
1156 ok(test_device
== device
, "Got result %p, expected %p\n", test_device
, device
);
1160 IDirect3DDevice9_Release(device
);
1164 hr
= d3dxmesh
->lpVtbl
->GetDeclaration(d3dxmesh
, test_decl
);
1165 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n", hr
);
1169 size
= sizeof(decl2
) / sizeof(decl2
[0]);
1170 for (i
= 0; i
< size
- 1; i
++)
1172 ok(test_decl
[i
].Stream
== decl2
[i
].Stream
, "Returned stream %d, expected %d\n", test_decl
[i
].Stream
, decl2
[i
].Stream
);
1173 ok(test_decl
[i
].Type
== decl2
[i
].Type
, "Returned type %d, expected %d\n", test_decl
[i
].Type
, decl2
[i
].Type
);
1174 ok(test_decl
[i
].Method
== decl2
[i
].Method
, "Returned method %d, expected %d\n", test_decl
[i
].Method
, decl2
[i
].Method
);
1175 ok(test_decl
[i
].Usage
== decl2
[i
].Usage
, "Returned usage %d, expected %d\n", test_decl
[i
].Usage
, decl2
[i
].Usage
);
1176 ok(test_decl
[i
].UsageIndex
== decl2
[i
].UsageIndex
, "Returned usage index %d, expected %d\n", test_decl
[i
].UsageIndex
, decl2
[i
].UsageIndex
);
1177 ok(test_decl
[i
].Offset
== decl2
[i
].Offset
, "Returned offset %d, expected %d\n", test_decl
[i
].Offset
, decl2
[i
].Offset
);
1179 ok(decl2
[size
-1].Stream
== 0xFF, "Returned too long vertex declaration\n"); /* end element */
1183 options
= d3dxmesh
->lpVtbl
->GetOptions(d3dxmesh
);
1184 ok(options
== D3DXMESH_MANAGED
, "Got result %x, expected %x (D3DXMESH_MANAGED)\n", options
, D3DXMESH_MANAGED
);
1187 if (!new_mesh(&mesh
, 3, 1))
1189 skip("Couldn't create mesh\n");
1193 memset(mesh
.vertices
, 0, mesh
.number_of_vertices
* sizeof(*mesh
.vertices
));
1194 memset(mesh
.faces
, 0, mesh
.number_of_faces
* sizeof(*mesh
.faces
));
1196 mesh
.vertex_size
= 60;
1198 compare_mesh("createmesh2", d3dxmesh
, &mesh
);
1203 d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
1206 IDirect3DDevice9_Release(device
);
1207 IDirect3D9_Release(d3d
);
1211 static void D3DXCreateMeshFVFTest(void)
1216 IDirect3DDevice9
*device
, *test_device
;
1217 D3DPRESENT_PARAMETERS d3dpp
;
1218 ID3DXMesh
*d3dxmesh
;
1220 D3DVERTEXELEMENT9 test_decl
[MAX_FVF_DECL_SIZE
];
1224 static const D3DVERTEXELEMENT9 decl
[3] = {
1225 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1226 {0, 12, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
1229 hr
= D3DXCreateMeshFVF(0, 0, 0, 0, NULL
, NULL
);
1230 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1232 hr
= D3DXCreateMeshFVF(1, 3, D3DXMESH_MANAGED
, D3DFVF_XYZ
| D3DFVF_NORMAL
, NULL
, &d3dxmesh
);
1233 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1235 wnd
= CreateWindow("static", "d3dx9_test", 0, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
);
1238 skip("Couldn't create application window\n");
1241 d3d
= Direct3DCreate9(D3D_SDK_VERSION
);
1244 skip("Couldn't create IDirect3D9 object\n");
1249 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
1250 d3dpp
.Windowed
= TRUE
;
1251 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1252 hr
= IDirect3D9_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, wnd
, D3DCREATE_MIXED_VERTEXPROCESSING
, &d3dpp
, &device
);
1255 skip("Failed to create IDirect3DDevice9 object %#x\n", hr
);
1256 IDirect3D9_Release(d3d
);
1261 hr
= D3DXCreateMeshFVF(0, 3, D3DXMESH_MANAGED
, D3DFVF_XYZ
| D3DFVF_NORMAL
, device
, &d3dxmesh
);
1262 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1264 hr
= D3DXCreateMeshFVF(1, 0, D3DXMESH_MANAGED
, D3DFVF_XYZ
| D3DFVF_NORMAL
, device
, &d3dxmesh
);
1265 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1267 hr
= D3DXCreateMeshFVF(1, 3, 0, D3DFVF_XYZ
| D3DFVF_NORMAL
, device
, &d3dxmesh
);
1268 ok(hr
== D3D_OK
, "Got result %x, expected %x (D3D_OK)\n", hr
, D3D_OK
);
1272 d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
1275 hr
= D3DXCreateMeshFVF(1, 3, D3DXMESH_MANAGED
, 0xdeadbeef, device
, &d3dxmesh
);
1276 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1278 hr
= D3DXCreateMeshFVF(1, 3, D3DXMESH_MANAGED
, D3DFVF_XYZ
| D3DFVF_NORMAL
, device
, NULL
);
1279 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1281 hr
= D3DXCreateMeshFVF(1, 3, D3DXMESH_MANAGED
, D3DFVF_XYZ
| D3DFVF_NORMAL
, device
, &d3dxmesh
);
1282 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n", hr
);
1287 hr
= d3dxmesh
->lpVtbl
->GetDevice(d3dxmesh
, NULL
);
1288 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1290 hr
= d3dxmesh
->lpVtbl
->GetDevice(d3dxmesh
, &test_device
);
1291 ok(hr
== D3D_OK
, "Got result %x, expected %x (D3D_OK)\n", hr
, D3D_OK
);
1292 ok(test_device
== device
, "Got result %p, expected %p\n", test_device
, device
);
1296 IDirect3DDevice9_Release(device
);
1300 hr
= d3dxmesh
->lpVtbl
->GetDeclaration(d3dxmesh
, NULL
);
1301 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1303 hr
= d3dxmesh
->lpVtbl
->GetDeclaration(d3dxmesh
, test_decl
);
1304 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n", hr
);
1308 size
= sizeof(decl
) / sizeof(decl
[0]);
1309 for (i
= 0; i
< size
- 1; i
++)
1311 ok(test_decl
[i
].Stream
== decl
[i
].Stream
, "Returned stream %d, expected %d\n", test_decl
[i
].Stream
, decl
[i
].Stream
);
1312 ok(test_decl
[i
].Type
== decl
[i
].Type
, "Returned type %d, expected %d\n", test_decl
[i
].Type
, decl
[i
].Type
);
1313 ok(test_decl
[i
].Method
== decl
[i
].Method
, "Returned method %d, expected %d\n", test_decl
[i
].Method
, decl
[i
].Method
);
1314 ok(test_decl
[i
].Usage
== decl
[i
].Usage
, "Returned usage %d, expected %d\n", test_decl
[i
].Usage
, decl
[i
].Usage
);
1315 ok(test_decl
[i
].UsageIndex
== decl
[i
].UsageIndex
, "Returned usage index %d, expected %d\n",
1316 test_decl
[i
].UsageIndex
, decl
[i
].UsageIndex
);
1317 ok(test_decl
[i
].Offset
== decl
[i
].Offset
, "Returned offset %d, expected %d\n", test_decl
[i
].Offset
, decl
[i
].Offset
);
1319 ok(decl
[size
-1].Stream
== 0xFF, "Returned too long vertex declaration\n"); /* end element */
1323 options
= d3dxmesh
->lpVtbl
->GetOptions(d3dxmesh
);
1324 ok(options
== D3DXMESH_MANAGED
, "Got result %x, expected %x (D3DXMESH_MANAGED)\n", options
, D3DXMESH_MANAGED
);
1327 if (!new_mesh(&mesh
, 3, 1))
1329 skip("Couldn't create mesh\n");
1333 memset(mesh
.vertices
, 0, mesh
.number_of_vertices
* sizeof(*mesh
.vertices
));
1334 memset(mesh
.faces
, 0, mesh
.number_of_faces
* sizeof(*mesh
.faces
));
1335 mesh
.fvf
= D3DFVF_XYZ
| D3DFVF_NORMAL
;
1337 compare_mesh("createmeshfvf", d3dxmesh
, &mesh
);
1342 d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
1345 IDirect3DDevice9_Release(device
);
1346 IDirect3D9_Release(d3d
);
1356 static void free_sincos_table(struct sincos_table
*sincos_table
)
1358 HeapFree(GetProcessHeap(), 0, sincos_table
->cos
);
1359 HeapFree(GetProcessHeap(), 0, sincos_table
->sin
);
1362 /* pre compute sine and cosine tables; caller must free */
1363 static BOOL
compute_sincos_table(struct sincos_table
*sincos_table
, float angle_start
, float angle_step
, int n
)
1368 sincos_table
->sin
= HeapAlloc(GetProcessHeap(), 0, n
* sizeof(*sincos_table
->sin
));
1369 if (!sincos_table
->sin
)
1373 sincos_table
->cos
= HeapAlloc(GetProcessHeap(), 0, n
* sizeof(*sincos_table
->cos
));
1374 if (!sincos_table
->cos
)
1376 HeapFree(GetProcessHeap(), 0, sincos_table
->sin
);
1380 angle
= angle_start
;
1381 for (i
= 0; i
< n
; i
++)
1383 sincos_table
->sin
[i
] = sin(angle
);
1384 sincos_table
->cos
[i
] = cos(angle
);
1385 angle
+= angle_step
;
1391 static WORD
vertex_index(UINT slices
, int slice
, int stack
)
1393 return stack
*slices
+slice
+1;
1396 /* slices = subdivisions along xy plane, stacks = subdivisions along z axis */
1397 static BOOL
compute_sphere(struct mesh
*mesh
, FLOAT radius
, UINT slices
, UINT stacks
)
1399 float theta_step
, theta_start
;
1400 struct sincos_table theta
;
1401 float phi_step
, phi_start
;
1402 struct sincos_table phi
;
1403 DWORD number_of_vertices
, number_of_faces
;
1407 /* theta = angle on xy plane wrt x axis */
1408 theta_step
= M_PI
/ stacks
;
1409 theta_start
= theta_step
;
1411 /* phi = angle on xz plane wrt z axis */
1412 phi_step
= -2 * M_PI
/ slices
;
1413 phi_start
= M_PI
/ 2;
1415 if (!compute_sincos_table(&theta
, theta_start
, theta_step
, stacks
))
1419 if (!compute_sincos_table(&phi
, phi_start
, phi_step
, slices
))
1421 free_sincos_table(&theta
);
1425 number_of_vertices
= 2 + slices
* (stacks
-1);
1426 number_of_faces
= 2 * slices
+ (stacks
- 2) * (2 * slices
);
1428 if (!new_mesh(mesh
, number_of_vertices
, number_of_faces
))
1430 free_sincos_table(&phi
);
1431 free_sincos_table(&theta
);
1439 mesh
->vertices
[vertex
].normal
.x
= 0.0f
;
1440 mesh
->vertices
[vertex
].normal
.y
= 0.0f
;
1441 mesh
->vertices
[vertex
].normal
.z
= 1.0f
;
1442 mesh
->vertices
[vertex
].position
.x
= 0.0f
;
1443 mesh
->vertices
[vertex
].position
.y
= 0.0f
;
1444 mesh
->vertices
[vertex
].position
.z
= radius
;
1447 for (stack
= 0; stack
< stacks
- 1; stack
++)
1449 for (slice
= 0; slice
< slices
; slice
++)
1451 mesh
->vertices
[vertex
].normal
.x
= theta
.sin
[stack
] * phi
.cos
[slice
];
1452 mesh
->vertices
[vertex
].normal
.y
= theta
.sin
[stack
] * phi
.sin
[slice
];
1453 mesh
->vertices
[vertex
].normal
.z
= theta
.cos
[stack
];
1454 mesh
->vertices
[vertex
].position
.x
= radius
* theta
.sin
[stack
] * phi
.cos
[slice
];
1455 mesh
->vertices
[vertex
].position
.y
= radius
* theta
.sin
[stack
] * phi
.sin
[slice
];
1456 mesh
->vertices
[vertex
].position
.z
= radius
* theta
.cos
[stack
];
1463 /* top stack is triangle fan */
1464 mesh
->faces
[face
][0] = 0;
1465 mesh
->faces
[face
][1] = slice
+ 1;
1466 mesh
->faces
[face
][2] = slice
;
1471 /* stacks in between top and bottom are quad strips */
1472 mesh
->faces
[face
][0] = vertex_index(slices
, slice
-1, stack
-1);
1473 mesh
->faces
[face
][1] = vertex_index(slices
, slice
, stack
-1);
1474 mesh
->faces
[face
][2] = vertex_index(slices
, slice
-1, stack
);
1477 mesh
->faces
[face
][0] = vertex_index(slices
, slice
, stack
-1);
1478 mesh
->faces
[face
][1] = vertex_index(slices
, slice
, stack
);
1479 mesh
->faces
[face
][2] = vertex_index(slices
, slice
-1, stack
);
1487 mesh
->faces
[face
][0] = 0;
1488 mesh
->faces
[face
][1] = 1;
1489 mesh
->faces
[face
][2] = slice
;
1494 mesh
->faces
[face
][0] = vertex_index(slices
, slice
-1, stack
-1);
1495 mesh
->faces
[face
][1] = vertex_index(slices
, 0, stack
-1);
1496 mesh
->faces
[face
][2] = vertex_index(slices
, slice
-1, stack
);
1499 mesh
->faces
[face
][0] = vertex_index(slices
, 0, stack
-1);
1500 mesh
->faces
[face
][1] = vertex_index(slices
, 0, stack
);
1501 mesh
->faces
[face
][2] = vertex_index(slices
, slice
-1, stack
);
1506 mesh
->vertices
[vertex
].position
.x
= 0.0f
;
1507 mesh
->vertices
[vertex
].position
.y
= 0.0f
;
1508 mesh
->vertices
[vertex
].position
.z
= -radius
;
1509 mesh
->vertices
[vertex
].normal
.x
= 0.0f
;
1510 mesh
->vertices
[vertex
].normal
.y
= 0.0f
;
1511 mesh
->vertices
[vertex
].normal
.z
= -1.0f
;
1513 /* bottom stack is triangle fan */
1514 for (slice
= 1; slice
< slices
; slice
++)
1516 mesh
->faces
[face
][0] = vertex_index(slices
, slice
-1, stack
-1);
1517 mesh
->faces
[face
][1] = vertex_index(slices
, slice
, stack
-1);
1518 mesh
->faces
[face
][2] = vertex
;
1522 mesh
->faces
[face
][0] = vertex_index(slices
, slice
-1, stack
-1);
1523 mesh
->faces
[face
][1] = vertex_index(slices
, 0, stack
-1);
1524 mesh
->faces
[face
][2] = vertex
;
1526 free_sincos_table(&phi
);
1527 free_sincos_table(&theta
);
1532 static void test_sphere(IDirect3DDevice9
*device
, FLOAT radius
, UINT slices
, UINT stacks
)
1539 hr
= D3DXCreateSphere(device
, radius
, slices
, stacks
, &sphere
, NULL
);
1540 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n", hr
);
1543 skip("Couldn't create sphere\n");
1547 if (!compute_sphere(&mesh
, radius
, slices
, stacks
))
1549 skip("Couldn't create mesh\n");
1550 sphere
->lpVtbl
->Release(sphere
);
1554 mesh
.fvf
= D3DFVF_XYZ
| D3DFVF_NORMAL
;
1556 sprintf(name
, "sphere (%g, %u, %u)", radius
, slices
, stacks
);
1557 compare_mesh(name
, sphere
, &mesh
);
1561 sphere
->lpVtbl
->Release(sphere
);
1564 static void D3DXCreateSphereTest(void)
1569 IDirect3DDevice9
* device
;
1570 D3DPRESENT_PARAMETERS d3dpp
;
1571 ID3DXMesh
* sphere
= NULL
;
1573 hr
= D3DXCreateSphere(NULL
, 0.0f
, 0, 0, NULL
, NULL
);
1574 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
1576 hr
= D3DXCreateSphere(NULL
, 0.1f
, 0, 0, NULL
, NULL
);
1577 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
1579 hr
= D3DXCreateSphere(NULL
, 0.0f
, 1, 0, NULL
, NULL
);
1580 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
1582 hr
= D3DXCreateSphere(NULL
, 0.0f
, 0, 1, NULL
, NULL
);
1583 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
1585 wnd
= CreateWindow("static", "d3dx9_test", 0, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
);
1586 d3d
= Direct3DCreate9(D3D_SDK_VERSION
);
1589 skip("Couldn't create application window\n");
1594 skip("Couldn't create IDirect3D9 object\n");
1599 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
1600 d3dpp
.Windowed
= TRUE
;
1601 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1602 hr
= IDirect3D9_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, wnd
, D3DCREATE_MIXED_VERTEXPROCESSING
, &d3dpp
, &device
);
1605 skip("Failed to create IDirect3DDevice9 object %#x\n", hr
);
1606 IDirect3D9_Release(d3d
);
1611 hr
= D3DXCreateSphere(device
, 1.0f
, 1, 1, &sphere
, NULL
);
1612 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
1614 hr
= D3DXCreateSphere(device
, 1.0f
, 2, 1, &sphere
, NULL
);
1615 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1617 hr
= D3DXCreateSphere(device
, 1.0f
, 1, 2, &sphere
, NULL
);
1618 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1620 hr
= D3DXCreateSphere(device
, -0.1f
, 1, 2, &sphere
, NULL
);
1621 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1623 test_sphere(device
, 0.0f
, 2, 2);
1624 test_sphere(device
, 1.0f
, 2, 2);
1625 test_sphere(device
, 1.0f
, 3, 2);
1626 test_sphere(device
, 1.0f
, 4, 4);
1627 test_sphere(device
, 1.0f
, 3, 4);
1628 test_sphere(device
, 5.0f
, 6, 7);
1629 test_sphere(device
, 10.0f
, 11, 12);
1631 IDirect3DDevice9_Release(device
);
1632 IDirect3D9_Release(d3d
);
1636 static BOOL
compute_cylinder(struct mesh
*mesh
, FLOAT radius1
, FLOAT radius2
, FLOAT length
, UINT slices
, UINT stacks
)
1638 float theta_step
, theta_start
;
1639 struct sincos_table theta
;
1640 FLOAT delta_radius
, radius
, radius_step
;
1641 FLOAT z
, z_step
, z_normal
;
1642 DWORD number_of_vertices
, number_of_faces
;
1646 /* theta = angle on xy plane wrt x axis */
1647 theta_step
= -2 * M_PI
/ slices
;
1648 theta_start
= M_PI
/ 2;
1650 if (!compute_sincos_table(&theta
, theta_start
, theta_step
, slices
))
1655 number_of_vertices
= 2 + (slices
* (3 + stacks
));
1656 number_of_faces
= 2 * slices
+ stacks
* (2 * slices
);
1658 if (!new_mesh(mesh
, number_of_vertices
, number_of_faces
))
1660 free_sincos_table(&theta
);
1668 delta_radius
= radius1
- radius2
;
1670 radius_step
= delta_radius
/ stacks
;
1673 z_step
= length
/ stacks
;
1674 z_normal
= delta_radius
/ length
;
1675 if (isnan(z_normal
))
1680 mesh
->vertices
[vertex
].normal
.x
= 0.0f
;
1681 mesh
->vertices
[vertex
].normal
.y
= 0.0f
;
1682 mesh
->vertices
[vertex
].normal
.z
= -1.0f
;
1683 mesh
->vertices
[vertex
].position
.x
= 0.0f
;
1684 mesh
->vertices
[vertex
].position
.y
= 0.0f
;
1685 mesh
->vertices
[vertex
++].position
.z
= z
;
1687 for (slice
= 0; slice
< slices
; slice
++, vertex
++)
1689 mesh
->vertices
[vertex
].normal
.x
= 0.0f
;
1690 mesh
->vertices
[vertex
].normal
.y
= 0.0f
;
1691 mesh
->vertices
[vertex
].normal
.z
= -1.0f
;
1692 mesh
->vertices
[vertex
].position
.x
= radius
* theta
.cos
[slice
];
1693 mesh
->vertices
[vertex
].position
.y
= radius
* theta
.sin
[slice
];
1694 mesh
->vertices
[vertex
].position
.z
= z
;
1698 mesh
->faces
[face
][0] = 0;
1699 mesh
->faces
[face
][1] = slice
;
1700 mesh
->faces
[face
++][2] = slice
+ 1;
1704 mesh
->faces
[face
][0] = 0;
1705 mesh
->faces
[face
][1] = slice
;
1706 mesh
->faces
[face
++][2] = 1;
1708 for (stack
= 1; stack
<= stacks
+1; stack
++)
1710 for (slice
= 0; slice
< slices
; slice
++, vertex
++)
1712 mesh
->vertices
[vertex
].normal
.x
= theta
.cos
[slice
];
1713 mesh
->vertices
[vertex
].normal
.y
= theta
.sin
[slice
];
1714 mesh
->vertices
[vertex
].normal
.z
= z_normal
;
1715 D3DXVec3Normalize(&mesh
->vertices
[vertex
].normal
, &mesh
->vertices
[vertex
].normal
);
1716 mesh
->vertices
[vertex
].position
.x
= radius
* theta
.cos
[slice
];
1717 mesh
->vertices
[vertex
].position
.y
= radius
* theta
.sin
[slice
];
1718 mesh
->vertices
[vertex
].position
.z
= z
;
1720 if (stack
> 1 && slice
> 0)
1722 mesh
->faces
[face
][0] = vertex_index(slices
, slice
-1, stack
-1);
1723 mesh
->faces
[face
][1] = vertex_index(slices
, slice
-1, stack
);
1724 mesh
->faces
[face
++][2] = vertex_index(slices
, slice
, stack
-1);
1726 mesh
->faces
[face
][0] = vertex_index(slices
, slice
, stack
-1);
1727 mesh
->faces
[face
][1] = vertex_index(slices
, slice
-1, stack
);
1728 mesh
->faces
[face
++][2] = vertex_index(slices
, slice
, stack
);
1734 mesh
->faces
[face
][0] = vertex_index(slices
, slice
-1, stack
-1);
1735 mesh
->faces
[face
][1] = vertex_index(slices
, slice
-1, stack
);
1736 mesh
->faces
[face
++][2] = vertex_index(slices
, 0, stack
-1);
1738 mesh
->faces
[face
][0] = vertex_index(slices
, 0, stack
-1);
1739 mesh
->faces
[face
][1] = vertex_index(slices
, slice
-1, stack
);
1740 mesh
->faces
[face
++][2] = vertex_index(slices
, 0, stack
);
1743 if (stack
< stacks
+ 1)
1746 radius
-= radius_step
;
1750 for (slice
= 0; slice
< slices
; slice
++, vertex
++)
1752 mesh
->vertices
[vertex
].normal
.x
= 0.0f
;
1753 mesh
->vertices
[vertex
].normal
.y
= 0.0f
;
1754 mesh
->vertices
[vertex
].normal
.z
= 1.0f
;
1755 mesh
->vertices
[vertex
].position
.x
= radius
* theta
.cos
[slice
];
1756 mesh
->vertices
[vertex
].position
.y
= radius
* theta
.sin
[slice
];
1757 mesh
->vertices
[vertex
].position
.z
= z
;
1761 mesh
->faces
[face
][0] = vertex_index(slices
, slice
-1, stack
);
1762 mesh
->faces
[face
][1] = number_of_vertices
- 1;
1763 mesh
->faces
[face
++][2] = vertex_index(slices
, slice
, stack
);
1767 mesh
->vertices
[vertex
].position
.x
= 0.0f
;
1768 mesh
->vertices
[vertex
].position
.y
= 0.0f
;
1769 mesh
->vertices
[vertex
].position
.z
= z
;
1770 mesh
->vertices
[vertex
].normal
.x
= 0.0f
;
1771 mesh
->vertices
[vertex
].normal
.y
= 0.0f
;
1772 mesh
->vertices
[vertex
].normal
.z
= 1.0f
;
1774 mesh
->faces
[face
][0] = vertex_index(slices
, slice
-1, stack
);
1775 mesh
->faces
[face
][1] = number_of_vertices
- 1;
1776 mesh
->faces
[face
][2] = vertex_index(slices
, 0, stack
);
1778 free_sincos_table(&theta
);
1783 static void test_cylinder(IDirect3DDevice9
*device
, FLOAT radius1
, FLOAT radius2
, FLOAT length
, UINT slices
, UINT stacks
)
1786 ID3DXMesh
*cylinder
;
1790 hr
= D3DXCreateCylinder(device
, radius1
, radius2
, length
, slices
, stacks
, &cylinder
, NULL
);
1791 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n", hr
);
1794 skip("Couldn't create cylinder\n");
1798 if (!compute_cylinder(&mesh
, radius1
, radius2
, length
, slices
, stacks
))
1800 skip("Couldn't create mesh\n");
1801 cylinder
->lpVtbl
->Release(cylinder
);
1805 mesh
.fvf
= D3DFVF_XYZ
| D3DFVF_NORMAL
;
1807 sprintf(name
, "cylinder (%g, %g, %g, %u, %u)", radius1
, radius2
, length
, slices
, stacks
);
1808 compare_mesh(name
, cylinder
, &mesh
);
1812 cylinder
->lpVtbl
->Release(cylinder
);
1815 static void D3DXCreateCylinderTest(void)
1820 IDirect3DDevice9
* device
;
1821 D3DPRESENT_PARAMETERS d3dpp
;
1822 ID3DXMesh
* cylinder
= NULL
;
1824 hr
= D3DXCreateCylinder(NULL
, 0.0f
, 0.0f
, 0.0f
, 0, 0, NULL
, NULL
);
1825 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
1827 hr
= D3DXCreateCylinder(NULL
, 1.0f
, 1.0f
, 1.0f
, 2, 1, &cylinder
, NULL
);
1828 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
1830 wnd
= CreateWindow("static", "d3dx9_test", 0, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
);
1831 d3d
= Direct3DCreate9(D3D_SDK_VERSION
);
1834 skip("Couldn't create application window\n");
1839 skip("Couldn't create IDirect3D9 object\n");
1844 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
1845 d3dpp
.Windowed
= TRUE
;
1846 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1847 hr
= IDirect3D9_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, wnd
, D3DCREATE_MIXED_VERTEXPROCESSING
, &d3dpp
, &device
);
1850 skip("Failed to create IDirect3DDevice9 object %#x\n", hr
);
1851 IDirect3D9_Release(d3d
);
1856 hr
= D3DXCreateCylinder(device
, -0.1f
, 1.0f
, 1.0f
, 2, 1, &cylinder
, NULL
);
1857 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
1859 hr
= D3DXCreateCylinder(device
, 0.0f
, 1.0f
, 1.0f
, 2, 1, &cylinder
, NULL
);
1860 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n",hr
);
1862 if (SUCCEEDED(hr
) && cylinder
)
1864 cylinder
->lpVtbl
->Release(cylinder
);
1867 hr
= D3DXCreateCylinder(device
, 1.0f
, -0.1f
, 1.0f
, 2, 1, &cylinder
, NULL
);
1868 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
1870 hr
= D3DXCreateCylinder(device
, 1.0f
, 0.0f
, 1.0f
, 2, 1, &cylinder
, NULL
);
1871 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n",hr
);
1873 if (SUCCEEDED(hr
) && cylinder
)
1875 cylinder
->lpVtbl
->Release(cylinder
);
1878 hr
= D3DXCreateCylinder(device
, 1.0f
, 1.0f
, -0.1f
, 2, 1, &cylinder
, NULL
);
1879 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
1881 /* Test with length == 0.0f succeeds */
1882 hr
= D3DXCreateCylinder(device
, 1.0f
, 1.0f
, 0.0f
, 2, 1, &cylinder
, NULL
);
1883 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n",hr
);
1885 if (SUCCEEDED(hr
) && cylinder
)
1887 cylinder
->lpVtbl
->Release(cylinder
);
1890 hr
= D3DXCreateCylinder(device
, 1.0f
, 1.0f
, 1.0f
, 1, 1, &cylinder
, NULL
);
1891 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
1893 hr
= D3DXCreateCylinder(device
, 1.0f
, 1.0f
, 1.0f
, 2, 0, &cylinder
, NULL
);
1894 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
1896 hr
= D3DXCreateCylinder(device
, 1.0f
, 1.0f
, 1.0f
, 2, 1, NULL
, NULL
);
1897 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
1899 test_cylinder(device
, 0.0f
, 0.0f
, 0.0f
, 2, 1);
1900 test_cylinder(device
, 1.0f
, 1.0f
, 1.0f
, 2, 1);
1901 test_cylinder(device
, 1.0f
, 1.0f
, 2.0f
, 3, 4);
1902 test_cylinder(device
, 3.0f
, 2.0f
, 4.0f
, 3, 4);
1903 test_cylinder(device
, 2.0f
, 3.0f
, 4.0f
, 3, 4);
1904 test_cylinder(device
, 3.0f
, 4.0f
, 5.0f
, 11, 20);
1906 IDirect3DDevice9_Release(device
);
1907 IDirect3D9_Release(d3d
);
1911 static void test_get_decl_length(void)
1913 static const D3DVERTEXELEMENT9 declaration1
[] =
1915 {0, 0, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1916 {1, 0, D3DDECLTYPE_FLOAT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1917 {2, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1918 {3, 0, D3DDECLTYPE_FLOAT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1919 {4, 0, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1920 {5, 0, D3DDECLTYPE_UBYTE4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1921 {6, 0, D3DDECLTYPE_SHORT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1922 {7, 0, D3DDECLTYPE_SHORT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1923 {8, 0, D3DDECLTYPE_UBYTE4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1924 {9, 0, D3DDECLTYPE_SHORT2N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1925 {10, 0, D3DDECLTYPE_SHORT4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1926 {11, 0, D3DDECLTYPE_UDEC3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1927 {12, 0, D3DDECLTYPE_DEC3N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1928 {13, 0, D3DDECLTYPE_FLOAT16_2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1929 {14, 0, D3DDECLTYPE_FLOAT16_4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1932 static const D3DVERTEXELEMENT9 declaration2
[] =
1934 {0, 8, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1935 {1, 8, D3DDECLTYPE_FLOAT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1936 {2, 8, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1937 {3, 8, D3DDECLTYPE_FLOAT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1938 {4, 8, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1939 {5, 8, D3DDECLTYPE_UBYTE4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1940 {6, 8, D3DDECLTYPE_SHORT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1941 {7, 8, D3DDECLTYPE_SHORT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1942 {0, 8, D3DDECLTYPE_UBYTE4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1943 {1, 8, D3DDECLTYPE_SHORT2N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1944 {2, 8, D3DDECLTYPE_SHORT4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1945 {3, 8, D3DDECLTYPE_UDEC3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1946 {4, 8, D3DDECLTYPE_DEC3N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1947 {5, 8, D3DDECLTYPE_FLOAT16_2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1948 {6, 8, D3DDECLTYPE_FLOAT16_4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1949 {7, 8, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1954 size
= D3DXGetDeclLength(declaration1
);
1955 ok(size
== 15, "Got size %u, expected 15.\n", size
);
1957 size
= D3DXGetDeclLength(declaration2
);
1958 ok(size
== 16, "Got size %u, expected 16.\n", size
);
1961 static void test_get_decl_vertex_size(void)
1963 static const D3DVERTEXELEMENT9 declaration1
[] =
1965 {0, 0, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1966 {1, 0, D3DDECLTYPE_FLOAT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1967 {2, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1968 {3, 0, D3DDECLTYPE_FLOAT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1969 {4, 0, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1970 {5, 0, D3DDECLTYPE_UBYTE4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1971 {6, 0, D3DDECLTYPE_SHORT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1972 {7, 0, D3DDECLTYPE_SHORT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1973 {8, 0, D3DDECLTYPE_UBYTE4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1974 {9, 0, D3DDECLTYPE_SHORT2N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1975 {10, 0, D3DDECLTYPE_SHORT4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1976 {11, 0, D3DDECLTYPE_UDEC3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1977 {12, 0, D3DDECLTYPE_DEC3N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1978 {13, 0, D3DDECLTYPE_FLOAT16_2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1979 {14, 0, D3DDECLTYPE_FLOAT16_4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1982 static const D3DVERTEXELEMENT9 declaration2
[] =
1984 {0, 8, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1985 {1, 8, D3DDECLTYPE_FLOAT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1986 {2, 8, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1987 {3, 8, D3DDECLTYPE_FLOAT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1988 {4, 8, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1989 {5, 8, D3DDECLTYPE_UBYTE4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1990 {6, 8, D3DDECLTYPE_SHORT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1991 {7, 8, D3DDECLTYPE_SHORT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1992 {0, 8, D3DDECLTYPE_UBYTE4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1993 {1, 8, D3DDECLTYPE_SHORT2N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1994 {2, 8, D3DDECLTYPE_SHORT4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1995 {3, 8, D3DDECLTYPE_UDEC3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1996 {4, 8, D3DDECLTYPE_DEC3N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1997 {5, 8, D3DDECLTYPE_FLOAT16_2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1998 {6, 8, D3DDECLTYPE_FLOAT16_4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1999 {7, 8, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
2002 static const UINT sizes1
[] =
2009 static const UINT sizes2
[] =
2017 size
= D3DXGetDeclVertexSize(NULL
, 0);
2018 ok(size
== 0, "Got size %#x, expected 0.\n", size
);
2020 for (i
= 0; i
< 16; ++i
)
2022 size
= D3DXGetDeclVertexSize(declaration1
, i
);
2023 ok(size
== sizes1
[i
], "Got size %u for stream %u, expected %u.\n", size
, i
, sizes1
[i
]);
2026 for (i
= 0; i
< 8; ++i
)
2028 size
= D3DXGetDeclVertexSize(declaration2
, i
);
2029 ok(size
== sizes2
[i
], "Got size %u for stream %u, expected %u.\n", size
, i
, sizes2
[i
]);
2035 D3DXBoundProbeTest();
2036 D3DXComputeBoundingBoxTest();
2037 D3DXComputeBoundingSphereTest();
2038 D3DXGetFVFVertexSizeTest();
2039 D3DXIntersectTriTest();
2040 D3DXCreateMeshTest();
2041 D3DXCreateMeshFVFTest();
2042 D3DXCreateSphereTest();
2043 D3DXCreateCylinderTest();
2044 test_get_decl_length();
2045 test_get_decl_vertex_size();
2046 test_fvf_decl_conversion();