+ spot_dir = d;
+}
+
+void Light::set_spot_exponent(float e)
+{
+ spot_exp = e;
+}
+
+void Light::set_spot_cutoff(float c)
+{
+ spot_cutoff = c;
+}
+
+void Light::set_attenuation(float c, float l, float q)
+{
+ attenuation[0] = c;
+ attenuation[1] = l;
+ attenuation[2] = q;
+}
+
+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, &position.x);
+ glLightfv(l, GL_SPOT_DIRECTION, &spot_dir.x);
+ glLightf(l, GL_SPOT_EXPONENT, spot_exp);
+ glLightf(l, GL_SPOT_CUTOFF, spot_cutoff);
+ 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;