Distributed under the LGPL
*/
+#include "except.h"
#include "light.h"
#include "misc.h"
+using namespace std;
+
namespace Msp {
namespace GL {
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
#ifndef MSP_GL_LIGHT_H_
#define MSP_GL_LIGHT_H_
+#include <vector>
#include "color.h"
namespace Msp {
float spot_cutoff;
float attenuation[3];
- static unsigned current;
+ static unsigned current_unit;
+ static std::vector<const Light *> current_lights;
public:
Light();
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
--- /dev/null
+/* $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
--- /dev/null
+/* $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
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
void disable(GLenum);
void set(GLenum, bool);
+void get(GLenum, int &);
+int get_i(GLenum);
+
} // namespace GL
} // namespace Msp