rev |
line source |
nuclear@4
|
1 #include "opengl.h"
|
nuclear@4
|
2 #include "light.h"
|
nuclear@4
|
3
|
nuclear@4
|
4 Light::Light(const Color &col)
|
nuclear@4
|
5 : color(col)
|
nuclear@4
|
6 {
|
nuclear@4
|
7 intensity = 1.0;
|
nuclear@23
|
8 vbo = 0;
|
nuclear@23
|
9 num_faces = 0;
|
nuclear@4
|
10 }
|
nuclear@4
|
11
|
nuclear@4
|
12 Light::~Light() {}
|
nuclear@4
|
13
|
nuclear@4
|
14 void Light::set_intensity(float val)
|
nuclear@4
|
15 {
|
nuclear@4
|
16 intensity = val;
|
nuclear@4
|
17 }
|
nuclear@4
|
18
|
nuclear@4
|
19 void Light::set_color(const Color &col)
|
nuclear@4
|
20 {
|
nuclear@4
|
21 color = col;
|
nuclear@4
|
22 }
|
nuclear@4
|
23
|
nuclear@21
|
24 Color Light::get_color(bool with_intensity) const
|
nuclear@21
|
25 {
|
nuclear@21
|
26 return with_intensity ? color * intensity : color;
|
nuclear@21
|
27 }
|
nuclear@21
|
28
|
nuclear@4
|
29 void Light::use(int id) const
|
nuclear@4
|
30 {
|
nuclear@4
|
31 glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, &color.x);
|
nuclear@4
|
32 glLightfv(GL_LIGHT0 + id, GL_SPECULAR, &color.x);
|
nuclear@4
|
33 }
|
nuclear@4
|
34
|
nuclear@23
|
35 void Light::draw() const
|
nuclear@23
|
36 {
|
nuclear@23
|
37 if(!vbo) {
|
nuclear@23
|
38 if(!((Light*)this)->create_mesh()) {
|
nuclear@23
|
39 return;
|
nuclear@23
|
40 }
|
nuclear@23
|
41 }
|
nuclear@23
|
42
|
nuclear@23
|
43 glEnableClientState(GL_VERTEX_ARRAY);
|
nuclear@23
|
44 glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
nuclear@23
|
45 glVertexPointer(3, GL_FLOAT, 0, 0);
|
nuclear@23
|
46
|
nuclear@23
|
47 glDrawArrays(GL_TRIANGLES, 0, num_faces * 3);
|
nuclear@23
|
48
|
nuclear@27
|
49 glBindBuffer(GL_ARRAY_BUFFER, 0);
|
nuclear@23
|
50 glDisableClientState(GL_VERTEX_ARRAY);
|
nuclear@23
|
51 }
|
nuclear@23
|
52
|
nuclear@23
|
53 bool Light::create_mesh()
|
nuclear@23
|
54 {
|
nuclear@23
|
55 fprintf(stderr, "%s: undefined\n", __FUNCTION__);
|
nuclear@23
|
56 return false;
|
nuclear@23
|
57 }
|
nuclear@23
|
58
|
nuclear@4
|
59
|
nuclear@4
|
60 PointLight::PointLight()
|
nuclear@4
|
61 {
|
nuclear@4
|
62 atten[0] = 1.0f;
|
nuclear@4
|
63 atten[1] = 0.0f;
|
nuclear@4
|
64 atten[2] = 0.0f;
|
nuclear@21
|
65 radius = 1.0;
|
nuclear@4
|
66 }
|
nuclear@4
|
67
|
nuclear@4
|
68 PointLight::PointLight(const Vector3 &pos, const Color &col)
|
nuclear@4
|
69 : Light(col)
|
nuclear@4
|
70 {
|
nuclear@4
|
71 this->pos = pos;
|
nuclear@4
|
72 atten[0] = 1.0f;
|
nuclear@4
|
73 atten[1] = 0.0f;
|
nuclear@4
|
74 atten[2] = 0.0f;
|
nuclear@21
|
75 radius = 1.0;
|
nuclear@4
|
76 }
|
nuclear@4
|
77
|
nuclear@4
|
78 void PointLight::set_position(const Vector3 &pos)
|
nuclear@4
|
79 {
|
nuclear@4
|
80 this->pos = pos;
|
nuclear@4
|
81 }
|
nuclear@4
|
82
|
nuclear@4
|
83 void PointLight::set_attenuation(float att_const, float att_lin, float att_quad)
|
nuclear@4
|
84 {
|
nuclear@4
|
85 atten[0] = att_const;
|
nuclear@4
|
86 atten[1] = att_lin;
|
nuclear@4
|
87 atten[2] = att_quad;
|
nuclear@4
|
88 }
|
nuclear@4
|
89
|
nuclear@21
|
90 void PointLight::set_radius(float rad)
|
nuclear@21
|
91 {
|
nuclear@21
|
92 radius = rad;
|
nuclear@21
|
93 }
|
nuclear@21
|
94
|
nuclear@21
|
95 float PointLight::get_radius() const
|
nuclear@21
|
96 {
|
nuclear@21
|
97 return radius;
|
nuclear@21
|
98 }
|
nuclear@21
|
99
|
nuclear@4
|
100 void PointLight::use(int id) const
|
nuclear@4
|
101 {
|
nuclear@4
|
102 float lpos[] = {pos.x, pos.y, pos.z, 1.0f};
|
nuclear@4
|
103 glLightfv(GL_LIGHT0 + id, GL_POSITION, lpos);
|
nuclear@4
|
104 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, atten[0]);
|
nuclear@4
|
105 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, atten[1]);
|
nuclear@4
|
106 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, atten[2]);
|
nuclear@4
|
107 }
|
nuclear@4
|
108
|
nuclear@23
|
109 void PointLight::draw() const
|
nuclear@23
|
110 {
|
nuclear@23
|
111 //glMatrixMode(GL_MODELVIEW);
|
nuclear@23
|
112 //glPushMatrix();
|
nuclear@23
|
113 //glScalef(radius, radius, radius);
|
nuclear@23
|
114
|
nuclear@23
|
115 Light::draw();
|
nuclear@23
|
116
|
nuclear@23
|
117 //glPopMatrix();
|
nuclear@23
|
118 }
|
nuclear@23
|
119
|
nuclear@23
|
120
|
nuclear@23
|
121
|
nuclear@23
|
122 Vector3 sphvertex(float u, float v)
|
nuclear@23
|
123 {
|
nuclear@23
|
124 float theta = u * M_PI * 2.0;
|
nuclear@23
|
125 float phi = v * M_PI;
|
nuclear@23
|
126
|
nuclear@23
|
127 Vector3 res;
|
nuclear@25
|
128 res.x = sin(theta) * sin(phi);
|
nuclear@25
|
129 res.y = cos(phi);
|
nuclear@25
|
130 res.z = cos(theta) * sin(phi);
|
nuclear@23
|
131 return res;
|
nuclear@23
|
132 }
|
nuclear@23
|
133
|
nuclear@23
|
134
|
nuclear@23
|
135 bool PointLight::create_mesh()
|
nuclear@23
|
136 {
|
nuclear@23
|
137 const static int udiv = 8;
|
nuclear@23
|
138 const static int vdiv = 4;
|
nuclear@23
|
139
|
nuclear@23
|
140 int nquads = udiv * vdiv;
|
nuclear@23
|
141 num_faces = nquads * 2;
|
nuclear@23
|
142 int nverts = num_faces * 3;
|
nuclear@23
|
143
|
nuclear@23
|
144 float du = 1.0 / (float)udiv;
|
nuclear@23
|
145 float dv = 1.0 / (float)vdiv;
|
nuclear@23
|
146
|
nuclear@23
|
147 glGenBuffers(1, &vbo);
|
nuclear@23
|
148 glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
nuclear@23
|
149 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof(Vector3), 0, GL_STATIC_DRAW);
|
nuclear@23
|
150
|
nuclear@23
|
151 Vector3 *vptr = (Vector3*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
|
nuclear@23
|
152
|
nuclear@23
|
153 for(int i=0; i<vdiv; i++) {
|
nuclear@23
|
154 float v = (float)i / (float)vdiv;
|
nuclear@23
|
155 for(int j=0; j<udiv; j++) {
|
nuclear@23
|
156 float u = (float)j / (float)udiv;
|
nuclear@23
|
157
|
nuclear@23
|
158 *vptr++ = sphvertex(u, v);
|
nuclear@23
|
159 *vptr++ = sphvertex(u + du, v);
|
nuclear@23
|
160 *vptr++ = sphvertex(u, v + dv);
|
nuclear@23
|
161
|
nuclear@23
|
162 *vptr++ = sphvertex(u + du, v);
|
nuclear@23
|
163 *vptr++ = sphvertex(u + du, v + dv);
|
nuclear@23
|
164 *vptr++ = sphvertex(u, v + dv);
|
nuclear@23
|
165 }
|
nuclear@23
|
166 }
|
nuclear@23
|
167 glUnmapBuffer(GL_ARRAY_BUFFER);
|
nuclear@27
|
168 glBindBuffer(GL_ARRAY_BUFFER, 0);
|
nuclear@23
|
169 return true;
|
nuclear@23
|
170 }
|
nuclear@4
|
171
|
nuclear@4
|
172 void set_light(int id, const Light *lt)
|
nuclear@4
|
173 {
|
nuclear@4
|
174 if(lt) {
|
nuclear@4
|
175 glDisable(GL_LIGHT0 + id);
|
nuclear@4
|
176 } else {
|
nuclear@4
|
177 glEnable(GL_LIGHT0 + id);
|
nuclear@4
|
178 lt->use(id);
|
nuclear@4
|
179 }
|
nuclear@4
|
180 }
|