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