dungeon_crawler

view prototype/src/light.cc @ 23:fa8f89d06f6f

progress with light rendering
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 23 Aug 2012 00:10:10 +0300
parents 0588f8a1a351
children 527fede30057
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 glDisableClientState(GL_VERTEX_ARRAY);
50 }
52 bool Light::create_mesh()
53 {
54 fprintf(stderr, "%s: undefined\n", __FUNCTION__);
55 return false;
56 }
59 PointLight::PointLight()
60 {
61 atten[0] = 1.0f;
62 atten[1] = 0.0f;
63 atten[2] = 0.0f;
64 radius = 1.0;
65 }
67 PointLight::PointLight(const Vector3 &pos, const Color &col)
68 : Light(col)
69 {
70 this->pos = pos;
71 atten[0] = 1.0f;
72 atten[1] = 0.0f;
73 atten[2] = 0.0f;
74 radius = 1.0;
75 }
77 void PointLight::set_position(const Vector3 &pos)
78 {
79 this->pos = pos;
80 }
82 void PointLight::set_attenuation(float att_const, float att_lin, float att_quad)
83 {
84 atten[0] = att_const;
85 atten[1] = att_lin;
86 atten[2] = att_quad;
87 }
89 void PointLight::set_radius(float rad)
90 {
91 radius = rad;
92 }
94 float PointLight::get_radius() const
95 {
96 return radius;
97 }
99 void PointLight::use(int id) const
100 {
101 float lpos[] = {pos.x, pos.y, pos.z, 1.0f};
102 glLightfv(GL_LIGHT0 + id, GL_POSITION, lpos);
103 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, atten[0]);
104 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, atten[1]);
105 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, atten[2]);
106 }
108 void PointLight::draw() const
109 {
110 //glMatrixMode(GL_MODELVIEW);
111 //glPushMatrix();
112 //glScalef(radius, radius, radius);
114 Light::draw();
116 //glPopMatrix();
117 }
121 Vector3 sphvertex(float u, float v)
122 {
123 float theta = u * M_PI * 2.0;
124 float phi = v * M_PI;
126 Vector3 res;
127 res.x = sin(theta) * cos(phi);
128 res.y = sin(theta);
129 res.z = cos(theta) * cos(phi);
130 return res;
131 }
134 bool PointLight::create_mesh()
135 {
136 const static int udiv = 8;
137 const static int vdiv = 4;
139 int nquads = udiv * vdiv;
140 num_faces = nquads * 2;
141 int nverts = num_faces * 3;
143 float du = 1.0 / (float)udiv;
144 float dv = 1.0 / (float)vdiv;
146 glGenBuffers(1, &vbo);
147 glBindBuffer(GL_ARRAY_BUFFER, vbo);
148 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof(Vector3), 0, GL_STATIC_DRAW);
150 Vector3 *vptr = (Vector3*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
152 for(int i=0; i<vdiv; i++) {
153 float v = (float)i / (float)vdiv;
154 for(int j=0; j<udiv; j++) {
155 float u = (float)j / (float)udiv;
157 *vptr++ = sphvertex(u, v);
158 *vptr++ = sphvertex(u + du, v);
159 *vptr++ = sphvertex(u, v + dv);
161 *vptr++ = sphvertex(u + du, v);
162 *vptr++ = sphvertex(u + du, v + dv);
163 *vptr++ = sphvertex(u, v + dv);
164 }
165 }
166 glUnmapBuffer(GL_ARRAY_BUFFER);
167 return true;
168 }
170 void set_light(int id, const Light *lt)
171 {
172 if(lt) {
173 glDisable(GL_LIGHT0 + id);
174 } else {
175 glEnable(GL_LIGHT0 + id);
176 lt->use(id);
177 }
178 }