//! destructor\r
COpenGLDriver::~COpenGLDriver()\r
{\r
+ RequestedLights.clear();\r
+\r
deleteMaterialRenders();\r
\r
CacheHandler->getTextureCache().clear();\r
}\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