From: Mikko Rasa Date: Thu, 9 Nov 2017 14:41:01 +0000 (+0200) Subject: Improve parameters and documentation of Light X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=47cfca889482f00093ee6fdeaf4f478dc5ea90f2;p=libs%2Fgl.git Improve parameters and documentation of Light --- diff --git a/source/light.cpp b/source/light.cpp index a3b3d014..f74b3acb 100644 --- a/source/light.cpp +++ b/source/light.cpp @@ -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::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::from_degrees(c)); +} + +void Light::set_spot_cutoff(const Geometry::Angle &c) +{ + if(c::zero() || (c>Geometry::Angle::right() && c!=Geometry::Angle::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::straight()); +} + void Light::set_attenuation(float c, float l, float q) { attenuation[0] = c; diff --git a/source/light.h b/source/light.h index ee62ce35..b775a711 100644 --- a/source/light.h +++ b/source/light.h @@ -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 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 &); + + /** 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 &get_spot_cutoff() const { return spot_cutoff; } void set_attenuation(float, float, float); const float *get_attenuation() const { return attenuation; }