dungeon_crawler

view 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 source
1 #include "mesh.h"
2 #include "opengl.h"
4 Mesh::Mesh()
5 {
6 nverts = nfaces = 0;
7 for(int i=0; i<NUM_MESH_ATTR; i++) {
8 vbo[i] = 0;
9 }
10 ibo = 0;
11 tang_loc = -1;
12 }
14 Mesh::~Mesh()
15 {
16 destroy();
17 }
19 bool Mesh::create(const aiScene *scn, aiMesh *aim)
20 {
21 if(vbo[MESH_ATTR_VERTEX]) {
22 destroy();
23 }
25 nverts = aim->mNumVertices;
26 nfaces = aim->mNumFaces;
28 glGenBuffers(1, vbo + MESH_ATTR_VERTEX);
29 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
30 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mVertices, aim->mVertices, GL_STATIC_DRAW);
32 if(aim->mNormals) {
33 glGenBuffers(1, vbo + MESH_ATTR_NORMAL);
34 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_NORMAL]);
35 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mNormals, aim->mNormals, GL_STATIC_DRAW);
36 }
37 if(aim->mTangents) {
38 glGenBuffers(1, vbo + MESH_ATTR_TANGENT);
39 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TANGENT]);
40 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mTangents, aim->mTangents, GL_STATIC_DRAW);
41 }
42 if(aim->mTextureCoords[0]) {
43 glGenBuffers(1, vbo + MESH_ATTR_TEXCOORD);
44 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TEXCOORD]);
45 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mTextureCoords[0], aim->mTextureCoords[0], GL_STATIC_DRAW);
46 }
48 glGenBuffers(1, &ibo);
49 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
50 glBufferData(GL_ELEMENT_ARRAY_BUFFER, nfaces * 3 * sizeof *aim->mFaces[0].mIndices, 0, GL_STATIC_DRAW);
52 /* map the buffer and fill it up */
53 unsigned int *iptr = (unsigned int*)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
55 for(int i=0; i<nfaces; i++) {
56 for(int j=0; j<3; j++) {
57 *iptr++ = aim->mFaces[i].mIndices[j];
58 }
59 }
60 glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
61 return true;
62 }
64 void Mesh::destroy()
65 {
66 for(int i=0; i<NUM_MESH_ATTR; i++) {
67 if(vbo[i]) {
68 glDeleteBuffers(1, vbo + i);
69 vbo[i] = 0;
70 }
71 }
72 glDeleteBuffers(1, &ibo);
73 ibo = 0;
75 nverts = nfaces = 0;
76 tang_loc = -1;
77 }
79 void Mesh::set_attrib_location(int attr, int loc)
80 {
81 if(attr == MESH_ATTR_TANGENT) {
82 tang_loc = loc;
83 }
84 }
86 int Mesh::get_attrib_location(int attr) const
87 {
88 return tang_loc;
89 }
91 void Mesh::draw() const
92 {
93 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
94 glVertexPointer(3, GL_FLOAT, 0, 0);
95 glEnableClientState(GL_VERTEX_ARRAY);
97 if(vbo[MESH_ATTR_NORMAL]) {
98 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_NORMAL]);
99 glNormalPointer(GL_FLOAT, 0, 0);
100 glEnableClientState(GL_NORMAL_ARRAY);
101 }
102 if(vbo[MESH_ATTR_TANGENT] && tang_loc >= 0) {
103 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TANGENT]);
104 glVertexAttribPointer(tang_loc, 3, GL_FLOAT, GL_FALSE, 0, 0);
105 glEnableVertexAttribArray(tang_loc);
106 }
107 if(vbo[MESH_ATTR_TEXCOORD]) {
108 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TEXCOORD]);
109 glTexCoordPointer(3, GL_FLOAT, 0, 0);
110 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
111 }
113 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
114 glDrawElements(GL_TRIANGLES, nfaces * 3, GL_UNSIGNED_INT, 0);
116 glDisableClientState(GL_VERTEX_ARRAY);
117 glDisableClientState(GL_NORMAL_ARRAY);
118 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
119 if(tang_loc >= 0) {
120 glDisableVertexAttribArray(tang_loc);
121 }
122 }