dungeon_crawler

view prototype/src/light.cc @ 27:cbf86e5198a9

fized the vbo state creep
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 25 Aug 2012 14:37:51 +0300
parents 527fede30057
children 2fc004802739
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 //glScalef(radius, radius, radius);
115 Light::draw();
117 //glPopMatrix();
118 }
122 Vector3 sphvertex(float u, float v)
123 {
124 float theta = u * M_PI * 2.0;
125 float phi = v * M_PI;
127 Vector3 res;
128 res.x = sin(theta) * sin(phi);
129 res.y = cos(phi);
130 res.z = cos(theta) * sin(phi);
131 return res;
132 }
135 bool PointLight::create_mesh()
136 {
137 const static int udiv = 8;
138 const static int vdiv = 4;
140 int nquads = udiv * vdiv;
141 num_faces = nquads * 2;
142 int nverts = num_faces * 3;
144 float du = 1.0 / (float)udiv;
145 float dv = 1.0 / (float)vdiv;
147 glGenBuffers(1, &vbo);
148 glBindBuffer(GL_ARRAY_BUFFER, vbo);
149 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof(Vector3), 0, GL_STATIC_DRAW);
151 Vector3 *vptr = (Vector3*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
153 for(int i=0; i<vdiv; i++) {
154 float v = (float)i / (float)vdiv;
155 for(int j=0; j<udiv; j++) {
156 float u = (float)j / (float)udiv;
158 *vptr++ = sphvertex(u, v);
159 *vptr++ = sphvertex(u + du, v);
160 *vptr++ = sphvertex(u, v + dv);
162 *vptr++ = sphvertex(u + du, v);
163 *vptr++ = sphvertex(u + du, v + dv);
164 *vptr++ = sphvertex(u, v + dv);
165 }
166 }
167 glUnmapBuffer(GL_ARRAY_BUFFER);
168 glBindBuffer(GL_ARRAY_BUFFER, 0);
169 return true;
170 }
172 void set_light(int id, const Light *lt)
173 {
174 if(lt) {
175 glDisable(GL_LIGHT0 + id);
176 } else {
177 glEnable(GL_LIGHT0 + id);
178 lt->use(id);
179 }
180 }