dungeon_crawler

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