dungeon_crawler

view prototype/src/light.cc @ 29:2fc004802739

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