Moved d3ddevice and direct3d objects files to ddraw root dir.
[wine] / dlls / ddraw / material.c
1 /* Direct3D Material
2  * Copyright (c) 2002 Lionel ULMER
3  *
4  * This file contains the implementation of Direct3DMaterial.
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
23 #include <stdarg.h>
24
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
27
28 #define CONST_VTABLE
29
30 #include "windef.h"
31 #include "winbase.h"
32 #include "winerror.h"
33 #include "objbase.h"
34 #include "wingdi.h"
35 #include "ddraw.h"
36 #include "d3d.h"
37 #include "wine/debug.h"
38
39 #include "d3d_private.h"
40 #include "opengl_private.h"
41
42 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
43
44 static void dump_material(LPD3DMATERIAL mat)
45 {
46     DPRINTF("  dwSize : %ld\n", mat->dwSize);
47 }
48
49 HRESULT WINAPI
50 Main_IDirect3DMaterialImpl_3_2T_1T_QueryInterface(LPDIRECT3DMATERIAL3 iface,
51                                                   REFIID riid,
52                                                   LPVOID* obp)
53 {
54     ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface);
55     TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
56
57     *obp = NULL;
58
59     if ( IsEqualGUID( &IID_IUnknown,  riid ) ) {
60         IDirect3DMaterial_AddRef(ICOM_INTERFACE(This, IDirect3DMaterial));
61         *obp = iface;
62         TRACE("  Creating IUnknown interface at %p.\n", *obp);
63         return S_OK;
64     }
65     if ( IsEqualGUID( &IID_IDirect3DMaterial, riid ) ) {
66         IDirect3DMaterial_AddRef(ICOM_INTERFACE(This, IDirect3DMaterial));
67         *obp = ICOM_INTERFACE(This, IDirect3DMaterial);
68         TRACE("  Creating IDirect3DMaterial interface %p\n", *obp);
69         return S_OK;
70     }
71     if ( IsEqualGUID( &IID_IDirect3DMaterial2, riid ) ) {
72         IDirect3DMaterial_AddRef(ICOM_INTERFACE(This, IDirect3DMaterial));
73         *obp = ICOM_INTERFACE(This, IDirect3DMaterial2);
74         TRACE("  Creating IDirect3DMaterial2 interface %p\n", *obp);
75         return S_OK;
76     }
77     if ( IsEqualGUID( &IID_IDirect3DMaterial3, riid ) ) {
78         IDirect3DMaterial_AddRef(ICOM_INTERFACE(This, IDirect3DMaterial));
79         *obp = ICOM_INTERFACE(This, IDirect3DMaterial3);
80         TRACE("  Creating IDirect3DMaterial3 interface %p\n", *obp);
81         return S_OK;
82     }
83     FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
84     return OLE_E_ENUM_NOMORE;
85 }
86
87 ULONG WINAPI
88 Main_IDirect3DMaterialImpl_3_2T_1T_AddRef(LPDIRECT3DMATERIAL3 iface)
89 {
90     ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface);
91     ULONG ref = InterlockedIncrement(&This->ref);
92
93     TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, ref - 1);
94
95     return ref;
96 }
97
98 ULONG WINAPI
99 Main_IDirect3DMaterialImpl_3_2T_1T_Release(LPDIRECT3DMATERIAL3 iface)
100 {
101     ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface);
102     ULONG ref = InterlockedDecrement(&This->ref);
103
104     TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1);
105
106     if (!ref) {
107         HeapFree(GetProcessHeap(), 0, This);
108         return 0;
109     }
110     return ref;
111 }
112
113 HRESULT WINAPI
114 Main_IDirect3DMaterialImpl_1_Initialize(LPDIRECT3DMATERIAL iface,
115                                         LPDIRECT3D lpDirect3D)
116 {
117     ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial, iface);
118     TRACE("(%p/%p)->(%p) no-op...!\n", This, iface, lpDirect3D);
119     return DD_OK;
120 }
121
122 HRESULT WINAPI
123 Main_IDirect3DMaterialImpl_1_Reserve(LPDIRECT3DMATERIAL iface)
124 {
125     ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial, iface);
126     TRACE("(%p/%p)->() not implemented.\n", This, iface);
127     return DD_OK;
128 }
129
130 HRESULT WINAPI
131 Main_IDirect3DMaterialImpl_1_Unreserve(LPDIRECT3DMATERIAL iface)
132 {
133     ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial, iface);
134     FIXME("(%p/%p)->() not implemented.\n", This, iface);
135     return DD_OK;
136 }
137
138 HRESULT WINAPI
139 Main_IDirect3DMaterialImpl_3_2T_1T_SetMaterial(LPDIRECT3DMATERIAL3 iface,
140                                                LPD3DMATERIAL lpMat)
141 {
142     ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface);
143     TRACE("(%p/%p)->(%p)\n", This, iface, lpMat);
144     if (TRACE_ON(ddraw))
145         dump_material(lpMat);
146
147     /* Stores the material */
148     memset(&This->mat, 0, sizeof(This->mat));
149     memcpy(&This->mat, lpMat, lpMat->dwSize);
150     
151     return DD_OK;
152 }
153
154 HRESULT WINAPI
155 Main_IDirect3DMaterialImpl_3_2T_1T_GetMaterial(LPDIRECT3DMATERIAL3 iface,
156                                                LPD3DMATERIAL lpMat)
157 {
158     ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface);
159     DWORD dwSize;
160     TRACE("(%p/%p)->(%p)\n", This, iface, lpMat);
161     if (TRACE_ON(ddraw)) {
162         TRACE("  Returning material : ");
163         dump_material(&This->mat);
164     }
165
166     /* Copies the material structure */
167     dwSize = lpMat->dwSize;
168     memset(lpMat, 0, dwSize);
169     memcpy(lpMat, &This->mat, dwSize);
170
171     return DD_OK;
172 }
173
174 HRESULT WINAPI
175 Main_IDirect3DMaterialImpl_3_2T_1T_GetHandle(LPDIRECT3DMATERIAL3 iface,
176                                              LPDIRECT3DDEVICE3 lpDirect3DDevice3,
177                                              LPD3DMATERIALHANDLE lpHandle)
178 {
179     ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface);
180     TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpDirect3DDevice3, lpHandle);
181
182     This->active_device = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice3, lpDirect3DDevice3);
183     *lpHandle = (DWORD) This; /* Warning: this is not 64 bit clean.
184                                  Maybe also we need to store this material somewhere in the device ? */
185
186     TRACE(" returning handle %08lx.\n", *lpHandle);
187     
188     return DD_OK;
189 }
190
191 HRESULT WINAPI
192 Thunk_IDirect3DMaterialImpl_2_GetHandle(LPDIRECT3DMATERIAL2 iface,
193                                         LPDIRECT3DDEVICE2 lpDirect3DDevice2,
194                                         LPD3DMATERIALHANDLE lpHandle)
195 {
196     TRACE("(%p)->(%p,%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpDirect3DDevice2, lpHandle);
197     return IDirect3DMaterial3_GetHandle(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface),
198                                         COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, lpDirect3DDevice2),
199                                         lpHandle);
200 }
201
202 HRESULT WINAPI
203 Thunk_IDirect3DMaterialImpl_1_GetHandle(LPDIRECT3DMATERIAL iface,
204                                         LPDIRECT3DDEVICE lpDirect3DDevice,
205                                         LPD3DMATERIALHANDLE lpHandle)
206 {
207     TRACE("(%p)->(%p,%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpDirect3DDevice, lpHandle);
208     return IDirect3DMaterial3_GetHandle(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface),
209                                         COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice3, lpDirect3DDevice),
210                                         lpHandle);
211 }
212
213 HRESULT WINAPI
214 Thunk_IDirect3DMaterialImpl_2_QueryInterface(LPDIRECT3DMATERIAL2 iface,
215                                              REFIID riid,
216                                              LPVOID* obp)
217 {
218     TRACE("(%p)->(%s,%p) thunking to IDirect3DMaterial3 interface.\n", iface, debugstr_guid(riid), obp);
219     return IDirect3DMaterial3_QueryInterface(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface),
220                                              riid,
221                                              obp);
222 }
223
224 HRESULT WINAPI
225 Thunk_IDirect3DMaterialImpl_1_QueryInterface(LPDIRECT3DMATERIAL iface,
226                                              REFIID riid,
227                                              LPVOID* obp)
228 {
229     TRACE("(%p)->(%s,%p) thunking to IDirect3DMaterial3 interface.\n", iface, debugstr_guid(riid), obp);
230     return IDirect3DMaterial3_QueryInterface(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface),
231                                              riid,
232                                              obp);
233 }
234
235 ULONG WINAPI
236 Thunk_IDirect3DMaterialImpl_2_AddRef(LPDIRECT3DMATERIAL2 iface)
237 {
238     TRACE("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface);
239     return IDirect3DMaterial3_AddRef(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface));
240 }
241
242 ULONG WINAPI
243 Thunk_IDirect3DMaterialImpl_1_AddRef(LPDIRECT3DMATERIAL iface)
244 {
245     TRACE("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface);
246     return IDirect3DMaterial3_AddRef(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface));
247 }
248
249 ULONG WINAPI
250 Thunk_IDirect3DMaterialImpl_2_Release(LPDIRECT3DMATERIAL2 iface)
251 {
252     TRACE("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface);
253     return IDirect3DMaterial3_Release(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface));
254 }
255
256 ULONG WINAPI
257 Thunk_IDirect3DMaterialImpl_1_Release(LPDIRECT3DMATERIAL iface)
258 {
259     TRACE("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface);
260     return IDirect3DMaterial3_Release(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface));
261 }
262
263 HRESULT WINAPI
264 Thunk_IDirect3DMaterialImpl_2_SetMaterial(LPDIRECT3DMATERIAL2 iface,
265                                           LPD3DMATERIAL lpMat)
266 {
267     TRACE("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat);
268     return IDirect3DMaterial3_SetMaterial(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface),
269                                           lpMat);
270 }
271
272 HRESULT WINAPI
273 Thunk_IDirect3DMaterialImpl_1_SetMaterial(LPDIRECT3DMATERIAL iface,
274                                           LPD3DMATERIAL lpMat)
275 {
276     TRACE("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat);
277     return IDirect3DMaterial3_SetMaterial(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface),
278                                           lpMat);
279 }
280
281 HRESULT WINAPI
282 Thunk_IDirect3DMaterialImpl_2_GetMaterial(LPDIRECT3DMATERIAL2 iface,
283                                           LPD3DMATERIAL lpMat)
284 {
285     TRACE("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat);
286     return IDirect3DMaterial3_GetMaterial(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface),
287                                           lpMat);
288 }
289
290 HRESULT WINAPI
291 Thunk_IDirect3DMaterialImpl_1_GetMaterial(LPDIRECT3DMATERIAL iface,
292                                           LPD3DMATERIAL lpMat)
293 {
294     TRACE("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat);
295     return IDirect3DMaterial3_GetMaterial(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface),
296                                           lpMat);
297 }
298
299 /*******************************************************************************
300  *                              Matrial2 static functions
301  */
302 static void activate(IDirect3DMaterialImpl* This) {
303     TRACE("Activating material %p\n", This);
304
305     /* Set the current Material */
306     ENTER_GL();
307     glMaterialfv(GL_FRONT_AND_BACK,
308                  GL_DIFFUSE,
309                  (float *) &(This->mat.u.diffuse));
310     glMaterialfv(GL_FRONT_AND_BACK,
311                  GL_AMBIENT,
312                  (float *) &(This->mat.u1.ambient));
313     glMaterialfv(GL_FRONT_AND_BACK,
314                  GL_SPECULAR,
315                  (float *) &(This->mat.u2.specular));
316     glMaterialfv(GL_FRONT_AND_BACK,
317                  GL_EMISSION,
318                  (float *) &(This->mat.u3.emissive));
319     LEAVE_GL();
320
321     if (TRACE_ON(ddraw)) {
322         DPRINTF(" - size  : %ld\n", This->mat.dwSize);
323         DPRINTF(" - diffuse : "); dump_D3DCOLORVALUE(&(This->mat.u.diffuse)); DPRINTF("\n");
324         DPRINTF(" - ambient : "); dump_D3DCOLORVALUE(&(This->mat.u1.ambient)); DPRINTF("\n");
325         DPRINTF(" - specular: "); dump_D3DCOLORVALUE(&(This->mat.u2.specular)); DPRINTF("\n");
326         DPRINTF(" - emissive: "); dump_D3DCOLORVALUE(&(This->mat.u3.emissive)); DPRINTF("\n");
327         DPRINTF(" - power : %f\n", This->mat.u4.power);
328         DPRINTF(" - texture handle : %08lx\n", (DWORD)This->mat.hTexture);
329     }
330 }
331
332 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
333 # define XCAST(fun)     (typeof(VTABLE_IDirect3DMaterial3.fun))
334 #else
335 # define XCAST(fun)     (void*)
336 #endif
337
338 static const IDirect3DMaterial3Vtbl VTABLE_IDirect3DMaterial3 =
339 {
340     XCAST(QueryInterface) Main_IDirect3DMaterialImpl_3_2T_1T_QueryInterface,
341     XCAST(AddRef) Main_IDirect3DMaterialImpl_3_2T_1T_AddRef,
342     XCAST(Release) Main_IDirect3DMaterialImpl_3_2T_1T_Release,
343     XCAST(SetMaterial) Main_IDirect3DMaterialImpl_3_2T_1T_SetMaterial,
344     XCAST(GetMaterial) Main_IDirect3DMaterialImpl_3_2T_1T_GetMaterial,
345     XCAST(GetHandle) Main_IDirect3DMaterialImpl_3_2T_1T_GetHandle,
346 };
347
348 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
349 #undef XCAST
350 #endif
351
352
353 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
354 # define XCAST(fun)     (typeof(VTABLE_IDirect3DMaterial2.fun))
355 #else
356 # define XCAST(fun)     (void*)
357 #endif
358
359 static const IDirect3DMaterial2Vtbl VTABLE_IDirect3DMaterial2 =
360 {
361     XCAST(QueryInterface) Thunk_IDirect3DMaterialImpl_2_QueryInterface,
362     XCAST(AddRef) Thunk_IDirect3DMaterialImpl_2_AddRef,
363     XCAST(Release) Thunk_IDirect3DMaterialImpl_2_Release,
364     XCAST(SetMaterial) Thunk_IDirect3DMaterialImpl_2_SetMaterial,
365     XCAST(GetMaterial) Thunk_IDirect3DMaterialImpl_2_GetMaterial,
366     XCAST(GetHandle) Thunk_IDirect3DMaterialImpl_2_GetHandle,
367 };
368
369 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
370 #undef XCAST
371 #endif
372
373
374 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
375 # define XCAST(fun)     (typeof(VTABLE_IDirect3DMaterial.fun))
376 #else
377 # define XCAST(fun)     (void*)
378 #endif
379
380 static const IDirect3DMaterialVtbl VTABLE_IDirect3DMaterial =
381 {
382     XCAST(QueryInterface) Thunk_IDirect3DMaterialImpl_1_QueryInterface,
383     XCAST(AddRef) Thunk_IDirect3DMaterialImpl_1_AddRef,
384     XCAST(Release) Thunk_IDirect3DMaterialImpl_1_Release,
385     XCAST(Initialize) Main_IDirect3DMaterialImpl_1_Initialize,
386     XCAST(SetMaterial) Thunk_IDirect3DMaterialImpl_1_SetMaterial,
387     XCAST(GetMaterial) Thunk_IDirect3DMaterialImpl_1_GetMaterial,
388     XCAST(GetHandle) Thunk_IDirect3DMaterialImpl_1_GetHandle,
389     XCAST(Reserve) Main_IDirect3DMaterialImpl_1_Reserve,
390     XCAST(Unreserve) Main_IDirect3DMaterialImpl_1_Unreserve,
391 };
392
393 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
394 #undef XCAST
395 #endif
396
397
398
399
400 HRESULT d3dmaterial_create(IDirect3DMaterialImpl **obj, IDirectDrawImpl *d3d)
401 {
402     IDirect3DMaterialImpl *object;
403
404     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DMaterialImpl));
405     if (object == NULL) return DDERR_OUTOFMEMORY;
406
407     object->ref = 1;
408     object->d3d = d3d;
409     object->activate = activate;
410     
411     ICOM_INIT_INTERFACE(object, IDirect3DMaterial,  VTABLE_IDirect3DMaterial);
412     ICOM_INIT_INTERFACE(object, IDirect3DMaterial2, VTABLE_IDirect3DMaterial2);
413     ICOM_INIT_INTERFACE(object, IDirect3DMaterial3, VTABLE_IDirect3DMaterial3);
414
415     *obj = object;
416     
417     TRACE(" creating implementation at %p.\n", *obj);
418     
419     return D3D_OK;
420 }