dungeon_crawler

diff prototype/src/mesh.cc @ 2:1f61f2a02832

added mesh class
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 09 Aug 2012 06:20:27 +0300
parents
children 158de53b4e18
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/prototype/src/mesh.cc	Thu Aug 09 06:20:27 2012 +0300
     1.3 @@ -0,0 +1,122 @@
     1.4 +#include "mesh.h"
     1.5 +#include "opengl.h"
     1.6 +
     1.7 +Mesh::Mesh()
     1.8 +{
     1.9 +	nverts = nfaces = 0;
    1.10 +	for(int i=0; i<NUM_MESH_ATTR; i++) {
    1.11 +		vbo[i] = 0;
    1.12 +	}
    1.13 +	ibo = 0;
    1.14 +	tang_loc = -1;
    1.15 +}
    1.16 +
    1.17 +Mesh::~Mesh()
    1.18 +{
    1.19 +	destroy();
    1.20 +}
    1.21 +
    1.22 +bool Mesh::create(const aiScene *scn, aiMesh *aim)
    1.23 +{
    1.24 +	if(vbo[MESH_ATTR_VERTEX]) {
    1.25 +		destroy();
    1.26 +	}
    1.27 +
    1.28 +	nverts = aim->mNumVertices;
    1.29 +	nfaces = aim->mNumFaces;
    1.30 +
    1.31 +	glGenBuffers(1, vbo + MESH_ATTR_VERTEX);
    1.32 +	glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
    1.33 +	glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mVertices, aim->mVertices, GL_STATIC_DRAW);
    1.34 +
    1.35 +	if(aim->mNormals) {
    1.36 +		glGenBuffers(1, vbo + MESH_ATTR_NORMAL);
    1.37 +		glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_NORMAL]);
    1.38 +		glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mNormals, aim->mNormals, GL_STATIC_DRAW);
    1.39 +	}
    1.40 +	if(aim->mTangents) {
    1.41 +		glGenBuffers(1, vbo + MESH_ATTR_TANGENT);
    1.42 +		glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TANGENT]);
    1.43 +		glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mTangents, aim->mTangents, GL_STATIC_DRAW);
    1.44 +	}
    1.45 +	if(aim->mTextureCoords[0]) {
    1.46 +		glGenBuffers(1, vbo + MESH_ATTR_TEXCOORD);
    1.47 +		glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TEXCOORD]);
    1.48 +		glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mTextureCoords[0], aim->mTextureCoords[0], GL_STATIC_DRAW);
    1.49 +	}
    1.50 +
    1.51 +	glGenBuffers(1, &ibo);
    1.52 +	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
    1.53 +	glBufferData(GL_ELEMENT_ARRAY_BUFFER, nfaces * 3 * sizeof *aim->mFaces[0].mIndices, 0, GL_STATIC_DRAW);
    1.54 +
    1.55 +	/* map the buffer and fill it up */
    1.56 +	unsigned int *iptr = (unsigned int*)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
    1.57 +
    1.58 +	for(int i=0; i<nfaces; i++) {
    1.59 +		for(int j=0; j<3; j++) {
    1.60 +			*iptr++ = aim->mFaces[i].mIndices[j];
    1.61 +		}
    1.62 +	}
    1.63 +	glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
    1.64 +	return true;
    1.65 +}
    1.66 +
    1.67 +void Mesh::destroy()
    1.68 +{
    1.69 +	for(int i=0; i<NUM_MESH_ATTR; i++) {
    1.70 +		if(vbo[i]) {
    1.71 +			glDeleteBuffers(1, vbo + i);
    1.72 +			vbo[i] = 0;
    1.73 +		}
    1.74 +	}
    1.75 +	glDeleteBuffers(1, &ibo);
    1.76 +	ibo = 0;
    1.77 +
    1.78 +	nverts = nfaces = 0;
    1.79 +	tang_loc = -1;
    1.80 +}
    1.81 +
    1.82 +void Mesh::set_attrib_location(int attr, int loc)
    1.83 +{
    1.84 +	if(attr == MESH_ATTR_TANGENT) {
    1.85 +		tang_loc = loc;
    1.86 +	}
    1.87 +}
    1.88 +
    1.89 +int Mesh::get_attrib_location(int attr) const
    1.90 +{
    1.91 +	return tang_loc;
    1.92 +}
    1.93 +
    1.94 +void Mesh::draw() const
    1.95 +{
    1.96 +	glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
    1.97 +	glVertexPointer(3, GL_FLOAT, 0, 0);
    1.98 +	glEnableClientState(GL_VERTEX_ARRAY);
    1.99 +
   1.100 +	if(vbo[MESH_ATTR_NORMAL]) {
   1.101 +		glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_NORMAL]);
   1.102 +		glNormalPointer(GL_FLOAT, 0, 0);
   1.103 +		glEnableClientState(GL_NORMAL_ARRAY);
   1.104 +	}
   1.105 +	if(vbo[MESH_ATTR_TANGENT] && tang_loc >= 0) {
   1.106 +		glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TANGENT]);
   1.107 +		glVertexAttribPointer(tang_loc, 3, GL_FLOAT, GL_FALSE, 0, 0);
   1.108 +		glEnableVertexAttribArray(tang_loc);
   1.109 +	}
   1.110 +	if(vbo[MESH_ATTR_TEXCOORD]) {
   1.111 +		glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TEXCOORD]);
   1.112 +		glTexCoordPointer(3, GL_FLOAT, 0, 0);
   1.113 +		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
   1.114 +	}
   1.115 +
   1.116 +	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
   1.117 +	glDrawElements(GL_TRIANGLES, nfaces * 3, GL_UNSIGNED_INT, 0);
   1.118 +
   1.119 +	glDisableClientState(GL_VERTEX_ARRAY);
   1.120 +	glDisableClientState(GL_NORMAL_ARRAY);
   1.121 +	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
   1.122 +	if(tang_loc >= 0) {
   1.123 +		glDisableVertexAttribArray(tang_loc);
   1.124 +	}
   1.125 +}