2 * Copyright 2011 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "wine/test.h"
33 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
43 if (abs(x
- y
) > ulps
)
49 static BOOL
compare_vec4(struct vec4
*vec
, float x
, float y
, float z
, float w
, unsigned int ulps
)
51 return compare_float(vec
->x
, x
, ulps
)
52 && compare_float(vec
->y
, y
, ulps
)
53 && compare_float(vec
->z
, z
, ulps
)
54 && compare_float(vec
->w
, w
, ulps
);
57 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
59 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
61 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
63 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
65 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
69 static D3DCOLOR
get_surface_color(IDirectDrawSurface4
*surface
, UINT x
, UINT y
)
71 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
72 DDSURFACEDESC2 surface_desc
;
76 memset(&surface_desc
, 0, sizeof(surface_desc
));
77 surface_desc
.dwSize
= sizeof(surface_desc
);
79 hr
= IDirectDrawSurface4_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
80 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
84 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
86 hr
= IDirectDrawSurface4_Unlock(surface
, &rect
);
87 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
92 static IDirectDraw4
*create_ddraw(void)
98 if (FAILED(DirectDrawCreate(NULL
, &ddraw1
, NULL
)))
101 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw4
, (void **)&ddraw4
);
102 IDirectDraw_Release(ddraw1
);
109 static IDirect3DDevice3
*create_device(HWND window
, DWORD coop_level
)
111 IDirect3DDevice3
*device
= NULL
;
112 IDirectDrawSurface4
*surface
;
113 DDSURFACEDESC2 surface_desc
;
114 IDirectDraw4
*ddraw4
;
118 if (!(ddraw4
= create_ddraw()))
121 hr
= IDirectDraw4_SetCooperativeLevel(ddraw4
, window
, coop_level
);
122 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
124 memset(&surface_desc
, 0, sizeof(surface_desc
));
125 surface_desc
.dwSize
= sizeof(surface_desc
);
126 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
127 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
128 surface_desc
.dwWidth
= 640;
129 surface_desc
.dwHeight
= 480;
131 hr
= IDirectDraw4_CreateSurface(ddraw4
, &surface_desc
, &surface
, NULL
);
132 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
134 if (coop_level
& DDSCL_NORMAL
)
136 IDirectDrawClipper
*clipper
;
138 hr
= IDirectDraw4_CreateClipper(ddraw4
, 0, &clipper
, NULL
);
139 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
140 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
141 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
142 hr
= IDirectDrawSurface4_SetClipper(surface
, clipper
);
143 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#x.\n", hr
);
144 IDirectDrawClipper_Release(clipper
);
147 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirect3D3
, (void **)&d3d3
);
148 IDirectDraw4_Release(ddraw4
);
151 IDirectDrawSurface4_Release(surface
);
155 hr
= IDirect3D3_CreateDevice(d3d3
, &IID_IDirect3DHALDevice
, surface
, &device
, NULL
);
156 IDirect3D3_Release(d3d3
);
157 IDirectDrawSurface4_Release(surface
);
164 static void test_process_vertices(void)
166 IDirect3DVertexBuffer
*src_vb
, *dst_vb
;
167 IDirect3DViewport3
*viewport
;
168 D3DVERTEXBUFFERDESC vb_desc
;
169 IDirect3DDevice3
*device
;
170 struct vec3
*src_data
;
171 struct vec4
*dst_data
;
178 static D3DMATRIX identity
=
180 1.0f
, 0.0f
, 0.0f
, 0.0f
,
181 0.0f
, 1.0f
, 0.0f
, 0.0f
,
182 0.0f
, 0.0f
, 1.0f
, 0.0f
,
183 0.0f
, 0.0f
, 0.0f
, 1.0f
,
185 static D3DMATRIX projection
=
187 1.0f
, 0.0f
, 0.0f
, 0.0f
,
188 0.0f
, 1.0f
, 0.0f
, 0.0f
,
189 0.0f
, 0.0f
, 1.0f
, 0.0f
,
190 6.0f
, 7.0f
, 8.0f
, 1.0f
,
193 window
= CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW
,
194 0, 0, 640, 480, 0, 0, 0, 0);
195 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
197 skip("Failed to create a 3D device, skipping test.\n");
198 DestroyWindow(window
);
202 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d3
);
203 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
205 memset(&vb_desc
, 0, sizeof(vb_desc
));
206 vb_desc
.dwSize
= sizeof(vb_desc
);
207 vb_desc
.dwFVF
= D3DFVF_XYZ
;
208 vb_desc
.dwNumVertices
= 3;
209 hr
= IDirect3D3_CreateVertexBuffer(d3d3
, &vb_desc
, &src_vb
, 0, NULL
);
210 ok(SUCCEEDED(hr
), "Failed to create source vertex buffer, hr %#x.\n", hr
);
212 hr
= IDirect3DVertexBuffer_Lock(src_vb
, DDLOCK_WRITEONLY
, (void **)&src_data
, NULL
);
213 ok(SUCCEEDED(hr
), "Failed to lock source vertex buffer, hr %#x.\n", hr
);
214 src_data
[0].x
= -1.0f
;
215 src_data
[0].y
= -1.0f
;
216 src_data
[0].z
= -1.0f
;
217 src_data
[1].x
= 0.0f
;
218 src_data
[1].y
= 0.0f
;
219 src_data
[1].z
= 0.0f
;
220 src_data
[2].x
= 1.0f
;
221 src_data
[2].y
= 1.0f
;
222 src_data
[2].z
= 1.0f
;
223 hr
= IDirect3DVertexBuffer_Unlock(src_vb
);
224 ok(SUCCEEDED(hr
), "Failed to unlock source vertex buffer, hr %#x.\n", hr
);
226 memset(&vb_desc
, 0, sizeof(vb_desc
));
227 vb_desc
.dwSize
= sizeof(vb_desc
);
228 vb_desc
.dwFVF
= D3DFVF_XYZRHW
;
229 vb_desc
.dwNumVertices
= 3;
230 hr
= IDirect3D3_CreateVertexBuffer(d3d3
, &vb_desc
, &dst_vb
, 0, NULL
);
231 ok(SUCCEEDED(hr
), "Failed to create destination vertex buffer, hr %#x.\n", hr
);
233 hr
= IDirect3D3_CreateViewport(d3d3
, &viewport
, NULL
);
234 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
235 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
236 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
237 vp2
.dwSize
= sizeof(vp2
);
244 vp2
.dvClipWidth
= 4.0f
;
245 vp2
.dvClipHeight
= 5.0f
;
248 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2
);
249 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
250 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
251 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
253 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &identity
);
254 ok(SUCCEEDED(hr
), "Failed to set world transformation, hr %#x.\n", hr
);
255 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &identity
);
256 ok(SUCCEEDED(hr
), "Failed to set view transformation, hr %#x.\n", hr
);
257 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &identity
);
258 ok(SUCCEEDED(hr
), "Failed to set projection transformation, hr %#x.\n", hr
);
260 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
261 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
263 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
264 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
265 ok(compare_vec4(&dst_data
[0], -6.500e+1f
, +1.800e+2f
, +2.000e-1f
, +1.000e+0f
, 4096),
266 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
267 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
268 ok(compare_vec4(&dst_data
[1], -4.000e+1f
, +1.400e+2f
, +4.000e-1f
, +1.000e+0f
, 4096),
269 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
270 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
271 ok(compare_vec4(&dst_data
[2], -1.500e+1f
, +1.000e+2f
, +6.000e-1f
, +1.000e+0f
, 4096),
272 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
273 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
274 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
275 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
277 hr
= IDirect3DDevice3_MultiplyTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &projection
);
278 ok(SUCCEEDED(hr
), "Failed to set projection transformation, hr %#x.\n", hr
);
280 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
281 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
283 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
284 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
285 ok(compare_vec4(&dst_data
[0], +8.500e+1f
, -1.000e+2f
, +1.800e+0f
, +1.000e+0f
, 4096),
286 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
287 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
288 ok(compare_vec4(&dst_data
[1], +1.100e+2f
, -1.400e+2f
, +2.000e+0f
, +1.000e+0f
, 4096),
289 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
290 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
291 ok(compare_vec4(&dst_data
[2], +1.350e+2f
, -1.800e+2f
, +2.200e+0f
, +1.000e+0f
, 4096),
292 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
293 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
294 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
295 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
297 vp2
.dwSize
= sizeof(vp2
);
304 vp2
.dvClipWidth
= 2.0f
;
305 vp2
.dvClipHeight
= 4.0f
;
308 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2
);
309 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
311 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
312 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
314 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
315 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
316 ok(compare_vec4(&dst_data
[0], +7.500e+1f
, +4.000e+1f
, -8.000e-1f
, +1.000e+0f
, 4096),
317 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
318 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
319 ok(compare_vec4(&dst_data
[1], +1.200e+2f
, +2.000e+1f
, -1.000e+0f
, +1.000e+0f
, 4096),
320 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
321 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
322 ok(compare_vec4(&dst_data
[2], +1.650e+2f
, +0.000e+0f
, -1.200e+0f
, +1.000e+0f
, 4096),
323 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
324 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
325 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
326 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
328 vp1
.dwSize
= sizeof(vp1
);
339 hr
= IDirect3DViewport3_SetViewport(viewport
, &vp1
);
340 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
342 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
343 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
345 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
346 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
347 ok(compare_vec4(&dst_data
[0], +1.100e+2f
, +6.800e+1f
, +7.000e+0f
, +1.000e+0f
, 4096),
348 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
349 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
350 ok(compare_vec4(&dst_data
[1], +1.170e+2f
, +6.600e+1f
, +8.000e+0f
, +1.000e+0f
, 4096),
351 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
352 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
353 ok(compare_vec4(&dst_data
[2], +1.240e+2f
, +6.400e+1f
, +9.000e+0f
, +1.000e+0f
, 4096),
354 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
355 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
356 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
357 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
359 hr
= IDirect3DDevice3_DeleteViewport(device
, viewport
);
360 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
362 IDirect3DVertexBuffer_Release(dst_vb
);
363 IDirect3DVertexBuffer_Release(src_vb
);
364 IDirect3DViewport3_Release(viewport
);
365 IDirect3D3_Release(d3d3
);
366 IDirect3DDevice3_Release(device
);
367 DestroyWindow(window
);
370 static void test_coop_level_create_device_window(void)
372 HWND focus_window
, device_window
;
376 focus_window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
377 0, 0, 640, 480, 0, 0, 0, 0);
378 if (!(ddraw
= create_ddraw()))
380 skip("Failed to create a ddraw object, skipping test.\n");
381 DestroyWindow(focus_window
);
385 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
386 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
387 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
388 ok(!device_window
, "Unexpected device window found.\n");
389 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
390 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
391 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
392 ok(!device_window
, "Unexpected device window found.\n");
393 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
394 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
395 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
396 ok(!device_window
, "Unexpected device window found.\n");
397 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
398 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
399 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
400 ok(!device_window
, "Unexpected device window found.\n");
401 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
402 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
403 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
404 ok(!device_window
, "Unexpected device window found.\n");
406 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
407 if (broken(hr
== DDERR_INVALIDPARAMS
))
409 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
410 IDirectDraw4_Release(ddraw
);
411 DestroyWindow(focus_window
);
415 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
416 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
417 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
418 ok(!device_window
, "Unexpected device window found.\n");
419 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
420 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
421 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
422 ok(!device_window
, "Unexpected device window found.\n");
424 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
425 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
426 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
427 ok(!device_window
, "Unexpected device window found.\n");
428 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
429 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
430 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
431 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
432 ok(!!device_window
, "Device window not found.\n");
434 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
435 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
436 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
437 ok(!device_window
, "Unexpected device window found.\n");
438 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
439 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
440 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
441 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
442 ok(!!device_window
, "Device window not found.\n");
444 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
445 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
446 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
447 ok(!device_window
, "Unexpected device window found.\n");
448 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
449 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
450 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
451 ok(!device_window
, "Unexpected device window found.\n");
452 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
453 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
454 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
455 ok(!device_window
, "Unexpected device window found.\n");
456 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
457 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
458 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
459 ok(!!device_window
, "Device window not found.\n");
461 IDirectDraw4_Release(ddraw
);
462 DestroyWindow(focus_window
);
465 static void test_clipper_blt(void)
467 IDirectDrawSurface4
*src_surface
, *dst_surface
;
468 RECT client_rect
, src_rect
, *rect
;
469 IDirectDrawClipper
*clipper
;
470 DDSURFACEDESC2 surface_desc
;
471 unsigned int i
, j
, x
, y
;
481 static const D3DCOLOR expected1
[] =
483 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
484 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
485 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
486 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
488 static const D3DCOLOR expected2
[] =
490 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
491 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
492 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
493 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
496 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
497 10, 10, 640, 480, 0, 0, 0, 0);
498 ShowWindow(window
, SW_SHOW
);
499 if (!(ddraw
= create_ddraw()))
501 skip("Failed to create a ddraw object, skipping test.\n");
502 DestroyWindow(window
);
506 ret
= GetClientRect(window
, &client_rect
);
507 ok(ret
, "Failed to get client rect.\n");
508 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
509 ok(ret
, "Failed to map client rect.\n");
511 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
512 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
514 hr
= IDirectDraw4_CreateClipper(ddraw
, 0, &clipper
, NULL
);
515 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
516 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
517 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
518 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
519 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
520 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
521 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
522 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
523 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
524 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
525 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
526 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
527 ok(rgn_data
->rdh
.nCount
== 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
528 ok(rgn_data
->rdh
.nRgnSize
== 16, "Got unexpected region size %u.\n", rgn_data
->rdh
.nRgnSize
);
529 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
530 "Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
531 rgn_data
->rdh
.rcBound
.left
, rgn_data
->rdh
.rcBound
.top
,
532 rgn_data
->rdh
.rcBound
.right
, rgn_data
->rdh
.rcBound
.bottom
,
533 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
534 rect
= (RECT
*)&rgn_data
->Buffer
[0];
535 ok(EqualRect(rect
, &client_rect
),
536 "Got unexpected clip rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
537 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
,
538 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
539 HeapFree(GetProcessHeap(), 0, rgn_data
);
541 r1
= CreateRectRgn(0, 0, 320, 240);
542 ok(!!r1
, "Failed to create region.\n");
543 r2
= CreateRectRgn(320, 240, 640, 480);
544 ok(!!r2
, "Failed to create region.\n");
545 CombineRgn(r1
, r1
, r2
, RGN_OR
);
546 ret
= GetRegionData(r1
, 0, NULL
);
547 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
548 ret
= GetRegionData(r1
, ret
, rgn_data
);
549 ok(!!ret
, "Failed to get region data.\n");
554 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
555 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
556 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
557 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
558 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
559 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
561 HeapFree(GetProcessHeap(), 0, rgn_data
);
563 memset(&surface_desc
, 0, sizeof(surface_desc
));
564 surface_desc
.dwSize
= sizeof(surface_desc
);
565 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
566 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
567 surface_desc
.dwWidth
= 640;
568 surface_desc
.dwHeight
= 480;
569 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
570 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
571 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
572 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
573 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
574 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
576 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
577 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
578 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
579 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
581 memset(&fx
, 0, sizeof(fx
));
582 fx
.dwSize
= sizeof(fx
);
583 hr
= IDirectDrawSurface4_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
584 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
585 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
586 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
588 hr
= IDirectDrawSurface4_Lock(src_surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
589 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
590 ((DWORD
*)surface_desc
.lpSurface
)[0] = 0xff0000ff;
591 ((DWORD
*)surface_desc
.lpSurface
)[1] = 0xff00ff00;
592 ((DWORD
*)surface_desc
.lpSurface
)[2] = 0xffff0000;
593 ((DWORD
*)surface_desc
.lpSurface
)[3] = 0xffffffff;
594 hr
= IDirectDrawSurface4_Unlock(src_surface
, NULL
);
595 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
597 hr
= IDirectDrawSurface4_SetClipper(dst_surface
, clipper
);
598 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
600 SetRect(&src_rect
, 0, 0, 4, 1);
601 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
602 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
603 for (i
= 0; i
< 4; ++i
)
605 for (j
= 0; j
< 4; ++j
)
607 x
= 80 * ((2 * j
) + 1);
608 y
= 60 * ((2 * i
) + 1);
609 color
= get_surface_color(dst_surface
, x
, y
);
610 ok(compare_color(color
, expected1
[i
* 4 + j
], 1),
611 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
615 U5(fx
).dwFillColor
= 0xff0000ff;
616 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
617 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
618 for (i
= 0; i
< 4; ++i
)
620 for (j
= 0; j
< 4; ++j
)
622 x
= 80 * ((2 * j
) + 1);
623 y
= 60 * ((2 * i
) + 1);
624 color
= get_surface_color(dst_surface
, x
, y
);
625 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
626 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
630 hr
= IDirectDrawSurface4_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
631 ok(hr
== DDERR_BLTFASTCANTCLIP
, "Got unexpected hr %#x.\n", hr
);
633 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
634 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
635 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
636 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
637 DestroyWindow(window
);
638 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
639 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
640 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
641 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
642 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
643 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
644 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
645 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
646 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
647 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
648 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
649 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
651 IDirectDrawSurface4_Release(dst_surface
);
652 IDirectDrawSurface4_Release(src_surface
);
653 IDirectDrawClipper_Release(clipper
);
654 IDirectDraw4_Release(ddraw
);
659 test_process_vertices();
660 test_coop_level_create_device_window();