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