Implement [ format specifier.
[wine] / dlls / ddraw / d3dlight.c
1 /* Direct3D Light
2  * Copyright (c) 1998 Lionel ULMER
3  *
4  * This file contains the implementation of Direct3DLight.
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 "mesa_private.h"
30
31 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
32
33 #define D3DLPRIVATE(x) mesa_d3dl_private*dlpriv=((mesa_d3dl_private*)x->private)
34
35 static ICOM_VTABLE(IDirect3DLight) light_vtable;
36
37 enum {
38   D3D_1,
39   D3D_2
40 };
41
42 /*******************************************************************************
43  *                              Light static functions
44  */
45 static const float zero_value[] = {
46   0.0, 0.0, 0.0, 0.0
47 };
48
49 static void update(IDirect3DLightImpl* This) {
50   D3DLPRIVATE(This);
51   switch (This->light.dltType) {
52   case D3DLIGHT_POINT:         /* 1 */
53     TRACE("Activating POINT\n");
54     break;
55
56   case D3DLIGHT_SPOT:          /* 2 */
57     TRACE("Activating SPOT\n");
58     break;
59
60   case D3DLIGHT_DIRECTIONAL: {  /* 3 */
61     float direction[4];
62
63     TRACE("Activating DIRECTIONAL\n");
64     TRACE("  direction : %f %f %f\n",
65           This->light.dvDirection.u1.x,
66           This->light.dvDirection.u2.y,
67           This->light.dvDirection.u3.z);
68     _dump_colorvalue(" color    ", This->light.dcvColor);
69
70     glLightfv(dlpriv->light_num, GL_AMBIENT, (float *) zero_value);
71     glLightfv(dlpriv->light_num, GL_DIFFUSE, (float *) &(This->light.dcvColor));
72
73     direction[0] = -This->light.dvDirection.u1.x;
74     direction[1] = -This->light.dvDirection.u2.y;
75     direction[2] = -This->light.dvDirection.u3.z;
76     direction[3] = 0.0; /* This is a directional light */
77
78     glLightfv(dlpriv->light_num, GL_POSITION, (float *) direction);
79   } break;
80
81   case D3DLIGHT_PARALLELPOINT:  /* 4 */
82     TRACE("Activating PARRALLEL-POINT\n");
83     break;
84
85   default:
86     TRACE("Not a known Light Type: %d\n",This->light.dltType);
87     break;
88   }
89 }
90
91 static void activate(IDirect3DLightImpl* This) {
92   D3DLPRIVATE(This);
93
94   ENTER_GL();
95   update(This);
96   /* If was not active, activate it */
97   if (This->is_active == 0) {
98     glEnable(dlpriv->light_num);
99     This->is_active = 1;
100   }
101   LEAVE_GL();
102
103   return ;
104 }
105
106 /*******************************************************************************
107  *                              Light Creation functions
108  */
109 LPDIRECT3DLIGHT d3dlight_create(IDirect3D2Impl* d3d2)
110 {
111   IDirect3DLightImpl* light;
112
113   light = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DLightImpl));
114   light->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dl_private));
115   light->ref = 1;
116   ICOM_VTBL(light) = &light_vtable;
117   light->d3d.d3d2 = d3d2;
118   light->type = D3D_2;
119
120   light->next = NULL;
121   light->prev = NULL;
122   light->activate = activate;
123   light->is_active = 0;
124
125   return (LPDIRECT3DLIGHT)light;
126 }
127
128 LPDIRECT3DLIGHT d3dlight_create_dx3(IDirect3DImpl* d3d1)
129 {
130   IDirect3DLightImpl* light;
131
132   light = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DLightImpl));
133   light->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dl_private));
134   light->ref = 1;
135   ICOM_VTBL(light) = &light_vtable;
136
137   light->d3d.d3d1 = d3d1;
138   light->type = D3D_1;
139
140   light->next = NULL;
141   light->prev = NULL;
142   light->activate = activate;
143   light->is_active = 0;
144
145   return (LPDIRECT3DLIGHT)light;
146 }
147
148 /*******************************************************************************
149  *                              IDirect3DLight methods
150  */
151
152 static HRESULT WINAPI IDirect3DLightImpl_QueryInterface(LPDIRECT3DLIGHT iface,
153                                                     REFIID riid,
154                                                     LPVOID* ppvObj)
155 {
156   ICOM_THIS(IDirect3DLightImpl,iface);
157
158   FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);
159
160   return S_OK;
161 }
162
163
164
165 static ULONG WINAPI IDirect3DLightImpl_AddRef(LPDIRECT3DLIGHT iface)
166 {
167   ICOM_THIS(IDirect3DLightImpl,iface);
168   TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
169
170   return ++(This->ref);
171 }
172
173
174
175 static ULONG WINAPI IDirect3DLightImpl_Release(LPDIRECT3DLIGHT iface)
176 {
177   ICOM_THIS(IDirect3DLightImpl,iface);
178   TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
179
180   if (!--(This->ref)) {
181     HeapFree(GetProcessHeap(),0,This->private);
182     HeapFree(GetProcessHeap(),0,This);
183     return 0;
184   }
185
186   return This->ref;
187 }
188
189 /*** IDirect3DLight methods ***/
190 static void dump_light(LPD3DLIGHT light)
191 {
192   DPRINTF("  dwSize : %ld\n", light->dwSize);
193 }
194
195 static HRESULT WINAPI IDirect3DLightImpl_GetLight(LPDIRECT3DLIGHT iface,
196                                               LPD3DLIGHT lpLight)
197 {
198   ICOM_THIS(IDirect3DLightImpl,iface);
199   TRACE("(%p)->(%p)\n", This, lpLight);
200   if (TRACE_ON(ddraw))
201     dump_light(lpLight);
202
203   /* Copies the light structure */
204   switch (This->type) {
205   case D3D_1:
206     *((LPD3DLIGHT)lpLight) = *((LPD3DLIGHT) &(This->light));
207     break;
208   case D3D_2:
209     *((LPD3DLIGHT2)lpLight) = *((LPD3DLIGHT2) &(This->light));
210     break;
211   }
212
213   return DD_OK;
214 }
215
216 static HRESULT WINAPI IDirect3DLightImpl_SetLight(LPDIRECT3DLIGHT iface,
217                                               LPD3DLIGHT lpLight)
218 {
219   ICOM_THIS(IDirect3DLightImpl,iface);
220   TRACE("(%p)->(%p)\n", This, lpLight);
221   if (TRACE_ON(ddraw))
222     dump_light(lpLight);
223
224   /* Stores the light */
225   switch (This->type) {
226   case D3D_1:
227     *((LPD3DLIGHT) &(This->light)) = *((LPD3DLIGHT)lpLight);
228     break;
229   case D3D_2:
230     *((LPD3DLIGHT2) &(This->light)) = *((LPD3DLIGHT2)lpLight);
231     break;
232   }
233
234   ENTER_GL();
235   if (This->is_active)
236     update(This);
237   LEAVE_GL();
238
239   return DD_OK;
240 }
241
242 static HRESULT WINAPI IDirect3DLightImpl_Initialize(LPDIRECT3DLIGHT iface,
243                                                 LPDIRECT3D lpDirect3D)
244
245 {
246   ICOM_THIS(IDirect3DLightImpl,iface);
247   TRACE("(%p)->(%p)\n", This, lpDirect3D);
248
249   return DDERR_ALREADYINITIALIZED;
250 }
251
252
253 /*******************************************************************************
254  *                              IDirect3DLight VTable
255  */
256 static ICOM_VTABLE(IDirect3DLight) light_vtable =
257 {
258   ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
259   /*** IUnknown methods ***/
260   IDirect3DLightImpl_QueryInterface,
261   IDirect3DLightImpl_AddRef,
262   IDirect3DLightImpl_Release,
263   /*** IDirect3DLight methods ***/
264   IDirect3DLightImpl_Initialize,
265   IDirect3DLightImpl_SetLight,
266   IDirect3DLightImpl_GetLight
267 };