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
21 #include "wine/port.h"
23 #include "ddraw_private.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
27 static void dump_material(const D3DMATERIAL
*mat
)
29 TRACE(" dwSize : %d\n", mat
->dwSize
);
32 static inline struct d3d_material
*impl_from_IDirect3DMaterial(IDirect3DMaterial
*iface
)
34 return CONTAINING_RECORD(iface
, struct d3d_material
, IDirect3DMaterial_iface
);
37 static inline struct d3d_material
*impl_from_IDirect3DMaterial2(IDirect3DMaterial2
*iface
)
39 return CONTAINING_RECORD(iface
, struct d3d_material
, IDirect3DMaterial2_iface
);
42 static inline struct d3d_material
*impl_from_IDirect3DMaterial3(IDirect3DMaterial3
*iface
)
44 return CONTAINING_RECORD(iface
, struct d3d_material
, IDirect3DMaterial3_iface
);
47 /*****************************************************************************
49 *****************************************************************************/
51 /*****************************************************************************
52 * IDirect3DMaterial3::QueryInterface
54 * QueryInterface for IDirect3DMaterial. Can query all IDirect3DMaterial
58 * riid: Interface id queried for
59 * obj: Address to pass the interface pointer back
63 * E_NOINTERFACE if the requested interface wasn't found
65 *****************************************************************************/
66 static HRESULT WINAPI
d3d_material3_QueryInterface(IDirect3DMaterial3
*iface
, REFIID riid
, void **obp
)
68 struct d3d_material
*material
= impl_from_IDirect3DMaterial3(iface
);
70 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obp
);
74 if (IsEqualGUID(&IID_IUnknown
, riid
))
76 IDirect3DMaterial3_AddRef(iface
);
78 TRACE(" Creating IUnknown interface at %p.\n", *obp
);
81 if (IsEqualGUID(&IID_IDirect3DMaterial
, riid
))
83 IDirect3DMaterial_AddRef(&material
->IDirect3DMaterial_iface
);
84 *obp
= &material
->IDirect3DMaterial_iface
;
85 TRACE(" Creating IDirect3DMaterial interface %p\n", *obp
);
88 if (IsEqualGUID(&IID_IDirect3DMaterial2
, riid
))
90 IDirect3DMaterial2_AddRef(&material
->IDirect3DMaterial2_iface
);
91 *obp
= &material
->IDirect3DMaterial2_iface
;
92 TRACE(" Creating IDirect3DMaterial2 interface %p\n", *obp
);
95 if (IsEqualGUID(&IID_IDirect3DMaterial3
, riid
))
97 IDirect3DMaterial3_AddRef(&material
->IDirect3DMaterial3_iface
);
98 *obp
= &material
->IDirect3DMaterial3_iface
;
99 TRACE(" Creating IDirect3DMaterial3 interface %p\n", *obp
);
103 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
105 return E_NOINTERFACE
;
108 /*****************************************************************************
109 * IDirect3DMaterial3::AddRef
111 * Increases the refcount.
116 *****************************************************************************/
117 static ULONG WINAPI
d3d_material3_AddRef(IDirect3DMaterial3
*iface
)
119 struct d3d_material
*material
= impl_from_IDirect3DMaterial3(iface
);
120 ULONG ref
= InterlockedIncrement(&material
->ref
);
122 TRACE("%p increasing refcount to %u.\n", material
, ref
);
127 /*****************************************************************************
128 * IDirect3DMaterial3::Release
130 * Reduces the refcount by one. If the refcount falls to 0, the object
136 *****************************************************************************/
137 static ULONG WINAPI
d3d_material3_Release(IDirect3DMaterial3
*iface
)
139 struct d3d_material
*material
= impl_from_IDirect3DMaterial3(iface
);
140 ULONG ref
= InterlockedDecrement(&material
->ref
);
142 TRACE("%p decreasing refcount to %u.\n", material
, ref
);
146 if (material
->Handle
)
148 wined3d_mutex_lock();
149 ddraw_free_handle(&material
->ddraw
->d3ddevice
->handle_table
, material
->Handle
- 1, DDRAW_HANDLE_MATERIAL
);
150 wined3d_mutex_unlock();
159 /*****************************************************************************
160 * IDirect3DMaterial Methods
161 *****************************************************************************/
163 /*****************************************************************************
164 * IDirect3DMaterial::Initialize
166 * A no-op initialization
169 * Direct3D: Pointer to a Direct3D interface
174 *****************************************************************************/
175 static HRESULT WINAPI
d3d_material1_Initialize(IDirect3DMaterial
*iface
, IDirect3D
*d3d
)
177 TRACE("iface %p, d3d %p.\n", iface
, d3d
);
182 /*****************************************************************************
183 * IDirect3DMaterial::Reserve
185 * DirectX 5 sdk: "The IDirect3DMaterial2::Reserve method is not implemented"
186 * Odd. They seem to have mixed their interfaces.
191 *****************************************************************************/
192 static HRESULT WINAPI
d3d_material1_Reserve(IDirect3DMaterial
*iface
)
194 TRACE("iface %p.\n", iface
);
196 return DDERR_UNSUPPORTED
;
199 /*****************************************************************************
200 * IDirect3DMaterial::Unreserve
207 *****************************************************************************/
208 static HRESULT WINAPI
d3d_material1_Unreserve(IDirect3DMaterial
*iface
)
210 TRACE("iface %p.\n", iface
);
212 return DDERR_UNSUPPORTED
;
215 /*****************************************************************************
216 * IDirect3DMaterial3::SetMaterial
218 * Sets the material description
221 * Mat: Material to set
225 * DDERR_INVALIDPARAMS if Mat is NULL
227 *****************************************************************************/
228 static HRESULT WINAPI
d3d_material3_SetMaterial(IDirect3DMaterial3
*iface
, D3DMATERIAL
*mat
)
230 struct d3d_material
*material
= impl_from_IDirect3DMaterial3(iface
);
232 TRACE("iface %p, mat %p.\n", iface
, mat
);
236 /* Stores the material */
237 wined3d_mutex_lock();
238 memset(&material
->mat
, 0, sizeof(material
->mat
));
239 memcpy(&material
->mat
, mat
, mat
->dwSize
);
240 wined3d_mutex_unlock();
245 /*****************************************************************************
246 * IDirect3DMaterial3::GetMaterial
248 * Returns the material assigned to this interface
251 * Mat: Pointer to a D3DMATERIAL structure to store the material description
255 * DDERR_INVALIDPARAMS if Mat is NULL
257 *****************************************************************************/
258 static HRESULT WINAPI
d3d_material3_GetMaterial(IDirect3DMaterial3
*iface
, D3DMATERIAL
*mat
)
260 struct d3d_material
*material
= impl_from_IDirect3DMaterial3(iface
);
263 TRACE("iface %p, mat %p.\n", iface
, mat
);
266 TRACE(" Returning material : ");
267 dump_material(&material
->mat
);
270 /* Copies the material structure */
271 wined3d_mutex_lock();
272 dwSize
= mat
->dwSize
;
273 memcpy(mat
, &material
->mat
, dwSize
);
274 wined3d_mutex_unlock();
279 /*****************************************************************************
280 * IDirect3DMaterial3::GetHandle
282 * Returns a handle for the material interface. The handle is simply a
283 * pointer to the material implementation
286 * Direct3DDevice3: The device this handle is assigned to
287 * Handle: Address to write the handle to
291 * DDERR_INVALIDPARAMS if Handle is NULL
293 *****************************************************************************/
294 static HRESULT WINAPI
d3d_material3_GetHandle(IDirect3DMaterial3
*iface
,
295 IDirect3DDevice3
*device
, D3DMATERIALHANDLE
*handle
)
297 struct d3d_material
*material
= impl_from_IDirect3DMaterial3(iface
);
298 struct d3d_device
*device_impl
= unsafe_impl_from_IDirect3DDevice3(device
);
300 TRACE("iface %p, device %p, handle %p.\n", iface
, device
, handle
);
302 wined3d_mutex_lock();
303 material
->active_device
= device_impl
;
304 if (!material
->Handle
)
306 DWORD h
= ddraw_allocate_handle(&device_impl
->handle_table
, material
, DDRAW_HANDLE_MATERIAL
);
307 if (h
== DDRAW_INVALID_HANDLE
)
309 ERR("Failed to allocate a material handle.\n");
310 wined3d_mutex_unlock();
311 return DDERR_INVALIDPARAMS
; /* Unchecked */
314 material
->Handle
= h
+ 1;
316 *handle
= material
->Handle
;
317 TRACE(" returning handle %08x.\n", *handle
);
318 wined3d_mutex_unlock();
323 static HRESULT WINAPI
d3d_material2_GetHandle(IDirect3DMaterial2
*iface
,
324 IDirect3DDevice2
*device
, D3DMATERIALHANDLE
*handle
)
326 struct d3d_material
*material
= impl_from_IDirect3DMaterial2(iface
);
327 struct d3d_device
*device_impl
= unsafe_impl_from_IDirect3DDevice2(device
);
329 TRACE("iface %p, device %p, handle %p.\n", iface
, device
, handle
);
331 return d3d_material3_GetHandle(&material
->IDirect3DMaterial3_iface
,
332 device_impl
? &device_impl
->IDirect3DDevice3_iface
: NULL
, handle
);
335 static HRESULT WINAPI
d3d_material1_GetHandle(IDirect3DMaterial
*iface
,
336 IDirect3DDevice
*device
, D3DMATERIALHANDLE
*handle
)
338 struct d3d_material
*material
= impl_from_IDirect3DMaterial(iface
);
339 struct d3d_device
*device_impl
= unsafe_impl_from_IDirect3DDevice(device
);
341 TRACE("iface %p, device %p, handle %p.\n", iface
, device
, handle
);
343 return d3d_material3_GetHandle(&material
->IDirect3DMaterial3_iface
,
344 device_impl
? &device_impl
->IDirect3DDevice3_iface
: NULL
, handle
);
347 static HRESULT WINAPI
d3d_material2_QueryInterface(IDirect3DMaterial2
*iface
, REFIID riid
, void **object
)
349 struct d3d_material
*material
= impl_from_IDirect3DMaterial2(iface
);
351 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
353 return d3d_material3_QueryInterface(&material
->IDirect3DMaterial3_iface
, riid
, object
);
356 static HRESULT WINAPI
d3d_material1_QueryInterface(IDirect3DMaterial
*iface
, REFIID riid
, void **object
)
358 struct d3d_material
*material
= impl_from_IDirect3DMaterial(iface
);
360 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
362 return d3d_material3_QueryInterface(&material
->IDirect3DMaterial3_iface
, riid
, object
);
365 static ULONG WINAPI
d3d_material2_AddRef(IDirect3DMaterial2
*iface
)
367 struct d3d_material
*material
= impl_from_IDirect3DMaterial2(iface
);
369 TRACE("iface %p.\n", iface
);
371 return d3d_material3_AddRef(&material
->IDirect3DMaterial3_iface
);
374 static ULONG WINAPI
d3d_material1_AddRef(IDirect3DMaterial
*iface
)
376 struct d3d_material
*material
= impl_from_IDirect3DMaterial(iface
);
378 TRACE("iface %p.\n", iface
);
380 return d3d_material3_AddRef(&material
->IDirect3DMaterial3_iface
);
383 static ULONG WINAPI
d3d_material2_Release(IDirect3DMaterial2
*iface
)
385 struct d3d_material
*material
= impl_from_IDirect3DMaterial2(iface
);
387 TRACE("iface %p.\n", iface
);
389 return d3d_material3_Release(&material
->IDirect3DMaterial3_iface
);
392 static ULONG WINAPI
d3d_material1_Release(IDirect3DMaterial
*iface
)
394 struct d3d_material
*material
= impl_from_IDirect3DMaterial(iface
);
396 TRACE("iface %p.\n", iface
);
398 return d3d_material3_Release(&material
->IDirect3DMaterial3_iface
);
401 static HRESULT WINAPI
d3d_material2_SetMaterial(IDirect3DMaterial2
*iface
, D3DMATERIAL
*mat
)
403 struct d3d_material
*material
= impl_from_IDirect3DMaterial2(iface
);
405 TRACE("iface %p, material %p.\n", iface
, mat
);
407 return d3d_material3_SetMaterial(&material
->IDirect3DMaterial3_iface
, mat
);
410 static HRESULT WINAPI
d3d_material1_SetMaterial(IDirect3DMaterial
*iface
, D3DMATERIAL
*mat
)
412 struct d3d_material
*material
= impl_from_IDirect3DMaterial(iface
);
414 TRACE("iface %p, material %p.\n", iface
, mat
);
416 return d3d_material3_SetMaterial(&material
->IDirect3DMaterial3_iface
, mat
);
419 static HRESULT WINAPI
d3d_material2_GetMaterial(IDirect3DMaterial2
*iface
, D3DMATERIAL
*mat
)
421 struct d3d_material
*material
= impl_from_IDirect3DMaterial2(iface
);
423 TRACE("iface %p, material %p.\n", iface
, mat
);
425 return d3d_material3_GetMaterial(&material
->IDirect3DMaterial3_iface
, mat
);
428 static HRESULT WINAPI
d3d_material1_GetMaterial(IDirect3DMaterial
*iface
, D3DMATERIAL
*mat
)
430 struct d3d_material
*material
= impl_from_IDirect3DMaterial(iface
);
432 TRACE("iface %p, material %p.\n", iface
, mat
);
434 return d3d_material3_GetMaterial(&material
->IDirect3DMaterial3_iface
, mat
);
438 /*****************************************************************************
441 * Uses IDirect3DDevice7::SetMaterial to activate the material
444 * This: Pointer to the material implementation to activate
446 *****************************************************************************/
447 void material_activate(struct d3d_material
*material
)
449 D3DMATERIAL7 d3d7mat
;
451 TRACE("Activating material %p.\n", material
);
453 d3d7mat
.u
.diffuse
= material
->mat
.u
.diffuse
;
454 d3d7mat
.u1
.ambient
= material
->mat
.u1
.ambient
;
455 d3d7mat
.u2
.specular
= material
->mat
.u2
.specular
;
456 d3d7mat
.u3
.emissive
= material
->mat
.u3
.emissive
;
457 d3d7mat
.u4
.power
= material
->mat
.u4
.power
;
459 IDirect3DDevice7_SetMaterial(&material
->active_device
->IDirect3DDevice7_iface
, &d3d7mat
);
462 static const struct IDirect3DMaterial3Vtbl d3d_material3_vtbl
=
464 /*** IUnknown Methods ***/
465 d3d_material3_QueryInterface
,
466 d3d_material3_AddRef
,
467 d3d_material3_Release
,
468 /*** IDirect3DMaterial3 Methods ***/
469 d3d_material3_SetMaterial
,
470 d3d_material3_GetMaterial
,
471 d3d_material3_GetHandle
,
474 static const struct IDirect3DMaterial2Vtbl d3d_material2_vtbl
=
476 /*** IUnknown Methods ***/
477 d3d_material2_QueryInterface
,
478 d3d_material2_AddRef
,
479 d3d_material2_Release
,
480 /*** IDirect3DMaterial2 Methods ***/
481 d3d_material2_SetMaterial
,
482 d3d_material2_GetMaterial
,
483 d3d_material2_GetHandle
,
486 static const struct IDirect3DMaterialVtbl d3d_material1_vtbl
=
488 /*** IUnknown Methods ***/
489 d3d_material1_QueryInterface
,
490 d3d_material1_AddRef
,
491 d3d_material1_Release
,
492 /*** IDirect3DMaterial1 Methods ***/
493 d3d_material1_Initialize
,
494 d3d_material1_SetMaterial
,
495 d3d_material1_GetMaterial
,
496 d3d_material1_GetHandle
,
497 d3d_material1_Reserve
,
498 d3d_material1_Unreserve
,
501 struct d3d_material
*d3d_material_create(struct ddraw
*ddraw
)
503 struct d3d_material
*material
;
505 if (!(material
= heap_alloc_zero(sizeof(*material
))))
508 material
->IDirect3DMaterial3_iface
.lpVtbl
= &d3d_material3_vtbl
;
509 material
->IDirect3DMaterial2_iface
.lpVtbl
= &d3d_material2_vtbl
;
510 material
->IDirect3DMaterial_iface
.lpVtbl
= &d3d_material1_vtbl
;
512 material
->ddraw
= ddraw
;