Add strmif.h to the headers included in libuuid.
[wine] / dlls / ddraw / d3dviewport.c
1 /* Direct3D Viewport
2  * Copyright (c) 1998 Lionel ULMER
3  *
4  * This file contains the implementation of Direct3DViewport2.
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #define NONAMELESSUNION
22 #define NONAMELESSSTRUCT
23 #include "config.h"
24 #include "windef.h"
25 #include "winerror.h"
26 #include "objbase.h"
27 #include "ddraw.h"
28 #include "d3d.h"
29 #include "wine/debug.h"
30
31 #include "d3d_private.h"
32
33 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
34
35 static void activate(IDirect3DViewportImpl* This) {
36     IDirect3DLightImpl* light;
37     D3DVIEWPORT7 vp;
38     
39     /* Activate all the lights associated with this context */
40     light = This->lights;
41
42     while (light != NULL) {
43         light->activate(light);
44         light = light->next;
45     }
46
47     /* And copy the values in the structure used by the device */
48     if (This->use_vp2) {
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;
55     } else {
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;
62     }
63     
64     /* And also set the viewport */
65     IDirect3DDevice7_SetViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice7), &vp);
66 }
67
68
69 static void _dump_D3DVIEWPORT(D3DVIEWPORT *lpvp)
70 {
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);
81 }
82
83 static void _dump_D3DVIEWPORT2(D3DVIEWPORT2 *lpvp)
84 {
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);
95 }
96
97 HRESULT WINAPI
98 Main_IDirect3DViewportImpl_3_2_1_QueryInterface(LPDIRECT3DVIEWPORT3 iface,
99                                                 REFIID riid,
100                                                 LPVOID* obp)
101 {
102     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
103     TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
104
105     *obp = NULL;
106
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);
114         return S_OK;
115     }
116     FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
117     return OLE_E_ENUM_NOMORE;
118 }
119
120 ULONG WINAPI
121 Main_IDirect3DViewportImpl_3_2_1_AddRef(LPDIRECT3DVIEWPORT3 iface)
122 {
123     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
124     TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
125     return ++(This->ref);
126 }
127
128 ULONG WINAPI
129 Main_IDirect3DViewportImpl_3_2_1_Release(LPDIRECT3DVIEWPORT3 iface)
130 {
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);
135         return 0;
136     }
137     return This->ref;
138 }
139
140
141 HRESULT WINAPI
142 Main_IDirect3DViewportImpl_3_2_1_Initialize(LPDIRECT3DVIEWPORT3 iface,
143                                             LPDIRECT3D lpDirect3D)
144 {
145     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
146     TRACE("(%p/%p)->(%p) no-op...\n", This, iface, lpDirect3D);
147     return DD_OK;
148 }
149
150 HRESULT WINAPI
151 Main_IDirect3DViewportImpl_3_2_1_GetViewport(LPDIRECT3DVIEWPORT3 iface,
152                                              LPD3DVIEWPORT lpData)
153 {
154     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
155     DWORD dwSize;
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;
160     }
161     dwSize = lpData->dwSize;
162     memset(lpData, 0, dwSize);
163     memcpy(lpData, &(This->viewports.vp1), dwSize);
164
165     if (TRACE_ON(ddraw)) {
166         TRACE("  returning D3DVIEWPORT :\n");
167         _dump_D3DVIEWPORT(lpData);
168     }
169     
170     return DD_OK;
171 }
172
173 HRESULT WINAPI
174 Main_IDirect3DViewportImpl_3_2_1_SetViewport(LPDIRECT3DVIEWPORT3 iface,
175                                              LPD3DVIEWPORT lpData)
176 {
177     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
178     TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
179
180     if (TRACE_ON(ddraw)) {
181         TRACE("  getting D3DVIEWPORT :\n");
182         _dump_D3DVIEWPORT(lpData);
183     }
184
185     This->use_vp2 = 0;
186     memset(&(This->viewports.vp1), 0, sizeof(This->viewports.vp1));
187     memcpy(&(This->viewports.vp1), lpData, lpData->dwSize);
188
189     /* Tests on two games shows that these values are never used properly so overide
190        them with proper ones :-)
191     */
192     This->viewports.vp1.dvMinZ = 0.0;
193     This->viewports.vp1.dvMaxZ = 1.0;
194     
195     return DD_OK;
196 }
197
198 HRESULT WINAPI
199 Main_IDirect3DViewportImpl_3_2_1_TransformVertices(LPDIRECT3DVIEWPORT3 iface,
200                                                    DWORD dwVertexCount,
201                                                    LPD3DTRANSFORMDATA lpData,
202                                                    DWORD dwFlags,
203                                                    LPDWORD lpOffScreen)
204 {
205     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
206     FIXME("(%p/%p)->(%08lx,%p,%08lx,%p): stub!\n", This, iface, dwVertexCount, lpData, dwFlags, lpOffScreen);
207     return DD_OK;
208 }
209
210 HRESULT WINAPI
211 Main_IDirect3DViewportImpl_3_2_1_LightElements(LPDIRECT3DVIEWPORT3 iface,
212                                                DWORD dwElementCount,
213                                                LPD3DLIGHTDATA lpData)
214 {
215     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
216     FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwElementCount, lpData);
217     return DD_OK;
218 }
219
220 HRESULT WINAPI
221 Main_IDirect3DViewportImpl_3_2_1_SetBackground(LPDIRECT3DVIEWPORT3 iface,
222                                                D3DMATERIALHANDLE hMat)
223 {
224     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
225     TRACE("(%p/%p)->(%08lx)\n", This, iface, (DWORD) hMat);
226     
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);
233
234     return DD_OK;
235 }
236
237 HRESULT WINAPI
238 Main_IDirect3DViewportImpl_3_2_1_GetBackground(LPDIRECT3DVIEWPORT3 iface,
239                                                LPD3DMATERIALHANDLE lphMat,
240                                                LPBOOL lpValid)
241 {
242     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
243     FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lphMat, lpValid);
244     return DD_OK;
245 }
246
247 HRESULT WINAPI
248 Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface,
249                                                     LPDIRECTDRAWSURFACE lpDDSurface)
250 {
251     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
252     FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpDDSurface);
253     return DD_OK;
254 }
255
256 HRESULT WINAPI
257 Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface,
258                                                     LPDIRECTDRAWSURFACE* lplpDDSurface,
259                                                     LPBOOL lpValid)
260 {
261     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
262     FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDDSurface, lpValid);
263     return DD_OK;
264 }
265
266 HRESULT WINAPI
267 Main_IDirect3DViewportImpl_3_2_1_Clear(LPDIRECT3DVIEWPORT3 iface,
268                                        DWORD dwCount,
269                                        LPD3DRECT lpRects,
270                                        DWORD dwFlags)
271 {
272     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
273     DWORD color = 0x00000000;
274     
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;
279     }
280     if (dwFlags & D3DCLEAR_TARGET) {
281         if (This->background == NULL) {
282             ERR(" Trying to clear the color buffer without background material !\n");
283         } else {
284             color = 
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);
289         }
290     }
291     return This->active_device->clear(This->active_device, dwCount, lpRects, 
292                                       dwFlags & (D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET),
293                                       color, 1.0, 0x00000000);
294 }
295
296 HRESULT WINAPI
297 Main_IDirect3DViewportImpl_3_2_1_AddLight(LPDIRECT3DVIEWPORT3 iface,
298                                           LPDIRECT3DLIGHT lpDirect3DLight)
299 {
300     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
301     IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight);
302     DWORD i = 0;
303     DWORD map = This->map_lights;
304     
305     TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DLight);
306     
307     if (This->num_lights >= 8)
308         return DDERR_INVALIDPARAMS;
309
310     /* Find a light number and update both light and viewports objects accordingly */
311     while(map&1) {
312         map>>=1;
313         i++;
314     }
315     lpDirect3DLightImpl->dwLightIndex = i;
316     This->num_lights++;
317     This->map_lights |= 1<<i;
318
319     /* Add the light in the 'linked' chain */
320     lpDirect3DLightImpl->next = This->lights;
321     This->lights = lpDirect3DLightImpl;
322
323     /* Attach the light to the viewport */
324     lpDirect3DLightImpl->active_viewport = This;
325     
326     /* If active, activate the light */
327     if (This->active_device != NULL) {
328         lpDirect3DLightImpl->activate(lpDirect3DLightImpl);
329     }
330     
331     return DD_OK;
332 }
333
334 HRESULT WINAPI
335 Main_IDirect3DViewportImpl_3_2_1_DeleteLight(LPDIRECT3DVIEWPORT3 iface,
336                                              LPDIRECT3DLIGHT lpDirect3DLight)
337 {
338     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
339     IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight);
340     IDirect3DLightImpl *cur_light, *prev_light = NULL;
341     
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;
351             This->num_lights--;
352             This->map_lights &= ~(1<<lpDirect3DLightImpl->dwLightIndex);
353             return DD_OK;
354         }
355         prev_light = cur_light;
356         cur_light = cur_light->next;
357     }
358     return DDERR_INVALIDPARAMS;
359 }
360
361 HRESULT WINAPI
362 Main_IDirect3DViewportImpl_3_2_1_NextLight(LPDIRECT3DVIEWPORT3 iface,
363                                            LPDIRECT3DLIGHT lpDirect3DLight,
364                                            LPDIRECT3DLIGHT* lplpDirect3DLight,
365                                            DWORD dwFlags)
366 {
367     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
368     FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpDirect3DLight, lplpDirect3DLight, dwFlags);
369     return DD_OK;
370 }
371
372 HRESULT WINAPI
373 Main_IDirect3DViewportImpl_3_2_GetViewport2(LPDIRECT3DVIEWPORT3 iface,
374                                             LPD3DVIEWPORT2 lpData)
375 {
376     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
377     DWORD dwSize;
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;
382     }
383     dwSize = lpData->dwSize;
384     memset(lpData, 0, dwSize);
385     memcpy(lpData, &(This->viewports.vp2), dwSize);
386
387     if (TRACE_ON(ddraw)) {
388         TRACE("  returning D3DVIEWPORT2 :\n");
389         _dump_D3DVIEWPORT2(lpData);
390     }
391     
392     return DD_OK;
393 }
394
395 HRESULT WINAPI
396 Main_IDirect3DViewportImpl_3_2_SetViewport2(LPDIRECT3DVIEWPORT3 iface,
397                                             LPD3DVIEWPORT2 lpData)
398 {
399     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
400     TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
401
402     if (TRACE_ON(ddraw)) {
403         TRACE("  getting D3DVIEWPORT2 :\n");
404         _dump_D3DVIEWPORT2(lpData);
405     }
406
407     This->use_vp2 = 1;
408     memset(&(This->viewports.vp2), 0, sizeof(This->viewports.vp2));
409     memcpy(&(This->viewports.vp2), lpData, lpData->dwSize);
410     return DD_OK;
411 }
412
413 HRESULT WINAPI
414 Main_IDirect3DViewportImpl_3_SetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface,
415                                                  LPDIRECTDRAWSURFACE4 lpDDS)
416 {
417     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
418     FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpDDS);
419     return DD_OK;
420 }
421
422 HRESULT WINAPI
423 Main_IDirect3DViewportImpl_3_GetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface,
424                                                  LPDIRECTDRAWSURFACE4* lplpDDS,
425                                                  LPBOOL lpValid)
426 {
427     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
428     FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDDS, lpValid);
429     return DD_OK;
430 }
431
432 HRESULT WINAPI
433 Main_IDirect3DViewportImpl_3_Clear2(LPDIRECT3DVIEWPORT3 iface,
434                                     DWORD dwCount,
435                                     LPD3DRECT lpRects,
436                                     DWORD dwFlags,
437                                     DWORD dwColor,
438                                     D3DVALUE dvZ,
439                                     DWORD dwStencil)
440 {
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;
446     }
447     return This->active_device->clear(This->active_device, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
448 }
449
450 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
451 # define XCAST(fun)     (typeof(VTABLE_IDirect3DViewport3.fun))
452 #else
453 # define XCAST(fun)     (void*)
454 #endif
455
456 ICOM_VTABLE(IDirect3DViewport3) VTABLE_IDirect3DViewport3 =
457 {
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,
480 };
481
482 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
483 #undef XCAST
484 #endif
485
486
487
488
489 HRESULT d3dviewport_create(IDirect3DViewportImpl **obj, IDirectDrawImpl *d3d)
490 {
491     IDirect3DViewportImpl *object;
492
493     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DViewportImpl));
494     if (object == NULL) return DDERR_OUTOFMEMORY;
495
496     object->ref = 1;
497     object->d3d = d3d;
498     object->activate = activate;
499     object->use_vp2 = 0xFF;
500     object->next = NULL;
501     object->lights = NULL;
502     object->num_lights = 0;
503     object->map_lights = 0;
504     
505     ICOM_INIT_INTERFACE(object, IDirect3DViewport3, VTABLE_IDirect3DViewport3);
506
507     *obj = object;
508
509     TRACE(" creating implementation at %p.\n", *obj);
510     
511     return D3D_OK;
512 }