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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #define NONAMELESSUNION
22 #define NONAMELESSSTRUCT
29 #include "wine/debug.h"
31 #include "d3d_private.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
35 static void activate(IDirect3DViewportImpl
* This
) {
36 IDirect3DLightImpl
* light
;
38 /* Activate all the lights associated with this context */
41 while (light
!= NULL
) {
42 light
->activate(light
);
48 static void _dump_D3DVIEWPORT(D3DVIEWPORT
*lpvp
)
50 TRACE(" - dwSize = %ld dwX = %ld dwY = %ld\n",
51 lpvp
->dwSize
, lpvp
->dwX
, lpvp
->dwY
);
52 TRACE(" - dwWidth = %ld dwHeight = %ld\n",
53 lpvp
->dwWidth
, lpvp
->dwHeight
);
54 TRACE(" - dvScaleX = %f dvScaleY = %f\n",
55 lpvp
->dvScaleX
, lpvp
->dvScaleY
);
56 TRACE(" - dvMaxX = %f dvMaxY = %f\n",
57 lpvp
->dvMaxX
, lpvp
->dvMaxY
);
58 TRACE(" - dvMinZ = %f dvMaxZ = %f\n",
59 lpvp
->dvMinZ
, lpvp
->dvMaxZ
);
62 static void _dump_D3DVIEWPORT2(D3DVIEWPORT2
*lpvp
)
64 TRACE(" - dwSize = %ld dwX = %ld dwY = %ld\n",
65 lpvp
->dwSize
, lpvp
->dwX
, lpvp
->dwY
);
66 TRACE(" - dwWidth = %ld dwHeight = %ld\n",
67 lpvp
->dwWidth
, lpvp
->dwHeight
);
68 TRACE(" - dvClipX = %f dvClipY = %f\n",
69 lpvp
->dvClipX
, lpvp
->dvClipY
);
70 TRACE(" - dvClipWidth = %f dvClipHeight = %f\n",
71 lpvp
->dvClipWidth
, lpvp
->dvClipHeight
);
72 TRACE(" - dvMinZ = %f dvMaxZ = %f\n",
73 lpvp
->dvMinZ
, lpvp
->dvMaxZ
);
77 Main_IDirect3DViewportImpl_3_2_1_QueryInterface(LPDIRECT3DVIEWPORT3 iface
,
81 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
82 TRACE("(%p/%p)->(%s,%p)\n", This
, iface
, debugstr_guid(riid
), obp
);
86 if ( IsEqualGUID(&IID_IUnknown
, riid
) ||
87 IsEqualGUID(&IID_IDirect3DViewport
, riid
) ||
88 IsEqualGUID(&IID_IDirect3DViewport2
, riid
) ||
89 IsEqualGUID(&IID_IDirect3DViewport3
, riid
) ) {
90 IDirect3DViewport3_AddRef(ICOM_INTERFACE(This
, IDirect3DViewport3
));
91 *obp
= ICOM_INTERFACE(This
, IDirect3DViewport3
);
92 TRACE(" Creating IDirect3DViewport1/2/3 interface %p\n", *obp
);
95 FIXME("(%p): interface for IID %s NOT found!\n", This
, debugstr_guid(riid
));
96 return OLE_E_ENUM_NOMORE
;
100 Main_IDirect3DViewportImpl_3_2_1_AddRef(LPDIRECT3DVIEWPORT3 iface
)
102 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
103 TRACE("(%p/%p)->() incrementing from %lu.\n", This
, iface
, This
->ref
);
104 return ++(This
->ref
);
108 Main_IDirect3DViewportImpl_3_2_1_Release(LPDIRECT3DVIEWPORT3 iface
)
110 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
111 TRACE("(%p/%p)->() decrementing from %lu.\n", This
, iface
, This
->ref
);
112 if (!--(This
->ref
)) {
113 HeapFree(GetProcessHeap(), 0, This
);
121 Main_IDirect3DViewportImpl_3_2_1_Initialize(LPDIRECT3DVIEWPORT3 iface
,
122 LPDIRECT3D lpDirect3D
)
124 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
125 TRACE("(%p/%p)->(%p) no-op...\n", This
, iface
, lpDirect3D
);
130 Main_IDirect3DViewportImpl_3_2_1_GetViewport(LPDIRECT3DVIEWPORT3 iface
,
131 LPD3DVIEWPORT lpData
)
133 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
135 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpData
);
136 if (This
->use_vp2
!= 0) {
137 ERR(" Requesting to get a D3DVIEWPORT struct where a D3DVIEWPORT2 was set !\n");
138 return DDERR_INVALIDPARAMS
;
140 dwSize
= lpData
->dwSize
;
141 memset(lpData
, 0, dwSize
);
142 memcpy(lpData
, &(This
->viewports
.vp1
), dwSize
);
144 if (TRACE_ON(ddraw
)) {
145 TRACE(" returning D3DVIEWPORT :\n");
146 _dump_D3DVIEWPORT(lpData
);
153 Main_IDirect3DViewportImpl_3_2_1_SetViewport(LPDIRECT3DVIEWPORT3 iface
,
154 LPD3DVIEWPORT lpData
)
156 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
157 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpData
);
159 if (TRACE_ON(ddraw
)) {
160 TRACE(" getting D3DVIEWPORT :\n");
161 _dump_D3DVIEWPORT(lpData
);
165 memset(&(This
->viewports
.vp1
), 0, sizeof(This
->viewports
.vp1
));
166 memcpy(&(This
->viewports
.vp1
), lpData
, lpData
->dwSize
);
171 Main_IDirect3DViewportImpl_3_2_1_TransformVertices(LPDIRECT3DVIEWPORT3 iface
,
173 LPD3DTRANSFORMDATA lpData
,
177 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
178 FIXME("(%p/%p)->(%08lx,%p,%08lx,%p): stub!\n", This
, iface
, dwVertexCount
, lpData
, dwFlags
, lpOffScreen
);
183 Main_IDirect3DViewportImpl_3_2_1_LightElements(LPDIRECT3DVIEWPORT3 iface
,
184 DWORD dwElementCount
,
185 LPD3DLIGHTDATA lpData
)
187 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
188 FIXME("(%p/%p)->(%08lx,%p): stub!\n", This
, iface
, dwElementCount
, lpData
);
193 Main_IDirect3DViewportImpl_3_2_1_SetBackground(LPDIRECT3DVIEWPORT3 iface
,
194 D3DMATERIALHANDLE hMat
)
196 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
197 TRACE("(%p/%p)->(%08lx)\n", This
, iface
, (DWORD
) hMat
);
199 This
->background
= (IDirect3DMaterialImpl
*) hMat
;
200 TRACE(" setting background color : %f %f %f %f\n",
201 This
->background
->mat
.u
.diffuse
.u1
.r
,
202 This
->background
->mat
.u
.diffuse
.u2
.g
,
203 This
->background
->mat
.u
.diffuse
.u3
.b
,
204 This
->background
->mat
.u
.diffuse
.u4
.a
);
210 Main_IDirect3DViewportImpl_3_2_1_GetBackground(LPDIRECT3DVIEWPORT3 iface
,
211 LPD3DMATERIALHANDLE lphMat
,
214 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
215 FIXME("(%p/%p)->(%p,%p): stub!\n", This
, iface
, lphMat
, lpValid
);
220 Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface
,
221 LPDIRECTDRAWSURFACE lpDDSurface
)
223 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
224 FIXME("(%p/%p)->(%p): stub!\n", This
, iface
, lpDDSurface
);
229 Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface
,
230 LPDIRECTDRAWSURFACE
* lplpDDSurface
,
233 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
234 FIXME("(%p/%p)->(%p,%p): stub!\n", This
, iface
, lplpDDSurface
, lpValid
);
239 Main_IDirect3DViewportImpl_3_2_1_Clear(LPDIRECT3DVIEWPORT3 iface
,
244 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
245 DWORD color
= 0x00000000;
247 TRACE("(%p/%p)->(%08lx,%p,%08lx)\n", This
, iface
, dwCount
, lpRects
, dwFlags
);
248 if (This
->active_device
== NULL
) {
249 ERR(" Trying to clear a viewport not attached to a device !\n");
250 return D3DERR_VIEWPORTHASNODEVICE
;
252 if (dwFlags
& D3DCLEAR_TARGET
) {
253 if (This
->background
== NULL
) {
254 ERR(" Trying to clear the color buffer without background material !\n");
257 ((int) ((This
->background
->mat
.u
.diffuse
.u1
.r
) * 255) << 16) |
258 ((int) ((This
->background
->mat
.u
.diffuse
.u2
.g
) * 255) << 8) |
259 ((int) ((This
->background
->mat
.u
.diffuse
.u3
.b
) * 255) << 0) |
260 ((int) ((This
->background
->mat
.u
.diffuse
.u4
.a
) * 255) << 24);
263 return This
->active_device
->clear(This
->active_device
, dwCount
, lpRects
,
264 dwFlags
& (D3DCLEAR_ZBUFFER
| D3DCLEAR_TARGET
),
265 color
, 1.0, 0x00000000);
269 Main_IDirect3DViewportImpl_3_2_1_AddLight(LPDIRECT3DVIEWPORT3 iface
,
270 LPDIRECT3DLIGHT lpDirect3DLight
)
272 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
273 IDirect3DLightImpl
*lpDirect3DLightImpl
= ICOM_OBJECT(IDirect3DLightImpl
, IDirect3DLight
, lpDirect3DLight
);
275 DWORD map
= This
->map_lights
;
277 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpDirect3DLight
);
279 if (This
->num_lights
>= 8)
280 return DDERR_INVALIDPARAMS
;
282 /* Find a light number and update both light and viewports objects accordingly */
287 lpDirect3DLightImpl
->dwLightIndex
= i
;
289 This
->map_lights
|= 1<<i
;
291 /* Add the light in the 'linked' chain */
292 lpDirect3DLightImpl
->next
= This
->lights
;
293 This
->lights
= lpDirect3DLightImpl
;
295 /* Attach the light to the viewport */
296 lpDirect3DLightImpl
->active_viewport
= This
;
298 /* If active, activate the light */
299 if (This
->active_device
!= NULL
) {
300 lpDirect3DLightImpl
->activate(lpDirect3DLightImpl
);
307 Main_IDirect3DViewportImpl_3_2_1_DeleteLight(LPDIRECT3DVIEWPORT3 iface
,
308 LPDIRECT3DLIGHT lpDirect3DLight
)
310 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
311 IDirect3DLightImpl
*lpDirect3DLightImpl
= ICOM_OBJECT(IDirect3DLightImpl
, IDirect3DLight
, lpDirect3DLight
);
312 IDirect3DLightImpl
*cur_light
, *prev_light
= NULL
;
314 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpDirect3DLight
);
315 cur_light
= This
->lights
;
316 while (cur_light
!= NULL
) {
317 if (cur_light
== lpDirect3DLightImpl
) {
318 lpDirect3DLightImpl
->desactivate(lpDirect3DLightImpl
);
319 if (prev_light
== NULL
) This
->lights
= cur_light
->next
;
320 else prev_light
->next
= cur_light
->next
;
321 /* Detach the light to the viewport */
322 cur_light
->active_viewport
= NULL
;
324 This
->map_lights
&= ~(1<<lpDirect3DLightImpl
->dwLightIndex
);
327 prev_light
= cur_light
;
328 cur_light
= cur_light
->next
;
330 return DDERR_INVALIDPARAMS
;
334 Main_IDirect3DViewportImpl_3_2_1_NextLight(LPDIRECT3DVIEWPORT3 iface
,
335 LPDIRECT3DLIGHT lpDirect3DLight
,
336 LPDIRECT3DLIGHT
* lplpDirect3DLight
,
339 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
340 FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This
, iface
, lpDirect3DLight
, lplpDirect3DLight
, dwFlags
);
345 Main_IDirect3DViewportImpl_3_2_GetViewport2(LPDIRECT3DVIEWPORT3 iface
,
346 LPD3DVIEWPORT2 lpData
)
348 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
350 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpData
);
351 if (This
->use_vp2
!= 1) {
352 ERR(" Requesting to get a D3DVIEWPORT2 struct where a D3DVIEWPORT was set !\n");
353 return DDERR_INVALIDPARAMS
;
355 dwSize
= lpData
->dwSize
;
356 memset(lpData
, 0, dwSize
);
357 memcpy(lpData
, &(This
->viewports
.vp2
), dwSize
);
359 if (TRACE_ON(ddraw
)) {
360 TRACE(" returning D3DVIEWPORT2 :\n");
361 _dump_D3DVIEWPORT2(lpData
);
368 Main_IDirect3DViewportImpl_3_2_SetViewport2(LPDIRECT3DVIEWPORT3 iface
,
369 LPD3DVIEWPORT2 lpData
)
371 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
372 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpData
);
374 if (TRACE_ON(ddraw
)) {
375 TRACE(" getting D3DVIEWPORT2 :\n");
376 _dump_D3DVIEWPORT2(lpData
);
380 memset(&(This
->viewports
.vp2
), 0, sizeof(This
->viewports
.vp2
));
381 memcpy(&(This
->viewports
.vp2
), lpData
, lpData
->dwSize
);
386 Main_IDirect3DViewportImpl_3_SetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface
,
387 LPDIRECTDRAWSURFACE4 lpDDS
)
389 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
390 FIXME("(%p/%p)->(%p): stub!\n", This
, iface
, lpDDS
);
395 Main_IDirect3DViewportImpl_3_GetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface
,
396 LPDIRECTDRAWSURFACE4
* lplpDDS
,
399 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
400 FIXME("(%p/%p)->(%p,%p): stub!\n", This
, iface
, lplpDDS
, lpValid
);
405 Main_IDirect3DViewportImpl_3_Clear2(LPDIRECT3DVIEWPORT3 iface
,
413 ICOM_THIS_FROM(IDirect3DViewportImpl
, IDirect3DViewport3
, iface
);
414 TRACE("(%p/%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This
, iface
, dwCount
, lpRects
, dwFlags
, dwColor
, dvZ
, dwStencil
);
415 if (This
->active_device
== NULL
) {
416 ERR(" Trying to clear a viewport not attached to a device !\n");
417 return D3DERR_VIEWPORTHASNODEVICE
;
419 return This
->active_device
->clear(This
->active_device
, dwCount
, lpRects
, dwFlags
, dwColor
, dvZ
, dwStencil
);
422 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
423 # define XCAST(fun) (typeof(VTABLE_IDirect3DViewport3.fun))
425 # define XCAST(fun) (void*)
428 ICOM_VTABLE(IDirect3DViewport3
) VTABLE_IDirect3DViewport3
=
430 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
431 XCAST(QueryInterface
) Main_IDirect3DViewportImpl_3_2_1_QueryInterface
,
432 XCAST(AddRef
) Main_IDirect3DViewportImpl_3_2_1_AddRef
,
433 XCAST(Release
) Main_IDirect3DViewportImpl_3_2_1_Release
,
434 XCAST(Initialize
) Main_IDirect3DViewportImpl_3_2_1_Initialize
,
435 XCAST(GetViewport
) Main_IDirect3DViewportImpl_3_2_1_GetViewport
,
436 XCAST(SetViewport
) Main_IDirect3DViewportImpl_3_2_1_SetViewport
,
437 XCAST(TransformVertices
) Main_IDirect3DViewportImpl_3_2_1_TransformVertices
,
438 XCAST(LightElements
) Main_IDirect3DViewportImpl_3_2_1_LightElements
,
439 XCAST(SetBackground
) Main_IDirect3DViewportImpl_3_2_1_SetBackground
,
440 XCAST(GetBackground
) Main_IDirect3DViewportImpl_3_2_1_GetBackground
,
441 XCAST(SetBackgroundDepth
) Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth
,
442 XCAST(GetBackgroundDepth
) Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth
,
443 XCAST(Clear
) Main_IDirect3DViewportImpl_3_2_1_Clear
,
444 XCAST(AddLight
) Main_IDirect3DViewportImpl_3_2_1_AddLight
,
445 XCAST(DeleteLight
) Main_IDirect3DViewportImpl_3_2_1_DeleteLight
,
446 XCAST(NextLight
) Main_IDirect3DViewportImpl_3_2_1_NextLight
,
447 XCAST(GetViewport2
) Main_IDirect3DViewportImpl_3_2_GetViewport2
,
448 XCAST(SetViewport2
) Main_IDirect3DViewportImpl_3_2_SetViewport2
,
449 XCAST(SetBackgroundDepth2
) Main_IDirect3DViewportImpl_3_SetBackgroundDepth2
,
450 XCAST(GetBackgroundDepth2
) Main_IDirect3DViewportImpl_3_GetBackgroundDepth2
,
451 XCAST(Clear2
) Main_IDirect3DViewportImpl_3_Clear2
,
454 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
461 HRESULT
d3dviewport_create(IDirect3DViewportImpl
**obj
, IDirect3DImpl
*d3d
)
463 IDirect3DViewportImpl
*object
;
465 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DViewportImpl
));
466 if (object
== NULL
) return DDERR_OUTOFMEMORY
;
470 object
->activate
= activate
;
471 object
->use_vp2
= 0xFF;
473 object
->lights
= NULL
;
474 object
->num_lights
= 0;
475 object
->map_lights
= 0;
477 ICOM_INIT_INTERFACE(object
, IDirect3DViewport3
, VTABLE_IDirect3DViewport3
);
481 TRACE(" creating implementation at %p.\n", *obj
);