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;
39 /* Activate all the lights associated with this context */
42 while (light != NULL) {
43 light->activate(light);
47 /* And copy the values in the structure used by the device */
49 vp.dwX = This->viewports.vp2.dwX;
50 vp.dwY = This->viewports.vp2.dwY;
51 vp.dwHeight = This->viewports.vp2.dwHeight;
52 vp.dwWidth = This->viewports.vp2.dwWidth;
53 vp.dvMinZ = This->viewports.vp2.dvMinZ;
54 vp.dvMaxZ = This->viewports.vp2.dvMaxZ;
56 vp.dwX = This->viewports.vp1.dwX;
57 vp.dwY = This->viewports.vp1.dwY;
58 vp.dwHeight = This->viewports.vp1.dwHeight;
59 vp.dwWidth = This->viewports.vp1.dwWidth;
60 vp.dvMinZ = This->viewports.vp1.dvMinZ;
61 vp.dvMaxZ = This->viewports.vp1.dvMaxZ;
64 /* And also set the viewport */
65 IDirect3DDevice7_SetViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice7), &vp);
69 static void _dump_D3DVIEWPORT(D3DVIEWPORT *lpvp)
71 TRACE(" - dwSize = %ld dwX = %ld dwY = %ld\n",
72 lpvp->dwSize, lpvp->dwX, lpvp->dwY);
73 TRACE(" - dwWidth = %ld dwHeight = %ld\n",
74 lpvp->dwWidth, lpvp->dwHeight);
75 TRACE(" - dvScaleX = %f dvScaleY = %f\n",
76 lpvp->dvScaleX, lpvp->dvScaleY);
77 TRACE(" - dvMaxX = %f dvMaxY = %f\n",
78 lpvp->dvMaxX, lpvp->dvMaxY);
79 TRACE(" - dvMinZ = %f dvMaxZ = %f\n",
80 lpvp->dvMinZ, lpvp->dvMaxZ);
83 static void _dump_D3DVIEWPORT2(D3DVIEWPORT2 *lpvp)
85 TRACE(" - dwSize = %ld dwX = %ld dwY = %ld\n",
86 lpvp->dwSize, lpvp->dwX, lpvp->dwY);
87 TRACE(" - dwWidth = %ld dwHeight = %ld\n",
88 lpvp->dwWidth, lpvp->dwHeight);
89 TRACE(" - dvClipX = %f dvClipY = %f\n",
90 lpvp->dvClipX, lpvp->dvClipY);
91 TRACE(" - dvClipWidth = %f dvClipHeight = %f\n",
92 lpvp->dvClipWidth, lpvp->dvClipHeight);
93 TRACE(" - dvMinZ = %f dvMaxZ = %f\n",
94 lpvp->dvMinZ, lpvp->dvMaxZ);
98 Main_IDirect3DViewportImpl_3_2_1_QueryInterface(LPDIRECT3DVIEWPORT3 iface,
102 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
103 TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
107 if ( IsEqualGUID(&IID_IUnknown, riid) ||
108 IsEqualGUID(&IID_IDirect3DViewport, riid) ||
109 IsEqualGUID(&IID_IDirect3DViewport2, riid) ||
110 IsEqualGUID(&IID_IDirect3DViewport3, riid) ) {
111 IDirect3DViewport3_AddRef(ICOM_INTERFACE(This, IDirect3DViewport3));
112 *obp = ICOM_INTERFACE(This, IDirect3DViewport3);
113 TRACE(" Creating IDirect3DViewport1/2/3 interface %p\n", *obp);
116 FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
117 return OLE_E_ENUM_NOMORE;
121 Main_IDirect3DViewportImpl_3_2_1_AddRef(LPDIRECT3DVIEWPORT3 iface)
123 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
124 TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
125 return ++(This->ref);
129 Main_IDirect3DViewportImpl_3_2_1_Release(LPDIRECT3DVIEWPORT3 iface)
131 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
132 TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
133 if (!--(This->ref)) {
134 HeapFree(GetProcessHeap(), 0, This);
142 Main_IDirect3DViewportImpl_3_2_1_Initialize(LPDIRECT3DVIEWPORT3 iface,
143 LPDIRECT3D lpDirect3D)
145 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
146 TRACE("(%p/%p)->(%p) no-op...\n", This, iface, lpDirect3D);
151 Main_IDirect3DViewportImpl_3_2_1_GetViewport(LPDIRECT3DVIEWPORT3 iface,
152 LPD3DVIEWPORT lpData)
154 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
156 TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
157 if (This->use_vp2 != 0) {
158 ERR(" Requesting to get a D3DVIEWPORT struct where a D3DVIEWPORT2 was set !\n");
159 return DDERR_INVALIDPARAMS;
161 dwSize = lpData->dwSize;
162 memset(lpData, 0, dwSize);
163 memcpy(lpData, &(This->viewports.vp1), dwSize);
165 if (TRACE_ON(ddraw)) {
166 TRACE(" returning D3DVIEWPORT :\n");
167 _dump_D3DVIEWPORT(lpData);
174 Main_IDirect3DViewportImpl_3_2_1_SetViewport(LPDIRECT3DVIEWPORT3 iface,
175 LPD3DVIEWPORT lpData)
177 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
178 TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
180 if (TRACE_ON(ddraw)) {
181 TRACE(" getting D3DVIEWPORT :\n");
182 _dump_D3DVIEWPORT(lpData);
186 memset(&(This->viewports.vp1), 0, sizeof(This->viewports.vp1));
187 memcpy(&(This->viewports.vp1), lpData, lpData->dwSize);
189 /* Tests on two games shows that these values are never used properly so overide
190 them with proper ones :-)
192 This->viewports.vp1.dvMinZ = 0.0;
193 This->viewports.vp1.dvMaxZ = 1.0;
199 Main_IDirect3DViewportImpl_3_2_1_TransformVertices(LPDIRECT3DVIEWPORT3 iface,
201 LPD3DTRANSFORMDATA lpData,
205 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
206 FIXME("(%p/%p)->(%08lx,%p,%08lx,%p): stub!\n", This, iface, dwVertexCount, lpData, dwFlags, lpOffScreen);
211 Main_IDirect3DViewportImpl_3_2_1_LightElements(LPDIRECT3DVIEWPORT3 iface,
212 DWORD dwElementCount,
213 LPD3DLIGHTDATA lpData)
215 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
216 FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwElementCount, lpData);
221 Main_IDirect3DViewportImpl_3_2_1_SetBackground(LPDIRECT3DVIEWPORT3 iface,
222 D3DMATERIALHANDLE hMat)
224 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
225 TRACE("(%p/%p)->(%08lx)\n", This, iface, (DWORD) hMat);
227 This->background = (IDirect3DMaterialImpl *) hMat;
228 TRACE(" setting background color : %f %f %f %f\n",
229 This->background->mat.u.diffuse.u1.r,
230 This->background->mat.u.diffuse.u2.g,
231 This->background->mat.u.diffuse.u3.b,
232 This->background->mat.u.diffuse.u4.a);
238 Main_IDirect3DViewportImpl_3_2_1_GetBackground(LPDIRECT3DVIEWPORT3 iface,
239 LPD3DMATERIALHANDLE lphMat,
242 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
243 FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lphMat, lpValid);
248 Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface,
249 LPDIRECTDRAWSURFACE lpDDSurface)
251 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
252 FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpDDSurface);
257 Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface,
258 LPDIRECTDRAWSURFACE* lplpDDSurface,
261 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
262 FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDDSurface, lpValid);
267 Main_IDirect3DViewportImpl_3_2_1_Clear(LPDIRECT3DVIEWPORT3 iface,
272 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
273 DWORD color = 0x00000000;
275 TRACE("(%p/%p)->(%08lx,%p,%08lx)\n", This, iface, dwCount, lpRects, dwFlags);
276 if (This->active_device == NULL) {
277 ERR(" Trying to clear a viewport not attached to a device !\n");
278 return D3DERR_VIEWPORTHASNODEVICE;
280 if (dwFlags & D3DCLEAR_TARGET) {
281 if (This->background == NULL) {
282 ERR(" Trying to clear the color buffer without background material !\n");
285 ((int) ((This->background->mat.u.diffuse.u1.r) * 255) << 16) |
286 ((int) ((This->background->mat.u.diffuse.u2.g) * 255) << 8) |
287 ((int) ((This->background->mat.u.diffuse.u3.b) * 255) << 0) |
288 ((int) ((This->background->mat.u.diffuse.u4.a) * 255) << 24);
291 return This->active_device->clear(This->active_device, dwCount, lpRects,
292 dwFlags & (D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET),
293 color, 1.0, 0x00000000);
297 Main_IDirect3DViewportImpl_3_2_1_AddLight(LPDIRECT3DVIEWPORT3 iface,
298 LPDIRECT3DLIGHT lpDirect3DLight)
300 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
301 IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight);
303 DWORD map = This->map_lights;
305 TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DLight);
307 if (This->num_lights >= 8)
308 return DDERR_INVALIDPARAMS;
310 /* Find a light number and update both light and viewports objects accordingly */
315 lpDirect3DLightImpl->dwLightIndex = i;
317 This->map_lights |= 1<<i;
319 /* Add the light in the 'linked' chain */
320 lpDirect3DLightImpl->next = This->lights;
321 This->lights = lpDirect3DLightImpl;
323 /* Attach the light to the viewport */
324 lpDirect3DLightImpl->active_viewport = This;
326 /* If active, activate the light */
327 if (This->active_device != NULL) {
328 lpDirect3DLightImpl->activate(lpDirect3DLightImpl);
335 Main_IDirect3DViewportImpl_3_2_1_DeleteLight(LPDIRECT3DVIEWPORT3 iface,
336 LPDIRECT3DLIGHT lpDirect3DLight)
338 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
339 IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight);
340 IDirect3DLightImpl *cur_light, *prev_light = NULL;
342 TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DLight);
343 cur_light = This->lights;
344 while (cur_light != NULL) {
345 if (cur_light == lpDirect3DLightImpl) {
346 lpDirect3DLightImpl->desactivate(lpDirect3DLightImpl);
347 if (prev_light == NULL) This->lights = cur_light->next;
348 else prev_light->next = cur_light->next;
349 /* Detach the light to the viewport */
350 cur_light->active_viewport = NULL;
352 This->map_lights &= ~(1<<lpDirect3DLightImpl->dwLightIndex);
355 prev_light = cur_light;
356 cur_light = cur_light->next;
358 return DDERR_INVALIDPARAMS;
362 Main_IDirect3DViewportImpl_3_2_1_NextLight(LPDIRECT3DVIEWPORT3 iface,
363 LPDIRECT3DLIGHT lpDirect3DLight,
364 LPDIRECT3DLIGHT* lplpDirect3DLight,
367 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
368 FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpDirect3DLight, lplpDirect3DLight, dwFlags);
373 Main_IDirect3DViewportImpl_3_2_GetViewport2(LPDIRECT3DVIEWPORT3 iface,
374 LPD3DVIEWPORT2 lpData)
376 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
378 TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
379 if (This->use_vp2 != 1) {
380 ERR(" Requesting to get a D3DVIEWPORT2 struct where a D3DVIEWPORT was set !\n");
381 return DDERR_INVALIDPARAMS;
383 dwSize = lpData->dwSize;
384 memset(lpData, 0, dwSize);
385 memcpy(lpData, &(This->viewports.vp2), dwSize);
387 if (TRACE_ON(ddraw)) {
388 TRACE(" returning D3DVIEWPORT2 :\n");
389 _dump_D3DVIEWPORT2(lpData);
396 Main_IDirect3DViewportImpl_3_2_SetViewport2(LPDIRECT3DVIEWPORT3 iface,
397 LPD3DVIEWPORT2 lpData)
399 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
400 TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
402 if (TRACE_ON(ddraw)) {
403 TRACE(" getting D3DVIEWPORT2 :\n");
404 _dump_D3DVIEWPORT2(lpData);
408 memset(&(This->viewports.vp2), 0, sizeof(This->viewports.vp2));
409 memcpy(&(This->viewports.vp2), lpData, lpData->dwSize);
414 Main_IDirect3DViewportImpl_3_SetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface,
415 LPDIRECTDRAWSURFACE4 lpDDS)
417 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
418 FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpDDS);
423 Main_IDirect3DViewportImpl_3_GetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface,
424 LPDIRECTDRAWSURFACE4* lplpDDS,
427 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
428 FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDDS, lpValid);
433 Main_IDirect3DViewportImpl_3_Clear2(LPDIRECT3DVIEWPORT3 iface,
441 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
442 TRACE("(%p/%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, iface, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
443 if (This->active_device == NULL) {
444 ERR(" Trying to clear a viewport not attached to a device !\n");
445 return D3DERR_VIEWPORTHASNODEVICE;
447 return This->active_device->clear(This->active_device, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
450 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
451 # define XCAST(fun) (typeof(VTABLE_IDirect3DViewport3.fun))
453 # define XCAST(fun) (void*)
456 ICOM_VTABLE(IDirect3DViewport3) VTABLE_IDirect3DViewport3 =
458 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
459 XCAST(QueryInterface) Main_IDirect3DViewportImpl_3_2_1_QueryInterface,
460 XCAST(AddRef) Main_IDirect3DViewportImpl_3_2_1_AddRef,
461 XCAST(Release) Main_IDirect3DViewportImpl_3_2_1_Release,
462 XCAST(Initialize) Main_IDirect3DViewportImpl_3_2_1_Initialize,
463 XCAST(GetViewport) Main_IDirect3DViewportImpl_3_2_1_GetViewport,
464 XCAST(SetViewport) Main_IDirect3DViewportImpl_3_2_1_SetViewport,
465 XCAST(TransformVertices) Main_IDirect3DViewportImpl_3_2_1_TransformVertices,
466 XCAST(LightElements) Main_IDirect3DViewportImpl_3_2_1_LightElements,
467 XCAST(SetBackground) Main_IDirect3DViewportImpl_3_2_1_SetBackground,
468 XCAST(GetBackground) Main_IDirect3DViewportImpl_3_2_1_GetBackground,
469 XCAST(SetBackgroundDepth) Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth,
470 XCAST(GetBackgroundDepth) Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth,
471 XCAST(Clear) Main_IDirect3DViewportImpl_3_2_1_Clear,
472 XCAST(AddLight) Main_IDirect3DViewportImpl_3_2_1_AddLight,
473 XCAST(DeleteLight) Main_IDirect3DViewportImpl_3_2_1_DeleteLight,
474 XCAST(NextLight) Main_IDirect3DViewportImpl_3_2_1_NextLight,
475 XCAST(GetViewport2) Main_IDirect3DViewportImpl_3_2_GetViewport2,
476 XCAST(SetViewport2) Main_IDirect3DViewportImpl_3_2_SetViewport2,
477 XCAST(SetBackgroundDepth2) Main_IDirect3DViewportImpl_3_SetBackgroundDepth2,
478 XCAST(GetBackgroundDepth2) Main_IDirect3DViewportImpl_3_GetBackgroundDepth2,
479 XCAST(Clear2) Main_IDirect3DViewportImpl_3_Clear2,
482 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
489 HRESULT d3dviewport_create(IDirect3DViewportImpl **obj, IDirectDrawImpl *d3d)
491 IDirect3DViewportImpl *object;
493 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DViewportImpl));
494 if (object == NULL) return DDERR_OUTOFMEMORY;
498 object->activate = activate;
499 object->use_vp2 = 0xFF;
501 object->lights = NULL;
502 object->num_lights = 0;
503 object->map_lights = 0;
505 ICOM_INIT_INTERFACE(object, IDirect3DViewport3, VTABLE_IDirect3DViewport3);
509 TRACE(" creating implementation at %p.\n", *obj);