2 * Copyright (c) 2002 Lionel ULMER
3 * Copyright (c) 2006 Stefan DÖSINGER
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "ddraw_private.h"
22 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
24 static void dump_material(const D3DMATERIAL
*mat
)
26 TRACE(" dwSize : %d\n", mat
->dwSize
);
29 static inline struct d3d_material
*impl_from_IDirect3DMaterial(IDirect3DMaterial
*iface
)
31 return CONTAINING_RECORD(iface
, struct d3d_material
, IDirect3DMaterial_iface
);
34 static inline struct d3d_material
*impl_from_IDirect3DMaterial2(IDirect3DMaterial2
*iface
)
36 return CONTAINING_RECORD(iface
, struct d3d_material
, IDirect3DMaterial2_iface
);
39 static inline struct d3d_material
*impl_from_IDirect3DMaterial3(IDirect3DMaterial3
*iface
)
41 return CONTAINING_RECORD(iface
, struct d3d_material
, IDirect3DMaterial3_iface
);
44 /*****************************************************************************
46 *****************************************************************************/
48 /*****************************************************************************
49 * IDirect3DMaterial3::QueryInterface
51 * QueryInterface for IDirect3DMaterial. Can query all IDirect3DMaterial
55 * riid: Interface id queried for
56 * obj: Address to pass the interface pointer back
60 * E_NOINTERFACE if the requested interface wasn't found
62 *****************************************************************************/
63 static HRESULT WINAPI
d3d_material3_QueryInterface(IDirect3DMaterial3
*iface
, REFIID riid
, void **obp
)
65 struct d3d_material
*material
= impl_from_IDirect3DMaterial3(iface
);
67 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obp
);
71 if (IsEqualGUID(&IID_IUnknown
, riid
))
73 IDirect3DMaterial3_AddRef(iface
);
75 TRACE(" Creating IUnknown interface at %p.\n", *obp
);
78 if (IsEqualGUID(&IID_IDirect3DMaterial
, riid
))
80 IDirect3DMaterial_AddRef(&material
->IDirect3DMaterial_iface
);
81 *obp
= &material
->IDirect3DMaterial_iface
;
82 TRACE(" Creating IDirect3DMaterial interface %p\n", *obp
);
85 if (IsEqualGUID(&IID_IDirect3DMaterial2
, riid
))
87 IDirect3DMaterial2_AddRef(&material
->IDirect3DMaterial2_iface
);
88 *obp
= &material
->IDirect3DMaterial2_iface
;
89 TRACE(" Creating IDirect3DMaterial2 interface %p\n", *obp
);
92 if (IsEqualGUID(&IID_IDirect3DMaterial3
, riid
))
94 IDirect3DMaterial3_AddRef(&material
->IDirect3DMaterial3_iface
);
95 *obp
= &material
->IDirect3DMaterial3_iface
;
96 TRACE(" Creating IDirect3DMaterial3 interface %p\n", *obp
);
100 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
102 return E_NOINTERFACE
;
105 /*****************************************************************************
106 * IDirect3DMaterial3::AddRef
108 * Increases the refcount.
113 *****************************************************************************/
114 static ULONG WINAPI
d3d_material3_AddRef(IDirect3DMaterial3
*iface
)
116 struct d3d_material
*material
= impl_from_IDirect3DMaterial3(iface
);
117 ULONG ref
= InterlockedIncrement(&material
->ref
);
119 TRACE("%p increasing refcount to %u.\n", material
, ref
);
124 /*****************************************************************************
125 * IDirect3DMaterial3::Release
127 * Reduces the refcount by one. If the refcount falls to 0, the object
133 *****************************************************************************/
134 static ULONG WINAPI
d3d_material3_Release(IDirect3DMaterial3
*iface
)
136 struct d3d_material
*material
= impl_from_IDirect3DMaterial3(iface
);
137 ULONG ref
= InterlockedDecrement(&material
->ref
);
139 TRACE("%p decreasing refcount to %u.\n", material
, ref
);
143 if (material
->Handle
)
145 wined3d_mutex_lock();
146 ddraw_free_handle(&material
->ddraw
->d3ddevice
->handle_table
, material
->Handle
- 1, DDRAW_HANDLE_MATERIAL
);
147 wined3d_mutex_unlock();
156 /*****************************************************************************
157 * IDirect3DMaterial Methods
158 *****************************************************************************/
160 /*****************************************************************************
161 * IDirect3DMaterial::Initialize
163 * A no-op initialization
166 * Direct3D: Pointer to a Direct3D interface
171 *****************************************************************************/
172 static HRESULT WINAPI
d3d_material1_Initialize(IDirect3DMaterial
*iface
, IDirect3D
*d3d
)
174 TRACE("iface %p, d3d %p.\n", iface
, d3d
);
179 /*****************************************************************************
180 * IDirect3DMaterial::Reserve
182 * DirectX 5 sdk: "The IDirect3DMaterial2::Reserve method is not implemented"
183 * Odd. They seem to have mixed their interfaces.
188 *****************************************************************************/
189 static HRESULT WINAPI
d3d_material1_Reserve(IDirect3DMaterial
*iface
)
191 TRACE("iface %p.\n", iface
);
193 return DDERR_UNSUPPORTED
;
196 /*****************************************************************************
197 * IDirect3DMaterial::Unreserve
204 *****************************************************************************/
205 static HRESULT WINAPI
d3d_material1_Unreserve(IDirect3DMaterial
*iface
)
207 TRACE("iface %p.\n", iface
);
209 return DDERR_UNSUPPORTED
;
212 /*****************************************************************************
213 * IDirect3DMaterial3::SetMaterial
215 * Sets the material description
218 * Mat: Material to set
222 * DDERR_INVALIDPARAMS if Mat is NULL
224 *****************************************************************************/
225 static HRESULT WINAPI
d3d_material3_SetMaterial(IDirect3DMaterial3
*iface
, D3DMATERIAL
*mat
)
227 struct d3d_material
*material
= impl_from_IDirect3DMaterial3(iface
);
229 TRACE("iface %p, mat %p.\n", iface
, mat
);
233 /* Stores the material */
234 wined3d_mutex_lock();
235 memset(&material
->mat
, 0, sizeof(material
->mat
));
236 memcpy(&material
->mat
, mat
, mat
->dwSize
);
237 wined3d_mutex_unlock();
242 /*****************************************************************************
243 * IDirect3DMaterial3::GetMaterial
245 * Returns the material assigned to this interface
248 * Mat: Pointer to a D3DMATERIAL structure to store the material description
252 * DDERR_INVALIDPARAMS if Mat is NULL
254 *****************************************************************************/
255 static HRESULT WINAPI
d3d_material3_GetMaterial(IDirect3DMaterial3
*iface
, D3DMATERIAL
*mat
)
257 struct d3d_material
*material
= impl_from_IDirect3DMaterial3(iface
);
260 TRACE("iface %p, mat %p.\n", iface
, mat
);
263 TRACE(" Returning material : ");
264 dump_material(&material
->mat
);
267 /* Copies the material structure */
268 wined3d_mutex_lock();
269 dwSize
= mat
->dwSize
;
270 memcpy(mat
, &material
->mat
, dwSize
);
271 wined3d_mutex_unlock();
276 /*****************************************************************************
277 * IDirect3DMaterial3::GetHandle
279 * Returns a handle for the material interface. The handle is simply a
280 * pointer to the material implementation
283 * Direct3DDevice3: The device this handle is assigned to
284 * Handle: Address to write the handle to
288 * DDERR_INVALIDPARAMS if Handle is NULL
290 *****************************************************************************/
291 static HRESULT WINAPI
d3d_material3_GetHandle(IDirect3DMaterial3
*iface
,
292 IDirect3DDevice3
*device
, D3DMATERIALHANDLE
*handle
)
294 struct d3d_material
*material
= impl_from_IDirect3DMaterial3(iface
);
295 struct d3d_device
*device_impl
= unsafe_impl_from_IDirect3DDevice3(device
);
297 TRACE("iface %p, device %p, handle %p.\n", iface
, device
, handle
);
299 wined3d_mutex_lock();
300 material
->active_device
= device_impl
;
301 if (!material
->Handle
)
303 DWORD h
= ddraw_allocate_handle(&device_impl
->handle_table
, material
, DDRAW_HANDLE_MATERIAL
);
304 if (h
== DDRAW_INVALID_HANDLE
)
306 ERR("Failed to allocate a material handle.\n");
307 wined3d_mutex_unlock();
308 return DDERR_INVALIDPARAMS
; /* Unchecked */
311 material
->Handle
= h
+ 1;
313 *handle
= material
->Handle
;
314 TRACE(" returning handle %08x.\n", *handle
);
315 wined3d_mutex_unlock();
320 static HRESULT WINAPI
d3d_material2_GetHandle(IDirect3DMaterial2
*iface
,
321 IDirect3DDevice2
*device
, D3DMATERIALHANDLE
*handle
)
323 struct d3d_material
*material
= impl_from_IDirect3DMaterial2(iface
);
324 struct d3d_device
*device_impl
= unsafe_impl_from_IDirect3DDevice2(device
);
326 TRACE("iface %p, device %p, handle %p.\n", iface
, device
, handle
);
328 return d3d_material3_GetHandle(&material
->IDirect3DMaterial3_iface
,
329 device_impl
? &device_impl
->IDirect3DDevice3_iface
: NULL
, handle
);
332 static HRESULT WINAPI
d3d_material1_GetHandle(IDirect3DMaterial
*iface
,
333 IDirect3DDevice
*device
, D3DMATERIALHANDLE
*handle
)
335 struct d3d_material
*material
= impl_from_IDirect3DMaterial(iface
);
336 struct d3d_device
*device_impl
= unsafe_impl_from_IDirect3DDevice(device
);
338 TRACE("iface %p, device %p, handle %p.\n", iface
, device
, handle
);
340 return d3d_material3_GetHandle(&material
->IDirect3DMaterial3_iface
,
341 device_impl
? &device_impl
->IDirect3DDevice3_iface
: NULL
, handle
);
344 static HRESULT WINAPI
d3d_material2_QueryInterface(IDirect3DMaterial2
*iface
, REFIID riid
, void **object
)
346 struct d3d_material
*material
= impl_from_IDirect3DMaterial2(iface
);
348 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
350 return d3d_material3_QueryInterface(&material
->IDirect3DMaterial3_iface
, riid
, object
);
353 static HRESULT WINAPI
d3d_material1_QueryInterface(IDirect3DMaterial
*iface
, REFIID riid
, void **object
)
355 struct d3d_material
*material
= impl_from_IDirect3DMaterial(iface
);
357 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
359 return d3d_material3_QueryInterface(&material
->IDirect3DMaterial3_iface
, riid
, object
);
362 static ULONG WINAPI
d3d_material2_AddRef(IDirect3DMaterial2
*iface
)
364 struct d3d_material
*material
= impl_from_IDirect3DMaterial2(iface
);
366 TRACE("iface %p.\n", iface
);
368 return d3d_material3_AddRef(&material
->IDirect3DMaterial3_iface
);
371 static ULONG WINAPI
d3d_material1_AddRef(IDirect3DMaterial
*iface
)
373 struct d3d_material
*material
= impl_from_IDirect3DMaterial(iface
);
375 TRACE("iface %p.\n", iface
);
377 return d3d_material3_AddRef(&material
->IDirect3DMaterial3_iface
);
380 static ULONG WINAPI
d3d_material2_Release(IDirect3DMaterial2
*iface
)
382 struct d3d_material
*material
= impl_from_IDirect3DMaterial2(iface
);
384 TRACE("iface %p.\n", iface
);
386 return d3d_material3_Release(&material
->IDirect3DMaterial3_iface
);
389 static ULONG WINAPI
d3d_material1_Release(IDirect3DMaterial
*iface
)
391 struct d3d_material
*material
= impl_from_IDirect3DMaterial(iface
);
393 TRACE("iface %p.\n", iface
);
395 return d3d_material3_Release(&material
->IDirect3DMaterial3_iface
);
398 static HRESULT WINAPI
d3d_material2_SetMaterial(IDirect3DMaterial2
*iface
, D3DMATERIAL
*mat
)
400 struct d3d_material
*material
= impl_from_IDirect3DMaterial2(iface
);
402 TRACE("iface %p, material %p.\n", iface
, mat
);
404 return d3d_material3_SetMaterial(&material
->IDirect3DMaterial3_iface
, mat
);
407 static HRESULT WINAPI
d3d_material1_SetMaterial(IDirect3DMaterial
*iface
, D3DMATERIAL
*mat
)
409 struct d3d_material
*material
= impl_from_IDirect3DMaterial(iface
);
411 TRACE("iface %p, material %p.\n", iface
, mat
);
413 return d3d_material3_SetMaterial(&material
->IDirect3DMaterial3_iface
, mat
);
416 static HRESULT WINAPI
d3d_material2_GetMaterial(IDirect3DMaterial2
*iface
, D3DMATERIAL
*mat
)
418 struct d3d_material
*material
= impl_from_IDirect3DMaterial2(iface
);
420 TRACE("iface %p, material %p.\n", iface
, mat
);
422 return d3d_material3_GetMaterial(&material
->IDirect3DMaterial3_iface
, mat
);
425 static HRESULT WINAPI
d3d_material1_GetMaterial(IDirect3DMaterial
*iface
, D3DMATERIAL
*mat
)
427 struct d3d_material
*material
= impl_from_IDirect3DMaterial(iface
);
429 TRACE("iface %p, material %p.\n", iface
, mat
);
431 return d3d_material3_GetMaterial(&material
->IDirect3DMaterial3_iface
, mat
);
435 /*****************************************************************************
438 * Uses IDirect3DDevice7::SetMaterial to activate the material
441 * This: Pointer to the material implementation to activate
443 *****************************************************************************/
444 void material_activate(struct d3d_material
*material
)
446 D3DMATERIAL7 d3d7mat
;
448 TRACE("Activating material %p.\n", material
);
450 d3d7mat
.u
.diffuse
= material
->mat
.u
.diffuse
;
451 d3d7mat
.u1
.ambient
= material
->mat
.u1
.ambient
;
452 d3d7mat
.u2
.specular
= material
->mat
.u2
.specular
;
453 d3d7mat
.u3
.emissive
= material
->mat
.u3
.emissive
;
454 d3d7mat
.u4
.power
= material
->mat
.u4
.power
;
456 IDirect3DDevice7_SetMaterial(&material
->active_device
->IDirect3DDevice7_iface
, &d3d7mat
);
459 static const struct IDirect3DMaterial3Vtbl d3d_material3_vtbl
=
461 /*** IUnknown Methods ***/
462 d3d_material3_QueryInterface
,
463 d3d_material3_AddRef
,
464 d3d_material3_Release
,
465 /*** IDirect3DMaterial3 Methods ***/
466 d3d_material3_SetMaterial
,
467 d3d_material3_GetMaterial
,
468 d3d_material3_GetHandle
,
471 static const struct IDirect3DMaterial2Vtbl d3d_material2_vtbl
=
473 /*** IUnknown Methods ***/
474 d3d_material2_QueryInterface
,
475 d3d_material2_AddRef
,
476 d3d_material2_Release
,
477 /*** IDirect3DMaterial2 Methods ***/
478 d3d_material2_SetMaterial
,
479 d3d_material2_GetMaterial
,
480 d3d_material2_GetHandle
,
483 static const struct IDirect3DMaterialVtbl d3d_material1_vtbl
=
485 /*** IUnknown Methods ***/
486 d3d_material1_QueryInterface
,
487 d3d_material1_AddRef
,
488 d3d_material1_Release
,
489 /*** IDirect3DMaterial1 Methods ***/
490 d3d_material1_Initialize
,
491 d3d_material1_SetMaterial
,
492 d3d_material1_GetMaterial
,
493 d3d_material1_GetHandle
,
494 d3d_material1_Reserve
,
495 d3d_material1_Unreserve
,
498 struct d3d_material
*d3d_material_create(struct ddraw
*ddraw
)
500 struct d3d_material
*material
;
502 if (!(material
= heap_alloc_zero(sizeof(*material
))))
505 material
->IDirect3DMaterial3_iface
.lpVtbl
= &d3d_material3_vtbl
;
506 material
->IDirect3DMaterial2_iface
.lpVtbl
= &d3d_material2_vtbl
;
507 material
->IDirect3DMaterial_iface
.lpVtbl
= &d3d_material1_vtbl
;
509 material
->ddraw
= ddraw
;