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