fdopen: don't rewind the file after creating the FILE* handle. Added
[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 #include "config.h"
22 #include "windef.h"
23 #include "winerror.h"
24 #include "objbase.h"
25 #include "ddraw.h"
26 #include "d3d.h"
27 #include "wine/debug.h"
28
29 #include "d3d_private.h"
30 #include "mesa_private.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
33
34 static void activate(IDirect3DViewportImpl* This) {
35     IDirect3DLightImpl* light;
36
37     /* Activate all the lights associated with this context */
38     light = This->lights;
39
40     while (light != NULL) {
41         light->activate(light);
42         light = light->next;
43     }
44 }
45
46
47 static void _dump_D3DVIEWPORT(D3DVIEWPORT *lpvp)
48 {
49     TRACE("    - dwSize = %ld   dwX = %ld   dwY = %ld\n",
50           lpvp->dwSize, lpvp->dwX, lpvp->dwY);
51     TRACE("    - dwWidth = %ld   dwHeight = %ld\n",
52           lpvp->dwWidth, lpvp->dwHeight);
53     TRACE("    - dvScaleX = %f   dvScaleY = %f\n",
54           lpvp->dvScaleX, lpvp->dvScaleY);
55     TRACE("    - dvMaxX = %f   dvMaxY = %f\n",
56           lpvp->dvMaxX, lpvp->dvMaxY);
57     TRACE("    - dvMinZ = %f   dvMaxZ = %f\n",
58           lpvp->dvMinZ, lpvp->dvMaxZ);
59 }
60
61 static void _dump_D3DVIEWPORT2(D3DVIEWPORT2 *lpvp)
62 {
63     TRACE("    - dwSize = %ld   dwX = %ld   dwY = %ld\n",
64           lpvp->dwSize, lpvp->dwX, lpvp->dwY);
65     TRACE("    - dwWidth = %ld   dwHeight = %ld\n",
66           lpvp->dwWidth, lpvp->dwHeight);
67     TRACE("    - dvClipX = %f   dvClipY = %f\n",
68           lpvp->dvClipX, lpvp->dvClipY);
69     TRACE("    - dvClipWidth = %f   dvClipHeight = %f\n",
70           lpvp->dvClipWidth, lpvp->dvClipHeight);
71     TRACE("    - dvMinZ = %f   dvMaxZ = %f\n",
72           lpvp->dvMinZ, lpvp->dvMaxZ);
73 }
74
75 HRESULT WINAPI
76 Main_IDirect3DViewportImpl_3_2_1_QueryInterface(LPDIRECT3DVIEWPORT3 iface,
77                                                 REFIID riid,
78                                                 LPVOID* obp)
79 {
80     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
81     TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
82
83     *obp = NULL;
84
85     if ( IsEqualGUID(&IID_IUnknown,  riid) ||
86          IsEqualGUID(&IID_IDirect3DViewport, riid) ||
87          IsEqualGUID(&IID_IDirect3DViewport2, riid) ||
88          IsEqualGUID(&IID_IDirect3DViewport3, riid) ) {
89         IDirect3DViewport3_AddRef(ICOM_INTERFACE(This, IDirect3DViewport3));
90         *obp = ICOM_INTERFACE(This, IDirect3DViewport3);
91         TRACE("  Creating IDirect3DViewport1/2/3 interface %p\n", *obp);
92         return S_OK;
93     }
94     FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
95     return OLE_E_ENUM_NOMORE;
96 }
97
98 ULONG WINAPI
99 Main_IDirect3DViewportImpl_3_2_1_AddRef(LPDIRECT3DVIEWPORT3 iface)
100 {
101     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
102     FIXME("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
103     return ++(This->ref);
104 }
105
106 ULONG WINAPI
107 Main_IDirect3DViewportImpl_3_2_1_Release(LPDIRECT3DVIEWPORT3 iface)
108 {
109     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
110     FIXME("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
111     if (!--(This->ref)) {
112         HeapFree(GetProcessHeap(), 0, This);
113         return 0;
114     }
115     return This->ref;
116 }
117
118
119 HRESULT WINAPI
120 Main_IDirect3DViewportImpl_3_2_1_Initialize(LPDIRECT3DVIEWPORT3 iface,
121                                             LPDIRECT3D lpDirect3D)
122 {
123     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
124     TRACE("(%p/%p)->(%p) no-op...\n", This, iface, lpDirect3D);
125     return DD_OK;
126 }
127
128 HRESULT WINAPI
129 Main_IDirect3DViewportImpl_3_2_1_GetViewport(LPDIRECT3DVIEWPORT3 iface,
130                                              LPD3DVIEWPORT lpData)
131 {
132     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
133     DWORD dwSize;
134     TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
135     if (This->use_vp2 != 0) {
136         ERR("  Requesting to get a D3DVIEWPORT struct where a D3DVIEWPORT2 was set !\n");
137         return DDERR_INVALIDPARAMS;
138     }
139     dwSize = lpData->dwSize;
140     memset(lpData, 0, dwSize);
141     memcpy(lpData, &(This->viewports.vp1), dwSize);
142
143     if (TRACE_ON(ddraw)) {
144         TRACE("  returning D3DVIEWPORT :\n");
145         _dump_D3DVIEWPORT(lpData);
146     }
147     
148     return DD_OK;
149 }
150
151 HRESULT WINAPI
152 Main_IDirect3DViewportImpl_3_2_1_SetViewport(LPDIRECT3DVIEWPORT3 iface,
153                                              LPD3DVIEWPORT lpData)
154 {
155     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
156     TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
157
158     if (TRACE_ON(ddraw)) {
159         TRACE("  getting D3DVIEWPORT :\n");
160         _dump_D3DVIEWPORT(lpData);
161     }
162
163     This->use_vp2 = 0;
164     memset(&(This->viewports.vp1), 0, sizeof(This->viewports.vp1));
165     memcpy(&(This->viewports.vp1), lpData, lpData->dwSize);
166     return DD_OK;
167 }
168
169 HRESULT WINAPI
170 Main_IDirect3DViewportImpl_3_2_1_TransformVertices(LPDIRECT3DVIEWPORT3 iface,
171                                                    DWORD dwVertexCount,
172                                                    LPD3DTRANSFORMDATA lpData,
173                                                    DWORD dwFlags,
174                                                    LPDWORD lpOffScreen)
175 {
176     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
177     FIXME("(%p/%p)->(%08lx,%p,%08lx,%p): stub!\n", This, iface, dwVertexCount, lpData, dwFlags, lpOffScreen);
178     return DD_OK;
179 }
180
181 HRESULT WINAPI
182 Main_IDirect3DViewportImpl_3_2_1_LightElements(LPDIRECT3DVIEWPORT3 iface,
183                                                DWORD dwElementCount,
184                                                LPD3DLIGHTDATA lpData)
185 {
186     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
187     FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwElementCount, lpData);
188     return DD_OK;
189 }
190
191 HRESULT WINAPI
192 Main_IDirect3DViewportImpl_3_2_1_SetBackground(LPDIRECT3DVIEWPORT3 iface,
193                                                D3DMATERIALHANDLE hMat)
194 {
195     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
196     FIXME("(%p/%p)->(%08lx): stub!\n", This, iface, (DWORD) hMat);
197     return DD_OK;
198 }
199
200 HRESULT WINAPI
201 Main_IDirect3DViewportImpl_3_2_1_GetBackground(LPDIRECT3DVIEWPORT3 iface,
202                                                LPD3DMATERIALHANDLE lphMat,
203                                                LPBOOL lpValid)
204 {
205     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
206     FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lphMat, lpValid);
207     return DD_OK;
208 }
209
210 HRESULT WINAPI
211 Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface,
212                                                     LPDIRECTDRAWSURFACE lpDDSurface)
213 {
214     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
215     FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpDDSurface);
216     return DD_OK;
217 }
218
219 HRESULT WINAPI
220 Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface,
221                                                     LPDIRECTDRAWSURFACE* lplpDDSurface,
222                                                     LPBOOL lpValid)
223 {
224     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
225     FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDDSurface, lpValid);
226     return DD_OK;
227 }
228
229 HRESULT WINAPI
230 Main_IDirect3DViewportImpl_3_2_1_Clear(LPDIRECT3DVIEWPORT3 iface,
231                                        DWORD dwCount,
232                                        LPD3DRECT lpRects,
233                                        DWORD dwFlags)
234 {
235     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
236     FIXME("(%p/%p)->(%08lx,%p,%08lx): stub!\n", This, iface, dwCount, lpRects, dwFlags);
237     return DD_OK;
238 }
239
240 HRESULT WINAPI
241 Main_IDirect3DViewportImpl_3_2_1_AddLight(LPDIRECT3DVIEWPORT3 iface,
242                                           LPDIRECT3DLIGHT lpDirect3DLight)
243 {
244     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
245     IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight);
246     
247     TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DLight);
248     
249     /* Add the light in the 'linked' chain */
250     lpDirect3DLightImpl->next = This->lights;
251     This->lights = lpDirect3DLightImpl;
252
253     /* If active, activate the light */
254     if (This->active_device != NULL) {
255         lpDirect3DLightImpl->activate(lpDirect3DLightImpl);
256     }
257     
258     return DD_OK;
259 }
260
261 HRESULT WINAPI
262 Main_IDirect3DViewportImpl_3_2_1_DeleteLight(LPDIRECT3DVIEWPORT3 iface,
263                                              LPDIRECT3DLIGHT lpDirect3DLight)
264 {
265     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
266     IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight);
267     IDirect3DLightImpl *cur_light, *prev_light = NULL;
268     
269     TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DLight);
270     cur_light = This->lights;
271     while (cur_light != NULL) {
272         if (cur_light == lpDirect3DLightImpl) {
273             lpDirect3DLightImpl->desactivate(lpDirect3DLightImpl);
274             if (prev_light == NULL) This->lights = cur_light->next;
275             else prev_light->next = cur_light->next;
276             return DD_OK;
277         }
278         prev_light = cur_light;
279         cur_light = cur_light->next;
280     }
281     return DDERR_INVALIDPARAMS;
282 }
283
284 HRESULT WINAPI
285 Main_IDirect3DViewportImpl_3_2_1_NextLight(LPDIRECT3DVIEWPORT3 iface,
286                                            LPDIRECT3DLIGHT lpDirect3DLight,
287                                            LPDIRECT3DLIGHT* lplpDirect3DLight,
288                                            DWORD dwFlags)
289 {
290     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
291     FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpDirect3DLight, lplpDirect3DLight, dwFlags);
292     return DD_OK;
293 }
294
295 HRESULT WINAPI
296 Main_IDirect3DViewportImpl_3_2_GetViewport2(LPDIRECT3DVIEWPORT3 iface,
297                                             LPD3DVIEWPORT2 lpData)
298 {
299     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
300     DWORD dwSize;
301     TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
302     if (This->use_vp2 != 1) {
303         ERR("  Requesting to get a D3DVIEWPORT2 struct where a D3DVIEWPORT was set !\n");
304         return DDERR_INVALIDPARAMS;
305     }
306     dwSize = lpData->dwSize;
307     memset(lpData, 0, dwSize);
308     memcpy(lpData, &(This->viewports.vp2), dwSize);
309
310     if (TRACE_ON(ddraw)) {
311         TRACE("  returning D3DVIEWPORT2 :\n");
312         _dump_D3DVIEWPORT2(lpData);
313     }
314     
315     return DD_OK;
316 }
317
318 HRESULT WINAPI
319 Main_IDirect3DViewportImpl_3_2_SetViewport2(LPDIRECT3DVIEWPORT3 iface,
320                                             LPD3DVIEWPORT2 lpData)
321 {
322     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
323     TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
324
325     if (TRACE_ON(ddraw)) {
326         TRACE("  getting D3DVIEWPORT2 :\n");
327         _dump_D3DVIEWPORT2(lpData);
328     }
329
330     This->use_vp2 = 1;
331     memset(&(This->viewports.vp2), 0, sizeof(This->viewports.vp2));
332     memcpy(&(This->viewports.vp2), lpData, lpData->dwSize);
333     return DD_OK;
334 }
335
336 HRESULT WINAPI
337 Main_IDirect3DViewportImpl_3_SetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface,
338                                                  LPDIRECTDRAWSURFACE4 lpDDS)
339 {
340     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
341     FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpDDS);
342     return DD_OK;
343 }
344
345 HRESULT WINAPI
346 Main_IDirect3DViewportImpl_3_GetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface,
347                                                  LPDIRECTDRAWSURFACE4* lplpDDS,
348                                                  LPBOOL lpValid)
349 {
350     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
351     FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDDS, lpValid);
352     return DD_OK;
353 }
354
355 HRESULT WINAPI
356 Main_IDirect3DViewportImpl_3_Clear2(LPDIRECT3DVIEWPORT3 iface,
357                                     DWORD dwCount,
358                                     LPD3DRECT lpRects,
359                                     DWORD dwFlags,
360                                     DWORD dwColor,
361                                     D3DVALUE dvZ,
362                                     DWORD dwStencil)
363 {
364     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
365     FIXME("(%p/%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx): stub!\n", This, iface, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
366     return DD_OK;
367 }
368
369 HRESULT WINAPI
370 GL_IDirect3DViewportImpl_3_2_1_Clear(LPDIRECT3DVIEWPORT3 iface,
371                                        DWORD dwCount,
372                                        LPD3DRECT lpRects,
373                                        DWORD dwFlags)
374 {
375     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
376     GLboolean ztest;
377     
378     TRACE("(%p/%p)->(%08lx,%p,%08lx)\n", This, iface, dwCount, lpRects, dwFlags);
379
380     if (dwCount != 1) {
381         WARN("  Warning, this function only for now clears the whole screen...\n");
382     }
383     
384     /* Clears the screen */
385     ENTER_GL();
386     glGetBooleanv(GL_DEPTH_WRITEMASK, &ztest);
387     glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
388     glClear(((dwFlags & D3DCLEAR_TARGET) ? GL_COLOR_BUFFER_BIT : 0) |
389             ((dwFlags & D3DCLEAR_ZBUFFER) ? GL_DEPTH_BUFFER_BIT : 0));
390     glDepthMask(ztest);
391     LEAVE_GL();
392     
393     return DD_OK;
394 }
395
396 HRESULT WINAPI
397 GL_IDirect3DViewportImpl_3_Clear2(LPDIRECT3DVIEWPORT3 iface,
398                                     DWORD dwCount,
399                                     LPD3DRECT lpRects,
400                                     DWORD dwFlags,
401                                     DWORD dwColor,
402                                     D3DVALUE dvZ,
403                                     DWORD dwStencil)
404 {
405     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
406     GLboolean ztest;
407     GLfloat old_z_clear_value;
408     GLbitfield bitfield = 0;
409     GLint old_stencil_clear_value;
410     GLfloat old_color_clear_value[4];
411     
412     TRACE("(%p/%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, iface, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
413
414     if (dwCount != 1) {
415         WARN("  Warning, this function only for now clears the whole screen...\n");
416     }
417
418     /* Clears the screen */
419     ENTER_GL();
420     if (dwFlags & D3DCLEAR_ZBUFFER) {
421         glGetBooleanv(GL_DEPTH_WRITEMASK, &ztest);
422         glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
423         glGetFloatv(GL_DEPTH_CLEAR_VALUE, &old_z_clear_value);
424         glClearDepth(dvZ);
425         TRACE(" Depth value : %f\n", dvZ);
426         bitfield |= GL_DEPTH_BUFFER_BIT;
427     }
428     if (dwFlags & D3DCLEAR_STENCIL) {
429         bitfield |= GL_STENCIL_BUFFER_BIT;
430         glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &old_stencil_clear_value);
431         glClearStencil(dwStencil);
432         TRACE(" Stencil value : %ld\n", dwStencil);
433     }    
434     if (dwFlags & D3DCLEAR_TARGET) {
435         bitfield |= GL_COLOR_BUFFER_BIT;
436         glGetFloatv(GL_COLOR_CLEAR_VALUE, old_color_clear_value);
437         glClearColor(((dwColor >> 16) & 0xFF) / 255.0,
438                      ((dwColor >>  8) & 0xFF) / 255.0,
439                      ((dwColor >>  0) & 0xFF) / 255.0,
440                      ((dwColor >> 24) & 0xFF) / 255.0);
441         TRACE("Color value (ARGB) : %08lx\n", dwColor);
442     }
443     
444     glClear(bitfield);
445     
446     if (dwFlags & D3DCLEAR_ZBUFFER) {
447         glDepthMask(ztest);
448         glClearDepth(old_z_clear_value);
449     }
450      if (dwFlags & D3DCLEAR_STENCIL) {
451         bitfield |= GL_STENCIL_BUFFER_BIT;
452         glClearStencil(old_stencil_clear_value);
453     }    
454     if (dwFlags & D3DCLEAR_TARGET) {
455         bitfield |= GL_COLOR_BUFFER_BIT;
456         glClearColor(old_color_clear_value[0],
457                      old_color_clear_value[1],
458                      old_color_clear_value[2],
459                      old_color_clear_value[3]);
460     }
461     
462     LEAVE_GL();
463     
464     return DD_OK;
465 }
466
467 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
468 # define XCAST(fun)     (typeof(VTABLE_IDirect3DViewport3.fun))
469 #else
470 # define XCAST(fun)     (void*)
471 #endif
472
473 ICOM_VTABLE(IDirect3DViewport3) VTABLE_IDirect3DViewport3 =
474 {
475     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
476     XCAST(QueryInterface) Main_IDirect3DViewportImpl_3_2_1_QueryInterface,
477     XCAST(AddRef) Main_IDirect3DViewportImpl_3_2_1_AddRef,
478     XCAST(Release) Main_IDirect3DViewportImpl_3_2_1_Release,
479     XCAST(Initialize) Main_IDirect3DViewportImpl_3_2_1_Initialize,
480     XCAST(GetViewport) Main_IDirect3DViewportImpl_3_2_1_GetViewport,
481     XCAST(SetViewport) Main_IDirect3DViewportImpl_3_2_1_SetViewport,
482     XCAST(TransformVertices) Main_IDirect3DViewportImpl_3_2_1_TransformVertices,
483     XCAST(LightElements) Main_IDirect3DViewportImpl_3_2_1_LightElements,
484     XCAST(SetBackground) Main_IDirect3DViewportImpl_3_2_1_SetBackground,
485     XCAST(GetBackground) Main_IDirect3DViewportImpl_3_2_1_GetBackground,
486     XCAST(SetBackgroundDepth) Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth,
487     XCAST(GetBackgroundDepth) Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth,
488     XCAST(Clear) GL_IDirect3DViewportImpl_3_2_1_Clear,
489     XCAST(AddLight) Main_IDirect3DViewportImpl_3_2_1_AddLight,
490     XCAST(DeleteLight) Main_IDirect3DViewportImpl_3_2_1_DeleteLight,
491     XCAST(NextLight) Main_IDirect3DViewportImpl_3_2_1_NextLight,
492     XCAST(GetViewport2) Main_IDirect3DViewportImpl_3_2_GetViewport2,
493     XCAST(SetViewport2) Main_IDirect3DViewportImpl_3_2_SetViewport2,
494     XCAST(SetBackgroundDepth2) Main_IDirect3DViewportImpl_3_SetBackgroundDepth2,
495     XCAST(GetBackgroundDepth2) Main_IDirect3DViewportImpl_3_GetBackgroundDepth2,
496     XCAST(Clear2) GL_IDirect3DViewportImpl_3_Clear2,
497 };
498
499 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
500 #undef XCAST
501 #endif
502
503
504
505
506 HRESULT d3dviewport_create(IDirect3DViewportImpl **obj, IDirect3DImpl *d3d)
507 {
508     IDirect3DViewportImpl *object;
509
510     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DViewportImpl));
511     if (object == NULL) return DDERR_OUTOFMEMORY;
512
513     object->ref = 1;
514     object->d3d = d3d;
515     object->activate = activate;
516     object->use_vp2 = 0xFF;
517     object->next = NULL;
518     object->lights = NULL;
519     
520     ICOM_INIT_INTERFACE(object, IDirect3DViewport3, VTABLE_IDirect3DViewport3);
521
522     *obj = object;
523
524     TRACE(" creating implementation at %p.\n", *obj);
525     
526     return D3D_OK;
527 }