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