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