]> git.tdb.fi Git - libs/gl.git/blob - source/light.cpp
Better state tracking for bound objects
[libs/gl.git] / source / light.cpp
1 #include <stdexcept>
2 #include "light.h"
3 #include "lightunit.h"
4 #include "misc.h"
5
6 using namespace std;
7
8 namespace Msp {
9 namespace GL {
10
11 Light::Light():
12         diffuse(1),
13         specular(1),
14         position(0, 0, 1, 0),
15         spot_dir(0, 0, -1),
16         spot_exp(0),
17         spot_cutoff(180)
18 {
19         attenuation[0] = 1;
20         attenuation[1] = 0;
21         attenuation[2] = 0;
22 }
23
24 void Light::update_parameter(int mask, int index) const
25 {
26         if(index<0)
27         {
28                 LightUnit *unit = LightUnit::find_unit(this);
29                 if(!unit)
30                         return;
31
32                 index = unit->get_index();
33         }
34
35         GLenum l = GL_LIGHT0+index;
36         if(mask&DIFFUSE)
37                 glLightfv(l, GL_DIFFUSE, &diffuse.r);
38         if(mask&SPECULAR)
39                 glLightfv(l, GL_SPECULAR, &specular.r);
40         if(mask&POSITION)
41                 glLightfv(l, GL_POSITION, &position.x);
42         if(mask&SPOT_DIR)
43                 glLightfv(l, GL_SPOT_DIRECTION, &spot_dir.x);
44         if(mask&SPOT_EXP)
45                 glLightf(l, GL_SPOT_EXPONENT, spot_exp);
46         if(mask&SPOT_CUTOFF)
47                 glLightf(l, GL_SPOT_CUTOFF, spot_cutoff);
48         if(mask&ATTENUATION)
49         {
50                 glLightf(l, GL_CONSTANT_ATTENUATION, attenuation[0]);
51                 glLightf(l, GL_LINEAR_ATTENUATION, attenuation[1]);
52                 glLightf(l, GL_QUADRATIC_ATTENUATION, attenuation[2]);
53         }
54 }
55
56 void Light::set_diffuse(const Color &c)
57 {
58         diffuse = c;
59         update_parameter(DIFFUSE);
60 }
61
62 void Light::set_specular(const Color &c)
63 {
64         specular = c;
65         update_parameter(SPECULAR);
66 }
67
68 void Light::set_position(const Vector4 &p)
69 {
70         position = p;
71         update_parameter(POSITION);
72 }
73
74 void Light::set_spot_direction(const Vector3 &d)
75 {
76         spot_dir = d;
77         update_parameter(SPOT_DIR);
78 }
79
80 void Light::set_spot_exponent(float e)
81 {
82         spot_exp = e;
83         update_parameter(SPOT_EXP);
84 }
85
86 void Light::set_spot_cutoff(float c)
87 {
88         spot_cutoff = c;
89         update_parameter(SPOT_CUTOFF);
90 }
91
92 void Light::set_attenuation(float c, float l, float q)
93 {
94         attenuation[0] = c;
95         attenuation[1] = l;
96         attenuation[2] = q;
97         update_parameter(ATTENUATION);
98 }
99
100 void Light::bind_to(unsigned i) const
101 {
102         LightUnit &unit = LightUnit::get_unit(i);
103         if(unit.set_light(this))
104         {
105                 enable(GL_LIGHT0+unit.get_index());
106                 update_parameter(-1, unit.get_index());
107         }
108 }
109
110 const Light *Light::current(unsigned i)
111 {
112         return LightUnit::get_unit(i).get_light();
113 }
114
115 void Light::unbind_from(unsigned i)
116 {
117         LightUnit &unit = LightUnit::get_unit(i);
118         if(unit.set_light(0))
119                 disable(GL_LIGHT0+unit.get_index());
120 }
121
122 } // namespace GL
123 } // namespace Msp