2 * Copyright (c) 1998 Lionel ULMER
4 * This file contains the implementation of Direct3DViewport2.
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
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
35 #include "wine/debug.h"
37 #include "d3d_private.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
41 static void activate(IDirect3DViewportImpl
* This
) {
42 IDirect3DLightImpl
* light
;
45 /* Activate all the lights associated with this context */
48 while (light
!= NULL
) {
49 light
->activate(light
);
53 /* And copy the values in the structure used by the device */
55 vp
.dwX
= This
->viewports
.vp2
.dwX
;
56 vp
.dwY
= This
->viewports
.vp2
.dwY
;
57 vp
.dwHeight
= This
->viewports
.vp2
.dwHeight
;
58 vp
.dwWidth
= This
->viewports
.vp2
.dwWidth
;
59 vp
.dvMinZ
= This
->viewports
.vp2
.dvMinZ
;
60 vp
.dvMaxZ
= This
->viewports
.vp2
.dvMaxZ
;
62 vp
.dwX
= This
->viewports
.vp1
.dwX
;
63 vp
.dwY
= This
->viewports
.vp1
.dwY
;
64 vp
.dwHeight
= This
->viewports
.vp1
.dwHeight
;
65 vp
.dwWidth
= This
->viewports
.vp1
.dwWidth
;
66 vp
.dvMinZ
= This
->viewports
.vp1
.dvMinZ
;
67 vp
.dvMaxZ
= This
->viewports
.vp1
.dvMaxZ
;
70 /* And also set the viewport */
71 IDirect3DDevice7_SetViewport(ICOM_INTERFACE(This
->active_device
, IDirect3DDevice7
), &vp
);
75 static void _dump_D3DVIEWPORT(D3DVIEWPORT
*lpvp
)
77 TRACE(" - dwSize = %ld dwX = %ld dwY = %ld\n",
78 lpvp
->dwSize
, lpvp
->dwX
, lpvp
->dwY
);
79 TRACE(" - dwWidth = %ld dwHeight = %ld\n",
80 lpvp
->dwWidth
, lpvp
->dwHeight
);
81 TRACE(" - dvScaleX = %f dvScaleY = %f\n",
82 lpvp
->dvScaleX
, lpvp
->dvScaleY
);
83 TRACE(" - dvMaxX = %f dvMaxY = %f\n",
84 lpvp
->dvMaxX
, lpvp
->dvMaxY
);
85 TRACE(" - dvMinZ = %f dvMaxZ = %f\n",
86 lpvp
->dvMinZ
, lpvp
->dvMaxZ
);
89 static void _dump_D3DVIEWPORT2(D3DVIEWPORT2
*lpvp
)
91 TRACE(" - dwSize = %ld dwX = %ld dwY = %ld\n",
92 lpvp
->dwSize
, lpvp
->dwX
, lpvp
->dwY
);
93 TRACE(" - dwWidth = %ld dwHeight = %ld\n",
94 lpvp
->dwWidth
, lpvp
->dwHeight
);
95 TRACE(" - dvClipX = %f dvClipY = %f\n",
96 lpvp
->dvClipX
, lpvp
->dvClipY
);
97 TRACE(" - dvClipWidth = %f dvClipHeight = %f\n",
98 lpvp
->dvClipWidth
, lpvp
->dvClipHeight
);
99 TRACE(" - dvMinZ = %f dvMaxZ = %f\n",
100 lpvp
->dvMinZ
, lpvp
->dvMaxZ
);
104 Main_IDirect3DViewportImpl_3_2_1_QueryInterface(LPDIRECT3DVIEWPORT3 iface
,
108 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
109 TRACE("(%p/%p)->(%s,%p)\n", This
, iface
, debugstr_guid(riid
), obp
);
113 if ( IsEqualGUID(&IID_IUnknown
, riid
) ||
114 IsEqualGUID(&IID_IDirect3DViewport
, riid
) ||
115 IsEqualGUID(&IID_IDirect3DViewport2
, riid
) ||
116 IsEqualGUID(&IID_IDirect3DViewport3
, riid
) ) {
117 IDirect3DViewport3_AddRef(ICOM_INTERFACE(This
, IDirect3DViewport3
));
118 *obp
= ICOM_INTERFACE(This
, IDirect3DViewport3
);
119 TRACE(" Creating IDirect3DViewport1/2/3 interface %p\n", *obp
);
122 FIXME("(%p): interface for IID %s NOT found!\n", This
, debugstr_guid(riid
));
123 return OLE_E_ENUM_NOMORE
;
127 Main_IDirect3DViewportImpl_3_2_1_AddRef(LPDIRECT3DVIEWPORT3 iface
)
129 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
130 ULONG ref
= InterlockedIncrement(&This
->ref
);
132 TRACE("(%p/%p)->() incrementing from %lu.\n", This
, iface
, ref
- 1);
138 Main_IDirect3DViewportImpl_3_2_1_Release(LPDIRECT3DVIEWPORT3 iface
)
140 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
141 ULONG ref
= InterlockedDecrement(&This
->ref
);
143 TRACE("(%p/%p)->() decrementing from %lu.\n", This
, iface
, ref
+ 1);
146 HeapFree(GetProcessHeap(), 0, This
);
154 Main_IDirect3DViewportImpl_3_2_1_Initialize(LPDIRECT3DVIEWPORT3 iface
,
155 LPDIRECT3D lpDirect3D
)
157 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
158 TRACE("(%p/%p)->(%p) no-op...\n", This
, iface
, lpDirect3D
);
163 Main_IDirect3DViewportImpl_3_2_1_GetViewport(LPDIRECT3DVIEWPORT3 iface
,
164 LPD3DVIEWPORT lpData
)
166 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
168 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpData
);
169 if (This
->use_vp2
!= 0) {
170 ERR(" Requesting to get a D3DVIEWPORT struct where a D3DVIEWPORT2 was set !\n");
171 return DDERR_INVALIDPARAMS
;
173 dwSize
= lpData
->dwSize
;
174 memset(lpData
, 0, dwSize
);
175 memcpy(lpData
, &(This
->viewports
.vp1
), dwSize
);
177 if (TRACE_ON(ddraw
)) {
178 TRACE(" returning D3DVIEWPORT :\n");
179 _dump_D3DVIEWPORT(lpData
);
186 Main_IDirect3DViewportImpl_3_2_1_SetViewport(LPDIRECT3DVIEWPORT3 iface
,
187 LPD3DVIEWPORT lpData
)
189 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
190 LPDIRECT3DVIEWPORT3 current_viewport
;
191 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpData
);
193 if (TRACE_ON(ddraw
)) {
194 TRACE(" getting D3DVIEWPORT :\n");
195 _dump_D3DVIEWPORT(lpData
);
199 memset(&(This
->viewports
.vp1
), 0, sizeof(This
->viewports
.vp1
));
200 memcpy(&(This
->viewports
.vp1
), lpData
, lpData
->dwSize
);
202 /* Tests on two games show that these values are never used properly so override
203 them with proper ones :-)
205 This
->viewports
.vp1
.dvMinZ
= 0.0;
206 This
->viewports
.vp1
.dvMaxZ
= 1.0;
208 if (This
->active_device
) {
209 IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This
->active_device
, IDirect3DDevice3
), ¤t_viewport
);
210 if (ICOM_OBJECT(IDirect3DViewportImpl
, IDirect3DViewport3
, current_viewport
) == This
)
211 This
->activate(This
);
212 IDirect3DViewport3_Release(current_viewport
);
219 Main_IDirect3DViewportImpl_3_2_1_TransformVertices(LPDIRECT3DVIEWPORT3 iface
,
221 LPD3DTRANSFORMDATA lpData
,
225 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
226 FIXME("(%p/%p)->(%08lx,%p,%08lx,%p): stub!\n", This
, iface
, dwVertexCount
, lpData
, dwFlags
, lpOffScreen
);
233 Main_IDirect3DViewportImpl_3_2_1_LightElements(LPDIRECT3DVIEWPORT3 iface
,
234 DWORD dwElementCount
,
235 LPD3DLIGHTDATA lpData
)
237 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
238 FIXME("(%p/%p)->(%08lx,%p): stub!\n", This
, iface
, dwElementCount
, lpData
);
243 Main_IDirect3DViewportImpl_3_2_1_SetBackground(LPDIRECT3DVIEWPORT3 iface
,
244 D3DMATERIALHANDLE hMat
)
246 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
247 TRACE("(%p/%p)->(%08lx)\n", This
, iface
, (DWORD
) hMat
);
249 This
->background
= (IDirect3DMaterialImpl
*) hMat
;
250 TRACE(" setting background color : %f %f %f %f\n",
251 This
->background
->mat
.u
.diffuse
.u1
.r
,
252 This
->background
->mat
.u
.diffuse
.u2
.g
,
253 This
->background
->mat
.u
.diffuse
.u3
.b
,
254 This
->background
->mat
.u
.diffuse
.u4
.a
);
260 Main_IDirect3DViewportImpl_3_2_1_GetBackground(LPDIRECT3DVIEWPORT3 iface
,
261 LPD3DMATERIALHANDLE lphMat
,
264 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
265 FIXME("(%p/%p)->(%p,%p): stub!\n", This
, iface
, lphMat
, lpValid
);
270 Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface
,
271 LPDIRECTDRAWSURFACE lpDDSurface
)
273 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
274 FIXME("(%p/%p)->(%p): stub!\n", This
, iface
, lpDDSurface
);
279 Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface
,
280 LPDIRECTDRAWSURFACE
* lplpDDSurface
,
283 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
284 FIXME("(%p/%p)->(%p,%p): stub!\n", This
, iface
, lplpDDSurface
, lpValid
);
289 Main_IDirect3DViewportImpl_3_2_1_Clear(LPDIRECT3DVIEWPORT3 iface
,
294 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
295 DWORD color
= 0x00000000;
297 TRACE("(%p/%p)->(%08lx,%p,%08lx)\n", This
, iface
, dwCount
, lpRects
, dwFlags
);
298 if (This
->active_device
== NULL
) {
299 ERR(" Trying to clear a viewport not attached to a device !\n");
300 return D3DERR_VIEWPORTHASNODEVICE
;
302 if (dwFlags
& D3DCLEAR_TARGET
) {
303 if (This
->background
== NULL
) {
304 ERR(" Trying to clear the color buffer without background material !\n");
307 ((int) ((This
->background
->mat
.u
.diffuse
.u1
.r
) * 255) << 16) |
308 ((int) ((This
->background
->mat
.u
.diffuse
.u2
.g
) * 255) << 8) |
309 ((int) ((This
->background
->mat
.u
.diffuse
.u3
.b
) * 255) << 0) |
310 ((int) ((This
->background
->mat
.u
.diffuse
.u4
.a
) * 255) << 24);
313 return This
->active_device
->clear(This
->active_device
, dwCount
, lpRects
,
314 dwFlags
& (D3DCLEAR_ZBUFFER
| D3DCLEAR_TARGET
),
315 color
, 1.0, 0x00000000);
319 Main_IDirect3DViewportImpl_3_2_1_AddLight(LPDIRECT3DVIEWPORT3 iface
,
320 LPDIRECT3DLIGHT lpDirect3DLight
)
322 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
323 IDirect3DLightImpl
*lpDirect3DLightImpl
= ICOM_OBJECT(IDirect3DLightImpl
, IDirect3DLight
, lpDirect3DLight
);
325 DWORD map
= This
->map_lights
;
327 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpDirect3DLight
);
329 if (This
->num_lights
>= 8)
330 return DDERR_INVALIDPARAMS
;
332 /* Find a light number and update both light and viewports objects accordingly */
337 lpDirect3DLightImpl
->dwLightIndex
= i
;
339 This
->map_lights
|= 1<<i
;
341 /* Add the light in the 'linked' chain */
342 lpDirect3DLightImpl
->next
= This
->lights
;
343 This
->lights
= lpDirect3DLightImpl
;
345 /* Attach the light to the viewport */
346 lpDirect3DLightImpl
->active_viewport
= This
;
348 /* If active, activate the light */
349 if (This
->active_device
!= NULL
) {
350 lpDirect3DLightImpl
->activate(lpDirect3DLightImpl
);
357 Main_IDirect3DViewportImpl_3_2_1_DeleteLight(LPDIRECT3DVIEWPORT3 iface
,
358 LPDIRECT3DLIGHT lpDirect3DLight
)
360 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
361 IDirect3DLightImpl
*lpDirect3DLightImpl
= ICOM_OBJECT(IDirect3DLightImpl
, IDirect3DLight
, lpDirect3DLight
);
362 IDirect3DLightImpl
*cur_light
, *prev_light
= NULL
;
364 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpDirect3DLight
);
365 cur_light
= This
->lights
;
366 while (cur_light
!= NULL
) {
367 if (cur_light
== lpDirect3DLightImpl
) {
368 lpDirect3DLightImpl
->desactivate(lpDirect3DLightImpl
);
369 if (prev_light
== NULL
) This
->lights
= cur_light
->next
;
370 else prev_light
->next
= cur_light
->next
;
371 /* Detach the light to the viewport */
372 cur_light
->active_viewport
= NULL
;
374 This
->map_lights
&= ~(1<<lpDirect3DLightImpl
->dwLightIndex
);
377 prev_light
= cur_light
;
378 cur_light
= cur_light
->next
;
380 return DDERR_INVALIDPARAMS
;
384 Main_IDirect3DViewportImpl_3_2_1_NextLight(LPDIRECT3DVIEWPORT3 iface
,
385 LPDIRECT3DLIGHT lpDirect3DLight
,
386 LPDIRECT3DLIGHT
* lplpDirect3DLight
,
389 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
390 FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This
, iface
, lpDirect3DLight
, lplpDirect3DLight
, dwFlags
);
395 Main_IDirect3DViewportImpl_3_2_GetViewport2(LPDIRECT3DVIEWPORT3 iface
,
396 LPD3DVIEWPORT2 lpData
)
398 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
400 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpData
);
401 if (This
->use_vp2
!= 1) {
402 ERR(" Requesting to get a D3DVIEWPORT2 struct where a D3DVIEWPORT was set !\n");
403 return DDERR_INVALIDPARAMS
;
405 dwSize
= lpData
->dwSize
;
406 memset(lpData
, 0, dwSize
);
407 memcpy(lpData
, &(This
->viewports
.vp2
), dwSize
);
409 if (TRACE_ON(ddraw
)) {
410 TRACE(" returning D3DVIEWPORT2 :\n");
411 _dump_D3DVIEWPORT2(lpData
);
418 Main_IDirect3DViewportImpl_3_2_SetViewport2(LPDIRECT3DVIEWPORT3 iface
,
419 LPD3DVIEWPORT2 lpData
)
421 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
422 LPDIRECT3DVIEWPORT3 current_viewport
;
423 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpData
);
425 if (TRACE_ON(ddraw
)) {
426 TRACE(" getting D3DVIEWPORT2 :\n");
427 _dump_D3DVIEWPORT2(lpData
);
431 memset(&(This
->viewports
.vp2
), 0, sizeof(This
->viewports
.vp2
));
432 memcpy(&(This
->viewports
.vp2
), lpData
, lpData
->dwSize
);
434 if (This
->active_device
) {
435 IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This
->active_device
, IDirect3DDevice3
), ¤t_viewport
);
436 if (ICOM_OBJECT(IDirect3DViewportImpl
, IDirect3DViewport3
, current_viewport
) == This
)
437 This
->activate(This
);
438 IDirect3DViewport3_Release(current_viewport
);
445 Main_IDirect3DViewportImpl_3_SetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface
,
446 LPDIRECTDRAWSURFACE4 lpDDS
)
448 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
449 FIXME("(%p/%p)->(%p): stub!\n", This
, iface
, lpDDS
);
454 Main_IDirect3DViewportImpl_3_GetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface
,
455 LPDIRECTDRAWSURFACE4
* lplpDDS
,
458 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
459 FIXME("(%p/%p)->(%p,%p): stub!\n", This
, iface
, lplpDDS
, lpValid
);
464 Main_IDirect3DViewportImpl_3_Clear2(LPDIRECT3DVIEWPORT3 iface
,
472 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
473 TRACE("(%p/%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This
, iface
, dwCount
, lpRects
, dwFlags
, dwColor
, dvZ
, dwStencil
);
474 if (This
->active_device
== NULL
) {
475 ERR(" Trying to clear a viewport not attached to a device !\n");
476 return D3DERR_VIEWPORTHASNODEVICE
;
478 return This
->active_device
->clear(This
->active_device
, dwCount
, lpRects
, dwFlags
, dwColor
, dvZ
, dwStencil
);
481 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
482 # define XCAST(fun) (typeof(VTABLE_IDirect3DViewport3.fun))
484 # define XCAST(fun) (void*)
487 static const IDirect3DViewport3Vtbl VTABLE_IDirect3DViewport3
=
489 XCAST(QueryInterface
) Main_IDirect3DViewportImpl_3_2_1_QueryInterface
,
490 XCAST(AddRef
) Main_IDirect3DViewportImpl_3_2_1_AddRef
,
491 XCAST(Release
) Main_IDirect3DViewportImpl_3_2_1_Release
,
492 XCAST(Initialize
) Main_IDirect3DViewportImpl_3_2_1_Initialize
,
493 XCAST(GetViewport
) Main_IDirect3DViewportImpl_3_2_1_GetViewport
,
494 XCAST(SetViewport
) Main_IDirect3DViewportImpl_3_2_1_SetViewport
,
495 XCAST(TransformVertices
) Main_IDirect3DViewportImpl_3_2_1_TransformVertices
,
496 XCAST(LightElements
) Main_IDirect3DViewportImpl_3_2_1_LightElements
,
497 XCAST(SetBackground
) Main_IDirect3DViewportImpl_3_2_1_SetBackground
,
498 XCAST(GetBackground
) Main_IDirect3DViewportImpl_3_2_1_GetBackground
,
499 XCAST(SetBackgroundDepth
) Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth
,
500 XCAST(GetBackgroundDepth
) Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth
,
501 XCAST(Clear
) Main_IDirect3DViewportImpl_3_2_1_Clear
,
502 XCAST(AddLight
) Main_IDirect3DViewportImpl_3_2_1_AddLight
,
503 XCAST(DeleteLight
) Main_IDirect3DViewportImpl_3_2_1_DeleteLight
,
504 XCAST(NextLight
) Main_IDirect3DViewportImpl_3_2_1_NextLight
,
505 XCAST(GetViewport2
) Main_IDirect3DViewportImpl_3_2_GetViewport2
,
506 XCAST(SetViewport2
) Main_IDirect3DViewportImpl_3_2_SetViewport2
,
507 XCAST(SetBackgroundDepth2
) Main_IDirect3DViewportImpl_3_SetBackgroundDepth2
,
508 XCAST(GetBackgroundDepth2
) Main_IDirect3DViewportImpl_3_GetBackgroundDepth2
,
509 XCAST(Clear2
) Main_IDirect3DViewportImpl_3_Clear2
,
512 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
519 HRESULT
d3dviewport_create(IDirect3DViewportImpl
**obj
, IDirectDrawImpl
*d3d
)
521 IDirect3DViewportImpl
*object
;
523 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DViewportImpl
));
524 if (object
== NULL
) return DDERR_OUTOFMEMORY
;
528 object
->activate
= activate
;
529 object
->use_vp2
= 0xFF;
531 object
->lights
= NULL
;
532 object
->num_lights
= 0;
533 object
->map_lights
= 0;
535 ICOM_INIT_INTERFACE(object
, IDirect3DViewport3
, VTABLE_IDirect3DViewport3
);
539 TRACE(" creating implementation at %p.\n", *obj
);