2 #include <msp/gl/extensions/msp_legacy_features.h>
3 #include <msp/strings/format.h>
8 #include "programdata.h"
21 spot_cutoff(Geometry::Angle<float>::straight())
30 while(LightUnit *unit = LightUnit::find_unit(this))
31 unbind_from(unit->get_index());
34 void Light::update_parameter(int mask, int index) const
38 LightUnit *unit = LightUnit::find_unit(this);
42 index = unit->get_index();
45 GLenum l = GL_LIGHT0+index;
47 glLightfv(l, GL_DIFFUSE, &diffuse.r);
49 glLightfv(l, GL_SPECULAR, &specular.r);
51 glLightfv(l, GL_POSITION, &position.x);
53 glLightfv(l, GL_SPOT_DIRECTION, &spot_dir.x);
55 glLightf(l, GL_SPOT_EXPONENT, spot_exp);
57 glLightf(l, GL_SPOT_CUTOFF, spot_cutoff.degrees());
60 glLightf(l, GL_CONSTANT_ATTENUATION, attenuation[0]);
61 glLightf(l, GL_LINEAR_ATTENUATION, attenuation[1]);
62 glLightf(l, GL_QUADRATIC_ATTENUATION, attenuation[2]);
66 void Light::set_diffuse(const Color &c)
69 update_parameter(DIFFUSE);
72 void Light::set_specular(const Color &c)
75 update_parameter(SPECULAR);
78 void Light::set_position(const Vector4 &p)
81 update_parameter(POSITION);
84 void Light::set_spot_direction(const Vector3 &d)
86 spot_dir = normalize(d);
87 update_parameter(SPOT_DIR);
90 void Light::set_spot_exponent(float e)
93 throw invalid_argument("Light::set_spot_exponent");
96 update_parameter(SPOT_EXP);
99 void Light::set_spot_cutoff(float c)
101 set_spot_cutoff(Geometry::Angle<float>::from_degrees(c));
104 void Light::set_spot_cutoff(const Geometry::Angle<float> &c)
106 if(c<Geometry::Angle<float>::zero() || (c>Geometry::Angle<float>::right() && c!=Geometry::Angle<float>::straight()))
107 throw invalid_argument("Light::set_spot_cutoff");
110 update_parameter(SPOT_CUTOFF);
113 void Light::disable_spot_cutoff()
115 set_spot_cutoff(Geometry::Angle<float>::straight());
118 void Light::set_attenuation(float c, float l, float q)
123 update_parameter(ATTENUATION);
126 void Light::update_shader_data(ProgramData &shdata, const Matrix &view_matrix, unsigned i) const
128 string base = format("light_sources[%d]", i);
129 shdata.uniform(base+".position", view_matrix*position);
130 shdata.uniform(base+".diffuse", diffuse);
131 shdata.uniform(base+".specular", specular);
134 void Light::bind_to(unsigned i) const
136 static Require _req(MSP_legacy_features);
138 LightUnit &unit = LightUnit::get_unit(i);
139 if(unit.set_light(this))
141 enable(GL_LIGHT0+unit.get_index());
142 update_parameter(-1, unit.get_index());
146 const Light *Light::current(unsigned i)
148 return LightUnit::get_unit(i).get_light();
151 void Light::unbind_from(unsigned i)
153 LightUnit &unit = LightUnit::get_unit(i);
154 if(unit.set_light(0))
155 disable(GL_LIGHT0+unit.get_index());