dungeon_crawler

annotate prototype/src/mesh.cc @ 7:8fb37db44fd8

first person motion
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 17 Aug 2012 14:29:37 +0300
parents 252a00508411
children 22562582c82d
rev   line source
nuclear@2 1 #include "mesh.h"
nuclear@2 2 #include "opengl.h"
nuclear@2 3
nuclear@2 4 Mesh::Mesh()
nuclear@2 5 {
nuclear@2 6 nverts = nfaces = 0;
nuclear@2 7 for(int i=0; i<NUM_MESH_ATTR; i++) {
nuclear@2 8 vbo[i] = 0;
nuclear@2 9 }
nuclear@2 10 ibo = 0;
nuclear@2 11 tang_loc = -1;
nuclear@2 12 }
nuclear@2 13
nuclear@2 14 Mesh::~Mesh()
nuclear@2 15 {
nuclear@2 16 destroy();
nuclear@2 17 }
nuclear@2 18
nuclear@7 19 void Mesh::set_name(const char *name)
nuclear@7 20 {
nuclear@7 21 this->name = name;
nuclear@7 22 }
nuclear@7 23
nuclear@4 24 const char *Mesh::get_name() const
nuclear@4 25 {
nuclear@4 26 return name.c_str();
nuclear@4 27 }
nuclear@4 28
nuclear@2 29 bool Mesh::create(const aiScene *scn, aiMesh *aim)
nuclear@2 30 {
nuclear@2 31 if(vbo[MESH_ATTR_VERTEX]) {
nuclear@2 32 destroy();
nuclear@2 33 }
nuclear@2 34
nuclear@5 35 name = aim->mName.data;
nuclear@5 36
nuclear@2 37 nverts = aim->mNumVertices;
nuclear@2 38 nfaces = aim->mNumFaces;
nuclear@2 39
nuclear@2 40 glGenBuffers(1, vbo + MESH_ATTR_VERTEX);
nuclear@2 41 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
nuclear@2 42 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mVertices, aim->mVertices, GL_STATIC_DRAW);
nuclear@2 43
nuclear@2 44 if(aim->mNormals) {
nuclear@2 45 glGenBuffers(1, vbo + MESH_ATTR_NORMAL);
nuclear@2 46 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_NORMAL]);
nuclear@2 47 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mNormals, aim->mNormals, GL_STATIC_DRAW);
nuclear@2 48 }
nuclear@2 49 if(aim->mTangents) {
nuclear@2 50 glGenBuffers(1, vbo + MESH_ATTR_TANGENT);
nuclear@2 51 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TANGENT]);
nuclear@2 52 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mTangents, aim->mTangents, GL_STATIC_DRAW);
nuclear@2 53 }
nuclear@2 54 if(aim->mTextureCoords[0]) {
nuclear@2 55 glGenBuffers(1, vbo + MESH_ATTR_TEXCOORD);
nuclear@2 56 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TEXCOORD]);
nuclear@2 57 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mTextureCoords[0], aim->mTextureCoords[0], GL_STATIC_DRAW);
nuclear@2 58 }
nuclear@2 59
nuclear@2 60 glGenBuffers(1, &ibo);
nuclear@2 61 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
nuclear@2 62 glBufferData(GL_ELEMENT_ARRAY_BUFFER, nfaces * 3 * sizeof *aim->mFaces[0].mIndices, 0, GL_STATIC_DRAW);
nuclear@2 63
nuclear@2 64 /* map the buffer and fill it up */
nuclear@2 65 unsigned int *iptr = (unsigned int*)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
nuclear@2 66
nuclear@4 67 for(int i=0; i<(int)nfaces; i++) {
nuclear@2 68 for(int j=0; j<3; j++) {
nuclear@2 69 *iptr++ = aim->mFaces[i].mIndices[j];
nuclear@2 70 }
nuclear@2 71 }
nuclear@2 72 glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
nuclear@2 73 return true;
nuclear@2 74 }
nuclear@2 75
nuclear@2 76 void Mesh::destroy()
nuclear@2 77 {
nuclear@2 78 for(int i=0; i<NUM_MESH_ATTR; i++) {
nuclear@2 79 if(vbo[i]) {
nuclear@2 80 glDeleteBuffers(1, vbo + i);
nuclear@2 81 vbo[i] = 0;
nuclear@2 82 }
nuclear@2 83 }
nuclear@2 84 glDeleteBuffers(1, &ibo);
nuclear@2 85 ibo = 0;
nuclear@2 86
nuclear@2 87 nverts = nfaces = 0;
nuclear@2 88 tang_loc = -1;
nuclear@2 89 }
nuclear@2 90
nuclear@7 91 void Mesh::set_xform(const Matrix4x4 &mat)
nuclear@7 92 {
nuclear@7 93 xform = mat;
nuclear@7 94 }
nuclear@7 95
nuclear@7 96 const Matrix4x4 &Mesh::get_xform() const
nuclear@7 97 {
nuclear@7 98 return xform;
nuclear@7 99 }
nuclear@7 100
nuclear@2 101 void Mesh::set_attrib_location(int attr, int loc)
nuclear@2 102 {
nuclear@2 103 if(attr == MESH_ATTR_TANGENT) {
nuclear@2 104 tang_loc = loc;
nuclear@2 105 }
nuclear@2 106 }
nuclear@2 107
nuclear@2 108 int Mesh::get_attrib_location(int attr) const
nuclear@2 109 {
nuclear@2 110 return tang_loc;
nuclear@2 111 }
nuclear@2 112
nuclear@2 113 void Mesh::draw() const
nuclear@2 114 {
nuclear@7 115 glMatrixMode(GL_MODELVIEW);
nuclear@7 116 glPushMatrix();
nuclear@7 117 mult_matrix(xform);
nuclear@7 118
nuclear@2 119 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
nuclear@2 120 glVertexPointer(3, GL_FLOAT, 0, 0);
nuclear@2 121 glEnableClientState(GL_VERTEX_ARRAY);
nuclear@2 122
nuclear@2 123 if(vbo[MESH_ATTR_NORMAL]) {
nuclear@2 124 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_NORMAL]);
nuclear@2 125 glNormalPointer(GL_FLOAT, 0, 0);
nuclear@2 126 glEnableClientState(GL_NORMAL_ARRAY);
nuclear@2 127 }
nuclear@2 128 if(vbo[MESH_ATTR_TANGENT] && tang_loc >= 0) {
nuclear@2 129 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TANGENT]);
nuclear@2 130 glVertexAttribPointer(tang_loc, 3, GL_FLOAT, GL_FALSE, 0, 0);
nuclear@2 131 glEnableVertexAttribArray(tang_loc);
nuclear@2 132 }
nuclear@2 133 if(vbo[MESH_ATTR_TEXCOORD]) {
nuclear@2 134 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TEXCOORD]);
nuclear@2 135 glTexCoordPointer(3, GL_FLOAT, 0, 0);
nuclear@2 136 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
nuclear@2 137 }
nuclear@2 138
nuclear@2 139 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
nuclear@2 140 glDrawElements(GL_TRIANGLES, nfaces * 3, GL_UNSIGNED_INT, 0);
nuclear@2 141
nuclear@2 142 glDisableClientState(GL_VERTEX_ARRAY);
nuclear@2 143 glDisableClientState(GL_NORMAL_ARRAY);
nuclear@2 144 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
nuclear@2 145 if(tang_loc >= 0) {
nuclear@2 146 glDisableVertexAttribArray(tang_loc);
nuclear@2 147 }
nuclear@7 148
nuclear@7 149 glPopMatrix();
nuclear@2 150 }