]> git.lizzy.rs Git - irrlicht.git/blobdiff - source/Irrlicht/COpenGLDriver.cpp
Add back lighting system
[irrlicht.git] / source / Irrlicht / COpenGLDriver.cpp
index c213283bbf1651c72ff42f3363eb236ce88949d9..6ae36e3f2f1b7dc941c597e1a33ea86e0750e3c4 100644 (file)
@@ -59,6 +59,8 @@ bool COpenGLDriver::initDriver()
 //! destructor\r
 COpenGLDriver::~COpenGLDriver()\r
 {\r
+       RequestedLights.clear();\r
+\r
        deleteMaterialRenders();\r
 \r
        CacheHandler->getTextureCache().clear();\r
@@ -2985,6 +2987,177 @@ const wchar_t* COpenGLDriver::getName() const
 }\r
 \r
 \r
+//! deletes all dynamic lights there are\r
+void COpenGLDriver::deleteAllDynamicLights()\r
+{\r
+       for (s32 i=0; i<MaxLights; ++i)\r
+               glDisable(GL_LIGHT0 + i);\r
+\r
+       RequestedLights.clear();\r
+\r
+       CNullDriver::deleteAllDynamicLights();\r
+}\r
+\r
+\r
+//! adds a dynamic light\r
+s32 COpenGLDriver::addDynamicLight(const SLight& light)\r
+{\r
+       CNullDriver::addDynamicLight(light);\r
+\r
+       RequestedLights.push_back(RequestedLight(light));\r
+\r
+       u32 newLightIndex = RequestedLights.size() - 1;\r
+\r
+       // Try and assign a hardware light just now, but don't worry if I can't\r
+       assignHardwareLight(newLightIndex);\r
+\r
+       return (s32)newLightIndex;\r
+}\r
+\r
+\r
+void COpenGLDriver::assignHardwareLight(u32 lightIndex)\r
+{\r
+       setTransform(ETS_WORLD, core::matrix4());\r
+\r
+       s32 lidx;\r
+       for (lidx=GL_LIGHT0; lidx < GL_LIGHT0 + MaxLights; ++lidx)\r
+       {\r
+               if(!glIsEnabled(lidx))\r
+               {\r
+                       RequestedLights[lightIndex].HardwareLightIndex = lidx;\r
+                       break;\r
+               }\r
+       }\r
+\r
+       if(lidx == GL_LIGHT0 + MaxLights) // There's no room for it just now\r
+               return;\r
+\r
+       GLfloat data[4];\r
+       const SLight & light = RequestedLights[lightIndex].LightData;\r
+\r
+       switch (light.Type)\r
+       {\r
+       case video::ELT_SPOT:\r
+               data[0] = light.Direction.X;\r
+               data[1] = light.Direction.Y;\r
+               data[2] = light.Direction.Z;\r
+               data[3] = 0.0f;\r
+               glLightfv(lidx, GL_SPOT_DIRECTION, data);\r
+\r
+               // set position\r
+               data[0] = light.Position.X;\r
+               data[1] = light.Position.Y;\r
+               data[2] = light.Position.Z;\r
+               data[3] = 1.0f; // 1.0f for positional light\r
+               glLightfv(lidx, GL_POSITION, data);\r
+\r
+               glLightf(lidx, GL_SPOT_EXPONENT, light.Falloff);\r
+               glLightf(lidx, GL_SPOT_CUTOFF, light.OuterCone);\r
+       break;\r
+       case video::ELT_POINT:\r
+               // set position\r
+               data[0] = light.Position.X;\r
+               data[1] = light.Position.Y;\r
+               data[2] = light.Position.Z;\r
+               data[3] = 1.0f; // 1.0f for positional light\r
+               glLightfv(lidx, GL_POSITION, data);\r
+\r
+               glLightf(lidx, GL_SPOT_EXPONENT, 0.0f);\r
+               glLightf(lidx, GL_SPOT_CUTOFF, 180.0f);\r
+       break;\r
+       case video::ELT_DIRECTIONAL:\r
+               // set direction\r
+               data[0] = -light.Direction.X;\r
+               data[1] = -light.Direction.Y;\r
+               data[2] = -light.Direction.Z;\r
+               data[3] = 0.0f; // 0.0f for directional light\r
+               glLightfv(lidx, GL_POSITION, data);\r
+\r
+               glLightf(lidx, GL_SPOT_EXPONENT, 0.0f);\r
+               glLightf(lidx, GL_SPOT_CUTOFF, 180.0f);\r
+       break;\r
+       default:\r
+       break;\r
+       }\r
+\r
+       // set diffuse color\r
+       data[0] = light.DiffuseColor.r;\r
+       data[1] = light.DiffuseColor.g;\r
+       data[2] = light.DiffuseColor.b;\r
+       data[3] = light.DiffuseColor.a;\r
+       glLightfv(lidx, GL_DIFFUSE, data);\r
+\r
+       // set specular color\r
+       data[0] = light.SpecularColor.r;\r
+       data[1] = light.SpecularColor.g;\r
+       data[2] = light.SpecularColor.b;\r
+       data[3] = light.SpecularColor.a;\r
+       glLightfv(lidx, GL_SPECULAR, data);\r
+\r
+       // set ambient color\r
+       data[0] = light.AmbientColor.r;\r
+       data[1] = light.AmbientColor.g;\r
+       data[2] = light.AmbientColor.b;\r
+       data[3] = light.AmbientColor.a;\r
+       glLightfv(lidx, GL_AMBIENT, data);\r
+\r
+       // 1.0f / (constant + linear * d + quadratic*(d*d);\r
+\r
+       // set attenuation\r
+       glLightf(lidx, GL_CONSTANT_ATTENUATION, light.Attenuation.X);\r
+       glLightf(lidx, GL_LINEAR_ATTENUATION, light.Attenuation.Y);\r
+       glLightf(lidx, GL_QUADRATIC_ATTENUATION, light.Attenuation.Z);\r
+\r
+       glEnable(lidx);\r
+}\r
+\r
+\r
+//! Turns a dynamic light on or off\r
+//! \param lightIndex: the index returned by addDynamicLight\r
+//! \param turnOn: true to turn the light on, false to turn it off\r
+void COpenGLDriver::turnLightOn(s32 lightIndex, bool turnOn)\r
+{\r
+       if(lightIndex < 0 || lightIndex >= (s32)RequestedLights.size())\r
+               return;\r
+\r
+       RequestedLight & requestedLight = RequestedLights[lightIndex];\r
+\r
+       requestedLight.DesireToBeOn = turnOn;\r
+\r
+       if(turnOn)\r
+       {\r
+               if(-1 == requestedLight.HardwareLightIndex)\r
+                       assignHardwareLight(lightIndex);\r
+       }\r
+       else\r
+       {\r
+               if(-1 != requestedLight.HardwareLightIndex)\r
+               {\r
+                       // It's currently assigned, so free up the hardware light\r
+                       glDisable(requestedLight.HardwareLightIndex);\r
+                       requestedLight.HardwareLightIndex = -1;\r
+\r
+                       // Now let the first light that's waiting on a free hardware light grab it\r
+                       for(u32 requested = 0; requested < RequestedLights.size(); ++requested)\r
+                               if(RequestedLights[requested].DesireToBeOn\r
+                                       &&\r
+                                       -1 == RequestedLights[requested].HardwareLightIndex)\r
+                               {\r
+                                       assignHardwareLight(requested);\r
+                                       break;\r
+                               }\r
+               }\r
+       }\r
+}\r
+\r
+\r
+//! returns the maximal amount of dynamic lights the device can handle\r
+u32 COpenGLDriver::getMaximalDynamicLightAmount() const\r
+{\r
+       return MaxLights;\r
+}\r
+\r
+\r
 //! Sets the dynamic ambient light color. The default color is\r
 //! (0,0,0,0) which means it is dark.\r
 //! \param color: New color of the ambient light.\r