diff -Nauwr Irrlicht/CColladaFileLoader.cpp Irrlicht/CColladaFileLoader.cpp --- Irrlicht/CColladaFileLoader.cpp 2005-08-20 22:17:50.000000000 +0200 +++ Irrlicht/CColladaFileLoader.cpp 2005-09-19 12:47:46.000000000 +0200 @@ -108,8 +108,7 @@ os::Printer::log("COLLADA: Constructing light instance:", Id.c_str()); #endif - scene::ILightSceneNode* l = mgr->addLightSceneNode(parent); - l->getLightData() = LightData; + scene::ILightSceneNode* l = mgr->addLightSceneNode( LightData ); return l; } }; diff -Nauwr Irrlicht/CD3D8NormalMapRenderer.cpp Irrlicht/CD3D8NormalMapRenderer.cpp --- Irrlicht/CD3D8NormalMapRenderer.cpp 2005-08-20 22:20:08.000000000 +0200 +++ Irrlicht/CD3D8NormalMapRenderer.cpp 2005-09-19 13:38:58.000000000 +0200 @@ -216,10 +216,10 @@ else { light.DiffuseColor.set(0,0,0); // make light dark - light.Radius = 1.0f; + light.OuterConeRadius = 1.0f; } - light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation + light.DiffuseColor.a = 1.0f/(light.OuterConeRadius*light.OuterConeRadius); // set attenuation services->setVertexShaderConstant(reinterpret_cast(&light.Position), 12+(i*2), 1); services->setVertexShaderConstant(reinterpret_cast(&light.DiffuseColor), 13+(i*2), 1); diff -Nauwr Irrlicht/CD3D8ParallaxMapRenderer.cpp Irrlicht/CD3D8ParallaxMapRenderer.cpp --- Irrlicht/CD3D8ParallaxMapRenderer.cpp 2005-08-20 22:20:12.000000000 +0200 +++ Irrlicht/CD3D8ParallaxMapRenderer.cpp 2005-09-19 13:38:58.000000000 +0200 @@ -273,10 +273,10 @@ else { light.DiffuseColor.set(0,0,0); // make light dark - light.Radius = 1.0f; + light.OuterConeRadius = 1.0f; } - light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation + light.DiffuseColor.a = 1.0f/(light.OuterConeRadius*light.OuterConeRadius); // set attenuation services->setVertexShaderConstant(reinterpret_cast(&light.Position), 12+(i*2), 1); services->setVertexShaderConstant(reinterpret_cast(&light.DiffuseColor), 13+(i*2), 1); diff -Nauwr Irrlicht/CD3D8Driver.cpp Irrlicht/CD3D8Driver.cpp --- Irrlicht/CD3D8Driver.cpp 2005-08-20 22:25:10.000000000 +0200 +++ Irrlicht/CD3D8Driver.cpp 2005-09-21 19:37:04.000000000 +0200 @@ -1662,7 +1785,7 @@ light.Range = MaxLightDistance; light.Attenuation0 = 0.0f; - light.Attenuation1 = 1.0f / dl.Radius; + light.Attenuation1 = 1.0f / dl.OuterConeRadius; light.Attenuation2 = 0.0f; ++LastSetLight; diff -Nauwr Irrlicht/CLightSceneNode.cpp Irrlicht/CLightSceneNode.cpp --- Irrlicht/CLightSceneNode.cpp 2005-08-20 22:17:52.000000000 +0200 +++ Irrlicht/CLightSceneNode.cpp 2005-09-19 13:42:14.000000000 +0200 @@ -12,21 +12,21 @@ { //! constructor -CLightSceneNode::CLightSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, - const core::vector3df& position, video::SColorf color,f32 radius) -: ILightSceneNode(parent, mgr, id, position) +CLightSceneNode::CLightSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, video::SLight& lightData ) +: ILightSceneNode(parent, mgr, id, lightData.Position) { #ifdef _DEBUG setDebugName("CLightSceneNode"); #endif AutomaticCullingEnabled = false; - LightData.Radius = radius; - LightData.DiffuseColor = color; - LightData.Position = position; + LightData = lightData; + LightData.Att0 = 0.0f; + LightData.Att1 = 1.0f / LightData.Range; + LightData.Att2 = 0.0f; // set some useful specular color - LightData.SpecularColor = color.getInterpolated(video::SColor(255,255,255,255),0.5f); + LightData.SpecularColor = LightData.DiffuseColor.getInterpolated(video::SColor(255,255,255,255),0.5f); } CLightSceneNode::~CLightSceneNode() diff -Nauwr Irrlicht/CLightSceneNode.h Irrlicht/CLightSceneNode.h --- Irrlicht/CLightSceneNode.h 2005-08-20 22:17:52.000000000 +0200 +++ Irrlicht/CLightSceneNode.h 2005-09-19 12:34:50.000000000 +0200 @@ -19,8 +19,7 @@ public: //! constructor - CLightSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, - const core::vector3df& position, video::SColorf color,f32 range); + CLightSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, video::SLight& lightData); virtual ~CLightSceneNode(); diff -Nauwr Irrlicht/CD3D9Driver.cpp Irrlicht/CD3D9Driver.cpp --- Irrlicht/CD3D9Driver.cpp 2005-08-20 22:25:16.000000000 +0200 +++ Irrlicht/CD3D9Driver.cpp 2005-09-23 10:19:28.000000000 +0200 @@ -1629,16 +1755,24 @@ D3DLIGHT9 light; - light.Type = D3DLIGHT_POINT; + light.Type = (D3DLIGHTTYPE)dl.Type; 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.Direction = *(D3DVECTOR*)((void*)(&dl.Direction)); + + if( dl.Range > MaxLightDistance ) light.Range = MaxLightDistance; + else + light.Range = dl.Range; - light.Attenuation0 = 0.0f; - light.Attenuation1 = 1.0f / dl.Radius; - light.Attenuation2 = 0.0f; + light.Falloff = dl.Falloff; + light.Theta = dl.InnerConeRadius; + light.Phi = dl.OuterConeRadius; + light.Attenuation0 = dl.Att0; + light.Attenuation1 = dl.Att1; + light.Attenuation2 = dl.Att2; ++LastSetLight; pID3DDevice->SetLight(LastSetLight, &light); diff -Nauwr Irrlicht/CD3D9NormalMapRenderer.cpp Irrlicht/CD3D9NormalMapRenderer.cpp --- Irrlicht/CD3D9NormalMapRenderer.cpp 2005-08-20 22:20:40.000000000 +0200 +++ Irrlicht/CD3D9NormalMapRenderer.cpp 2005-09-19 13:38:58.000000000 +0200 @@ -209,10 +209,10 @@ else { light.DiffuseColor.set(0,0,0); // make light dark - light.Radius = 1.0f; + light.OuterConeRadius = 1.0f; } - light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation + light.DiffuseColor.a = 1.0f/(light.OuterConeRadius*light.OuterConeRadius); // set attenuation services->setVertexShaderConstant(reinterpret_cast(&light.Position), 12+(i*2), 1); services->setVertexShaderConstant(reinterpret_cast(&light.DiffuseColor), 13+(i*2), 1); diff -Nauwr Irrlicht/CD3D9ParallaxMapRenderer.cpp Irrlicht/CD3D9ParallaxMapRenderer.cpp --- Irrlicht/CD3D9ParallaxMapRenderer.cpp 2005-08-20 22:20:44.000000000 +0200 +++ Irrlicht/CD3D9ParallaxMapRenderer.cpp 2005-09-19 13:38:58.000000000 +0200 @@ -362,10 +362,10 @@ else { light.DiffuseColor.set(0,0,0); // make light dark - light.Radius = 1.0f; + light.OuterConeRadius = 1.0f; } - light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation + light.DiffuseColor.a = 1.0f/(light.OuterConeRadius*light.OuterConeRadius); // set attenuation services->setVertexShaderConstant(reinterpret_cast(&light.Position), 12+(i*2), 1); services->setVertexShaderConstant(reinterpret_cast(&light.DiffuseColor), 13+(i*2), 1); diff -Nauwr Irrlicht/COCTLoader.cpp Irrlicht/COCTLoader.cpp --- Irrlicht/COCTLoader.cpp 2005-08-20 22:17:50.000000000 +0200 +++ Irrlicht/COCTLoader.cpp 2005-09-19 12:47:38.000000000 +0200 @@ -15,6 +15,7 @@ #include "SAnimatedMesh.h" #include "SMeshBufferLightMap.h" #include "irrString.h" +#include "SLight.h" #include namespace irr @@ -71,9 +72,19 @@ //irr::scene::ISceneNode* node = scene->addTestSceneNode(30,parent,-1, core::vector3df(lights[i].pos[0], lights[i].pos[2], lights[i].pos[1])); //node->getMaterial(0).AmbientColor = video::SColorf(lights[i].color[0] * intensity, lights[i].color[1] * intensity, lights[i].color[2] * intensity).toSColor(); - scene->addLightSceneNode(parent, core::vector3df(lights[i].pos[0], lights[i].pos[2], lights[i].pos[1]), - video::SColorf(lights[i].color[0] * intensity, lights[i].color[1] * intensity, lights[i].color[2] * intensity, 1.0f), - radius); + //scene->addLightSceneNode(parent, core::vector3df(lights[i].pos[0], lights[i].pos[2], lights[i].pos[1]), + // video::SColorf(lights[i].color[0] * intensity, lights[i].color[1] * intensity, lights[i].color[2] * intensity, 1.0f), + // radius); + + video::SLight lData; + lData.Position.X = lights[i].pos[0]; + lData.Position.Y = lights[i].pos[1]; + lData.Position.Z = lights[i].pos[2]; + lData.DiffuseColor.r = lights[i].color[0] * intensity; + lData.DiffuseColor.g = lights[i].color[1] * intensity; + lData.DiffuseColor.b = lights[i].color[2] * intensity; + + scene->addLightSceneNode( lData, parent, -1 ); } } diff -Nauwr Irrlicht/COpenGLDriver.cpp Irrlicht/COpenGLDriver.cpp --- Irrlicht/COpenGLDriver.cpp 2005-08-24 20:40:26.000000000 +0200 +++ Irrlicht/COpenGLDriver.cpp 2005-09-21 19:36:50.000000000 +0200 @@ -1613,12 +1991,12 @@ s32 lidx = GL_LIGHT0 + LastSetLight; GLfloat data[4]; - // set position - data[0] = light.Position.X; - data[1] = light.Position.Y; - data[2] = light.Position.Z; - data[3] = 1.0f; - glLightfv(lidx, GL_POSITION, data); + // set ambient color + data[0] = light.AmbientColor.r; + data[1] = light.AmbientColor.g; + data[2] = light.AmbientColor.b; + data[3] = light.AmbientColor.a; + glLightfv(lidx, GL_AMBIENT, data); // set diffuse color data[0] = light.DiffuseColor.r; @@ -1628,25 +2006,42 @@ glLightfv(lidx, GL_DIFFUSE, data); // set specular color - data[0] = 0;//light.SpecularColor.r; - data[1] = 0;//light.SpecularColor.g; - data[2] = 0;//light.SpecularColor.b; - data[3] = 0;//light.SpecularColor.a; + data[0] = light.SpecularColor.r; + data[1] = light.SpecularColor.g; + data[2] = light.SpecularColor.b; + data[3] = light.SpecularColor.a; glLightfv(lidx, GL_SPECULAR, data); - // set ambient color - data[0] = light.AmbientColor.r; - data[1] = light.AmbientColor.g; - data[2] = light.AmbientColor.b; - data[3] = light.AmbientColor.a; - glLightfv(lidx, GL_AMBIENT, data); + // set position + data[0] = light.Position.X; + data[1] = light.Position.Y; + data[2] = light.Position.Z; + data[3] = 1.0f; + glLightfv(lidx, GL_POSITION, data); + + if( light.Type == video::ELT_DIRECTIONAL || light.Type == video::ELT_SPOT ) + { + // set direction + data[0] = light.Direction.X; + data[1] = light.Direction.Y; + data[2] = light.Direction.Z; + data[3] = 1.0f; + glLightfv(lidx, GL_SPOT_DIRECTION, data); + } - // 1.0f / (constant + linar * d + quadratic*(d*d); + if( light.Type == video::ELT_SPOT ) + { + // set maximum spread angle of light for spot light + glLightf(lidx, GL_SPOT_CUTOFF, core::RADTODEG * light.InnerConeRadius); + + // set the falloff for spot light + glLightf(lidx, GL_SPOT_EXPONENT, light.Falloff ); + } // set attenuation - glLightf(lidx, GL_CONSTANT_ATTENUATION, 0.0f); - glLightf(lidx, GL_LINEAR_ATTENUATION, 1.0f / light.Radius); - glLightf(lidx, GL_QUADRATIC_ATTENUATION, 0.0f); + glLightf(lidx, GL_CONSTANT_ATTENUATION, light.Att0 ); + glLightf(lidx, GL_LINEAR_ATTENUATION, light.Att1 ); + glLightf(lidx, GL_QUADRATIC_ATTENUATION, light.Att2 ); glEnable(lidx); } diff -Nauwr Irrlicht/COpenGLNormalMapRenderer.cpp Irrlicht/COpenGLNormalMapRenderer.cpp --- Irrlicht/COpenGLNormalMapRenderer.cpp 2005-08-20 22:21:04.000000000 +0200 +++ Irrlicht/COpenGLNormalMapRenderer.cpp 2005-09-19 13:38:58.000000000 +0200 @@ -277,10 +277,10 @@ else { light.DiffuseColor.set(0,0,0); // make light dark - light.Radius = 1.0f; + light.OuterConeRadius = 1.0f; } - light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation + light.DiffuseColor.a = 1.0f/(light.OuterConeRadius*light.OuterConeRadius); // set attenuation services->setVertexShaderConstant( reinterpret_cast(&light.Position), 12+(i*2), 1); diff -Nauwr Irrlicht/COpenGLParallaxMapRenderer.cpp Irrlicht/COpenGLParallaxMapRenderer.cpp --- Irrlicht/COpenGLParallaxMapRenderer.cpp 2005-08-20 22:21:10.000000000 +0200 +++ Irrlicht/COpenGLParallaxMapRenderer.cpp 2005-09-19 13:38:58.000000000 +0200 @@ -334,10 +334,10 @@ else { light.DiffuseColor.set(0,0,0); // make light dark - light.Radius = 1.0f; + light.OuterConeRadius = 1.0f; } - light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation + light.DiffuseColor.a = 1.0f/(light.OuterConeRadius*light.OuterConeRadius); // set attenuation services->setVertexShaderConstant( reinterpret_cast(&light.Position), 12+(i*2), 1); diff -Nauwr Irrlicht/CSceneManager.cpp Irrlicht/CSceneManager.cpp --- Irrlicht/CSceneManager.cpp 2005-08-24 18:01:14.000000000 +0200 +++ Irrlicht/CSceneManager.cpp 2005-09-27 15:50:08.000000000 +0200 @@ -384,13 +385,12 @@ //! Adds a dynamic light scene node. The light will cast dynamic light on all //! other scene nodes in the scene, which have the material flag video::MTF_LIGHTING //! turned on. (This is the default setting in most scene nodes). -ILightSceneNode* CSceneManager::addLightSceneNode(ISceneNode* parent, - const core::vector3df& position, video::SColorf color, f32 range, s32 id) +ILightSceneNode* CSceneManager::addLightSceneNode(video::SLight& lightData, ISceneNode* parent, s32 id) { if (!parent) parent = this; - ILightSceneNode* node = new CLightSceneNode(parent, this, id, position, color, range); + ILightSceneNode* node = new CLightSceneNode(parent, this, id, lightData); node->drop(); return node; diff -Nauwr Irrlicht/CSceneManager.h Irrlicht/CSceneManager.h --- Irrlicht/CSceneManager.h 2005-08-20 22:17:50.000000000 +0200 +++ Irrlicht/CSceneManager.h 2005-09-27 15:46:54.000000000 +0200 @@ -111,9 +111,7 @@ //! Adds a dynamic light scene node. The light will cast dynamic light on all //! other scene nodes in the scene, which have the material flag video::MTF_LIGHTING //! turned on. (This is the default setting in most scene nodes). - 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 range=100.0f, s32 id=-1); + virtual ILightSceneNode* addLightSceneNode(video::SLight& lightData, ISceneNode* parent=0, s32 id=-1); //! Adds a billboard scene node to the scene. A billboard is like a 3d sprite: A 2d element, //! which always looks to the camera. It is usually used for things like explosions, fire, diff -Nauwr Irrlicht/include/ISceneManager.h Irrlicht/include/ISceneManager.h --- Irrlicht/include/ISceneManager.h 2005-08-23 18:51:58.000000000 +0200 +++ Irrlicht/include/ISceneManager.h 2005-09-27 15:46:10.000000000 +0200 @@ -33,6 +33,7 @@ namespace video { class IVideoDriver; + struct SLight; } @@ -519,9 +527,7 @@ \param id: id of the node. This id can be used to identify the node. \return Returns pointer to the interface of the light if successful, otherwise NULL. This pointer should not be dropped. See IUnknown::drop() for more information. */ - 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; + virtual ILightSceneNode* addLightSceneNode(video::SLight& lightData, ISceneNode* parent=0, s32 id=-1) = 0; //! Adds a billboard scene node to the scene graph. /** A billboard is like a 3d sprite: A 2d element, diff -Nauwr Irrlicht/include/SLight.h Irrlicht/include/SLight.h --- Irrlicht/include/SLight.h 2005-08-20 22:17:44.000000000 +0200 +++ Irrlicht/include/SLight.h 2005-09-19 13:37:12.000000000 +0200 @@ -12,17 +12,37 @@ namespace video { + //! Enumeration for different types of lights + enum E_LIGHT_TYPE + { + //! Point Light + ELT_POINT = 1, + + //! Spot Light + ELT_SPOT = 2, + + //! Directional Light + ELT_DIRECTIONAL = 3, + + //! Force 32 bit + ELT_FORCE_32BIT = 0x7fffffff + }; + //! structure for holding data describing a dynamic point light. /** ambient light and point lights are the only light supported by the irrlicht engine. */ struct SLight { - SLight() : AmbientColor(0.0f,0.0f,0.0f), DiffuseColor(1.0f, 1.0f, 1.0f), - SpecularColor(1.0f,1.0f,1.0f), Position(0.0f, 0.0f, 0.0f), Radius(100.0f), - CastShadows(true) + SLight() : Type(ELT_POINT), AmbientColor(0.0f,0.0f,0.0f), DiffuseColor(1.0f, 1.0f, 1.0f), + SpecularColor(1.0f,1.0f,1.0f), Position(0.0f, 0.0f, 0.0f), Direction( 0.0f, 1.0f, 0.0f ), + CastShadows(true), Range(100.0f), InnerConeRadius(0.0f), OuterConeRadius(0.0f), + Att0(0.0f), Att1(1.0f), Att2(0.0f), Falloff( 1.0f ) {}; + //! Type of light + E_LIGHT_TYPE Type; + //! Ambient color emitted by the light SColorf AmbientColor; @@ -37,11 +57,32 @@ //! Position of the light. core::vector3df Position; - //! Radius of light. Everything within this radius be be lighted. - f32 Radius; + //! Direction of the light, only valid for and ELT_DIRECTIONAL. + core::vector3df Direction; //! Does the light cast shadows? bool CastShadows; + + //! Distance beyond which the light has no effect. Max value is the square root of FLT_MAX. Not valid for ELT_DIRECTIONAL. + f32 Range; + + //! Angle, in Radians, defining the inner cone of a ELT_SPOT. + f32 InnerConeRadius; + + //! Angle, in Radians, defining the outer edge of a ELT_SPOT's outer cone. + f32 OuterConeRadius; + + //! Value specifying how the light intensity changes over distance( Constant attenuation factor ) + f32 Att0; + + //! Value specifying how the light intensity changes over distance( Linear attenuation factor ) + f32 Att1; + + //! Value specifying how the light intensity changes over distance ( Quadratic attenuation factor ) + f32 Att2; + + //! Decrease in illumination between ELT_SPOT's Phi Theta and Phi values. + f32 Falloff; }; } // end namespace video