2 * Copyright (c) 1998 / 2002 Lionel ULMER
4 * This file contains the implementation of Direct3DLight.
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.
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.
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
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
35 #include "wine/debug.h"
37 #include "d3d_private.h"
38 #include "opengl_private.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
42 /* First, the 'main' interface... */
44 Main_IDirect3DLightImpl_1_QueryInterface(LPDIRECT3DLIGHT iface
,
48 ICOM_THIS_FROM(IDirect3DLightImpl
, IDirect3DLight
, iface
);
49 FIXME("(%p/%p)->(%s,%p): stub!\n", This
, iface
, debugstr_guid(riid
), obp
);
54 Main_IDirect3DLightImpl_1_AddRef(LPDIRECT3DLIGHT iface
)
56 ICOM_THIS_FROM(IDirect3DLightImpl
, IDirect3DLight
, iface
);
57 ULONG ref
= InterlockedIncrement(&This
->ref
);
59 TRACE("(%p/%p)->() incrementing from %lu.\n", This
, iface
, ref
- 1);
65 Main_IDirect3DLightImpl_1_Release(LPDIRECT3DLIGHT iface
)
67 ICOM_THIS_FROM(IDirect3DLightImpl
, IDirect3DLight
, iface
);
68 ULONG ref
= InterlockedDecrement(&This
->ref
);
70 TRACE("(%p/%p)->() decrementing from %lu.\n", This
, iface
, ref
+ 1);
73 HeapFree(GetProcessHeap(), 0, This
);
80 Main_IDirect3DLightImpl_1_Initialize(LPDIRECT3DLIGHT iface
,
81 LPDIRECT3D lpDirect3D
)
83 ICOM_THIS_FROM(IDirect3DLightImpl
, IDirect3DLight
, iface
);
84 TRACE("(%p/%p)->(%p) no-op...\n", This
, iface
, lpDirect3D
);
88 /*** IDirect3DLight methods ***/
89 static void dump_light(LPD3DLIGHT2 light
)
91 DPRINTF(" - dwSize : %ld\n", light
->dwSize
);
94 static const float zero_value
[] = {
99 Main_IDirect3DLightImpl_1_SetLight(LPDIRECT3DLIGHT iface
,
102 ICOM_THIS_FROM(IDirect3DLightImpl
, IDirect3DLight
, iface
);
103 LPD3DLIGHT7 light7
= &(This
->light7
);
104 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpLight
);
105 if (TRACE_ON(ddraw
)) {
106 TRACE(" Light definition : \n");
107 dump_light((LPD3DLIGHT2
) lpLight
);
110 if ( (lpLight
->dltType
== 0) || (lpLight
->dltType
> D3DLIGHT_PARALLELPOINT
) )
111 return DDERR_INVALIDPARAMS
;
113 if ( lpLight
->dltType
== D3DLIGHT_PARALLELPOINT
)
114 FIXME("D3DLIGHT_PARALLELPOINT no supported\n");
116 /* Translate D3DLIGH2 structure to D3DLIGHT7 */
117 light7
->dltType
= lpLight
->dltType
;
118 light7
->dcvDiffuse
= lpLight
->dcvColor
;
119 if ((((LPD3DLIGHT2
)lpLight
)->dwFlags
& D3DLIGHT_NO_SPECULAR
) != 0)
120 light7
->dcvSpecular
= lpLight
->dcvColor
;
122 light7
->dcvSpecular
= *(const D3DCOLORVALUE
*)zero_value
;
123 light7
->dcvAmbient
= lpLight
->dcvColor
;
124 light7
->dvPosition
= lpLight
->dvPosition
;
125 light7
->dvDirection
= lpLight
->dvDirection
;
126 light7
->dvRange
= lpLight
->dvRange
;
127 light7
->dvFalloff
= lpLight
->dvFalloff
;
128 light7
->dvAttenuation0
= lpLight
->dvAttenuation0
;
129 light7
->dvAttenuation1
= lpLight
->dvAttenuation1
;
130 light7
->dvAttenuation2
= lpLight
->dvAttenuation2
;
131 light7
->dvTheta
= lpLight
->dvTheta
;
132 light7
->dvPhi
= lpLight
->dvPhi
;
134 memcpy(&This
->light
, lpLight
, lpLight
->dwSize
);
135 if ((This
->light
.dwFlags
& D3DLIGHT_ACTIVE
) != 0) {
142 Main_IDirect3DLightImpl_1_GetLight(LPDIRECT3DLIGHT iface
,
145 ICOM_THIS_FROM(IDirect3DLightImpl
, IDirect3DLight
, iface
);
146 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpLight
);
147 if (TRACE_ON(ddraw
)) {
148 TRACE(" Returning light definition : \n");
149 dump_light(&This
->light
);
151 memcpy(lpLight
, &This
->light
, lpLight
->dwSize
);
155 /*******************************************************************************
156 * Light static functions
159 static void update(IDirect3DLightImpl
* This
) {
160 IDirect3DDeviceImpl
* device
;
161 if (!This
->active_viewport
||!This
->active_viewport
->active_device
)
163 device
= This
->active_viewport
->active_device
;
164 IDirect3DDevice7_SetLight(ICOM_INTERFACE(device
,IDirect3DDevice7
),This
->dwLightIndex
,&(This
->light7
));
167 static void activate(IDirect3DLightImpl
* This
) {
168 IDirect3DLightGLImpl
*glThis
= (IDirect3DLightGLImpl
*) This
;
170 TRACE("(%p)\n", This
);
174 /* If was not active, activate it */
175 if ((glThis
->parent
.light
.dwFlags
& D3DLIGHT_ACTIVE
) == 0) {
176 glEnable(glThis
->light_num
);
177 glThis
->parent
.light
.dwFlags
|= D3DLIGHT_ACTIVE
;
182 static void desactivate(IDirect3DLightImpl
* This
) {
183 IDirect3DLightGLImpl
*glThis
= (IDirect3DLightGLImpl
*) This
;
185 TRACE("(%p)\n", This
);
188 /* If was not active, activate it */
189 if ((glThis
->parent
.light
.dwFlags
& D3DLIGHT_ACTIVE
) != 0) {
190 glDisable(glThis
->light_num
);
191 glThis
->parent
.light
.dwFlags
&= ~D3DLIGHT_ACTIVE
;
197 GL_IDirect3DLightImpl_1_Release(LPDIRECT3DLIGHT iface
)
199 ICOM_THIS_FROM(IDirect3DLightImpl
, IDirect3DLight
, iface
);
200 IDirect3DLightGLImpl
*glThis
= (IDirect3DLightGLImpl
*) This
;
201 ULONG ref
= InterlockedDecrement(&This
->ref
);
203 TRACE("(%p/%p)->() decrementing from %lu.\n", This
, iface
, ref
+ 1);
206 ((IDirect3DGLImpl
*) This
->d3d
->d3d_private
)->light_released(This
->d3d
, glThis
->light_num
);
207 HeapFree(GetProcessHeap(), 0, This
);
213 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
214 # define XCAST(fun) (typeof(VTABLE_IDirect3DLight.fun))
216 # define XCAST(fun) (void*)
219 static const IDirect3DLightVtbl VTABLE_IDirect3DLight
=
221 XCAST(QueryInterface
) Main_IDirect3DLightImpl_1_QueryInterface
,
222 XCAST(AddRef
) Main_IDirect3DLightImpl_1_AddRef
,
223 XCAST(Release
) GL_IDirect3DLightImpl_1_Release
,
224 XCAST(Initialize
) Main_IDirect3DLightImpl_1_Initialize
,
225 XCAST(SetLight
) Main_IDirect3DLightImpl_1_SetLight
,
226 XCAST(GetLight
) Main_IDirect3DLightImpl_1_GetLight
,
229 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
236 HRESULT
d3dlight_create(IDirect3DLightImpl
**obj
, IDirectDrawImpl
*d3d
, GLenum light_num
)
238 IDirect3DLightImpl
*object
;
239 IDirect3DLightGLImpl
*gl_object
;
241 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DLightGLImpl
));
242 if (object
== NULL
) return DDERR_OUTOFMEMORY
;
243 gl_object
= (IDirect3DLightGLImpl
*) object
;
248 object
->activate
= activate
;
249 object
->desactivate
= desactivate
;
250 object
->update
= update
;
251 object
->active_viewport
= NULL
;
252 gl_object
->light_num
= light_num
;
254 ICOM_INIT_INTERFACE(object
, IDirect3DLight
, VTABLE_IDirect3DLight
);
258 TRACE(" creating implementation at %p.\n", *obj
);