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 +}