Some ddraw/d3d bugfixes, updated Diablo/WC4 ddraw status.
[wine] / graphics / 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 "windows.h"
8 #include "wintypes.h"
9 #include "winerror.h"
10 #include "wine/obj_base.h"
11 #include "heap.h"
12 #include "ddraw.h"
13 #include "d3d.h"
14 #include "debug.h"
15 #include "objbase.h"
16
17 #include "d3d_private.h"
18
19
20 #ifdef HAVE_MESAGL
21
22 static IDirect3DViewport2_VTable viewport2_vtable;
23
24 /*******************************************************************************
25  *                              Viewport1/2 static functions
26  */
27 static void activate(LPDIRECT3DVIEWPORT2 this) {
28   LPDIRECT3DLIGHT l;
29   
30   /* Activate all the lights associated with this context */
31   l = this->lights;
32
33   while (l != NULL) {
34     l->activate(l);
35     l = l->next;
36   }
37 }
38
39 /*******************************************************************************
40  *                              Viewport1/2 Creation functions
41  */
42 LPDIRECT3DVIEWPORT2 d3dviewport2_create(LPDIRECT3D2 d3d)
43 {
44   LPDIRECT3DVIEWPORT2 vp;
45   
46   vp = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DViewport2));
47   vp->ref = 1;
48   vp->lpvtbl = &viewport2_vtable;
49   vp->d3d.d3d2 = d3d;
50   vp->use_d3d2 = 1;
51
52   vp->device.active_device2 = NULL;
53   vp->activate = activate;
54
55   vp->lights = NULL;
56
57   vp->nextlight = GL_LIGHT0;
58   
59   return vp;
60 }
61
62 LPDIRECT3DVIEWPORT d3dviewport_create(LPDIRECT3D d3d)
63 {
64   LPDIRECT3DVIEWPORT2 vp;
65   
66   vp = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DViewport2));
67   vp->ref = 1;
68   vp->lpvtbl = &viewport2_vtable;
69   vp->d3d.d3d1 = d3d;
70   vp->use_d3d2 = 0;
71
72   vp->device.active_device1 = NULL;
73   vp->activate = activate;
74
75   vp->lights = NULL;
76
77   vp->nextlight = GL_LIGHT0;
78   
79   return (LPDIRECT3DVIEWPORT) vp;
80 }
81
82 /*******************************************************************************
83  *                              IDirect3DViewport2 methods
84  */
85
86 static HRESULT WINAPI IDirect3DViewport2_QueryInterface(LPDIRECT3DVIEWPORT2 this,
87                                                         REFIID riid,
88                                                         LPVOID* ppvObj)
89 {
90   char xrefiid[50];
91   
92   WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
93   FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj);
94   
95   return S_OK;
96 }
97
98
99
100 static ULONG WINAPI IDirect3DViewport2_AddRef(LPDIRECT3DVIEWPORT2 this)
101 {
102   TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref );
103   
104   return ++(this->ref);
105 }
106
107
108
109 static ULONG WINAPI IDirect3DViewport2_Release(LPDIRECT3DVIEWPORT2 this)
110 {
111   FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
112   
113   if (!--(this->ref)) {
114     HeapFree(GetProcessHeap(),0,this);
115     return 0;
116   }
117   
118   return this->ref;
119 }
120
121 /*** IDirect3DViewport methods ***/
122 static HRESULT WINAPI IDirect3DViewport2_Initialize(LPDIRECT3DVIEWPORT2 this,
123                                                     LPDIRECT3D d3d)
124 {
125   FIXME(ddraw, "(%p)->(%p): stub\n", this, d3d);
126   
127   return DD_OK;
128 }
129
130 static HRESULT WINAPI IDirect3DViewport2_GetViewport(LPDIRECT3DVIEWPORT2 this,
131                                                      LPD3DVIEWPORT lpvp)
132 {
133   FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
134   
135   if (this->use_vp2 != 0)
136     return DDERR_INVALIDPARAMS;
137
138   *lpvp = this->viewport.vp1;
139   
140   return DD_OK;
141 }
142
143 static HRESULT WINAPI IDirect3DViewport2_SetViewport(LPDIRECT3DVIEWPORT2 this,
144                                                      LPD3DVIEWPORT lpvp)
145 {
146   FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
147
148   this->use_vp2 = 0;
149   this->viewport.vp1 = *lpvp;
150   
151   TRACE(ddraw, "dwSize = %ld   dwX = %ld   dwY = %ld\n",
152         lpvp->dwSize, lpvp->dwX, lpvp->dwY);
153   TRACE(ddraw, "dwWidth = %ld   dwHeight = %ld\n",
154         lpvp->dwWidth, lpvp->dwHeight);
155   TRACE(ddraw, "dvScaleX = %f   dvScaleY = %f\n",
156         lpvp->dvScaleX, lpvp->dvScaleY);
157   TRACE(ddraw, "dvMaxX = %f   dvMaxY = %f\n",
158         lpvp->dvMaxX, lpvp->dvMaxY);
159   TRACE(ddraw, "dvMinZ = %f   dvMaxZ = %f\n",
160         lpvp->dvMinZ, lpvp->dvMaxZ);
161
162   
163   return DD_OK;
164 }
165
166 static HRESULT WINAPI IDirect3DViewport2_TransformVertices(LPDIRECT3DVIEWPORT2 this,
167                                                            DWORD dwVertexCount,
168                                                            LPD3DTRANSFORMDATA lpData,
169                                                            DWORD dwFlags,
170                                                            LPDWORD lpOffScreen)
171 {
172   FIXME(ddraw, "(%p)->(%8ld,%p,%08lx,%p): stub\n",
173         this, dwVertexCount, lpData, dwFlags, lpOffScreen);
174   
175   return DD_OK;
176 }
177
178 static HRESULT WINAPI IDirect3DViewport2_LightElements(LPDIRECT3DVIEWPORT2 this,
179                                                        DWORD dwElementCount,
180                                                        LPD3DLIGHTDATA lpData)
181 {
182   FIXME(ddraw, "(%p)->(%8ld,%p): stub\n", this, dwElementCount, lpData);
183   
184   return DD_OK;
185 }
186
187 static HRESULT WINAPI IDirect3DViewport2_SetBackground(LPDIRECT3DVIEWPORT2 this,
188                                                        D3DMATERIALHANDLE hMat)
189 {
190   FIXME(ddraw, "(%p)->(%08lx): stub\n", this, (DWORD) hMat);
191   
192   return DD_OK;
193 }
194
195 static HRESULT WINAPI IDirect3DViewport2_GetBackground(LPDIRECT3DVIEWPORT2 this,
196                                                        LPD3DMATERIALHANDLE lphMat,
197                                                        LPBOOL32 lpValid)
198 {
199   FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lphMat, lpValid);
200   
201   return DD_OK;
202 }
203
204 static HRESULT WINAPI IDirect3DViewport2_SetBackgroundDepth(LPDIRECT3DVIEWPORT2 this,
205                                                             LPDIRECTDRAWSURFACE lpDDSurface)
206 {
207   FIXME(ddraw, "(%p)->(%p): stub\n", this, lpDDSurface);
208   
209   return DD_OK;
210 }
211
212 static HRESULT WINAPI IDirect3DViewport2_GetBackgroundDepth(LPDIRECT3DVIEWPORT2 this,
213                                                             LPDIRECTDRAWSURFACE* lplpDDSurface,
214                                                             LPBOOL32 lpValid)
215 {
216   FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lplpDDSurface, lpValid);
217   
218   return DD_OK;
219 }
220
221 static HRESULT WINAPI IDirect3DViewport2_Clear(LPDIRECT3DVIEWPORT2 this,
222                                                DWORD dwCount,
223                                                LPD3DRECT lpRects,
224                                                DWORD dwFlags)
225 {
226   GLboolean ztest;
227   FIXME(ddraw, "(%p)->(%8ld,%p,%08lx): stub\n", this, dwCount, lpRects, dwFlags);
228
229   /* For the moment, ignore the rectangles */
230   if (this->device.active_device1 != NULL) {
231     /* Get the rendering context */
232     if (this->use_d3d2)
233       this->device.active_device2->set_context(this->device.active_device2);
234     else
235       this->device.active_device1->set_context(this->device.active_device1);
236   }
237
238     /* Clears the screen */
239     glGetBooleanv(GL_DEPTH_TEST, &ztest);
240     glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
241     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
242     glDepthMask(ztest);
243   
244   return DD_OK;
245 }
246
247 static HRESULT WINAPI IDirect3DViewport2_AddLight(LPDIRECT3DVIEWPORT2 this,
248                                                   LPDIRECT3DLIGHT lpLight)
249 {
250   FIXME(ddraw, "(%p)->(%p): stub\n", this, lpLight);
251
252   /* Add the light in the 'linked' chain */
253   lpLight->next = this->lights;
254   this->lights = lpLight;
255
256   /* If active, activate the light */
257   if (this->device.active_device1 != NULL) {
258     /* Get the rendering context */
259     if (this->use_d3d2)
260       this->device.active_device2->set_context(this->device.active_device2);
261     else
262       this->device.active_device1->set_context(this->device.active_device1);
263     
264     /* Activate the light */
265     lpLight->light_num = this->nextlight++;
266     lpLight->activate(lpLight);
267   }
268   
269   return DD_OK;
270 }
271
272 static HRESULT WINAPI IDirect3DViewport2_DeleteLight(LPDIRECT3DVIEWPORT2 this,
273                                                      LPDIRECT3DLIGHT lpLight)
274 {
275   FIXME(ddraw, "(%p)->(%p): stub\n", this, lpLight);
276   
277   return DD_OK;
278 }
279
280 static HRESULT WINAPI IDirect3DViewport2_NextLight(LPDIRECT3DVIEWPORT2 this,
281                                                    LPDIRECT3DLIGHT lpLight,
282                                                    LPDIRECT3DLIGHT* lplpLight,
283                                                    DWORD dwFlags)
284 {
285   FIXME(ddraw, "(%p)->(%p,%p,%08lx): stub\n", this, lpLight, lplpLight, dwFlags);
286   
287   return DD_OK;
288 }
289
290 /*** IDirect3DViewport2 methods ***/
291 static HRESULT WINAPI IDirect3DViewport2_GetViewport2(LPDIRECT3DVIEWPORT2 this,
292                                                       LPD3DVIEWPORT2 lpViewport2)
293 {
294   TRACE(ddraw, "(%p)->(%p)\n", this, lpViewport2);
295
296   if (this->use_vp2 != 1)
297     return DDERR_INVALIDPARAMS;
298
299   *lpViewport2 = this->viewport.vp2;
300   
301   return DD_OK;
302 }
303
304 static HRESULT WINAPI IDirect3DViewport2_SetViewport2(LPDIRECT3DVIEWPORT2 this,
305                                                       LPD3DVIEWPORT2 lpViewport2)
306 {
307   TRACE(ddraw, "(%p)->(%p)\n", this, lpViewport2);
308
309   TRACE(ddraw, "dwSize = %ld   dwX = %ld   dwY = %ld\n",
310         lpViewport2->dwSize, lpViewport2->dwX, lpViewport2->dwY);
311   TRACE(ddraw, "dwWidth = %ld   dwHeight = %ld\n",
312         lpViewport2->dwWidth, lpViewport2->dwHeight);
313   TRACE(ddraw, "dvClipX = %f   dvClipY = %f\n",
314         lpViewport2->dvClipX, lpViewport2->dvClipY);
315   TRACE(ddraw, "dvClipWidth = %f   dvClipHeight = %f\n",
316         lpViewport2->dvClipWidth, lpViewport2->dvClipHeight);
317   TRACE(ddraw, "dvMinZ = %f   dvMaxZ = %f\n",
318         lpViewport2->dvMinZ, lpViewport2->dvMaxZ);
319
320   this->viewport.vp2 = *lpViewport2;
321   this->use_vp2 = 1;
322   
323   return DD_OK;
324 }
325
326
327 /*******************************************************************************
328  *                              IDirect3DViewport1/2 VTable
329  */
330 static IDirect3DViewport2_VTable viewport2_vtable = {
331   /*** IUnknown methods ***/
332   IDirect3DViewport2_QueryInterface,
333   IDirect3DViewport2_AddRef,
334   IDirect3DViewport2_Release,
335   /*** IDirect3DViewport methods ***/
336   IDirect3DViewport2_Initialize,
337   IDirect3DViewport2_GetViewport,
338   IDirect3DViewport2_SetViewport,
339   IDirect3DViewport2_TransformVertices,
340   IDirect3DViewport2_LightElements,
341   IDirect3DViewport2_SetBackground,
342   IDirect3DViewport2_GetBackground,
343   IDirect3DViewport2_SetBackgroundDepth,
344   IDirect3DViewport2_GetBackgroundDepth,
345   IDirect3DViewport2_Clear,
346   IDirect3DViewport2_AddLight,
347   IDirect3DViewport2_DeleteLight,
348   IDirect3DViewport2_NextLight,
349   /*** IDirect3DViewport2 methods ***/
350   IDirect3DViewport2_GetViewport2,
351   IDirect3DViewport2_SetViewport2
352 };
353
354 #else /* HAVE_MESAGL */
355
356 LPDIRECT3DVIEWPORT d3dviewport_create(LPDIRECT3D d3d) {
357   ERR(ddraw, "Should not be called...\n");
358   return NULL;
359 }
360
361 LPDIRECT3DVIEWPORT2 d3dviewport2_create(LPDIRECT3D2 d3d) {
362   ERR(ddraw, "Should not be called...\n");
363   return NULL;
364 }
365
366 #endif /* HAVE_MESAGL */