static HRESULT WINAPI d3d_light_SetLight(IDirect3DLight *iface, D3DLIGHT *data) { struct d3d_light *light = impl_from_IDirect3DLight(iface); DWORD flags = data->dwSize >= sizeof(D3DLIGHT2) ? ((D3DLIGHT2 *)data)->dwFlags : D3DLIGHT_ACTIVE; D3DLIGHT7 *light7 = &light->light7; TRACE("iface %p, data %p.\n", iface, data); if ((!data->dltType) || (data->dltType > D3DLIGHT_PARALLELPOINT)) return DDERR_INVALIDPARAMS; if (data->dltType == D3DLIGHT_PARALLELPOINT) FIXME("D3DLIGHT_PARALLELPOINT not implemented.\n"); /* Translate D3DLIGHT2 structure to D3DLIGHT7. */ light7->dltType = data->dltType; light7->dcvDiffuse = data->dcvColor; if (!(flags & D3DLIGHT_NO_SPECULAR)) light7->dcvSpecular = data->dcvColor; else light7->dcvSpecular = *(const D3DCOLORVALUE *)zero_value; light7->dcvAmbient = data->dcvColor; light7->dvPosition = data->dvPosition; light7->dvDirection = data->dvDirection; light7->dvRange = data->dvRange; light7->dvFalloff = data->dvFalloff; light7->dvAttenuation0 = data->dvAttenuation0; light7->dvAttenuation1 = data->dvAttenuation1; light7->dvAttenuation2 = data->dvAttenuation2; light7->dvTheta = data->dvTheta; light7->dvPhi = data->dvPhi; wined3d_mutex_lock(); memcpy(&light->light, data, sizeof(D3DLIGHT)); if (!(light->light.dwFlags & D3DLIGHT_ACTIVE) && flags & D3DLIGHT_ACTIVE) light_activate(light); else if (light->light.dwFlags & D3DLIGHT_ACTIVE && !(flags & D3DLIGHT_ACTIVE)) light_deactivate(light); else if (flags & D3DLIGHT_ACTIVE) light_update(light); light->light.dwFlags = flags; wined3d_mutex_unlock(); return D3D_OK; }
/***************************************************************************** * IDirect3DViewport3::AddLight * * Adds an light to the viewport * * Params: * lpDirect3DLight: Interface of the light to add * * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if Direct3DLight is NULL * DDERR_INVALIDPARAMS if there are 8 lights or more * *****************************************************************************/ static HRESULT WINAPI IDirect3DViewportImpl_AddLight(IDirect3DViewport3 *iface, IDirect3DLight *lpDirect3DLight) { IDirect3DViewportImpl *This = (IDirect3DViewportImpl *)iface; IDirect3DLightImpl *lpDirect3DLightImpl = (IDirect3DLightImpl *)lpDirect3DLight; DWORD i = 0; DWORD map = This->map_lights; TRACE("iface %p, light %p.\n", iface, lpDirect3DLight); EnterCriticalSection(&ddraw_cs); if (This->num_lights >= 8) { LeaveCriticalSection(&ddraw_cs); 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; IDirect3DLight_AddRef(lpDirect3DLight); /* Attach the light to the viewport */ lpDirect3DLightImpl->active_viewport = This; /* If active, activate the light */ if (This->active_device) light_activate(lpDirect3DLightImpl); LeaveCriticalSection(&ddraw_cs); return D3D_OK; }
/***************************************************************************** * viewport_activate * * activates the viewport using IDirect3DDevice7::SetViewport * *****************************************************************************/ void viewport_activate(IDirect3DViewportImpl* This, BOOL ignore_lights) { IDirect3DLightImpl* light; D3DVIEWPORT7 vp; if (!ignore_lights) { /* Activate all the lights associated with this context */ light = This->lights; while (light) { light_activate(light); light = light->next; } } /* And copy the values in the structure used by the device */ if (This->use_vp2) { vp.dwX = This->viewports.vp2.dwX; vp.dwY = This->viewports.vp2.dwY; vp.dwHeight = This->viewports.vp2.dwHeight; vp.dwWidth = This->viewports.vp2.dwWidth; vp.dvMinZ = This->viewports.vp2.dvMinZ; vp.dvMaxZ = This->viewports.vp2.dvMaxZ; } else { vp.dwX = This->viewports.vp1.dwX; vp.dwY = This->viewports.vp1.dwY; vp.dwHeight = This->viewports.vp1.dwHeight; vp.dwWidth = This->viewports.vp1.dwWidth; vp.dvMinZ = This->viewports.vp1.dvMinZ; vp.dvMaxZ = This->viewports.vp1.dvMaxZ; } /* And also set the viewport */ IDirect3DDevice7_SetViewport((IDirect3DDevice7 *)This->active_device, &vp); }