]> git.tdb.fi Git - libs/gl.git/commitdiff
Convert Light to object model
authorMikko Rasa <tdb@tdb.fi>
Sun, 28 Sep 2008 15:40:26 +0000 (15:40 +0000)
committerMikko Rasa <tdb@tdb.fi>
Sun, 28 Sep 2008 15:40:26 +0000 (15:40 +0000)
Add class Lighting to encapsulate lighting state as a whole

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

index 5b0fa1d768c0601112ebf9dc91313a961ab49949..899e22c9853d964ed7c0a591d4585cbfb2591c0c 100644 (file)
@@ -5,9 +5,12 @@ Copyright © 2007  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
+#include "except.h"
 #include "light.h"
 #include "misc.h"
 
+using namespace std;
+
 namespace Msp {
 namespace GL {
 
@@ -44,22 +47,50 @@ void Light::set_position(float x_, float y_, float z_, float w_)
        w=w_;
 }
 
-void Light::apply() const
+void Light::bind() const
+{
+       if(current_lights[current_unit]!=this)
+       {
+               GLenum l=GL_LIGHT0+current_unit;
+               enable(l);
+               glLightfv(l, GL_AMBIENT, &ambient.r);
+               glLightfv(l, GL_DIFFUSE, &diffuse.r);
+               glLightfv(l, GL_SPECULAR, &specular.r);
+               glLightfv(l, GL_POSITION, &x);
+               current_lights[current_unit]=this;
+       }
+}
+
+void Light::bind_to(unsigned i) const
+{
+       activate(i);
+       bind();
+}
+
+void Light::activate(unsigned i)
 {
-       apply_to(current);
+       static unsigned max_lights=get_i(GL_MAX_LIGHTS);
+
+       if(i>=max_lights)
+               throw InvalidParameterValue("Light unit index out of range");
+
+       if(i>=current_lights.size())
+               current_lights.resize(i+1);
+
+       current_unit=i;
 }
 
-void Light::apply_to(unsigned l) const
+void Light::unbind()
 {
-       l+=GL_LIGHT0;
-       enable(l);
-       glLightfv(l, GL_AMBIENT, &ambient.r);
-       glLightfv(l, GL_DIFFUSE, &diffuse.r);
-       glLightfv(l, GL_SPECULAR, &specular.r);
-       glLightfv(l, GL_POSITION, &x);
+       if(current_lights[current_unit])
+       {
+               disable(GL_LIGHT0+current_unit);
+               current_lights[current_unit]=0;
+       }
 }
 
-unsigned Light::current=0;
+unsigned Light::current_unit=0;
+vector<const Light *> Light::current_lights(1);
 
 } // namespace GL
 } // namespace Msp
index 6a6868412f7614a70e2241f02f2871d2d0077437..e9b032694565e7e857e32fada5d84a0d70013505 100644 (file)
@@ -8,6 +8,7 @@ Distributed under the LGPL
 #ifndef MSP_GL_LIGHT_H_
 #define MSP_GL_LIGHT_H_
 
+#include <vector>
 #include "color.h"
 
 namespace Msp {
@@ -25,7 +26,8 @@ private:
        float spot_cutoff;
        float attenuation[3];
 
-       static unsigned current;
+       static unsigned current_unit;
+       static std::vector<const Light *> current_lights;
 
 public:
        Light();
@@ -33,10 +35,11 @@ public:
        void set_diffuse(const Color &c);
        void set_specular(const Color &c);
        void set_position(float, float, float, float);
-       void apply() const;
-       void apply_to(unsigned) const;
+       void bind() const;
+       void bind_to(unsigned) const;
 
        static void activate(unsigned);
+       static void unbind();
 };
 
 } // namespace GL
diff --git a/source/lighting.cpp b/source/lighting.cpp
new file mode 100644 (file)
index 0000000..6b6af57
--- /dev/null
@@ -0,0 +1,71 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2008  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include "light.h"
+#include "lighting.h"
+#include "misc.h"
+
+namespace Msp {
+namespace GL {
+
+Lighting::Lighting():
+       ambient(0.2)
+{ }
+
+void Lighting::set_ambient(const Color &a)
+{
+       ambient=a;
+}
+
+void Lighting::attach(unsigned i, const Light &l)
+{
+       if(i>=lights.size())
+               lights.resize(i+1);
+
+       lights[i]=&l;
+}
+
+void Lighting::detach(unsigned i)
+{
+       if(i>=lights.size())
+               return;
+
+       lights[i]=0;
+}
+
+void Lighting::bind() const
+{
+       if(current!=this)
+       {
+               enable(LIGHTING);
+               glLightModelfv(GL_LIGHT_MODEL_AMBIENT, &ambient.r);
+               for(unsigned i=0; i<lights.size(); ++i)
+                       if(lights[i])
+                               lights[i]->bind_to(i);
+               current=this;
+       }
+}
+
+void Lighting::unbind()
+{
+       if(current)
+       {
+               for(unsigned i=0; i<current->lights.size(); ++i)
+                       if(current->lights[i])
+                       {
+                               Light::activate(i);
+                               Light::unbind();
+                       }
+               disable(LIGHTING);
+               current=0;
+       }
+}
+
+const Lighting *Lighting::current=0;
+
+} // namespace GL
+} // namespace Msp
diff --git a/source/lighting.h b/source/lighting.h
new file mode 100644 (file)
index 0000000..85d5fb0
--- /dev/null
@@ -0,0 +1,52 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2008  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GL_LIGHTING_H_
+#define MSP_GL_LIGHTING_H_
+
+#include <vector>
+#include "color.h"
+#include "gl.h"
+
+namespace Msp {
+namespace GL {
+
+class Light;
+
+enum
+{
+       LIGHTING = GL_LIGHTING
+};
+
+/**
+Encapsulates global lighting parameters and a number of individual lights.
+*/
+class Lighting
+{
+private:
+       Color ambient;
+       std::vector<const Light *> lights;
+
+       static const Lighting *current;
+
+public:
+       Lighting();
+
+       void set_ambient(const Color &);
+       const Color &get_ambient() const { return ambient; }
+
+       void attach(unsigned, const Light &);
+       void detach(unsigned);
+       void bind() const;
+
+       static void unbind();
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif
index 9815383a793ade89f5e7b5d23221af70b77e7a1b..70b300a661783e5398b3ca891a6b646b3ceeae87 100644 (file)
@@ -28,5 +28,17 @@ void set(GLenum state, bool value)
                disable(state);
 }
 
+void get(GLenum state, int &data)
+{
+       glGetIntegerv(state, &data);
+}
+
+int get_i(GLenum state)
+{
+       int data;
+       get(state, data);
+       return data;
+}
+
 } // namespace GL
 } // namespace Msp
index 8a956a5ab4a26306f06abd4869a2dd6b42a93d43..e9ed91bfa672b300214a69afe06c680b12993bae 100644 (file)
@@ -17,6 +17,9 @@ void enable(GLenum);
 void disable(GLenum);
 void set(GLenum, bool);
 
+void get(GLenum, int &);
+int get_i(GLenum);
+
 } // namespace GL
 } // namespace Msp