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);