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