]> git.tdb.fi Git - libs/gl.git/commitdiff
Rewrite light binding to match textures
authorMikko Rasa <tdb@tdb.fi>
Thu, 28 Nov 2013 00:02:49 +0000 (02:02 +0200)
committerMikko Rasa <tdb@tdb.fi>
Thu, 28 Nov 2013 00:02:49 +0000 (02:02 +0200)
Both have multiple multiple parallel bind points, so it makes sense they
behave in the same way.

source/light.cpp
source/light.h
source/lightunit.cpp [new file with mode: 0644]
source/lightunit.h [new file with mode: 0644]

index 2192536450fdfd3a3d69235a02f641848833b16e..f9b45c87bfeac3bf5712dec6001fe29f7419d1f6 100644 (file)
@@ -1,5 +1,6 @@
 #include <stdexcept>
 #include "light.h"
+#include "lightunit.h"
 #include "misc.h"
 
 using namespace std;
@@ -7,9 +8,6 @@ using namespace std;
 namespace Msp {
 namespace GL {
 
-unsigned Light::current_unit = 0;
-vector<const Light *> Light::current_lights(1);
-
 Light::Light():
        diffuse(1),
        specular(1),
@@ -60,11 +58,12 @@ void Light::set_attenuation(float c, float l, float q)
        attenuation[2] = q;
 }
 
-void Light::bind() const
+void Light::bind_to(unsigned i) const
 {
-       if(current_lights[current_unit]!=this)
+       LightUnit &unit = LightUnit::get_unit(i);
+       if(unit.set_light(this))
        {
-               GLenum l = GL_LIGHT0+current_unit;
+               GLenum l = GL_LIGHT0+unit.get_index();
                enable(l);
                glLightfv(l, GL_DIFFUSE, &diffuse.r);
                glLightfv(l, GL_SPECULAR, &specular.r);
@@ -75,42 +74,19 @@ void Light::bind() const
                glLightf(l, GL_CONSTANT_ATTENUATION, attenuation[0]);
                glLightf(l, GL_LINEAR_ATTENUATION, attenuation[1]);
                glLightf(l, GL_QUADRATIC_ATTENUATION, attenuation[2]);
-               current_lights[current_unit] = this;
        }
 }
 
-void Light::bind_to(unsigned i) const
-{
-       activate(i);
-       bind();
-}
-
-void Light::activate(unsigned i)
-{
-       static unsigned max_lights = get_i(GL_MAX_LIGHTS);
-
-       if(i>=max_lights)
-               throw out_of_range("Light::activate");
-
-       if(i>=current_lights.size())
-               current_lights.resize(i+1);
-
-       current_unit = i;
-}
-
-void Light::unbind()
+const Light *Light::current(unsigned i)
 {
-       if(current_lights[current_unit])
-       {
-               disable(GL_LIGHT0+current_unit);
-               current_lights[current_unit] = 0;
-       }
+       return LightUnit::get_unit(i).get_light();
 }
 
 void Light::unbind_from(unsigned i)
 {
-       activate(i);
-       unbind();
+       LightUnit &unit = LightUnit::get_unit(i);
+       if(unit.set_light(0))
+               disable(GL_LIGHT0+unit.get_index());
 }
 
 } // namespace GL
index 658e828781ae32af78f1e70fafe99e984cb99ac7..cf9ab8a1acb69cdbec2cdfead4ad2580e66f40e7 100644 (file)
@@ -19,9 +19,6 @@ private:
        float spot_cutoff;
        float attenuation[3];
 
-       static unsigned current_unit;
-       static std::vector<const Light *> current_lights;
-
 public:
        Light();
 
@@ -41,11 +38,11 @@ public:
        void set_attenuation(float, float, float);
        const float *get_attenuation() const { return attenuation; }
 
-       void bind() const;
+       void bind() const { return bind_to(0); }
        void bind_to(unsigned) const;
 
-       static void activate(unsigned);
-       static void unbind();
+       static const Light *current(unsigned = 0);
+       static void unbind() { return unbind_from(0); }
        static void unbind_from(unsigned);
 };
 
diff --git a/source/lightunit.cpp b/source/lightunit.cpp
new file mode 100644 (file)
index 0000000..58d42e6
--- /dev/null
@@ -0,0 +1,48 @@
+#include <stdexcept>
+#include "gl.h"
+#include "misc.h"
+#include "lightunit.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+vector<LightUnit> LightUnit::units;
+LightUnit *LightUnit::cur_unit = 0;
+
+LightUnit::LightUnit():
+       light(0)
+{ }
+
+bool LightUnit::set_light(const Light *l)
+{
+       bool result = (l!=light);
+       light = l;
+       return result;
+}
+
+unsigned LightUnit::get_n_units()
+{
+       static int count = get_i(GL_MAX_LIGHTS);
+       return count;
+}
+
+LightUnit &LightUnit::get_unit(unsigned n)
+{
+       if(n>=get_n_units())
+               throw out_of_range("LightUnit::get_unit");
+
+       if(units.size()<=n)
+       {
+               unsigned i = units.size();
+               units.resize(n+1, LightUnit());
+               for(; i<units.size(); ++i)
+                       units[i].index = i;
+       }
+
+       return units[n];
+}
+
+} // namespace GL
+} // namespace Msp
diff --git a/source/lightunit.h b/source/lightunit.h
new file mode 100644 (file)
index 0000000..3f65d77
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef MSP_GL_LIGHTUNIT_H_
+#define MSP_GL_LIGHTUNIT_H_
+
+#include <vector>
+
+namespace Msp {
+namespace GL {
+
+class Light;
+
+class LightUnit
+{
+private:
+       unsigned index;
+       const Light *light;
+
+       static std::vector<LightUnit> units;
+       static LightUnit *cur_unit;
+
+       LightUnit();
+
+public:
+       unsigned get_index() const { return index; }
+       bool set_light(const Light *);
+       const Light *get_light() const { return light; }
+
+       static unsigned get_n_units();
+       static LightUnit &get_unit(unsigned i);
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif