]> git.tdb.fi Git - libs/gl.git/commitdiff
Improve parameters and documentation of Light
authorMikko Rasa <tdb@tdb.fi>
Thu, 9 Nov 2017 14:41:01 +0000 (16:41 +0200)
committerMikko Rasa <tdb@tdb.fi>
Thu, 9 Nov 2017 14:50:06 +0000 (16:50 +0200)
source/light.cpp
source/light.h

index a3b3d014c0a51a16762c7a82285f4a6a8960247c..f74b3acb149071238d9053d41a400141854085d5 100644 (file)
@@ -18,7 +18,7 @@ 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;
@@ -54,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]);
@@ -83,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;
index ee62ce35634213f2e6af365f5169e2d2cf0e59c7..b775a71188c690ce17d9c78aac0d9d6ac7dce933 100644 (file)
@@ -12,7 +12,15 @@ class Matrix;
 class ProgramData;
 
 /**
-Stores properties of a single light source.
+Stores properties of a single light source.  Lights can be directional, point
+lights or spotlights.  No explicit type parameter is provided; rather the
+other parameters determine what kind of light it is.  If the fourth component
+of position is zero, it's a directional light.  Otherwise, if the spot cutoff
+is not 180 degrees, it's a spotlight.  Otherwise it's an omnidirectional point
+light.
+
+Lights are usually grouped with a Lighting object, which can be used in a
+Pipeline::Pass.
 
 Lights do not cast shadows by themselves.  See ShadowMap for that.
 */
@@ -35,7 +43,7 @@ private:
        Vector4 position;
        Vector3 spot_dir;
        float spot_exp;
-       float spot_cutoff;
+       Geometry::Angle<float> spot_cutoff;
        float attenuation[3];
 
 public:
@@ -51,7 +59,7 @@ public:
        void set_diffuse(const Color &c);
 
        /** Sets the specular (direction-dependent) color of the Light.  Provided to
-       shaders with the name light_sources[i].diffuse. */
+       shaders with the name light_sources[i].specular. */
        void set_specular(const Color &c);
 
        const Color &get_diffuse() const { return diffuse; }
@@ -63,12 +71,28 @@ public:
 
        const Vector4 &get_position() const { return position; }
 
+       /** Sets the direction of a spotlight.  Has no effect if spotlight cutoff is
+       not set. */
        void set_spot_direction(const Vector3 &);
+
+       /** Sets the angular falloff exponent of the spotlight.  Must be >= 0. */
        void set_spot_exponent(float);
+
+       /// Deprecated.
        void set_spot_cutoff(float);
+
+       /** Sets the cutoff angle of a spotlight.  Beyond this angle from its axis
+       the spotlight provides no illumination.  Must be between 0 and 90 degrees,
+       or exactly 180 degrees to indicate a non-spotlight. */
+       void set_spot_cutoff(const Geometry::Angle<float> &);
+
+       /** Disables spotlight, reverting to an omnidirectional point light.
+       Equivalent to setting the spot cutoff to 180 degrees. */
+       void disable_spot_cutoff();
+
        const Vector3 &get_spot_direction() const { return spot_dir; }
        float get_spot_exponent() const { return spot_exp; }
-       float get_spot_cutoff() const { return spot_cutoff; }
+       const Geometry::Angle<float> &get_spot_cutoff() const { return spot_cutoff; }
        void set_attenuation(float, float, float);
        const float *get_attenuation() const { return attenuation; }