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