1c2c66affSColin Finck /* Direct3D Light
2c2c66affSColin Finck * Copyright (c) 1998 / 2002 Lionel ULMER
3c2c66affSColin Finck * Copyright (c) 2006 Stefan DÖSINGER
4c2c66affSColin Finck *
5c2c66affSColin Finck * This library is free software; you can redistribute it and/or
6c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
7c2c66affSColin Finck * License as published by the Free Software Foundation; either
8c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
9c2c66affSColin Finck *
10c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
11c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
12c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13c2c66affSColin Finck * Lesser General Public License for more details.
14c2c66affSColin Finck *
15c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
16c2c66affSColin Finck * License along with this library; if not, write to the Free Software
17c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18c2c66affSColin Finck */
19c2c66affSColin Finck
20*9987f029SAmine Khaldi #include "config.h"
21*9987f029SAmine Khaldi #include "wine/port.h"
22*9987f029SAmine Khaldi
23c2c66affSColin Finck #include "ddraw_private.h"
24c2c66affSColin Finck
25*9987f029SAmine Khaldi WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
26*9987f029SAmine Khaldi
27c2c66affSColin Finck /*****************************************************************************
28c2c66affSColin Finck * light_update
29c2c66affSColin Finck *
30c2c66affSColin Finck * Updates the Direct3DDevice7 lighting parameters
31c2c66affSColin Finck *
32c2c66affSColin Finck *****************************************************************************/
light_update(struct d3d_light * light)33c2c66affSColin Finck static void light_update(struct d3d_light *light)
34c2c66affSColin Finck {
35c2c66affSColin Finck struct d3d_device *device;
36c2c66affSColin Finck
37c2c66affSColin Finck TRACE("light %p.\n", light);
38c2c66affSColin Finck
39c2c66affSColin Finck if (!light->active_viewport || !light->active_viewport->active_device) return;
40c2c66affSColin Finck device = light->active_viewport->active_device;
41c2c66affSColin Finck
42c2c66affSColin Finck IDirect3DDevice7_SetLight(&device->IDirect3DDevice7_iface, light->dwLightIndex, &light->light7);
43c2c66affSColin Finck }
44c2c66affSColin Finck
45c2c66affSColin Finck /*****************************************************************************
46c2c66affSColin Finck * light_activate
47c2c66affSColin Finck *
48c2c66affSColin Finck * Uses the Direct3DDevice7::LightEnable method to active the light
49c2c66affSColin Finck *
50c2c66affSColin Finck *****************************************************************************/
light_activate(struct d3d_light * light)51c2c66affSColin Finck void light_activate(struct d3d_light *light)
52c2c66affSColin Finck {
53c2c66affSColin Finck struct d3d_device *device;
54c2c66affSColin Finck
55c2c66affSColin Finck TRACE("light %p.\n", light);
56c2c66affSColin Finck
57c2c66affSColin Finck if (!light->active_viewport || !light->active_viewport->active_device) return;
58c2c66affSColin Finck device = light->active_viewport->active_device;
59c2c66affSColin Finck
60c2c66affSColin Finck light_update(light);
61c2c66affSColin Finck if (!(light->light.dwFlags & D3DLIGHT_ACTIVE))
62c2c66affSColin Finck {
63c2c66affSColin Finck IDirect3DDevice7_LightEnable(&device->IDirect3DDevice7_iface, light->dwLightIndex, TRUE);
64c2c66affSColin Finck light->light.dwFlags |= D3DLIGHT_ACTIVE;
65c2c66affSColin Finck }
66c2c66affSColin Finck }
67c2c66affSColin Finck
68c2c66affSColin Finck /*****************************************************************************
69c2c66affSColin Finck *
70c2c66affSColin Finck * light_deactivate
71c2c66affSColin Finck *
72c2c66affSColin Finck * Uses the Direct3DDevice7::LightEnable method to deactivate the light
73c2c66affSColin Finck *
74c2c66affSColin Finck *****************************************************************************/
light_deactivate(struct d3d_light * light)75c2c66affSColin Finck void light_deactivate(struct d3d_light *light)
76c2c66affSColin Finck {
77c2c66affSColin Finck struct d3d_device *device;
78c2c66affSColin Finck
79c2c66affSColin Finck TRACE("light %p.\n", light);
80c2c66affSColin Finck
81c2c66affSColin Finck if (!light->active_viewport || !light->active_viewport->active_device) return;
82c2c66affSColin Finck device = light->active_viewport->active_device;
83c2c66affSColin Finck
84c2c66affSColin Finck if (light->light.dwFlags & D3DLIGHT_ACTIVE)
85c2c66affSColin Finck {
86c2c66affSColin Finck IDirect3DDevice7_LightEnable(&device->IDirect3DDevice7_iface, light->dwLightIndex, FALSE);
87c2c66affSColin Finck light->light.dwFlags &= ~D3DLIGHT_ACTIVE;
88c2c66affSColin Finck }
89c2c66affSColin Finck }
90c2c66affSColin Finck
impl_from_IDirect3DLight(IDirect3DLight * iface)91c2c66affSColin Finck static inline struct d3d_light *impl_from_IDirect3DLight(IDirect3DLight *iface)
92c2c66affSColin Finck {
93c2c66affSColin Finck return CONTAINING_RECORD(iface, struct d3d_light, IDirect3DLight_iface);
94c2c66affSColin Finck }
95c2c66affSColin Finck
96c2c66affSColin Finck /*****************************************************************************
97c2c66affSColin Finck * IDirect3DLight::QueryInterface
98c2c66affSColin Finck *
99c2c66affSColin Finck * Queries the object for different interfaces. Unimplemented for this
100c2c66affSColin Finck * object at the moment
101c2c66affSColin Finck *
102c2c66affSColin Finck * Params:
103c2c66affSColin Finck * riid: Interface id asked for
104c2c66affSColin Finck * obj: Address to return the resulting pointer at.
105c2c66affSColin Finck *
106c2c66affSColin Finck * Returns:
107c2c66affSColin Finck * E_NOINTERFACE, because it's a stub
108c2c66affSColin Finck *****************************************************************************/
d3d_light_QueryInterface(IDirect3DLight * iface,REFIID riid,void ** object)109c2c66affSColin Finck static HRESULT WINAPI d3d_light_QueryInterface(IDirect3DLight *iface, REFIID riid, void **object)
110c2c66affSColin Finck {
111c2c66affSColin Finck FIXME("iface %p, riid %s, object %p stub!\n", iface, debugstr_guid(riid), object);
112c2c66affSColin Finck
113c2c66affSColin Finck *object = NULL;
114c2c66affSColin Finck return E_NOINTERFACE;
115c2c66affSColin Finck }
116c2c66affSColin Finck
d3d_light_AddRef(IDirect3DLight * iface)117c2c66affSColin Finck static ULONG WINAPI d3d_light_AddRef(IDirect3DLight *iface)
118c2c66affSColin Finck {
119c2c66affSColin Finck struct d3d_light *light = impl_from_IDirect3DLight(iface);
120c2c66affSColin Finck ULONG ref = InterlockedIncrement(&light->ref);
121c2c66affSColin Finck
122c2c66affSColin Finck TRACE("%p increasing refcount to %u.\n", light, ref);
123c2c66affSColin Finck
124c2c66affSColin Finck return ref;
125c2c66affSColin Finck }
126c2c66affSColin Finck
d3d_light_Release(IDirect3DLight * iface)127c2c66affSColin Finck static ULONG WINAPI d3d_light_Release(IDirect3DLight *iface)
128c2c66affSColin Finck {
129c2c66affSColin Finck struct d3d_light *light = impl_from_IDirect3DLight(iface);
130c2c66affSColin Finck ULONG ref = InterlockedDecrement(&light->ref);
131c2c66affSColin Finck
132c2c66affSColin Finck TRACE("%p decreasing refcount to %u.\n", light, ref);
133c2c66affSColin Finck
134c2c66affSColin Finck if (!ref)
135c2c66affSColin Finck {
136*9987f029SAmine Khaldi heap_free(light);
137c2c66affSColin Finck return 0;
138c2c66affSColin Finck }
139c2c66affSColin Finck return ref;
140c2c66affSColin Finck }
141c2c66affSColin Finck
142c2c66affSColin Finck /*****************************************************************************
143c2c66affSColin Finck * IDirect3DLight Methods.
144c2c66affSColin Finck *****************************************************************************/
145c2c66affSColin Finck
146c2c66affSColin Finck /*****************************************************************************
147c2c66affSColin Finck * IDirect3DLight::Initialize
148c2c66affSColin Finck *
149c2c66affSColin Finck * Initializes the interface. This implementation is a no-op, because
150c2c66affSColin Finck * initialization takes place at creation time
151c2c66affSColin Finck *
152c2c66affSColin Finck * Params:
153c2c66affSColin Finck * Direct3D: Pointer to an IDirect3D interface.
154c2c66affSColin Finck *
155c2c66affSColin Finck * Returns:
156c2c66affSColin Finck * D3D_OK
157c2c66affSColin Finck *
158c2c66affSColin Finck *****************************************************************************/
d3d_light_Initialize(IDirect3DLight * iface,IDirect3D * d3d)159c2c66affSColin Finck static HRESULT WINAPI d3d_light_Initialize(IDirect3DLight *iface, IDirect3D *d3d)
160c2c66affSColin Finck {
161c2c66affSColin Finck TRACE("iface %p, d3d %p.\n", iface, d3d);
162c2c66affSColin Finck
163c2c66affSColin Finck return D3D_OK;
164c2c66affSColin Finck }
165c2c66affSColin Finck
d3d_light_SetLight(IDirect3DLight * iface,D3DLIGHT * data)166c2c66affSColin Finck static HRESULT WINAPI d3d_light_SetLight(IDirect3DLight *iface, D3DLIGHT *data)
167c2c66affSColin Finck {
168c2c66affSColin Finck static const D3DCOLORVALUE zero_value = {{0.0f}, {0.0f}, {0.0f}, {0.0f}};
169c2c66affSColin Finck struct d3d_light *light = impl_from_IDirect3DLight(iface);
170c2c66affSColin Finck DWORD flags = data->dwSize >= sizeof(D3DLIGHT2) ? ((D3DLIGHT2 *)data)->dwFlags : D3DLIGHT_ACTIVE;
171c2c66affSColin Finck D3DLIGHT7 *light7 = &light->light7;
172c2c66affSColin Finck
173c2c66affSColin Finck TRACE("iface %p, data %p.\n", iface, data);
174c2c66affSColin Finck
175c2c66affSColin Finck if ((!data->dltType) || (data->dltType > D3DLIGHT_PARALLELPOINT))
176c2c66affSColin Finck return DDERR_INVALIDPARAMS;
177c2c66affSColin Finck
178c2c66affSColin Finck /* Translate D3DLIGHT2 structure to D3DLIGHT7. */
179c2c66affSColin Finck light7->dltType = data->dltType;
180c2c66affSColin Finck light7->dcvDiffuse = data->dcvColor;
181c2c66affSColin Finck if (flags & D3DLIGHT_NO_SPECULAR)
182c2c66affSColin Finck light7->dcvSpecular = zero_value;
183c2c66affSColin Finck else
184c2c66affSColin Finck light7->dcvSpecular = data->dcvColor;
185c2c66affSColin Finck light7->dcvAmbient = data->dcvColor;
186c2c66affSColin Finck light7->dvPosition = data->dvPosition;
187c2c66affSColin Finck light7->dvDirection = data->dvDirection;
188c2c66affSColin Finck light7->dvRange = data->dvRange;
189c2c66affSColin Finck light7->dvFalloff = data->dvFalloff;
190c2c66affSColin Finck light7->dvAttenuation0 = data->dvAttenuation0;
191c2c66affSColin Finck light7->dvAttenuation1 = data->dvAttenuation1;
192c2c66affSColin Finck light7->dvAttenuation2 = data->dvAttenuation2;
193c2c66affSColin Finck light7->dvTheta = data->dvTheta;
194c2c66affSColin Finck light7->dvPhi = data->dvPhi;
195c2c66affSColin Finck
196c2c66affSColin Finck wined3d_mutex_lock();
197c2c66affSColin Finck memcpy(&light->light, data, sizeof(*data));
198c2c66affSColin Finck if (!(light->light.dwFlags & D3DLIGHT_ACTIVE) && flags & D3DLIGHT_ACTIVE)
199c2c66affSColin Finck light_activate(light);
200c2c66affSColin Finck else if (light->light.dwFlags & D3DLIGHT_ACTIVE && !(flags & D3DLIGHT_ACTIVE))
201c2c66affSColin Finck light_deactivate(light);
202c2c66affSColin Finck else if (flags & D3DLIGHT_ACTIVE)
203c2c66affSColin Finck light_update(light);
204c2c66affSColin Finck light->light.dwFlags = flags;
205c2c66affSColin Finck wined3d_mutex_unlock();
206c2c66affSColin Finck
207c2c66affSColin Finck return D3D_OK;
208c2c66affSColin Finck }
209c2c66affSColin Finck
210c2c66affSColin Finck /*****************************************************************************
211c2c66affSColin Finck * IDirect3DLight::GetLight
212c2c66affSColin Finck *
213c2c66affSColin Finck * Returns the parameters currently assigned to the IDirect3DLight object
214c2c66affSColin Finck *
215c2c66affSColin Finck * Params:
216c2c66affSColin Finck * Light: Pointer to an D3DLIGHT structure to store the parameters
217c2c66affSColin Finck *
218c2c66affSColin Finck * Returns:
219c2c66affSColin Finck * D3D_OK on success
220c2c66affSColin Finck * DDERR_INVALIDPARAMS if Light is NULL
221c2c66affSColin Finck *****************************************************************************/
d3d_light_GetLight(IDirect3DLight * iface,D3DLIGHT * lpLight)222c2c66affSColin Finck static HRESULT WINAPI d3d_light_GetLight(IDirect3DLight *iface, D3DLIGHT *lpLight)
223c2c66affSColin Finck {
224c2c66affSColin Finck struct d3d_light *light = impl_from_IDirect3DLight(iface);
225c2c66affSColin Finck
226c2c66affSColin Finck TRACE("iface %p, light %p.\n", iface, lpLight);
227c2c66affSColin Finck
228c2c66affSColin Finck wined3d_mutex_lock();
229c2c66affSColin Finck memcpy(lpLight, &light->light, lpLight->dwSize);
230c2c66affSColin Finck wined3d_mutex_unlock();
231c2c66affSColin Finck
232c2c66affSColin Finck return DD_OK;
233c2c66affSColin Finck }
234c2c66affSColin Finck
235c2c66affSColin Finck static const struct IDirect3DLightVtbl d3d_light_vtbl =
236c2c66affSColin Finck {
237c2c66affSColin Finck /*** IUnknown Methods ***/
238c2c66affSColin Finck d3d_light_QueryInterface,
239c2c66affSColin Finck d3d_light_AddRef,
240c2c66affSColin Finck d3d_light_Release,
241c2c66affSColin Finck /*** IDirect3DLight Methods ***/
242c2c66affSColin Finck d3d_light_Initialize,
243c2c66affSColin Finck d3d_light_SetLight,
244c2c66affSColin Finck d3d_light_GetLight
245c2c66affSColin Finck };
246c2c66affSColin Finck
d3d_light_init(struct d3d_light * light,struct ddraw * ddraw)247c2c66affSColin Finck void d3d_light_init(struct d3d_light *light, struct ddraw *ddraw)
248c2c66affSColin Finck {
249c2c66affSColin Finck light->IDirect3DLight_iface.lpVtbl = &d3d_light_vtbl;
250c2c66affSColin Finck light->ref = 1;
251c2c66affSColin Finck light->ddraw = ddraw;
252c2c66affSColin Finck }
253c2c66affSColin Finck
unsafe_impl_from_IDirect3DLight(IDirect3DLight * iface)254c2c66affSColin Finck struct d3d_light *unsafe_impl_from_IDirect3DLight(IDirect3DLight *iface)
255c2c66affSColin Finck {
256c2c66affSColin Finck if (!iface)
257c2c66affSColin Finck return NULL;
258c2c66affSColin Finck assert(iface->lpVtbl == &d3d_light_vtbl);
259c2c66affSColin Finck
260c2c66affSColin Finck return impl_from_IDirect3DLight(iface);
261c2c66affSColin Finck }
262