]> git.tdb.fi Git - libs/gl.git/blobdiff - source/light.cpp
Improve parameters and documentation of Light
[libs/gl.git] / source / light.cpp
index 11f4826cd74748acde5b1bfba24d8efd32ea3203..f74b3acb149071238d9053d41a400141854085d5 100644 (file)
@@ -1,4 +1,5 @@
 #include <stdexcept>
+#include <msp/gl/extensions/msp_legacy_features.h>
 #include <msp/strings/format.h>
 #include "light.h"
 #include "lightunit.h"
@@ -17,13 +18,19 @@ Light::Light():
        position(0, 0, 1, 0),
        spot_dir(0, 0, -1),
        spot_exp(0),
-       spot_cutoff(180)
+       spot_cutoff(Geometry::Angle<float>::straight())
 {
        attenuation[0] = 1;
        attenuation[1] = 0;
        attenuation[2] = 0;
 }
 
+Light::~Light()
+{
+       while(LightUnit *unit = LightUnit::find_unit(this))
+               unbind_from(unit->get_index());
+}
+
 void Light::update_parameter(int mask, int index) const
 {
        if(index<0)
@@ -47,7 +54,7 @@ void Light::update_parameter(int mask, int index) const
        if(mask&SPOT_EXP)
                glLightf(l, GL_SPOT_EXPONENT, spot_exp);
        if(mask&SPOT_CUTOFF)
-               glLightf(l, GL_SPOT_CUTOFF, spot_cutoff);
+               glLightf(l, GL_SPOT_CUTOFF, spot_cutoff.degrees());
        if(mask&ATTENUATION)
        {
                glLightf(l, GL_CONSTANT_ATTENUATION, attenuation[0]);
@@ -76,22 +83,38 @@ void Light::set_position(const Vector4 &p)
 
 void Light::set_spot_direction(const Vector3 &d)
 {
-       spot_dir = d;
+       spot_dir = normalize(d);
        update_parameter(SPOT_DIR);
 }
 
 void Light::set_spot_exponent(float e)
 {
+       if(e<0)
+               throw invalid_argument("Light::set_spot_exponent");
+
        spot_exp = e;
        update_parameter(SPOT_EXP);
 }
 
 void Light::set_spot_cutoff(float c)
 {
+       set_spot_cutoff(Geometry::Angle<float>::from_degrees(c));
+}
+
+void Light::set_spot_cutoff(const Geometry::Angle<float> &c)
+{
+       if(c<Geometry::Angle<float>::zero() || (c>Geometry::Angle<float>::right() && c!=Geometry::Angle<float>::straight()))
+               throw invalid_argument("Light::set_spot_cutoff");
+
        spot_cutoff = c;
        update_parameter(SPOT_CUTOFF);
 }
 
+void Light::disable_spot_cutoff()
+{
+       set_spot_cutoff(Geometry::Angle<float>::straight());
+}
+
 void Light::set_attenuation(float c, float l, float q)
 {
        attenuation[0] = c;
@@ -110,6 +133,8 @@ void Light::update_shader_data(ProgramData &shdata, const Matrix &view_matrix, u
 
 void Light::bind_to(unsigned i) const
 {
+       static Require _req(MSP_legacy_features);
+
        LightUnit &unit = LightUnit::get_unit(i);
        if(unit.set_light(this))
        {