]> git.tdb.fi Git - libs/gl.git/blob - source/lighting.cpp
Support hemispherical skylight in ProgramBuilder
[libs/gl.git] / source / lighting.cpp
1 #include <stdexcept>
2 #include "light.h"
3 #include "lighting.h"
4 #include "lightunit.h"
5 #include "matrix.h"
6 #include "misc.h"
7
8 using namespace std;
9
10 namespace Msp {
11 namespace GL {
12
13 Lighting::Lighting():
14         ambient(0.2),
15         sky_direction(0, 0, 1),
16         horizon_angle(Geometry::Angle<float>::zero())
17 { }
18
19 void Lighting::set_ambient(const Color &a)
20 {
21         ambient = a;
22 }
23
24 void Lighting::set_sky_color(const Color &s)
25 {
26         sky_color = s;
27 }
28
29 void Lighting::set_sky_direction(const Vector3 &d)
30 {
31         sky_direction = d;
32 }
33
34 void Lighting::set_horizon_angle(const Geometry::Angle<float> &a)
35 {
36         horizon_angle = a;
37 }
38
39 void Lighting::attach(unsigned i, const Light &l)
40 {
41         if(i>=LightUnit::get_n_units())
42                 throw out_of_range("Lighting::attach");
43
44         if(i>=lights.size())
45                 lights.resize(i+1);
46
47         lights[i] = &l;
48         if(current()==this)
49                 l.bind_to(i);
50 }
51
52 void Lighting::detach(unsigned i)
53 {
54         if(i>=lights.size())
55                 return;
56
57         lights[i] = 0;
58         if(current()==this)
59                 Light::unbind_from(i);
60 }
61
62 void Lighting::update_shader_data(ProgramData &shdata, const Matrix &view_matrix) const
63 {
64         shdata.uniform("ambient_color", ambient);
65         shdata.uniform("sky_color", sky_color);
66         shdata.uniform("eye_sky_dir", Vector3(view_matrix*Vector4(sky_direction, 0.0f)));
67         shdata.uniform("horizon_limit", horizon_angle.radians());
68
69         for(unsigned i=0; i<lights.size(); ++i)
70                 if(lights[i])
71                         lights[i]->update_shader_data(shdata, view_matrix, i);
72 }
73
74 void Lighting::bind() const
75 {
76         if(!set_current(this))
77                 return;
78
79         enable(GL_LIGHTING);
80         glLightModelfv(GL_LIGHT_MODEL_AMBIENT, &ambient.r);
81         for(unsigned i=0; i<lights.size(); ++i)
82                 if(lights[i])
83                         lights[i]->bind_to(i);
84 }
85
86 void Lighting::unbind()
87 {
88         const Lighting *old = current();
89         if(!set_current(0))
90                 return;
91
92         for(unsigned i=0; i<old->lights.size(); ++i)
93                 if(old->lights[i])
94                         Light::unbind_from(i);
95
96         disable(GL_LIGHTING);
97 }
98
99 } // namespace GL
100 } // namespace Msp