dungeon_crawler

annotate prototype/src/light.cc @ 35:d0e93b4d9ec9

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