vrheights

annotate src/mesh.cc @ 8:3f221bdc9bab

mesh loading walk polys
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 03 Oct 2014 04:16:16 +0300
parents
children 25cab9e20c9c
rev   line source
nuclear@8 1 #include <string.h>
nuclear@8 2 #include "mesh.h"
nuclear@8 3 #include "opengl.h"
nuclear@8 4
nuclear@8 5 Mesh::Mesh()
nuclear@8 6 {
nuclear@8 7 set_primitive(GL_TRIANGLES);
nuclear@8 8
nuclear@8 9 for(int i=0; i<NUM_MESH_ATTRIBS; i++) {
nuclear@8 10 attrib[i].nelems = 3;
nuclear@8 11 attrib[i].sdrloc = -1;
nuclear@8 12 attrib[i].vbo = 0;
nuclear@8 13 attrib[i].vbo_valid = false;
nuclear@8 14 }
nuclear@8 15 num_verts = 0;
nuclear@8 16
nuclear@8 17 num_idx = 0;
nuclear@8 18 ibo = 0;
nuclear@8 19 ibo_size = 0;
nuclear@8 20 ibo_valid = false;
nuclear@8 21
nuclear@8 22 vbo_usage = ibo_usage = GL_STATIC_DRAW;
nuclear@8 23 }
nuclear@8 24
nuclear@8 25 Mesh::~Mesh()
nuclear@8 26 {
nuclear@8 27 clear();
nuclear@8 28
nuclear@8 29 for(int i=0; i<NUM_MESH_ATTRIBS; i++) {
nuclear@8 30 if(attrib[i].vbo) {
nuclear@8 31 glDeleteBuffers(1, &attrib[i].vbo);
nuclear@8 32 }
nuclear@8 33 }
nuclear@8 34 if(ibo) {
nuclear@8 35 glDeleteBuffers(1, &ibo);
nuclear@8 36 }
nuclear@8 37 }
nuclear@8 38
nuclear@8 39 void Mesh::clear()
nuclear@8 40 {
nuclear@8 41 for(int i=0; i<NUM_MESH_ATTRIBS; i++) {
nuclear@8 42 attrib[i].vbo_valid = false;
nuclear@8 43 attrib[i].data.clear();
nuclear@8 44
nuclear@8 45 }
nuclear@8 46 ibo_valid = false;
nuclear@8 47 index.clear();
nuclear@8 48 }
nuclear@8 49
nuclear@8 50 void Mesh::set_primitive(int prim)
nuclear@8 51 {
nuclear@8 52 if(prim == -1) {
nuclear@8 53 this->prim = GL_TRIANGLES;
nuclear@8 54 } else {
nuclear@8 55 this->prim = prim;
nuclear@8 56 }
nuclear@8 57
nuclear@8 58 switch(this->prim) {
nuclear@8 59 case GL_TRIANGLES:
nuclear@8 60 prim_verts = 3;
nuclear@8 61 break;
nuclear@8 62
nuclear@8 63 case GL_QUADS:
nuclear@8 64 prim_verts = 4;
nuclear@8 65 break;
nuclear@8 66
nuclear@8 67 case GL_LINES:
nuclear@8 68 prim_verts = 2;
nuclear@8 69 break;
nuclear@8 70
nuclear@8 71 case GL_POINTS:
nuclear@8 72 prim_verts = 1;
nuclear@8 73 break;
nuclear@8 74
nuclear@8 75 default:
nuclear@8 76 break;
nuclear@8 77 }
nuclear@8 78 }
nuclear@8 79
nuclear@8 80 void Mesh::set_attrib_location(int attr, int loc)
nuclear@8 81 {
nuclear@8 82 attrib[attr].sdrloc = loc;
nuclear@8 83 }
nuclear@8 84
nuclear@8 85 float *Mesh::set_vertex_data(int attr, int nelem, int count, float *data)
nuclear@8 86 {
nuclear@8 87 attrib[attr].data.resize(count * nelem);
nuclear@8 88 if(data) {
nuclear@8 89 memcpy(&attrib[attr].data[0], data, nelem * count * sizeof(float));
nuclear@8 90 }
nuclear@8 91
nuclear@8 92 attrib[attr].nelems = nelem;
nuclear@8 93 attrib[attr].vbo_valid = false;
nuclear@8 94
nuclear@8 95 num_verts = count;
nuclear@8 96
nuclear@8 97 return &attrib[attr].data[0];
nuclear@8 98 }
nuclear@8 99
nuclear@8 100 unsigned int *Mesh::set_index_data(int count, unsigned int *data)
nuclear@8 101 {
nuclear@8 102 index.resize(count);
nuclear@8 103 if(data) {
nuclear@8 104 memcpy(&index[0], data, count * sizeof(unsigned int));
nuclear@8 105 }
nuclear@8 106
nuclear@8 107 num_idx = count;
nuclear@8 108 ibo_valid = false;
nuclear@8 109
nuclear@8 110 return &index[0];
nuclear@8 111 }
nuclear@8 112
nuclear@8 113 int Mesh::get_vertex_count() const
nuclear@8 114 {
nuclear@8 115 return num_verts;
nuclear@8 116 }
nuclear@8 117
nuclear@8 118 float *Mesh::get_vertex_data(int attr)
nuclear@8 119 {
nuclear@8 120 if(attrib[attr].data.empty()) {
nuclear@8 121 return 0;
nuclear@8 122 }
nuclear@8 123 return &attrib[attr].data[0];
nuclear@8 124 }
nuclear@8 125
nuclear@8 126 const float *Mesh::get_vertex_data(int attr) const
nuclear@8 127 {
nuclear@8 128 if(attrib[attr].data.empty()) {
nuclear@8 129 return 0;
nuclear@8 130 }
nuclear@8 131 return &attrib[attr].data[0];
nuclear@8 132 }
nuclear@8 133
nuclear@8 134 int Mesh::get_index_count() const
nuclear@8 135 {
nuclear@8 136 return num_idx;
nuclear@8 137 }
nuclear@8 138
nuclear@8 139 unsigned int *Mesh::get_index_data()
nuclear@8 140 {
nuclear@8 141 if(index.empty()) {
nuclear@8 142 return 0;
nuclear@8 143 }
nuclear@8 144 return &index[0];
nuclear@8 145 }
nuclear@8 146
nuclear@8 147 const unsigned int *Mesh::get_index_data() const
nuclear@8 148 {
nuclear@8 149 if(index.empty()) {
nuclear@8 150 return 0;
nuclear@8 151 }
nuclear@8 152 return &index[0];
nuclear@8 153 }
nuclear@8 154
nuclear@8 155 int Mesh::get_face_count() const
nuclear@8 156 {
nuclear@8 157 if(index.empty()) {
nuclear@8 158 return get_vertex_count() / prim_verts;
nuclear@8 159 }
nuclear@8 160 return get_index_count() / prim_verts;
nuclear@8 161 }
nuclear@8 162
nuclear@8 163 MeshFace Mesh::get_face(int idx) const
nuclear@8 164 {
nuclear@8 165 MeshFace face;
nuclear@8 166 face.vcount = prim_verts;
nuclear@8 167
nuclear@8 168 int nfaces = get_face_count();
nuclear@8 169 if(idx < 0 || idx >= nfaces) {
nuclear@8 170 return face;
nuclear@8 171 }
nuclear@8 172
nuclear@8 173 const Vector3 *verts = (const Vector3*)&attrib[MESH_VERTEX].data[0];
nuclear@8 174
nuclear@8 175 if(index.empty()) {
nuclear@8 176 for(int i=0; i<3; i++) {
nuclear@8 177 face.v[i] = verts[idx * 3 + i];
nuclear@8 178 }
nuclear@8 179
nuclear@8 180 } else {
nuclear@8 181 for(int i=0; i<3; i++) {
nuclear@8 182 int vidx = index[idx * 3 + i];
nuclear@8 183 face.v[i] = verts[vidx];
nuclear@8 184 }
nuclear@8 185 }
nuclear@8 186
nuclear@8 187 return face;
nuclear@8 188 }
nuclear@8 189
nuclear@8 190
nuclear@8 191 void Mesh::begin(int prim)
nuclear@8 192 {
nuclear@8 193 if(prim == -1) {
nuclear@8 194 this->prim = GL_TRIANGLES;
nuclear@8 195 } else {
nuclear@8 196 this->prim = prim;
nuclear@8 197 }
nuclear@8 198
nuclear@8 199 clear();
nuclear@8 200
nuclear@8 201 cur_norm_valid = false;
nuclear@8 202 cur_tc_valid = false;
nuclear@8 203 cur_tang_valid = false;
nuclear@8 204 }
nuclear@8 205
nuclear@8 206 void Mesh::end()
nuclear@8 207 {
nuclear@8 208 }
nuclear@8 209
nuclear@8 210 void Mesh::vertex(float x, float y, float z)
nuclear@8 211 {
nuclear@8 212 if(cur_norm_valid) {
nuclear@8 213 attrib[MESH_NORMAL].data.push_back(cur_norm.x);
nuclear@8 214 attrib[MESH_NORMAL].data.push_back(cur_norm.y);
nuclear@8 215 attrib[MESH_NORMAL].data.push_back(cur_norm.z);
nuclear@8 216 }
nuclear@8 217 if(cur_tc_valid) {
nuclear@8 218 attrib[MESH_TEXCOORD].data.push_back(cur_tc.x);
nuclear@8 219 attrib[MESH_TEXCOORD].data.push_back(cur_tc.y);
nuclear@8 220 }
nuclear@8 221 if(cur_tang_valid) {
nuclear@8 222 attrib[MESH_TANGENT].data.push_back(cur_tang.x);
nuclear@8 223 attrib[MESH_TANGENT].data.push_back(cur_tang.y);
nuclear@8 224 attrib[MESH_TANGENT].data.push_back(cur_tang.z);
nuclear@8 225 }
nuclear@8 226 attrib[MESH_VERTEX].data.push_back(x);
nuclear@8 227 attrib[MESH_VERTEX].data.push_back(y);
nuclear@8 228 attrib[MESH_VERTEX].data.push_back(z);
nuclear@8 229 }
nuclear@8 230
nuclear@8 231 void Mesh::normal(float x, float y, float z)
nuclear@8 232 {
nuclear@8 233 cur_norm = Vector3(x, y, z);
nuclear@8 234 cur_norm_valid = true;
nuclear@8 235 }
nuclear@8 236
nuclear@8 237 void Mesh::texcoord(float x, float y)
nuclear@8 238 {
nuclear@8 239 cur_tc = Vector2(x, y);
nuclear@8 240 cur_tc_valid = true;
nuclear@8 241 }
nuclear@8 242
nuclear@8 243 void Mesh::tangent(float x, float y, float z)
nuclear@8 244 {
nuclear@8 245 cur_tang = Vector3(x, y, z);
nuclear@8 246 cur_tang_valid = true;
nuclear@8 247 }
nuclear@8 248
nuclear@8 249 void Mesh::draw() const
nuclear@8 250 {
nuclear@8 251 if(attrib[MESH_VERTEX].data.empty()) {
nuclear@8 252 return;
nuclear@8 253 }
nuclear@8 254
nuclear@8 255 bool use_norm = !attrib[MESH_NORMAL].data.empty();
nuclear@8 256 bool use_tc = !attrib[MESH_TEXCOORD].data.empty();
nuclear@8 257 bool use_tang = !attrib[MESH_TANGENT].data.empty();
nuclear@8 258 int norm_loc, tc_loc, tang_loc;
nuclear@8 259
nuclear@8 260 const float *ptr = &attrib[MESH_VERTEX].data[0];
nuclear@8 261 int loc = attrib[MESH_VERTEX].sdrloc;
nuclear@8 262 if(loc == -1) {
nuclear@8 263 glEnableClientState(GL_VERTEX_ARRAY);
nuclear@8 264 glVertexPointer(attrib[MESH_VERTEX].nelems, GL_FLOAT, 0, ptr);
nuclear@8 265 } else {
nuclear@8 266 glEnableVertexAttribArray(loc);
nuclear@8 267 glVertexAttribPointer(loc, attrib[MESH_VERTEX].nelems, GL_FLOAT, 0, 0, ptr);
nuclear@8 268 }
nuclear@8 269
nuclear@8 270 if(use_norm) {
nuclear@8 271 const float *ptr = &attrib[MESH_NORMAL].data[0];
nuclear@8 272 norm_loc = attrib[MESH_NORMAL].sdrloc;
nuclear@8 273 if(norm_loc == -1) {
nuclear@8 274 glEnableClientState(GL_NORMAL_ARRAY);
nuclear@8 275 glNormalPointer(GL_FLOAT, 0, ptr);
nuclear@8 276 } else {
nuclear@8 277 glEnableVertexAttribArray(norm_loc);
nuclear@8 278 glVertexAttribPointer(norm_loc, attrib[MESH_NORMAL].nelems, GL_FLOAT, 0, 0, ptr);
nuclear@8 279 }
nuclear@8 280 }
nuclear@8 281
nuclear@8 282 if(use_tc) {
nuclear@8 283 const float *ptr = &attrib[MESH_TEXCOORD].data[0];
nuclear@8 284 tc_loc = attrib[MESH_TEXCOORD].sdrloc;
nuclear@8 285 if(tc_loc == -1) {
nuclear@8 286 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
nuclear@8 287 glTexCoordPointer(attrib[MESH_TEXCOORD].nelems, GL_FLOAT, 0, ptr);
nuclear@8 288 } else {
nuclear@8 289 glEnableVertexAttribArray(tc_loc);
nuclear@8 290 glVertexAttribPointer(tc_loc, attrib[MESH_TEXCOORD].nelems, GL_FLOAT, 0, 0, ptr);
nuclear@8 291 }
nuclear@8 292 }
nuclear@8 293
nuclear@8 294 if(!attrib[MESH_TANGENT].data.empty()) {
nuclear@8 295 const float *ptr = &attrib[MESH_TANGENT].data[0];
nuclear@8 296 tang_loc = attrib[MESH_TANGENT].sdrloc;
nuclear@8 297 if(tang_loc != -1) {
nuclear@8 298 glEnableVertexAttribArray(tang_loc);
nuclear@8 299 glVertexAttribPointer(tang_loc, attrib[MESH_TANGENT].nelems, GL_FLOAT, 0, 0, ptr);
nuclear@8 300 }
nuclear@8 301 }
nuclear@8 302
nuclear@8 303 if(!index.empty()) {
nuclear@8 304 glDrawElements(prim, num_idx, GL_UNSIGNED_INT, &index[0]);
nuclear@8 305 } else {
nuclear@8 306 glDrawArrays(prim, 0, num_verts * 3);
nuclear@8 307 }
nuclear@8 308
nuclear@8 309 if(use_norm) {
nuclear@8 310 if(norm_loc == -1) {
nuclear@8 311 glDisableClientState(GL_NORMAL_ARRAY);
nuclear@8 312 } else {
nuclear@8 313 glDisableVertexAttribArray(norm_loc);
nuclear@8 314 }
nuclear@8 315 }
nuclear@8 316 if(use_tc) {
nuclear@8 317 if(tc_loc == -1) {
nuclear@8 318 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
nuclear@8 319 } else {
nuclear@8 320 glDisableVertexAttribArray(tc_loc);
nuclear@8 321 }
nuclear@8 322 }
nuclear@8 323 if(use_tang) {
nuclear@8 324 if(tang_loc != -1) {
nuclear@8 325 glDisableVertexAttribArray(tang_loc);
nuclear@8 326 }
nuclear@8 327 }
nuclear@8 328 }