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