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