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
;
63 static void free_mesh(struct mesh
*mesh
)
65 HeapFree(GetProcessHeap(), 0, mesh
->faces
);
66 HeapFree(GetProcessHeap(), 0, mesh
->vertices
);
69 static BOOL
new_mesh(struct mesh
*mesh
, DWORD number_of_vertices
, DWORD number_of_faces
)
71 mesh
->vertices
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, number_of_vertices
* sizeof(*mesh
->vertices
));
76 mesh
->number_of_vertices
= number_of_vertices
;
78 mesh
->faces
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, number_of_faces
* sizeof(*mesh
->faces
));
81 HeapFree(GetProcessHeap(), 0, mesh
->vertices
);
84 mesh
->number_of_faces
= number_of_faces
;
89 static void compare_mesh(const char *name
, ID3DXMesh
*d3dxmesh
, struct mesh
*mesh
)
92 DWORD number_of_vertices
, number_of_faces
;
93 IDirect3DVertexBuffer9
*vertex_buffer
;
94 IDirect3DIndexBuffer9
*index_buffer
;
95 D3DVERTEXBUFFER_DESC vertex_buffer_description
;
96 D3DINDEXBUFFER_DESC index_buffer_description
;
97 struct vertex
*vertices
;
101 number_of_vertices
= d3dxmesh
->lpVtbl
->GetNumVertices(d3dxmesh
);
102 ok(number_of_vertices
== mesh
->number_of_vertices
, "Test %s, result %u, expected %d\n",
103 name
, number_of_vertices
, mesh
->number_of_vertices
);
105 number_of_faces
= d3dxmesh
->lpVtbl
->GetNumFaces(d3dxmesh
);
106 ok(number_of_faces
== mesh
->number_of_faces
, "Test %s, result %u, expected %d\n",
107 name
, number_of_faces
, mesh
->number_of_faces
);
110 hr
= d3dxmesh
->lpVtbl
->GetVertexBuffer(d3dxmesh
, &vertex_buffer
);
111 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
115 skip("Couldn't get vertex buffer\n");
119 hr
= IDirect3DVertexBuffer9_GetDesc(vertex_buffer
, &vertex_buffer_description
);
120 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
124 skip("Couldn't get vertex buffer description\n");
128 ok(vertex_buffer_description
.Format
== D3DFMT_VERTEXDATA
, "Test %s, result %x, expected %x (D3DFMT_VERTEXDATA)\n",
129 name
, vertex_buffer_description
.Format
, D3DFMT_VERTEXDATA
);
130 ok(vertex_buffer_description
.Type
== D3DRTYPE_VERTEXBUFFER
, "Test %s, result %x, expected %x (D3DRTYPE_VERTEXBUFFER)\n",
131 name
, vertex_buffer_description
.Type
, D3DRTYPE_VERTEXBUFFER
);
132 ok(vertex_buffer_description
.Usage
== 0, "Test %s, result %x, expected %x\n", name
, vertex_buffer_description
.Usage
, 0);
133 ok(vertex_buffer_description
.Pool
== D3DPOOL_MANAGED
, "Test %s, result %x, expected %x (D3DPOOL_DEFAULT)\n",
134 name
, vertex_buffer_description
.Pool
, D3DPOOL_DEFAULT
);
135 expected
= number_of_vertices
* sizeof(D3DXVECTOR3
) * 2;
136 ok(vertex_buffer_description
.Size
== expected
, "Test %s, result %x, expected %x\n",
137 name
, vertex_buffer_description
.Size
, expected
);
138 ok(vertex_buffer_description
.FVF
== (D3DFVF_XYZ
| D3DFVF_NORMAL
), "Test %s, result %x, expected %x (D3DFVF_XYZ | D3DFVF_NORMAL)\n",
139 name
, vertex_buffer_description
.FVF
, D3DFVF_XYZ
| D3DFVF_NORMAL
);
142 /* specify offset and size to avoid potential overruns */
143 hr
= IDirect3DVertexBuffer9_Lock(vertex_buffer
, 0, number_of_vertices
* sizeof(D3DXVECTOR3
) * 2,
144 (LPVOID
*)&vertices
, D3DLOCK_DISCARD
);
145 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
149 skip("Couldn't lock vertex buffer\n");
153 for (i
= 0; i
< number_of_vertices
; i
++)
155 ok(compare_vec3(vertices
[i
].position
, mesh
->vertices
[i
].position
),
156 "Test %s, vertex position %d, result (%g, %g, %g), expected (%g, %g, %g)\n", name
, i
,
157 vertices
[i
].position
.x
, vertices
[i
].position
.y
, vertices
[i
].position
.z
,
158 mesh
->vertices
[i
].position
.x
, mesh
->vertices
[i
].position
.y
, mesh
->vertices
[i
].position
.z
);
159 ok(compare_vec3(vertices
[i
].normal
, mesh
->vertices
[i
].normal
),
160 "Test %s, vertex normal %d, result (%g, %g, %g), expected (%g, %g, %g)\n", name
, i
,
161 vertices
[i
].normal
.x
, vertices
[i
].normal
.y
, vertices
[i
].normal
.z
,
162 mesh
->vertices
[i
].normal
.x
, mesh
->vertices
[i
].normal
.y
, mesh
->vertices
[i
].normal
.z
);
165 IDirect3DVertexBuffer9_Unlock(vertex_buffer
);
168 IDirect3DVertexBuffer9_Release(vertex_buffer
);
172 hr
= d3dxmesh
->lpVtbl
->GetIndexBuffer(d3dxmesh
, &index_buffer
);
173 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
177 skip("Couldn't get index buffer\n");
181 hr
= IDirect3DIndexBuffer9_GetDesc(index_buffer
, &index_buffer_description
);
182 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
186 skip("Couldn't get index buffer description\n");
190 ok(index_buffer_description
.Format
== D3DFMT_INDEX16
, "Test %s, result %x, expected %x (D3DFMT_INDEX16)\n",
191 name
, index_buffer_description
.Format
, D3DFMT_INDEX16
);
192 ok(index_buffer_description
.Type
== D3DRTYPE_INDEXBUFFER
, "Test %s, result %x, expected %x (D3DRTYPE_INDEXBUFFER)\n",
193 name
, index_buffer_description
.Type
, D3DRTYPE_INDEXBUFFER
);
194 ok(index_buffer_description
.Usage
== 0, "Test %s, result %x, expected %x\n", name
, index_buffer_description
.Usage
, 0);
195 ok(index_buffer_description
.Pool
== D3DPOOL_MANAGED
, "Test %s, result %x, expected %x (D3DPOOL_DEFAULT)\n",
196 name
, index_buffer_description
.Pool
, D3DPOOL_DEFAULT
);
197 expected
= number_of_faces
* sizeof(WORD
) * 3;
198 ok(index_buffer_description
.Size
== expected
, "Test %s, result %x, expected %x\n",
199 name
, index_buffer_description
.Size
, expected
);
202 /* specify offset and size to avoid potential overruns */
203 hr
= IDirect3DIndexBuffer9_Lock(index_buffer
, 0, number_of_faces
* sizeof(WORD
) * 3,
204 (LPVOID
*)&faces
, D3DLOCK_DISCARD
);
205 ok(hr
== D3D_OK
, "Test %s, result %x, expected 0 (D3D_OK)\n", name
, hr
);
209 skip("Couldn't lock index buffer\n");
213 for (i
= 0; i
< number_of_faces
; i
++)
215 ok(compare_face(faces
[i
], mesh
->faces
[i
]),
216 "Test %s, face %d, result (%u, %u, %u), expected (%u, %u, %u)\n", name
, i
,
217 faces
[i
][0], faces
[i
][1], faces
[i
][2],
218 mesh
->faces
[i
][0], mesh
->faces
[i
][1], mesh
->faces
[i
][2]);
221 IDirect3DIndexBuffer9_Unlock(index_buffer
);
224 IDirect3DIndexBuffer9_Release(index_buffer
);
228 static void D3DXBoundProbeTest(void)
231 D3DXVECTOR3 bottom_point
, center
, top_point
, raydirection
, rayposition
;
234 /*____________Test the Box case___________________________*/
235 bottom_point
.x
= -3.0f
; bottom_point
.y
= -2.0f
; bottom_point
.z
= -1.0f
;
236 top_point
.x
= 7.0f
; top_point
.y
= 8.0f
; top_point
.z
= 9.0f
;
238 raydirection
.x
= -4.0f
; raydirection
.y
= -5.0f
; raydirection
.z
= -6.0f
;
239 rayposition
.x
= 5.0f
; rayposition
.y
= 5.0f
; rayposition
.z
= 11.0f
;
240 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
241 ok(result
== TRUE
, "expected TRUE, received FALSE\n");
243 raydirection
.x
= 4.0f
; raydirection
.y
= 5.0f
; raydirection
.z
= 6.0f
;
244 rayposition
.x
= 5.0f
; rayposition
.y
= 5.0f
; rayposition
.z
= 11.0f
;
245 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
246 ok(result
== FALSE
, "expected FALSE, received TRUE\n");
248 rayposition
.x
= -4.0f
; rayposition
.y
= 1.0f
; rayposition
.z
= -2.0f
;
249 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
250 ok(result
== TRUE
, "expected TRUE, received FALSE\n");
252 bottom_point
.x
= 1.0f
; bottom_point
.y
= 0.0f
; bottom_point
.z
= 0.0f
;
253 top_point
.x
= 1.0f
; top_point
.y
= 0.0f
; top_point
.z
= 0.0f
;
254 rayposition
.x
= 0.0f
; rayposition
.y
= 1.0f
; rayposition
.z
= 0.0f
;
255 raydirection
.x
= 0.0f
; raydirection
.y
= 3.0f
; raydirection
.z
= 0.0f
;
256 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
257 ok(result
== FALSE
, "expected FALSE, received TRUE\n");
259 bottom_point
.x
= 1.0f
; bottom_point
.y
= 2.0f
; bottom_point
.z
= 3.0f
;
260 top_point
.x
= 10.0f
; top_point
.y
= 15.0f
; top_point
.z
= 20.0f
;
262 raydirection
.x
= 7.0f
; raydirection
.y
= 8.0f
; raydirection
.z
= 9.0f
;
263 rayposition
.x
= 3.0f
; rayposition
.y
= 7.0f
; rayposition
.z
= -6.0f
;
264 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
265 ok(result
== TRUE
, "expected TRUE, received FALSE\n");
267 bottom_point
.x
= 0.0f
; bottom_point
.y
= 0.0f
; bottom_point
.z
= 0.0f
;
268 top_point
.x
= 1.0f
; top_point
.y
= 1.0f
; top_point
.z
= 1.0f
;
270 raydirection
.x
= 0.0f
; raydirection
.y
= 1.0f
; raydirection
.z
= .0f
;
271 rayposition
.x
= -3.0f
; rayposition
.y
= 0.0f
; rayposition
.z
= 0.0f
;
272 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
273 ok(result
== FALSE
, "expected FALSE, received TRUE\n");
275 raydirection
.x
= 1.0f
; raydirection
.y
= 0.0f
; raydirection
.z
= .0f
;
276 rayposition
.x
= -3.0f
; rayposition
.y
= 0.0f
; rayposition
.z
= 0.0f
;
277 result
= D3DXBoxBoundProbe(&bottom_point
, &top_point
, &rayposition
, &raydirection
);
278 ok(result
== TRUE
, "expected TRUE, received FALSE\n");
280 /*____________Test the Sphere case________________________*/
281 radius
= sqrt(77.0f
);
282 center
.x
= 1.0f
; center
.y
= 2.0f
; center
.z
= 3.0f
;
283 raydirection
.x
= 2.0f
; raydirection
.y
= -4.0f
; raydirection
.z
= 2.0f
;
285 rayposition
.x
= 5.0f
; rayposition
.y
= 5.0f
; rayposition
.z
= 9.0f
;
286 result
= D3DXSphereBoundProbe(¢er
, radius
, &rayposition
, &raydirection
);
287 ok(result
== TRUE
, "expected TRUE, received FALSE\n");
289 rayposition
.x
= 45.0f
; rayposition
.y
= -75.0f
; rayposition
.z
= 49.0f
;
290 result
= D3DXSphereBoundProbe(¢er
, radius
, &rayposition
, &raydirection
);
291 ok(result
== FALSE
, "expected FALSE, received TRUE\n");
293 rayposition
.x
= 5.0f
; rayposition
.y
= 11.0f
; rayposition
.z
= 9.0f
;
294 result
= D3DXSphereBoundProbe(¢er
, radius
, &rayposition
, &raydirection
);
295 ok(result
== FALSE
, "expected FALSE, received TRUE\n");
298 static void D3DXComputeBoundingBoxTest(void)
300 D3DXVECTOR3 exp_max
, exp_min
, got_max
, got_min
, vertex
[5];
303 vertex
[0].x
= 1.0f
; vertex
[0].y
= 1.0f
; vertex
[0].z
= 1.0f
;
304 vertex
[1].x
= 1.0f
; vertex
[1].y
= 1.0f
; vertex
[1].z
= 1.0f
;
305 vertex
[2].x
= 1.0f
; vertex
[2].y
= 1.0f
; vertex
[2].z
= 1.0f
;
306 vertex
[3].x
= 1.0f
; vertex
[3].y
= 1.0f
; vertex
[3].z
= 1.0f
;
307 vertex
[4].x
= 9.0f
; vertex
[4].y
= 9.0f
; vertex
[4].z
= 9.0f
;
309 exp_min
.x
= 1.0f
; exp_min
.y
= 1.0f
; exp_min
.z
= 1.0f
;
310 exp_max
.x
= 9.0f
; exp_max
.y
= 9.0f
; exp_max
.z
= 9.0f
;
312 hr
= D3DXComputeBoundingBox(&vertex
[3],2,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_min
,&got_max
);
314 ok( hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
315 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
);
316 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
);
318 /*________________________*/
320 vertex
[0].x
= 2.0f
; vertex
[0].y
= 5.9f
; vertex
[0].z
= -1.2f
;
321 vertex
[1].x
= -1.87f
; vertex
[1].y
= 7.9f
; vertex
[1].z
= 7.4f
;
322 vertex
[2].x
= 7.43f
; vertex
[2].y
= -0.9f
; vertex
[2].z
= 11.9f
;
323 vertex
[3].x
= -6.92f
; vertex
[3].y
= 6.3f
; vertex
[3].z
= -3.8f
;
324 vertex
[4].x
= 11.4f
; vertex
[4].y
= -8.1f
; vertex
[4].z
= 4.5f
;
326 exp_min
.x
= -6.92f
; exp_min
.y
= -8.1f
; exp_min
.z
= -3.80f
;
327 exp_max
.x
= 11.4f
; exp_max
.y
= 7.90f
; exp_max
.z
= 11.9f
;
329 hr
= D3DXComputeBoundingBox(&vertex
[0],5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_min
,&got_max
);
331 ok( hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
332 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
);
333 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
);
335 /*________________________*/
337 vertex
[0].x
= 2.0f
; vertex
[0].y
= 5.9f
; vertex
[0].z
= -1.2f
;
338 vertex
[1].x
= -1.87f
; vertex
[1].y
= 7.9f
; vertex
[1].z
= 7.4f
;
339 vertex
[2].x
= 7.43f
; vertex
[2].y
= -0.9f
; vertex
[2].z
= 11.9f
;
340 vertex
[3].x
= -6.92f
; vertex
[3].y
= 6.3f
; vertex
[3].z
= -3.8f
;
341 vertex
[4].x
= 11.4f
; vertex
[4].y
= -8.1f
; vertex
[4].z
= 4.5f
;
343 exp_min
.x
= -6.92f
; exp_min
.y
= -0.9f
; exp_min
.z
= -3.8f
;
344 exp_max
.x
= 7.43f
; exp_max
.y
= 7.90f
; exp_max
.z
= 11.9f
;
346 hr
= D3DXComputeBoundingBox(&vertex
[0],4,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_min
,&got_max
);
348 ok( hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
349 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
);
350 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
);
352 /*________________________*/
353 hr
= D3DXComputeBoundingBox(NULL
,5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_min
,&got_max
);
354 ok( hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
356 /*________________________*/
357 hr
= D3DXComputeBoundingBox(&vertex
[3],5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),NULL
,&got_max
);
358 ok( hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
360 /*________________________*/
361 hr
= D3DXComputeBoundingBox(&vertex
[3],5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_min
,NULL
);
362 ok( hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
365 static void D3DXComputeBoundingSphereTest(void)
367 D3DXVECTOR3 exp_cen
, got_cen
, vertex
[5];
368 FLOAT exp_rad
, got_rad
;
371 vertex
[0].x
= 1.0f
; vertex
[0].y
= 1.0f
; vertex
[0].z
= 1.0f
;
372 vertex
[1].x
= 1.0f
; vertex
[1].y
= 1.0f
; vertex
[1].z
= 1.0f
;
373 vertex
[2].x
= 1.0f
; vertex
[2].y
= 1.0f
; vertex
[2].z
= 1.0f
;
374 vertex
[3].x
= 1.0f
; vertex
[3].y
= 1.0f
; vertex
[3].z
= 1.0f
;
375 vertex
[4].x
= 9.0f
; vertex
[4].y
= 9.0f
; vertex
[4].z
= 9.0f
;
378 exp_cen
.x
= 5.0; exp_cen
.y
= 5.0; exp_cen
.z
= 5.0;
380 hr
= D3DXComputeBoundingSphere(&vertex
[3],2,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_cen
,&got_rad
);
382 ok( hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
383 ok( compare(exp_rad
, got_rad
), "Expected radius: %f, got radius: %f\n", exp_rad
, got_rad
);
384 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
);
386 /*________________________*/
388 vertex
[0].x
= 2.0f
; vertex
[0].y
= 5.9f
; vertex
[0].z
= -1.2f
;
389 vertex
[1].x
= -1.87f
; vertex
[1].y
= 7.9f
; vertex
[1].z
= 7.4f
;
390 vertex
[2].x
= 7.43f
; vertex
[2].y
= -0.9f
; vertex
[2].z
= 11.9f
;
391 vertex
[3].x
= -6.92f
; vertex
[3].y
= 6.3f
; vertex
[3].z
= -3.8f
;
392 vertex
[4].x
= 11.4f
; vertex
[4].y
= -8.1f
; vertex
[4].z
= 4.5f
;
394 exp_rad
= 13.707883f
;
395 exp_cen
.x
= 2.408f
; exp_cen
.y
= 2.22f
; exp_cen
.z
= 3.76f
;
397 hr
= D3DXComputeBoundingSphere(&vertex
[0],5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_cen
,&got_rad
);
399 ok( hr
== D3D_OK
, "Expected D3D_OK, got %#x\n", hr
);
400 ok( compare(exp_rad
, got_rad
), "Expected radius: %f, got radius: %f\n", exp_rad
, got_rad
);
401 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
);
403 /*________________________*/
404 hr
= D3DXComputeBoundingSphere(NULL
,5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_cen
,&got_rad
);
405 ok( hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
407 /*________________________*/
408 hr
= D3DXComputeBoundingSphere(&vertex
[3],5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),NULL
,&got_rad
);
409 ok( hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
411 /*________________________*/
412 hr
= D3DXComputeBoundingSphere(&vertex
[3],5,D3DXGetFVFVertexSize(D3DFVF_XYZ
),&got_cen
,NULL
);
413 ok( hr
== D3DERR_INVALIDCALL
, "Expected D3DERR_INVALIDCALL, got %#x\n", hr
);
416 static void D3DXDeclaratorFromFVFTest(void)
418 D3DVERTEXELEMENT9 decl
[MAX_FVF_DECL_SIZE
];
422 static const D3DVERTEXELEMENT9 exp1
[6] = {
423 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
424 {0, 0xC, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
425 {0, 0x18, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 0},
426 {0, 0x1C, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 1},
427 {0, 0x20, D3DDECLTYPE_FLOAT2
, D3DDECLMETHOD_DEFAULT
,D3DDECLUSAGE_TEXCOORD
, 0},
430 static const D3DVERTEXELEMENT9 exp2
[3] = {
431 {0, 0, D3DDECLTYPE_FLOAT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITIONT
, 0},
432 {0, 0x10, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_PSIZE
, 0},
435 static const D3DVERTEXELEMENT9 exp3
[4] = {
436 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
437 {0, 0xC, D3DDECLTYPE_FLOAT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_BLENDWEIGHT
, 0},
438 {0, 0x1C, D3DDECLTYPE_UBYTE4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_BLENDINDICES
, 0},
441 /* Note: passing NULL as declaration segfaults */
444 hr
= D3DXDeclaratorFromFVF(0, decl
);
445 ok(hr
== D3D_OK
, "D3DXDeclaratorFromFVF returned %#x, expected %#x\n", hr
, D3D_OK
);
446 ok(decl
[0].Stream
== 0xFF, "D3DXDeclaratorFromFVF returned an incorrect vertex declaration\n"); /* end element */
448 hr
= D3DXDeclaratorFromFVF(D3DFVF_XYZ
| D3DFVF_NORMAL
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
| D3DFVF_TEX1
, decl
);
449 ok(hr
== D3D_OK
, "D3DXDeclaratorFromFVF returned %#x, expected %#x\n", hr
, D3D_OK
);
453 size
= sizeof(exp1
)/sizeof(exp1
[0]);
454 for (i
=0; i
<size
-1; i
++)
456 ok(decl
[i
].Stream
== exp1
[i
].Stream
, "Returned stream %d, expected %d\n", decl
[i
].Stream
, exp1
[i
].Stream
);
457 ok(decl
[i
].Type
== exp1
[i
].Type
, "Returned type %d, expected %d\n", decl
[i
].Type
, exp1
[i
].Type
);
458 ok(decl
[i
].Method
== exp1
[i
].Method
, "Returned method %d, expected %d\n", decl
[i
].Method
, exp1
[i
].Method
);
459 ok(decl
[i
].Usage
== exp1
[i
].Usage
, "Returned usage %d, expected %d\n", decl
[i
].Usage
, exp1
[i
].Usage
);
460 ok(decl
[i
].UsageIndex
== exp1
[i
].UsageIndex
, "Returned usage index %d, expected %d\n", decl
[i
].UsageIndex
, exp1
[i
].UsageIndex
);
461 ok(decl
[i
].Offset
== exp1
[i
].Offset
, "Returned offset %d, expected %d\n", decl
[i
].Offset
, exp1
[i
].Offset
);
463 ok(decl
[size
-1].Stream
== 0xFF, "Returned too long vertex declaration\n"); /* end element */
469 hr
= D3DXDeclaratorFromFVF(D3DFVF_XYZRHW
| D3DFVF_PSIZE
, decl
);
470 ok(hr
== D3D_OK
, "D3DXDeclaratorFromFVF returned %#x, expected %#x\n", hr
, D3D_OK
);
474 size
= sizeof(exp2
)/sizeof(exp2
[0]);
475 for (i
=0; i
<size
-1; i
++)
477 ok(decl
[i
].Stream
== exp2
[i
].Stream
, "Returned stream %d, expected %d\n", decl
[i
].Stream
, exp2
[i
].Stream
);
478 ok(decl
[i
].Type
== exp2
[i
].Type
, "Returned type %d, expected %d\n", decl
[i
].Type
, exp1
[i
].Type
);
479 ok(decl
[i
].Method
== exp2
[i
].Method
, "Returned method %d, expected %d\n", decl
[i
].Method
, exp2
[i
].Method
);
480 ok(decl
[i
].Usage
== exp2
[i
].Usage
, "Returned usage %d, expected %d\n", decl
[i
].Usage
, exp2
[i
].Usage
);
481 ok(decl
[i
].UsageIndex
== exp2
[i
].UsageIndex
, "Returned usage index %d, expected %d\n", decl
[i
].UsageIndex
, exp2
[i
].UsageIndex
);
482 ok(decl
[i
].Offset
== exp2
[i
].Offset
, "Returned offset %d, expected %d\n", decl
[i
].Offset
, exp2
[i
].Offset
);
484 ok(decl
[size
-1].Stream
== 0xFF, "Returned too long vertex declaration\n"); /* end element */
490 hr
= D3DXDeclaratorFromFVF(D3DFVF_XYZB5
, decl
);
491 ok(hr
== D3DERR_INVALIDCALL
, "D3DXDeclaratorFromFVF returned %#x, expected %#x\n", hr
, D3DERR_INVALIDCALL
);
493 hr
= D3DXDeclaratorFromFVF(D3DFVF_XYZB5
| D3DFVF_LASTBETA_UBYTE4
, decl
);
494 ok(hr
== D3D_OK
, "D3DXDeclaratorFromFVF returned %#x, expected %#x\n", hr
, D3D_OK
);
498 size
= sizeof(exp3
)/sizeof(exp3
[0]);
499 for (i
=0; i
<size
-1; i
++)
501 ok(decl
[i
].Stream
== exp3
[i
].Stream
, "Returned stream %d, expected %d\n", decl
[i
].Stream
, exp3
[i
].Stream
);
502 ok(decl
[i
].Type
== exp3
[i
].Type
, "Returned type %d, expected %d\n", decl
[i
].Type
, exp3
[i
].Type
);
503 ok(decl
[i
].Method
== exp3
[i
].Method
, "Returned method %d, expected %d\n", decl
[i
].Method
, exp3
[i
].Method
);
504 ok(decl
[i
].Usage
== exp3
[i
].Usage
, "Returned usage %d, expected %d\n", decl
[i
].Usage
, exp3
[i
].Usage
);
505 ok(decl
[i
].UsageIndex
== exp3
[i
].UsageIndex
, "Returned usage index %d, expected %d\n", decl
[i
].UsageIndex
, exp3
[i
].UsageIndex
);
506 ok(decl
[i
].Offset
== exp3
[i
].Offset
, "Returned offset %d, expected %d\n", decl
[i
].Offset
, exp3
[i
].Offset
);
508 ok(decl
[size
-1].Stream
== 0xFF, "Returned too long vertex declaration\n"); /* end element */
513 static void D3DXGetFVFVertexSizeTest(void)
517 compare_vertex_sizes (D3DFVF_XYZ
, 12);
519 compare_vertex_sizes (D3DFVF_XYZB3
, 24);
521 compare_vertex_sizes (D3DFVF_XYZB5
, 32);
523 compare_vertex_sizes (D3DFVF_XYZ
| D3DFVF_NORMAL
, 24);
525 compare_vertex_sizes (D3DFVF_XYZ
| D3DFVF_DIFFUSE
, 16);
527 compare_vertex_sizes (
530 D3DFVF_TEXCOORDSIZE1(0), 16);
531 compare_vertex_sizes (
534 D3DFVF_TEXCOORDSIZE1(0) |
535 D3DFVF_TEXCOORDSIZE1(1), 20);
537 compare_vertex_sizes (
540 D3DFVF_TEXCOORDSIZE2(0), 20);
542 compare_vertex_sizes (
545 D3DFVF_TEXCOORDSIZE2(0) |
546 D3DFVF_TEXCOORDSIZE2(1), 28);
548 compare_vertex_sizes (
551 D3DFVF_TEXCOORDSIZE2(0) |
552 D3DFVF_TEXCOORDSIZE2(1) |
553 D3DFVF_TEXCOORDSIZE2(2) |
554 D3DFVF_TEXCOORDSIZE2(3) |
555 D3DFVF_TEXCOORDSIZE2(4) |
556 D3DFVF_TEXCOORDSIZE2(5), 60);
558 compare_vertex_sizes (
561 D3DFVF_TEXCOORDSIZE2(0) |
562 D3DFVF_TEXCOORDSIZE2(1) |
563 D3DFVF_TEXCOORDSIZE2(2) |
564 D3DFVF_TEXCOORDSIZE2(3) |
565 D3DFVF_TEXCOORDSIZE2(4) |
566 D3DFVF_TEXCOORDSIZE2(5) |
567 D3DFVF_TEXCOORDSIZE2(6) |
568 D3DFVF_TEXCOORDSIZE2(7), 76);
570 compare_vertex_sizes (
573 D3DFVF_TEXCOORDSIZE3(0), 24);
575 compare_vertex_sizes (
578 D3DFVF_TEXCOORDSIZE3(0) |
579 D3DFVF_TEXCOORDSIZE3(1) |
580 D3DFVF_TEXCOORDSIZE3(2) |
581 D3DFVF_TEXCOORDSIZE3(3), 60);
583 compare_vertex_sizes (
586 D3DFVF_TEXCOORDSIZE4(0), 28);
588 compare_vertex_sizes (
591 D3DFVF_TEXCOORDSIZE4(0) |
592 D3DFVF_TEXCOORDSIZE4(1), 44);
594 compare_vertex_sizes (
597 D3DFVF_TEXCOORDSIZE4(0) |
598 D3DFVF_TEXCOORDSIZE4(1) |
599 D3DFVF_TEXCOORDSIZE4(2), 60);
601 compare_vertex_sizes (
607 D3DFVF_TEXCOORDSIZE4(0) |
608 D3DFVF_TEXCOORDSIZE4(1) |
609 D3DFVF_TEXCOORDSIZE4(2) |
610 D3DFVF_TEXCOORDSIZE4(3) |
611 D3DFVF_TEXCOORDSIZE4(4) |
612 D3DFVF_TEXCOORDSIZE4(5) |
613 D3DFVF_TEXCOORDSIZE4(6) |
614 D3DFVF_TEXCOORDSIZE4(7), 180);
617 static void D3DXIntersectTriTest(void)
619 BOOL exp_res
, got_res
;
620 D3DXVECTOR3 position
, ray
, vertex
[3];
621 FLOAT exp_dist
, got_dist
, exp_u
, got_u
, exp_v
, got_v
;
623 vertex
[0].x
= 1.0f
; vertex
[0].y
= 0.0f
; vertex
[0].z
= 0.0f
;
624 vertex
[1].x
= 2.0f
; vertex
[1].y
= 0.0f
; vertex
[1].z
= 0.0f
;
625 vertex
[2].x
= 1.0f
; vertex
[2].y
= 1.0f
; vertex
[2].z
= 0.0f
;
627 position
.x
= -14.5f
; position
.y
= -23.75f
; position
.z
= -32.0f
;
629 ray
.x
= 2.0f
; ray
.y
= 3.0f
; ray
.z
= 4.0f
;
631 exp_res
= TRUE
; exp_u
= 0.5f
; exp_v
= 0.25f
; exp_dist
= 8.0f
;
633 got_res
= D3DXIntersectTri(&vertex
[0],&vertex
[1],&vertex
[2],&position
,&ray
,&got_u
,&got_v
,&got_dist
);
634 ok( got_res
== exp_res
, "Expected result = %d, got %d\n",exp_res
,got_res
);
635 ok( compare(exp_u
,got_u
), "Expected u = %f, got %f\n",exp_u
,got_u
);
636 ok( compare(exp_v
,got_v
), "Expected v = %f, got %f\n",exp_v
,got_v
);
637 ok( compare(exp_dist
,got_dist
), "Expected distance = %f, got %f\n",exp_dist
,got_dist
);
639 /*Only positive ray is taken in account*/
641 vertex
[0].x
= 1.0f
; vertex
[0].y
= 0.0f
; vertex
[0].z
= 0.0f
;
642 vertex
[1].x
= 2.0f
; vertex
[1].y
= 0.0f
; vertex
[1].z
= 0.0f
;
643 vertex
[2].x
= 1.0f
; vertex
[2].y
= 1.0f
; vertex
[2].z
= 0.0f
;
645 position
.x
= 17.5f
; position
.y
= 24.25f
; position
.z
= 32.0f
;
647 ray
.x
= 2.0f
; ray
.y
= 3.0f
; ray
.z
= 4.0f
;
651 got_res
= D3DXIntersectTri(&vertex
[0],&vertex
[1],&vertex
[2],&position
,&ray
,&got_u
,&got_v
,&got_dist
);
652 ok( got_res
== exp_res
, "Expected result = %d, got %d\n",exp_res
,got_res
);
654 /*Intersection between ray and triangle in a same plane is considered as empty*/
656 vertex
[0].x
= 4.0f
; vertex
[0].y
= 0.0f
; vertex
[0].z
= 0.0f
;
657 vertex
[1].x
= 6.0f
; vertex
[1].y
= 0.0f
; vertex
[1].z
= 0.0f
;
658 vertex
[2].x
= 4.0f
; vertex
[2].y
= 2.0f
; vertex
[2].z
= 0.0f
;
660 position
.x
= 1.0f
; position
.y
= 1.0f
; position
.z
= 0.0f
;
662 ray
.x
= 1.0f
; ray
.y
= 0.0f
; ray
.z
= 0.0f
;
666 got_res
= D3DXIntersectTri(&vertex
[0],&vertex
[1],&vertex
[2],&position
,&ray
,&got_u
,&got_v
,&got_dist
);
667 ok( got_res
== exp_res
, "Expected result = %d, got %d\n",exp_res
,got_res
);
670 static void D3DXCreateMeshTest(void)
675 IDirect3DDevice9
*device
, *test_device
;
676 D3DPRESENT_PARAMETERS d3dpp
;
679 D3DVERTEXELEMENT9 test_decl
[MAX_FVF_DECL_SIZE
];
683 static const D3DVERTEXELEMENT9 decl
[3] = {
684 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
685 {0, 0xC, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_NORMAL
, 0},
688 hr
= D3DXCreateMesh(0, 0, 0, NULL
, NULL
, NULL
);
689 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
691 hr
= D3DXCreateMesh(1, 3, D3DXMESH_MANAGED
, (LPD3DVERTEXELEMENT9
*)&decl
, NULL
, &d3dxmesh
);
692 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
694 wnd
= CreateWindow("static", "d3dx9_test", 0, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
);
697 skip("Couldn't create application window\n");
700 d3d
= Direct3DCreate9(D3D_SDK_VERSION
);
703 skip("Couldn't create IDirect3D9 object\n");
708 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
709 d3dpp
.Windowed
= TRUE
;
710 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
711 hr
= IDirect3D9_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, wnd
, D3DCREATE_MIXED_VERTEXPROCESSING
, &d3dpp
, &device
);
714 skip("Failed to create IDirect3DDevice9 object %#x\n", hr
);
715 IDirect3D9_Release(d3d
);
720 hr
= D3DXCreateMesh(0, 3, D3DXMESH_MANAGED
, (LPD3DVERTEXELEMENT9
*)&decl
, device
, &d3dxmesh
);
721 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
723 hr
= D3DXCreateMesh(1, 0, D3DXMESH_MANAGED
, (LPD3DVERTEXELEMENT9
*)&decl
, device
, &d3dxmesh
);
724 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
726 hr
= D3DXCreateMesh(1, 3, 0, (LPD3DVERTEXELEMENT9
*)&decl
, device
, &d3dxmesh
);
727 todo_wine
ok(hr
== D3D_OK
, "Got result %x, expected %x (D3D_OK)\n", hr
, D3D_OK
);
731 d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
734 hr
= D3DXCreateMesh(1, 3, D3DXMESH_MANAGED
, 0, device
, &d3dxmesh
);
735 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
737 hr
= D3DXCreateMesh(1, 3, D3DXMESH_MANAGED
, (LPD3DVERTEXELEMENT9
*)&decl
, device
, NULL
);
738 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
740 hr
= D3DXCreateMesh(1, 3, D3DXMESH_MANAGED
, (LPD3DVERTEXELEMENT9
*)&decl
, device
, &d3dxmesh
);
741 todo_wine
ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n", hr
);
746 hr
= d3dxmesh
->lpVtbl
->GetDevice(d3dxmesh
, NULL
);
747 ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
749 hr
= d3dxmesh
->lpVtbl
->GetDevice(d3dxmesh
, &test_device
);
750 ok(hr
== D3D_OK
, "Got result %x, expected %x (D3D_OK)\n", hr
, D3D_OK
);
751 ok(test_device
== device
, "Got result %p, expected %p\n", test_device
, device
);
755 IDirect3DDevice9_Release(device
);
759 hr
= d3dxmesh
->lpVtbl
->GetDeclaration(d3dxmesh
, test_decl
);
760 ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n", hr
);
764 size
= sizeof(decl
) / sizeof(decl
[0]);
765 for (i
= 0; i
< size
- 1; i
++)
767 ok(test_decl
[i
].Stream
== decl
[i
].Stream
, "Returned stream %d, expected %d\n", test_decl
[i
].Stream
, decl
[i
].Stream
);
768 ok(test_decl
[i
].Type
== decl
[i
].Type
, "Returned type %d, expected %d\n", test_decl
[i
].Type
, decl
[i
].Type
);
769 ok(test_decl
[i
].Method
== decl
[i
].Method
, "Returned method %d, expected %d\n", test_decl
[i
].Method
, decl
[i
].Method
);
770 ok(test_decl
[i
].Usage
== decl
[i
].Usage
, "Returned usage %d, expected %d\n", test_decl
[i
].Usage
, decl
[i
].Usage
);
771 ok(test_decl
[i
].UsageIndex
== decl
[i
].UsageIndex
, "Returned usage index %d, expected %d\n", test_decl
[i
].UsageIndex
, decl
[i
].UsageIndex
);
772 ok(test_decl
[i
].Offset
== decl
[i
].Offset
, "Returned offset %d, expected %d\n", decl
[1].Offset
, decl
[i
].Offset
);
774 ok(decl
[size
-1].Stream
== 0xFF, "Returned too long vertex declaration\n"); /* end element */
778 fvf
= d3dxmesh
->lpVtbl
->GetFVF(d3dxmesh
);
779 ok(fvf
== (D3DFVF_XYZ
| D3DFVF_NORMAL
), "Got result %x, expected %x (D3DFVF_XYZ | D3DFVF_NORMAL)\n", fvf
, D3DFVF_XYZ
| D3DFVF_NORMAL
);
782 options
= d3dxmesh
->lpVtbl
->GetOptions(d3dxmesh
);
783 ok(options
== D3DXMESH_MANAGED
, "Got result %x, expected %x (D3DXMESH_MANAGED)\n", options
, D3DXMESH_MANAGED
);
786 if (!new_mesh(&mesh
, 3, 1))
788 skip("Couldn't create mesh\n");
792 memset(mesh
.vertices
, 0, mesh
.number_of_vertices
* sizeof(*mesh
.vertices
));
793 memset(mesh
.faces
, 0, mesh
.number_of_faces
* sizeof(*mesh
.faces
));
795 compare_mesh("createmeshfvf", d3dxmesh
, &mesh
);
800 d3dxmesh
->lpVtbl
->Release(d3dxmesh
);
803 IDirect3DDevice9_Release(device
);
804 IDirect3D9_Release(d3d
);
814 static void free_sincos_table(struct sincos_table
*sincos_table
)
816 HeapFree(GetProcessHeap(), 0, sincos_table
->cos
);
817 HeapFree(GetProcessHeap(), 0, sincos_table
->sin
);
820 /* pre compute sine and cosine tables; caller must free */
821 static BOOL
compute_sincos_table(struct sincos_table
*sincos_table
, float angle_start
, float angle_step
, int n
)
826 sincos_table
->sin
= HeapAlloc(GetProcessHeap(), 0, n
* sizeof(*sincos_table
->sin
));
827 if (!sincos_table
->sin
)
831 sincos_table
->cos
= HeapAlloc(GetProcessHeap(), 0, n
* sizeof(*sincos_table
->cos
));
832 if (!sincos_table
->cos
)
834 HeapFree(GetProcessHeap(), 0, sincos_table
->sin
);
839 for (i
= 0; i
< n
; i
++)
841 sincos_table
->sin
[i
] = sin(angle
);
842 sincos_table
->cos
[i
] = cos(angle
);
849 static WORD
sphere_vertex(UINT slices
, int slice
, int stack
)
851 return stack
*slices
+slice
+1;
854 /* slices = subdivisions along xy plane, stacks = subdivisions along z axis */
855 static BOOL
compute_sphere(struct mesh
*mesh
, FLOAT radius
, UINT slices
, UINT stacks
)
857 float theta_step
, theta_start
;
858 struct sincos_table theta
;
859 float phi_step
, phi_start
;
860 struct sincos_table phi
;
861 DWORD number_of_vertices
, number_of_faces
;
865 /* theta = angle on xy plane wrt x axis */
866 theta_step
= M_PI
/ stacks
;
867 theta_start
= theta_step
;
869 /* phi = angle on xz plane wrt z axis */
870 phi_step
= -2 * M_PI
/ slices
;
871 phi_start
= M_PI
/ 2;
873 if (!compute_sincos_table(&theta
, theta_start
, theta_step
, stacks
))
877 if (!compute_sincos_table(&phi
, phi_start
, phi_step
, slices
))
879 free_sincos_table(&theta
);
883 number_of_vertices
= 2 + slices
* (stacks
-1);
884 number_of_faces
= 2 * slices
+ (stacks
- 2) * (2 * slices
);
886 if (!new_mesh(mesh
, number_of_vertices
, number_of_faces
))
888 free_sincos_table(&phi
);
889 free_sincos_table(&theta
);
897 mesh
->vertices
[vertex
].normal
.x
= 0.0f
;
898 mesh
->vertices
[vertex
].normal
.y
= 0.0f
;
899 mesh
->vertices
[vertex
].normal
.z
= 1.0f
;
900 mesh
->vertices
[vertex
].position
.x
= 0.0f
;
901 mesh
->vertices
[vertex
].position
.y
= 0.0f
;
902 mesh
->vertices
[vertex
].position
.z
= radius
;
905 for (stack
= 0; stack
< stacks
- 1; stack
++)
907 for (slice
= 0; slice
< slices
; slice
++)
909 mesh
->vertices
[vertex
].normal
.x
= theta
.sin
[stack
] * phi
.cos
[slice
];
910 mesh
->vertices
[vertex
].normal
.y
= theta
.sin
[stack
] * phi
.sin
[slice
];
911 mesh
->vertices
[vertex
].normal
.z
= theta
.cos
[stack
];
912 mesh
->vertices
[vertex
].position
.x
= radius
* theta
.sin
[stack
] * phi
.cos
[slice
];
913 mesh
->vertices
[vertex
].position
.y
= radius
* theta
.sin
[stack
] * phi
.sin
[slice
];
914 mesh
->vertices
[vertex
].position
.z
= radius
* theta
.cos
[stack
];
921 /* top stack is triangle fan */
922 mesh
->faces
[face
][0] = 0;
923 mesh
->faces
[face
][1] = slice
+ 1;
924 mesh
->faces
[face
][2] = slice
;
929 /* stacks in between top and bottom are quad strips */
930 mesh
->faces
[face
][0] = sphere_vertex(slices
, slice
-1, stack
-1);
931 mesh
->faces
[face
][1] = sphere_vertex(slices
, slice
, stack
-1);
932 mesh
->faces
[face
][2] = sphere_vertex(slices
, slice
-1, stack
);
935 mesh
->faces
[face
][0] = sphere_vertex(slices
, slice
, stack
-1);
936 mesh
->faces
[face
][1] = sphere_vertex(slices
, slice
, stack
);
937 mesh
->faces
[face
][2] = sphere_vertex(slices
, slice
-1, stack
);
945 mesh
->faces
[face
][0] = 0;
946 mesh
->faces
[face
][1] = 1;
947 mesh
->faces
[face
][2] = slice
;
952 mesh
->faces
[face
][0] = sphere_vertex(slices
, slice
-1, stack
-1);
953 mesh
->faces
[face
][1] = sphere_vertex(slices
, 0, stack
-1);
954 mesh
->faces
[face
][2] = sphere_vertex(slices
, slice
-1, stack
);
957 mesh
->faces
[face
][0] = sphere_vertex(slices
, 0, stack
-1);
958 mesh
->faces
[face
][1] = sphere_vertex(slices
, 0, stack
);
959 mesh
->faces
[face
][2] = sphere_vertex(slices
, slice
-1, stack
);
964 mesh
->vertices
[vertex
].position
.x
= 0.0f
;
965 mesh
->vertices
[vertex
].position
.y
= 0.0f
;
966 mesh
->vertices
[vertex
].position
.z
= -radius
;
967 mesh
->vertices
[vertex
].normal
.x
= 0.0f
;
968 mesh
->vertices
[vertex
].normal
.y
= 0.0f
;
969 mesh
->vertices
[vertex
].normal
.z
= -1.0f
;
971 /* bottom stack is triangle fan */
972 for (slice
= 1; slice
< slices
; slice
++)
974 mesh
->faces
[face
][0] = sphere_vertex(slices
, slice
-1, stack
-1);
975 mesh
->faces
[face
][1] = sphere_vertex(slices
, slice
, stack
-1);
976 mesh
->faces
[face
][2] = vertex
;
980 mesh
->faces
[face
][0] = sphere_vertex(slices
, slice
-1, stack
-1);
981 mesh
->faces
[face
][1] = sphere_vertex(slices
, 0, stack
-1);
982 mesh
->faces
[face
][2] = vertex
;
984 free_sincos_table(&phi
);
985 free_sincos_table(&theta
);
990 static void test_sphere(IDirect3DDevice9
*device
, FLOAT radius
, UINT slices
, UINT stacks
)
997 hr
= D3DXCreateSphere(device
, radius
, slices
, stacks
, &sphere
, NULL
);
998 todo_wine
ok(hr
== D3D_OK
, "Got result %x, expected 0 (D3D_OK)\n", hr
);
1001 skip("Couldn't create sphere\n");
1005 if (!compute_sphere(&mesh
, radius
, slices
, stacks
))
1007 skip("Couldn't create mesh\n");
1008 sphere
->lpVtbl
->Release(sphere
);
1012 sprintf(name
, "sphere (%g, %u, %u)", radius
, slices
, stacks
);
1013 compare_mesh(name
, sphere
, &mesh
);
1017 sphere
->lpVtbl
->Release(sphere
);
1020 static void D3DXCreateSphereTest(void)
1025 IDirect3DDevice9
* device
;
1026 D3DPRESENT_PARAMETERS d3dpp
;
1027 ID3DXMesh
* sphere
= NULL
;
1029 hr
= D3DXCreateSphere(NULL
, 0.0f
, 0, 0, NULL
, NULL
);
1030 todo_wine
ok( hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
1032 hr
= D3DXCreateSphere(NULL
, 0.1f
, 0, 0, NULL
, NULL
);
1033 todo_wine
ok( hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
1035 hr
= D3DXCreateSphere(NULL
, 0.0f
, 1, 0, NULL
, NULL
);
1036 todo_wine
ok( hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
1038 hr
= D3DXCreateSphere(NULL
, 0.0f
, 0, 1, NULL
, NULL
);
1039 todo_wine
ok( hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
1041 wnd
= CreateWindow("static", "d3dx9_test", 0, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
);
1042 d3d
= Direct3DCreate9(D3D_SDK_VERSION
);
1045 skip("Couldn't create application window\n");
1050 skip("Couldn't create IDirect3D9 object\n");
1055 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
1056 d3dpp
.Windowed
= TRUE
;
1057 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1058 hr
= IDirect3D9_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, wnd
, D3DCREATE_MIXED_VERTEXPROCESSING
, &d3dpp
, &device
);
1061 skip("Failed to create IDirect3DDevice9 object %#x\n", hr
);
1062 IDirect3D9_Release(d3d
);
1067 hr
= D3DXCreateSphere(device
, 1.0f
, 1, 1, &sphere
, NULL
);
1068 todo_wine
ok( hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr
,D3DERR_INVALIDCALL
);
1070 hr
= D3DXCreateSphere(device
, 1.0f
, 2, 1, &sphere
, NULL
);
1071 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1073 hr
= D3DXCreateSphere(device
, 1.0f
, 1, 2, &sphere
, NULL
);
1074 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1076 hr
= D3DXCreateSphere(device
, -0.1f
, 1, 2, &sphere
, NULL
);
1077 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr
, D3DERR_INVALIDCALL
);
1079 test_sphere(device
, 0.0f
, 2, 2);
1080 test_sphere(device
, 1.0f
, 2, 2);
1081 test_sphere(device
, 1.0f
, 3, 2);
1082 test_sphere(device
, 1.0f
, 4, 4);
1083 test_sphere(device
, 1.0f
, 3, 4);
1084 test_sphere(device
, 5.0f
, 6, 7);
1085 test_sphere(device
, 10.0f
, 11, 12);
1087 IDirect3DDevice9_Release(device
);
1088 IDirect3D9_Release(d3d
);
1092 static void test_get_decl_vertex_size(void)
1094 static const D3DVERTEXELEMENT9 declaration1
[] =
1096 {0, 0, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1097 {1, 0, D3DDECLTYPE_FLOAT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1098 {2, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1099 {3, 0, D3DDECLTYPE_FLOAT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1100 {4, 0, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1101 {5, 0, D3DDECLTYPE_UBYTE4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1102 {6, 0, D3DDECLTYPE_SHORT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1103 {7, 0, D3DDECLTYPE_SHORT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1104 {8, 0, D3DDECLTYPE_UBYTE4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1105 {9, 0, D3DDECLTYPE_SHORT2N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1106 {10, 0, D3DDECLTYPE_SHORT4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1107 {11, 0, D3DDECLTYPE_UDEC3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1108 {12, 0, D3DDECLTYPE_DEC3N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1109 {13, 0, D3DDECLTYPE_FLOAT16_2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1110 {14, 0, D3DDECLTYPE_FLOAT16_4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1113 static const D3DVERTEXELEMENT9 declaration2
[] =
1115 {0, 8, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1116 {1, 8, D3DDECLTYPE_FLOAT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1117 {2, 8, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1118 {3, 8, D3DDECLTYPE_FLOAT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1119 {4, 8, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1120 {5, 8, D3DDECLTYPE_UBYTE4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1121 {6, 8, D3DDECLTYPE_SHORT2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1122 {7, 8, D3DDECLTYPE_SHORT4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1123 {0, 8, D3DDECLTYPE_UBYTE4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1124 {1, 8, D3DDECLTYPE_SHORT2N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1125 {2, 8, D3DDECLTYPE_SHORT4N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1126 {3, 8, D3DDECLTYPE_UDEC3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1127 {4, 8, D3DDECLTYPE_DEC3N
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1128 {5, 8, D3DDECLTYPE_FLOAT16_2
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1129 {6, 8, D3DDECLTYPE_FLOAT16_4
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1130 {7, 8, D3DDECLTYPE_FLOAT1
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1133 static const UINT sizes1
[] =
1140 static const UINT sizes2
[] =
1148 size
= D3DXGetDeclVertexSize(NULL
, 0);
1149 ok(size
== 0, "Got size %#x, expected 0.\n", size
);
1151 for (i
= 0; i
< 16; ++i
)
1153 size
= D3DXGetDeclVertexSize(declaration1
, i
);
1154 ok(size
== sizes1
[i
], "Got size %u for stream %u, expected %u.\n", size
, i
, sizes1
[i
]);
1157 for (i
= 0; i
< 8; ++i
)
1159 size
= D3DXGetDeclVertexSize(declaration2
, i
);
1160 ok(size
== sizes2
[i
], "Got size %u for stream %u, expected %u.\n", size
, i
, sizes2
[i
]);
1166 D3DXBoundProbeTest();
1167 D3DXComputeBoundingBoxTest();
1168 D3DXComputeBoundingSphereTest();
1169 D3DXDeclaratorFromFVFTest();
1170 D3DXGetFVFVertexSizeTest();
1171 D3DXIntersectTriTest();
1172 D3DXCreateMeshTest();
1173 D3DXCreateSphereTest();
1174 test_get_decl_vertex_size();