]> git.tdb.fi Git - libs/gl.git/blobdiff - source/materials/light.h
Split the Light class into subclasses by light type
[libs/gl.git] / source / materials / light.h
index 05a05aa90040a65bbf1017a070fdc9ab85cb75c0..606ec67325812d535d305c5756ca82bcfb439528 100644 (file)
@@ -1,11 +1,11 @@
 #ifndef MSP_GL_LIGHT_H_
 #define MSP_GL_LIGHT_H_
 
+#include <string>
+#include <msp/datafile/dynamicobjectloader.h>
 #include <msp/datafile/objectloader.h>
-#include <msp/geometry/angle.h>
 #include "color.h"
 #include "placeable.h"
-#include "vector.h"
 
 namespace Msp {
 namespace GL {
@@ -13,12 +13,8 @@ namespace GL {
 class ProgramData;
 
 /**
-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.
+Base class for light sources.  The DirectionalLight and PointLight classes
+implement different types of lights.
 
 Lights are usually grouped with a Lighting object, which can be used in a
 Sequence::Step.
@@ -27,87 +23,53 @@ Lights do not cast shadows by themselves.  See ShadowMap for that.
 */
 class Light: public Placeable
 {
-public:
+protected:
        class Loader: public DataFile::ObjectLoader<Light>
        {
-       public:
+       protected:
                Loader(Light &);
 
+               virtual void init_actions();
+
        private:
-               void attenuation(float, float, float);
                void color(float, float, float);
-               void position(float, float, float, float);
-               void spot_direction(float, float, float);
-               void spot_exponent(float);
-               void spot_cutoff(float);
        };
 
-private:
+public:
+       class GenericLoader: public DataFile::DynamicObjectLoader<Light>
+       {
+               friend class Light;
+
+       public:
+               GenericLoader(Collection &c): DynamicObjectLoader<Light>(&c) { }
+
+       protected:
+               virtual const TypeRegistry &get_type_registry() const { return Light::get_light_registry(); }
+       };
+
+protected:
        Color color;
-       Color transmittance;
-       Vector4 position;
-       Vector3 spot_dir;
-       Vector3 direction;
-       float spot_exp;
-       Geometry::Angle<float> spot_cutoff;
-       float attenuation[3];
        unsigned generation;
 
 public:
        Light();
 
-private:
-       void update_matrix();
-
-public:
-       /** Sets the color of the Light.  Provided
-       to shaders as light_sources[i].color. */
+       /** Sets the color of the Light. */
        void set_color(const Color &);
 
-       /** Sets a multiplier on how much light actually reaches the target.  Used
-       when modeling an atmosphere. */
-       void set_transmittance(const Color &);
-
        const Color &get_color() const { return color; }
-       const Color &get_transmittance() const { return transmittance; }
-
-       /** Sets the postion and orientation of the Light from a matrix.  Negative Z
-       axis is used as the spot direction, other axes are ignored. */
-       virtual void set_matrix(const Matrix &);
-
-       /** Sets the position of the Light.  For a directional light, set the xyz
-       components to a vector pointing towards the light and the w component to 0. */
-       void set_position(const Vector4 &);
-
-       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);
-
-       /** 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; }
-       const Geometry::Angle<float> &get_spot_cutoff() const { return spot_cutoff; }
-       void set_attenuation(float, float, float);
-       const float *get_attenuation() const { return attenuation; }
 
        unsigned get_generation() const { return generation; }
 
        /** Updates a ProgramData object with the uniforms for the Light.  A light
        source index must be passed in.  Primarily used by Lighting. */
        void update_shader_data(ProgramData &, unsigned) const;
+
+protected:
+       virtual void update_shader_data(ProgramData &, const std::string &) const = 0;
+
+private:
+       static GenericLoader::TypeRegistry &get_light_registry();
 };
 
 } // namespace GL