vrheights
diff 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 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/mesh.cc Fri Oct 03 04:16:16 2014 +0300 1.3 @@ -0,0 +1,328 @@ 1.4 +#include <string.h> 1.5 +#include "mesh.h" 1.6 +#include "opengl.h" 1.7 + 1.8 +Mesh::Mesh() 1.9 +{ 1.10 + set_primitive(GL_TRIANGLES); 1.11 + 1.12 + for(int i=0; i<NUM_MESH_ATTRIBS; i++) { 1.13 + attrib[i].nelems = 3; 1.14 + attrib[i].sdrloc = -1; 1.15 + attrib[i].vbo = 0; 1.16 + attrib[i].vbo_valid = false; 1.17 + } 1.18 + num_verts = 0; 1.19 + 1.20 + num_idx = 0; 1.21 + ibo = 0; 1.22 + ibo_size = 0; 1.23 + ibo_valid = false; 1.24 + 1.25 + vbo_usage = ibo_usage = GL_STATIC_DRAW; 1.26 +} 1.27 + 1.28 +Mesh::~Mesh() 1.29 +{ 1.30 + clear(); 1.31 + 1.32 + for(int i=0; i<NUM_MESH_ATTRIBS; i++) { 1.33 + if(attrib[i].vbo) { 1.34 + glDeleteBuffers(1, &attrib[i].vbo); 1.35 + } 1.36 + } 1.37 + if(ibo) { 1.38 + glDeleteBuffers(1, &ibo); 1.39 + } 1.40 +} 1.41 + 1.42 +void Mesh::clear() 1.43 +{ 1.44 + for(int i=0; i<NUM_MESH_ATTRIBS; i++) { 1.45 + attrib[i].vbo_valid = false; 1.46 + attrib[i].data.clear(); 1.47 + 1.48 + } 1.49 + ibo_valid = false; 1.50 + index.clear(); 1.51 +} 1.52 + 1.53 +void Mesh::set_primitive(int prim) 1.54 +{ 1.55 + if(prim == -1) { 1.56 + this->prim = GL_TRIANGLES; 1.57 + } else { 1.58 + this->prim = prim; 1.59 + } 1.60 + 1.61 + switch(this->prim) { 1.62 + case GL_TRIANGLES: 1.63 + prim_verts = 3; 1.64 + break; 1.65 + 1.66 + case GL_QUADS: 1.67 + prim_verts = 4; 1.68 + break; 1.69 + 1.70 + case GL_LINES: 1.71 + prim_verts = 2; 1.72 + break; 1.73 + 1.74 + case GL_POINTS: 1.75 + prim_verts = 1; 1.76 + break; 1.77 + 1.78 + default: 1.79 + break; 1.80 + } 1.81 +} 1.82 + 1.83 +void Mesh::set_attrib_location(int attr, int loc) 1.84 +{ 1.85 + attrib[attr].sdrloc = loc; 1.86 +} 1.87 + 1.88 +float *Mesh::set_vertex_data(int attr, int nelem, int count, float *data) 1.89 +{ 1.90 + attrib[attr].data.resize(count * nelem); 1.91 + if(data) { 1.92 + memcpy(&attrib[attr].data[0], data, nelem * count * sizeof(float)); 1.93 + } 1.94 + 1.95 + attrib[attr].nelems = nelem; 1.96 + attrib[attr].vbo_valid = false; 1.97 + 1.98 + num_verts = count; 1.99 + 1.100 + return &attrib[attr].data[0]; 1.101 +} 1.102 + 1.103 +unsigned int *Mesh::set_index_data(int count, unsigned int *data) 1.104 +{ 1.105 + index.resize(count); 1.106 + if(data) { 1.107 + memcpy(&index[0], data, count * sizeof(unsigned int)); 1.108 + } 1.109 + 1.110 + num_idx = count; 1.111 + ibo_valid = false; 1.112 + 1.113 + return &index[0]; 1.114 +} 1.115 + 1.116 +int Mesh::get_vertex_count() const 1.117 +{ 1.118 + return num_verts; 1.119 +} 1.120 + 1.121 +float *Mesh::get_vertex_data(int attr) 1.122 +{ 1.123 + if(attrib[attr].data.empty()) { 1.124 + return 0; 1.125 + } 1.126 + return &attrib[attr].data[0]; 1.127 +} 1.128 + 1.129 +const float *Mesh::get_vertex_data(int attr) const 1.130 +{ 1.131 + if(attrib[attr].data.empty()) { 1.132 + return 0; 1.133 + } 1.134 + return &attrib[attr].data[0]; 1.135 +} 1.136 + 1.137 +int Mesh::get_index_count() const 1.138 +{ 1.139 + return num_idx; 1.140 +} 1.141 + 1.142 +unsigned int *Mesh::get_index_data() 1.143 +{ 1.144 + if(index.empty()) { 1.145 + return 0; 1.146 + } 1.147 + return &index[0]; 1.148 +} 1.149 + 1.150 +const unsigned int *Mesh::get_index_data() const 1.151 +{ 1.152 + if(index.empty()) { 1.153 + return 0; 1.154 + } 1.155 + return &index[0]; 1.156 +} 1.157 + 1.158 +int Mesh::get_face_count() const 1.159 +{ 1.160 + if(index.empty()) { 1.161 + return get_vertex_count() / prim_verts; 1.162 + } 1.163 + return get_index_count() / prim_verts; 1.164 +} 1.165 + 1.166 +MeshFace Mesh::get_face(int idx) const 1.167 +{ 1.168 + MeshFace face; 1.169 + face.vcount = prim_verts; 1.170 + 1.171 + int nfaces = get_face_count(); 1.172 + if(idx < 0 || idx >= nfaces) { 1.173 + return face; 1.174 + } 1.175 + 1.176 + const Vector3 *verts = (const Vector3*)&attrib[MESH_VERTEX].data[0]; 1.177 + 1.178 + if(index.empty()) { 1.179 + for(int i=0; i<3; i++) { 1.180 + face.v[i] = verts[idx * 3 + i]; 1.181 + } 1.182 + 1.183 + } else { 1.184 + for(int i=0; i<3; i++) { 1.185 + int vidx = index[idx * 3 + i]; 1.186 + face.v[i] = verts[vidx]; 1.187 + } 1.188 + } 1.189 + 1.190 + return face; 1.191 +} 1.192 + 1.193 + 1.194 +void Mesh::begin(int prim) 1.195 +{ 1.196 + if(prim == -1) { 1.197 + this->prim = GL_TRIANGLES; 1.198 + } else { 1.199 + this->prim = prim; 1.200 + } 1.201 + 1.202 + clear(); 1.203 + 1.204 + cur_norm_valid = false; 1.205 + cur_tc_valid = false; 1.206 + cur_tang_valid = false; 1.207 +} 1.208 + 1.209 +void Mesh::end() 1.210 +{ 1.211 +} 1.212 + 1.213 +void Mesh::vertex(float x, float y, float z) 1.214 +{ 1.215 + if(cur_norm_valid) { 1.216 + attrib[MESH_NORMAL].data.push_back(cur_norm.x); 1.217 + attrib[MESH_NORMAL].data.push_back(cur_norm.y); 1.218 + attrib[MESH_NORMAL].data.push_back(cur_norm.z); 1.219 + } 1.220 + if(cur_tc_valid) { 1.221 + attrib[MESH_TEXCOORD].data.push_back(cur_tc.x); 1.222 + attrib[MESH_TEXCOORD].data.push_back(cur_tc.y); 1.223 + } 1.224 + if(cur_tang_valid) { 1.225 + attrib[MESH_TANGENT].data.push_back(cur_tang.x); 1.226 + attrib[MESH_TANGENT].data.push_back(cur_tang.y); 1.227 + attrib[MESH_TANGENT].data.push_back(cur_tang.z); 1.228 + } 1.229 + attrib[MESH_VERTEX].data.push_back(x); 1.230 + attrib[MESH_VERTEX].data.push_back(y); 1.231 + attrib[MESH_VERTEX].data.push_back(z); 1.232 +} 1.233 + 1.234 +void Mesh::normal(float x, float y, float z) 1.235 +{ 1.236 + cur_norm = Vector3(x, y, z); 1.237 + cur_norm_valid = true; 1.238 +} 1.239 + 1.240 +void Mesh::texcoord(float x, float y) 1.241 +{ 1.242 + cur_tc = Vector2(x, y); 1.243 + cur_tc_valid = true; 1.244 +} 1.245 + 1.246 +void Mesh::tangent(float x, float y, float z) 1.247 +{ 1.248 + cur_tang = Vector3(x, y, z); 1.249 + cur_tang_valid = true; 1.250 +} 1.251 + 1.252 +void Mesh::draw() const 1.253 +{ 1.254 + if(attrib[MESH_VERTEX].data.empty()) { 1.255 + return; 1.256 + } 1.257 + 1.258 + bool use_norm = !attrib[MESH_NORMAL].data.empty(); 1.259 + bool use_tc = !attrib[MESH_TEXCOORD].data.empty(); 1.260 + bool use_tang = !attrib[MESH_TANGENT].data.empty(); 1.261 + int norm_loc, tc_loc, tang_loc; 1.262 + 1.263 + const float *ptr = &attrib[MESH_VERTEX].data[0]; 1.264 + int loc = attrib[MESH_VERTEX].sdrloc; 1.265 + if(loc == -1) { 1.266 + glEnableClientState(GL_VERTEX_ARRAY); 1.267 + glVertexPointer(attrib[MESH_VERTEX].nelems, GL_FLOAT, 0, ptr); 1.268 + } else { 1.269 + glEnableVertexAttribArray(loc); 1.270 + glVertexAttribPointer(loc, attrib[MESH_VERTEX].nelems, GL_FLOAT, 0, 0, ptr); 1.271 + } 1.272 + 1.273 + if(use_norm) { 1.274 + const float *ptr = &attrib[MESH_NORMAL].data[0]; 1.275 + norm_loc = attrib[MESH_NORMAL].sdrloc; 1.276 + if(norm_loc == -1) { 1.277 + glEnableClientState(GL_NORMAL_ARRAY); 1.278 + glNormalPointer(GL_FLOAT, 0, ptr); 1.279 + } else { 1.280 + glEnableVertexAttribArray(norm_loc); 1.281 + glVertexAttribPointer(norm_loc, attrib[MESH_NORMAL].nelems, GL_FLOAT, 0, 0, ptr); 1.282 + } 1.283 + } 1.284 + 1.285 + if(use_tc) { 1.286 + const float *ptr = &attrib[MESH_TEXCOORD].data[0]; 1.287 + tc_loc = attrib[MESH_TEXCOORD].sdrloc; 1.288 + if(tc_loc == -1) { 1.289 + glEnableClientState(GL_TEXTURE_COORD_ARRAY); 1.290 + glTexCoordPointer(attrib[MESH_TEXCOORD].nelems, GL_FLOAT, 0, ptr); 1.291 + } else { 1.292 + glEnableVertexAttribArray(tc_loc); 1.293 + glVertexAttribPointer(tc_loc, attrib[MESH_TEXCOORD].nelems, GL_FLOAT, 0, 0, ptr); 1.294 + } 1.295 + } 1.296 + 1.297 + if(!attrib[MESH_TANGENT].data.empty()) { 1.298 + const float *ptr = &attrib[MESH_TANGENT].data[0]; 1.299 + tang_loc = attrib[MESH_TANGENT].sdrloc; 1.300 + if(tang_loc != -1) { 1.301 + glEnableVertexAttribArray(tang_loc); 1.302 + glVertexAttribPointer(tang_loc, attrib[MESH_TANGENT].nelems, GL_FLOAT, 0, 0, ptr); 1.303 + } 1.304 + } 1.305 + 1.306 + if(!index.empty()) { 1.307 + glDrawElements(prim, num_idx, GL_UNSIGNED_INT, &index[0]); 1.308 + } else { 1.309 + glDrawArrays(prim, 0, num_verts * 3); 1.310 + } 1.311 + 1.312 + if(use_norm) { 1.313 + if(norm_loc == -1) { 1.314 + glDisableClientState(GL_NORMAL_ARRAY); 1.315 + } else { 1.316 + glDisableVertexAttribArray(norm_loc); 1.317 + } 1.318 + } 1.319 + if(use_tc) { 1.320 + if(tc_loc == -1) { 1.321 + glDisableClientState(GL_TEXTURE_COORD_ARRAY); 1.322 + } else { 1.323 + glDisableVertexAttribArray(tc_loc); 1.324 + } 1.325 + } 1.326 + if(use_tang) { 1.327 + if(tang_loc != -1) { 1.328 + glDisableVertexAttribArray(tang_loc); 1.329 + } 1.330 + } 1.331 +}