dungeon_crawler

annotate prototype/src/light.cc @ 41:acfe0c0110fc

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