Improved DIBSection support for IDirectDrawSurface::GetDC.
[wine] / dlls / ddraw / d3dviewport.c
1 /* Direct3D Viewport
2    (c) 1998 Lionel ULMER
3    
4    This files contains the implementation of Direct3DViewport2. */
5
6 #include "config.h"
7 #include "windef.h"
8 #include "winerror.h"
9 #include "wine/obj_base.h"
10 #include "heap.h"
11 #include "ddraw.h"
12 #include "d3d.h"
13 #include "debugtools.h"
14 #include "x11drv.h"
15
16 #include "d3d_private.h"
17 #include "mesa_private.h"
18
19 DEFAULT_DEBUG_CHANNEL(ddraw)
20
21 #ifdef HAVE_OPENGL
22
23 #define D3DVPRIVATE(x) mesa_d3dv_private*dvpriv=((mesa_d3dv_private*)x->private)
24 #define D3DLPRIVATE(x) mesa_d3dl_private*dlpriv=((mesa_d3dl_private*)x->private)
25
26 static ICOM_VTABLE(IDirect3DViewport2) viewport2_vtable;
27
28 /*******************************************************************************
29  *                              Viewport1/2 static functions
30  */
31 static void activate(IDirect3DViewport2Impl* This) {
32   IDirect3DLightImpl* l;
33   
34   /* Activate all the lights associated with this context */
35   l = This->lights;
36
37   while (l != NULL) {
38     l->activate(l);
39     l = l->next;
40   }
41 }
42
43 /*******************************************************************************
44  *                              Viewport1/2 Creation functions
45  */
46 LPDIRECT3DVIEWPORT2 d3dviewport2_create(IDirect3D2Impl* d3d2)
47 {
48   IDirect3DViewport2Impl* vp;
49   
50   vp = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DViewport2Impl));
51   vp->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dv_private));
52   vp->ref = 1;
53   ICOM_VTBL(vp) = &viewport2_vtable;
54   vp->d3d.d3d2 = d3d2;
55   vp->use_d3d2 = 1;
56
57   vp->device.active_device2 = NULL;
58   vp->activate = activate;
59
60   vp->lights = NULL;
61
62   ((mesa_d3dv_private *) vp->private)->nextlight = GL_LIGHT0;
63   
64   return (LPDIRECT3DVIEWPORT2)vp;
65 }
66
67 LPDIRECT3DVIEWPORT d3dviewport_create(IDirect3DImpl* d3d1)
68 {
69   IDirect3DViewport2Impl* vp;
70   
71   vp = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DViewport2Impl));
72   vp->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dv_private));
73   vp->ref = 1;
74   ICOM_VTBL(vp) = &viewport2_vtable;
75   vp->d3d.d3d1 = d3d1;
76   vp->use_d3d2 = 0;
77
78   vp->device.active_device1 = NULL;
79   vp->activate = activate;
80
81   vp->lights = NULL;
82
83   ((mesa_d3dv_private *) vp->private)->nextlight = GL_LIGHT0;
84   
85   return (LPDIRECT3DVIEWPORT) vp;
86 }
87
88 /*******************************************************************************
89  *                              IDirect3DViewport2 methods
90  */
91
92 HRESULT WINAPI IDirect3DViewport2Impl_QueryInterface(LPDIRECT3DVIEWPORT2 iface,
93                                                         REFIID riid,
94                                                         LPVOID* ppvObj)
95 {
96   ICOM_THIS(IDirect3DViewport2Impl,iface);
97   
98   FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);
99   
100   return S_OK;
101 }
102
103
104
105 ULONG WINAPI IDirect3DViewport2Impl_AddRef(LPDIRECT3DVIEWPORT2 iface)
106 {
107   ICOM_THIS(IDirect3DViewport2Impl,iface);
108   TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
109   
110   return ++(This->ref);
111 }
112
113
114
115 ULONG WINAPI IDirect3DViewport2Impl_Release(LPDIRECT3DVIEWPORT2 iface)
116 {
117   ICOM_THIS(IDirect3DViewport2Impl,iface);
118   FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );
119   
120   if (!--(This->ref)) {
121     HeapFree(GetProcessHeap(),0,This);
122     return 0;
123   }
124   
125   return This->ref;
126 }
127
128 /*** IDirect3DViewport methods ***/
129 HRESULT WINAPI IDirect3DViewport2Impl_Initialize(LPDIRECT3DVIEWPORT2 iface,
130                                                     LPDIRECT3D d3d)
131 {
132   ICOM_THIS(IDirect3DViewport2Impl,iface);
133   FIXME("(%p)->(%p): stub\n", This, d3d);
134   
135   return DD_OK;
136 }
137
138 HRESULT WINAPI IDirect3DViewport2Impl_GetViewport(LPDIRECT3DVIEWPORT2 iface,
139                                                      LPD3DVIEWPORT lpvp)
140 {
141   ICOM_THIS(IDirect3DViewport2Impl,iface);
142   FIXME("(%p)->(%p): stub\n", This, lpvp);
143   
144   if (This->use_vp2 != 0)
145     return DDERR_INVALIDPARAMS;
146
147   *lpvp = This->viewport.vp1;
148   
149   return DD_OK;
150 }
151
152 HRESULT WINAPI IDirect3DViewport2Impl_SetViewport(LPDIRECT3DVIEWPORT2 iface,
153                                                      LPD3DVIEWPORT lpvp)
154 {
155   ICOM_THIS(IDirect3DViewport2Impl,iface);
156   FIXME("(%p)->(%p): stub\n", This, lpvp);
157
158   This->use_vp2 = 0;
159   This->viewport.vp1 = *lpvp;
160   
161   TRACE("dwSize = %ld   dwX = %ld   dwY = %ld\n",
162         lpvp->dwSize, lpvp->dwX, lpvp->dwY);
163   TRACE("dwWidth = %ld   dwHeight = %ld\n",
164         lpvp->dwWidth, lpvp->dwHeight);
165   TRACE("dvScaleX = %f   dvScaleY = %f\n",
166         lpvp->dvScaleX, lpvp->dvScaleY);
167   TRACE("dvMaxX = %f   dvMaxY = %f\n",
168         lpvp->dvMaxX, lpvp->dvMaxY);
169   TRACE("dvMinZ = %f   dvMaxZ = %f\n",
170         lpvp->dvMinZ, lpvp->dvMaxZ);
171
172   
173   return DD_OK;
174 }
175
176 HRESULT WINAPI IDirect3DViewport2Impl_TransformVertices(LPDIRECT3DVIEWPORT2 iface,
177                                                            DWORD dwVertexCount,
178                                                            LPD3DTRANSFORMDATA lpData,
179                                                            DWORD dwFlags,
180                                                            LPDWORD lpOffScreen)
181 {
182   ICOM_THIS(IDirect3DViewport2Impl,iface);
183   FIXME("(%p)->(%8ld,%p,%08lx,%p): stub\n",
184         This, dwVertexCount, lpData, dwFlags, lpOffScreen);
185   
186   return DD_OK;
187 }
188
189 HRESULT WINAPI IDirect3DViewport2Impl_LightElements(LPDIRECT3DVIEWPORT2 iface,
190                                                        DWORD dwElementCount,
191                                                        LPD3DLIGHTDATA lpData)
192 {
193   ICOM_THIS(IDirect3DViewport2Impl,iface);
194   FIXME("(%p)->(%8ld,%p): stub\n", This, dwElementCount, lpData);
195   
196   return DD_OK;
197 }
198
199 HRESULT WINAPI IDirect3DViewport2Impl_SetBackground(LPDIRECT3DVIEWPORT2 iface,
200                                                        D3DMATERIALHANDLE hMat)
201 {
202   ICOM_THIS(IDirect3DViewport2Impl,iface);
203   FIXME("(%p)->(%08lx): stub\n", This, (DWORD) hMat);
204   
205   return DD_OK;
206 }
207
208 HRESULT WINAPI IDirect3DViewport2Impl_GetBackground(LPDIRECT3DVIEWPORT2 iface,
209                                                        LPD3DMATERIALHANDLE lphMat,
210                                                        LPBOOL lpValid)
211 {
212   ICOM_THIS(IDirect3DViewport2Impl,iface);
213   FIXME("(%p)->(%p,%p): stub\n", This, lphMat, lpValid);
214   
215   return DD_OK;
216 }
217
218 HRESULT WINAPI IDirect3DViewport2Impl_SetBackgroundDepth(LPDIRECT3DVIEWPORT2 iface,
219                                                             LPDIRECTDRAWSURFACE lpDDSurface)
220 {
221   ICOM_THIS(IDirect3DViewport2Impl,iface);
222   FIXME("(%p)->(%p): stub\n", This, lpDDSurface);
223   
224   return DD_OK;
225 }
226
227 HRESULT WINAPI IDirect3DViewport2Impl_GetBackgroundDepth(LPDIRECT3DVIEWPORT2 iface,
228                                                             LPDIRECTDRAWSURFACE* lplpDDSurface,
229                                                             LPBOOL lpValid)
230 {
231   ICOM_THIS(IDirect3DViewport2Impl,iface);
232   FIXME("(%p)->(%p,%p): stub\n", This, lplpDDSurface, lpValid);
233   
234   return DD_OK;
235 }
236
237 HRESULT WINAPI IDirect3DViewport2Impl_Clear(LPDIRECT3DVIEWPORT2 iface,
238                                                DWORD dwCount,
239                                                LPD3DRECT lpRects,
240                                                DWORD dwFlags)
241 {
242   ICOM_THIS(IDirect3DViewport2Impl,iface);
243   GLboolean ztest;
244   FIXME("(%p)->(%8ld,%p,%08lx): stub\n", This, dwCount, lpRects, dwFlags);
245
246   /* For the moment, ignore the rectangles */
247   if (This->device.active_device1 != NULL) {
248     /* Get the rendering context */
249     if (This->use_d3d2)
250       This->device.active_device2->set_context(This->device.active_device2);
251     else
252       This->device.active_device1->set_context(This->device.active_device1);
253   }
254
255     /* Clears the screen */
256     ENTER_GL();
257     glGetBooleanv(GL_DEPTH_TEST, &ztest);
258     glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
259     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
260     glDepthMask(ztest);
261     LEAVE_GL();
262   
263   return DD_OK;
264 }
265
266 HRESULT WINAPI IDirect3DViewport2Impl_AddLight(LPDIRECT3DVIEWPORT2 iface,
267                                                   LPDIRECT3DLIGHT lpLight)
268 {
269   ICOM_THIS(IDirect3DViewport2Impl,iface);
270   IDirect3DLightImpl* ilpLight=(IDirect3DLightImpl*)lpLight;
271   FIXME("(%p)->(%p): stub\n", This, ilpLight);
272
273   /* Add the light in the 'linked' chain */
274   ilpLight->next = This->lights;
275   This->lights = ilpLight;
276
277   /* If active, activate the light */
278   if (This->device.active_device1 != NULL) {
279     D3DVPRIVATE(This);
280     D3DLPRIVATE(ilpLight);
281     
282     /* Get the rendering context */
283     if (This->use_d3d2)
284       This->device.active_device2->set_context(This->device.active_device2);
285     else
286       This->device.active_device1->set_context(This->device.active_device1);
287     
288     /* Activate the light */
289     dlpriv->light_num = dvpriv->nextlight++;
290     ilpLight->activate(ilpLight);
291   }
292   
293   return DD_OK;
294 }
295
296 HRESULT WINAPI IDirect3DViewport2Impl_DeleteLight(LPDIRECT3DVIEWPORT2 iface,
297                                                      LPDIRECT3DLIGHT lpLight)
298 {
299   ICOM_THIS(IDirect3DViewport2Impl,iface);
300   FIXME("(%p)->(%p): stub\n", This, lpLight);
301   
302   return DD_OK;
303 }
304
305 HRESULT WINAPI IDirect3DViewport2Impl_NextLight(LPDIRECT3DVIEWPORT2 iface,
306                                                    LPDIRECT3DLIGHT lpLight,
307                                                    LPDIRECT3DLIGHT* lplpLight,
308                                                    DWORD dwFlags)
309 {
310   ICOM_THIS(IDirect3DViewport2Impl,iface);
311   FIXME("(%p)->(%p,%p,%08lx): stub\n", This, lpLight, lplpLight, dwFlags);
312   
313   return DD_OK;
314 }
315
316 /*** IDirect3DViewport2 methods ***/
317 HRESULT WINAPI IDirect3DViewport2Impl_GetViewport2(LPDIRECT3DVIEWPORT2 iface,
318                                                       LPD3DVIEWPORT2 lpViewport2)
319 {
320   ICOM_THIS(IDirect3DViewport2Impl,iface);
321   TRACE("(%p)->(%p)\n", This, lpViewport2);
322
323   if (This->use_vp2 != 1)
324     return DDERR_INVALIDPARAMS;
325
326   *lpViewport2 = This->viewport.vp2;
327   
328   return DD_OK;
329 }
330
331 HRESULT WINAPI IDirect3DViewport2Impl_SetViewport2(LPDIRECT3DVIEWPORT2 iface,
332                                                       LPD3DVIEWPORT2 lpViewport2)
333 {
334   ICOM_THIS(IDirect3DViewport2Impl,iface);
335   TRACE("(%p)->(%p)\n", This, lpViewport2);
336
337   TRACE("dwSize = %ld   dwX = %ld   dwY = %ld\n",
338         lpViewport2->dwSize, lpViewport2->dwX, lpViewport2->dwY);
339   TRACE("dwWidth = %ld   dwHeight = %ld\n",
340         lpViewport2->dwWidth, lpViewport2->dwHeight);
341   TRACE("dvClipX = %f   dvClipY = %f\n",
342         lpViewport2->dvClipX, lpViewport2->dvClipY);
343   TRACE("dvClipWidth = %f   dvClipHeight = %f\n",
344         lpViewport2->dvClipWidth, lpViewport2->dvClipHeight);
345   TRACE("dvMinZ = %f   dvMaxZ = %f\n",
346         lpViewport2->dvMinZ, lpViewport2->dvMaxZ);
347
348   This->viewport.vp2 = *lpViewport2;
349   This->use_vp2 = 1;
350   
351   return DD_OK;
352 }
353
354
355 /*******************************************************************************
356  *                              IDirect3DViewport1/2 VTable
357  */
358 static ICOM_VTABLE(IDirect3DViewport2) viewport2_vtable = 
359 {
360   ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
361   /*** IUnknown methods ***/
362   IDirect3DViewport2Impl_QueryInterface,
363   IDirect3DViewport2Impl_AddRef,
364   IDirect3DViewport2Impl_Release,
365   /*** IDirect3DViewport methods ***/
366   IDirect3DViewport2Impl_Initialize,
367   IDirect3DViewport2Impl_GetViewport,
368   IDirect3DViewport2Impl_SetViewport,
369   IDirect3DViewport2Impl_TransformVertices,
370   IDirect3DViewport2Impl_LightElements,
371   IDirect3DViewport2Impl_SetBackground,
372   IDirect3DViewport2Impl_GetBackground,
373   IDirect3DViewport2Impl_SetBackgroundDepth,
374   IDirect3DViewport2Impl_GetBackgroundDepth,
375   IDirect3DViewport2Impl_Clear,
376   IDirect3DViewport2Impl_AddLight,
377   IDirect3DViewport2Impl_DeleteLight,
378   IDirect3DViewport2Impl_NextLight,
379   /*** IDirect3DViewport2 methods ***/
380   IDirect3DViewport2Impl_GetViewport2,
381   IDirect3DViewport2Impl_SetViewport2
382 };
383
384 #else /* HAVE_OPENGL */
385
386 LPDIRECT3DVIEWPORT d3dviewport_create(IDirect3DImpl* d3d1) {
387   ERR("Should not be called...\n");
388   return NULL;
389 }
390
391 LPDIRECT3DVIEWPORT2 d3dviewport2_create(IDirect3D2Impl* d3d2) {
392   ERR("Should not be called...\n");
393   return NULL;
394 }
395
396 #endif /* HAVE_OPENGL */