Directional and spot lights for D3D8/9...

A forum to store posts deemed exceptionally wise and useful
Post Reply
R00mpel
Posts: 41
Joined: Sun Nov 09, 2003 10:12 am
Location: Russia, Nizhny Novgorod

Directional and spot lights for D3D8/9...

Post by R00mpel »

Hi all!
I've just implemented directional and spot lights for Direct3D 8/9, but i'm not sure if they'll work correctly :roll: OK, if someone is interested, here's the source:

first, open SLight.h file and add the following code to the SLight struct:

Code: Select all

s32 type;
//Direction is used only for directional and spot lights.
core::vector3df dir;
//Note that theta and phi are used ONLY for spot lights.
f32 theta;
f32 phi;
f32 falloff;
then, change CVideoDirectX8::addDynamicLight() and CVideoDirectX9::addDynamicLight() functions so they look like this:

Code: Select all

void CVideoDirectX8::addDynamicLight(const SLight& dl)
{
	if ((u32)LastSetLight == Caps.MaxActiveLights-1)
		return;

	CVideoNull::addDynamicLight(dl);

	D3DLIGHT8 light;

	switch(dl.type)
	{
	case 1:
		light.Type = D3DLIGHT_POINT;
		break;
	case 2:
		light.Type = D3DLIGHT_SPOT;
		break;
	case 3:
		light.Type = D3DLIGHT_DIRECTIONAL;
		break;
	default:
		light.Type = D3DLIGHT_POINT;
		break;
	}
	light.Diffuse = *(D3DCOLORVALUE*)((void*)(&dl.DiffuseColor));
	light.Specular = *(D3DCOLORVALUE*)((void*)(&dl.SpecularColor));
	light.Ambient = *(D3DCOLORVALUE*)((void*)(&dl.AmbientColor));
	light.Position = *(D3DVECTOR*)((void*)(&dl.Position));
	light.Range = MaxLightDistance;
	
	light.Direction = *(D3DVECTOR*)((void*)(&dl.dir));
	light.Theta = dl.theta;
	light.Phi = dl.phi;
	light.Falloff = dl.falloff;
	
	light.Attenuation0 = 0.0f;
	light.Attenuation1 = 1.0f / dl.Radius;
	light.Attenuation2 = 0.0f;

	++LastSetLight;
	pID3DDevice->SetLight(LastSetLight, &light);
	pID3DDevice->LightEnable(LastSetLight, true);
}


void CVideoDirectX9::addDynamicLight(const SLight& dl)
{
	if ((u32)LastSetLight == Caps.MaxActiveLights-1)
		return;

	CVideoNull::addDynamicLight(dl);

	D3DLIGHT9 light;

	switch(dl.type)
	{
	case 1:
		light.Type = D3DLIGHT_POINT;
		break;
	case 2:
		light.Type = D3DLIGHT_SPOT;
		break;
	case 3:
		light.Type = D3DLIGHT_DIRECTIONAL;
		break;
	default:
		light.Type = D3DLIGHT_POINT;
		break;
	}
	light.Diffuse = *(D3DCOLORVALUE*)((void*)(&dl.DiffuseColor));
	light.Specular = *(D3DCOLORVALUE*)((void*)(&dl.SpecularColor));
	light.Ambient = *(D3DCOLORVALUE*)((void*)(&dl.AmbientColor));
	light.Position = *(D3DVECTOR*)((void*)(&dl.Position));
	light.Range = MaxLightDistance;

	light.Direction = *(D3DVECTOR*)((void*)(&dl.dir));
	light.Theta = dl.theta;
	light.Phi = dl.phi;
	light.Falloff = dl.falloff;

	light.Attenuation0 = 0.0f;
	light.Attenuation1 = 1.0f / dl.Radius;
	light.Attenuation2 = 0.0f;

	++LastSetLight;
	pID3DDevice->SetLight(LastSetLight, &light);
	pID3DDevice->LightEnable(LastSetLight, true);
}
After that, open ISceneManager.h file and change the following code:

Code: Select all

virtual ILightSceneNode* addLightSceneNode(ISceneNode* parent = 0,
			const core::vector3df& position = core::vector3df(0,0,0),
			video::SColorf color = video::SColorf(1.0f, 1.0f, 1.0f), f32 radius=100.0f, s32 id=-1) = 0;
to

Code: Select all

virtual ILightSceneNode* addLightSceneNode(ISceneNode* parent = 0,
			const core::vector3df& position = core::vector3df(0,0,0),
			video::SColorf color = video::SColorf(1.0f, 1.0f, 1.0f), f32 radius=100.0f, s32 id=-1,
			s32 type=1, core::vector3df& dir=core::vector3df(1.0f, 0.0f, 0.0f), f32 theta=50.0f, f32 phi=100.0f, f32 falloff=1.0f) = 0;
Then do the same for the CSceneManager.h, CSceneManager.cpp. Then change the following code in CLightSceneNode.h and CLightSceneNode.cpp

Code: Select all

CLightSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,	
		const core::vector3df& position, video::SColorf color,f32 range);
to

Code: Select all

CLightSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,	
		const core::vector3df& position, video::SColorf color,f32 range,
		s32 type, core::vector3df& dir, f32 theta, f32 phi, f32 falloff);
That's all... Please post here all that you think about it... :roll:

P.S. Niko, are you going to implement something like this in the next version? IMHO it would be very useful...
The only thing to fear is running out of beer!
Post Reply