Changelog : Make D3D1..3 lights code rely on D3D7. Christian Costa titan.costa@wanadoo.fr
diff -u -r ../../../../winebase/wine/dlls/ddraw/d3d_private.h ./d3d_private.h --- ../../../../winebase/wine/dlls/ddraw/d3d_private.h Wed Jan 8 20:31:50 2003 +++ ./d3d_private.h Thu Jan 16 22:26:47 2003 @@ -90,8 +90,13 @@ DWORD ref; /* IDirect3DLight fields */ IDirect3DImpl *d3d; + /* If this light is active for one viewport, put the viewport here */ + IDirect3DViewportImpl *active_viewport; D3DLIGHT2 light; + D3DLIGHT7 light7; + + DWORD dwLightIndex; /* Chained list used for adding / removing from viewports */ IDirect3DLightImpl *next; @@ -131,6 +136,9 @@ IDirect3DImpl *d3d; /* If this viewport is active for one device, put the device here */ IDirect3DDeviceImpl *active_device; + + DWORD num_lights; + DWORD map_lights; int use_vp2; union { diff -u -r ../../../../winebase/wine/dlls/ddraw/d3dlight.c ./d3dlight.c --- ../../../../winebase/wine/dlls/ddraw/d3dlight.c Wed Jan 8 20:31:50 2003 +++ ./d3dlight.c Thu Jan 16 23:16:00 2003 @@ -79,16 +79,46 @@ DPRINTF(" - dwSize : %ld\n", light->dwSize); } +static const float zero_value[] = { + 0.0, 0.0, 0.0, 0.0 +}; + HRESULT WINAPI Main_IDirect3DLightImpl_1_SetLight(LPDIRECT3DLIGHT iface, LPD3DLIGHT lpLight) { ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface); + LPD3DLIGHT7 light7 = &(This->light7); TRACE("(%p/%p)->(%p)\n", This, iface, lpLight); if (TRACE_ON(ddraw)) { TRACE(" Light definition : \n"); dump_light((LPD3DLIGHT2) lpLight); } + + if ( (lpLight->dltType == 0) || (lpLight->dltType > D3DLIGHT_PARALLELPOINT) ) + return DDERR_INVALIDPARAMS; + + if ( lpLight->dltType == D3DLIGHT_PARALLELPOINT ) + FIXME("D3DLIGHT_PARALLELPOINT no supported\n"); + + /* Translate D3DLIGH2 structure to D3DLIGHT7 */ + light7->dltType = lpLight->dltType; + light7->dcvDiffuse = lpLight->dcvColor; + if ((((LPD3DLIGHT2)lpLight)->dwFlags & D3DLIGHT_NO_SPECULAR) != 0) + light7->dcvSpecular = lpLight->dcvColor; + else + light7->dcvSpecular = *(D3DCOLORVALUE*)zero_value; + light7->dcvAmbient = lpLight->dcvColor; + light7->dvPosition = lpLight->dvPosition; + light7->dvDirection = lpLight->dvDirection; + light7->dvRange = lpLight->dvRange; + light7->dvFalloff = lpLight->dvFalloff; + light7->dvAttenuation0 = lpLight->dvAttenuation0; + light7->dvAttenuation1 = lpLight->dvAttenuation1; + light7->dvAttenuation2 = lpLight->dvAttenuation2; + light7->dvTheta = lpLight->dvTheta; + light7->dvPhi = lpLight->dvPhi; + memcpy(&This->light, lpLight, lpLight->dwSize); if ((This->light.dwFlags & D3DLIGHT_ACTIVE) != 0) { This->update(This); @@ -113,50 +143,10 @@ /******************************************************************************* * Light static functions */ -static const float zero_value[] = { - 0.0, 0.0, 0.0, 0.0 -}; static void update(IDirect3DLightImpl* This) { - IDirect3DLightGLImpl *glThis = (IDirect3DLightGLImpl *) This; - ENTER_GL(); - switch (glThis->parent.light.dltType) { - case D3DLIGHT_POINT: /* 1 */ - FIXME("Activating POINT - not supported yet\n"); - break; - - case D3DLIGHT_SPOT: /* 2 */ - FIXME("Activating SPOT - not supported yet\n"); - break; - - case D3DLIGHT_DIRECTIONAL: { /* 3 */ - float direction[4]; - - if (TRACE_ON(ddraw)) { - TRACE("Activating DIRECTIONAL\n"); - DPRINTF(" - direction : "); dump_D3DVECTOR(&(glThis->parent.light.dvDirection)); DPRINTF("\n"); - DPRINTF(" - color : "); dump_D3DCOLORVALUE(&(glThis->parent.light.dcvColor)); DPRINTF("\n"); - } - glLightfv(glThis->light_num, GL_AMBIENT, (float *) zero_value); - glLightfv(glThis->light_num, GL_DIFFUSE, (float *) &(glThis->parent.light.dcvColor)); - - direction[0] = -glThis->parent.light.dvDirection.u1.x; - direction[1] = -glThis->parent.light.dvDirection.u2.y; - direction[2] = -glThis->parent.light.dvDirection.u3.z; - direction[3] = 0.0; /* This is a directional light */ - - glLightfv(glThis->light_num, GL_POSITION, (float *) direction); - } break; - - case D3DLIGHT_PARALLELPOINT: /* 4 */ - FIXME("Activating PARRALLEL-POINT - not supported yet\n"); - break; - - default: - WARN("Not a known Light Type: %d\n", glThis->parent.light.dltType); - break; - } - LEAVE_GL(); + IDirect3DDeviceImpl* device = This->active_viewport->active_device; + IDirect3DDevice7_SetLight(ICOM_INTERFACE(device,IDirect3DDevice7),This->dwLightIndex,&(This->light7)); } static void activate(IDirect3DLightImpl* This) { @@ -236,6 +226,7 @@ object->activate = activate; object->desactivate = desactivate; object->update = update; + object->active_viewport = NULL; gl_object->light_num = light_num; ICOM_INIT_INTERFACE(object, IDirect3DLight, VTABLE_IDirect3DLight); diff -u -r ../../../../winebase/wine/dlls/ddraw/d3dviewport.c ./d3dviewport.c --- ../../../../winebase/wine/dlls/ddraw/d3dviewport.c Wed Jan 8 20:31:50 2003 +++ ./d3dviewport.c Thu Jan 16 23:13:43 2003 @@ -271,13 +271,30 @@ { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight); + DWORD i = 0; + DWORD map = This->map_lights; TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DLight); + if (This->num_lights >= 8) + return DDERR_INVALIDPARAMS; + + /* Find a light number and update both light and viewports objects accordingly */ + while(map&1) { + map>>=1; + i++; + } + lpDirect3DLightImpl->dwLightIndex = i; + This->num_lights++; + This->map_lights |= 1<<i; + /* Add the light in the 'linked' chain */ lpDirect3DLightImpl->next = This->lights; This->lights = lpDirect3DLightImpl; + /* Attach the light to the viewport */ + lpDirect3DLightImpl->active_viewport = This; + /* If active, activate the light */ if (This->active_device != NULL) { lpDirect3DLightImpl->activate(lpDirect3DLightImpl); @@ -301,6 +318,10 @@ lpDirect3DLightImpl->desactivate(lpDirect3DLightImpl); if (prev_light == NULL) This->lights = cur_light->next; else prev_light->next = cur_light->next; + /* Detach the light to the viewport */ + cur_light->active_viewport = NULL; + This->num_lights--; + This->map_lights &= ~(1<<lpDirect3DLightImpl->dwLightIndex); return DD_OK; } prev_light = cur_light; @@ -450,6 +471,8 @@ object->use_vp2 = 0xFF; object->next = NULL; object->lights = NULL; + object->num_lights = 0; + object->map_lights = 0; ICOM_INIT_INTERFACE(object, IDirect3DViewport3, VTABLE_IDirect3DViewport3);