dungeon_crawler

view 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
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 void Mesh::set_name(const char *name)
20 {
21 this->name = name;
22 }
24 const char *Mesh::get_name() const
25 {
26 return name.c_str();
27 }
29 bool Mesh::create(const aiScene *scn, aiMesh *aim)
30 {
31 if(vbo[MESH_ATTR_VERTEX]) {
32 destroy();
33 }
35 name = aim->mName.data;
37 nverts = aim->mNumVertices;
38 nfaces = aim->mNumFaces;
40 glGenBuffers(1, vbo + MESH_ATTR_VERTEX);
41 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
42 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mVertices, aim->mVertices, GL_STATIC_DRAW);
44 if(aim->mNormals) {
45 glGenBuffers(1, vbo + MESH_ATTR_NORMAL);
46 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_NORMAL]);
47 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mNormals, aim->mNormals, GL_STATIC_DRAW);
48 }
49 if(aim->mTangents) {
50 glGenBuffers(1, vbo + MESH_ATTR_TANGENT);
51 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TANGENT]);
52 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mTangents, aim->mTangents, GL_STATIC_DRAW);
53 }
54 if(aim->mTextureCoords[0]) {
55 glGenBuffers(1, vbo + MESH_ATTR_TEXCOORD);
56 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TEXCOORD]);
57 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mTextureCoords[0], aim->mTextureCoords[0], GL_STATIC_DRAW);
58 }
60 glGenBuffers(1, &ibo);
61 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
62 glBufferData(GL_ELEMENT_ARRAY_BUFFER, nfaces * 3 * sizeof *aim->mFaces[0].mIndices, 0, GL_STATIC_DRAW);
64 /* map the buffer and fill it up */
65 unsigned int *iptr = (unsigned int*)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
67 for(int i=0; i<(int)nfaces; i++) {
68 for(int j=0; j<3; j++) {
69 *iptr++ = aim->mFaces[i].mIndices[j];
70 }
71 }
72 glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
73 return true;
74 }
76 void Mesh::destroy()
77 {
78 for(int i=0; i<NUM_MESH_ATTR; i++) {
79 if(vbo[i]) {
80 glDeleteBuffers(1, vbo + i);
81 vbo[i] = 0;
82 }
83 }
84 glDeleteBuffers(1, &ibo);
85 ibo = 0;
87 nverts = nfaces = 0;
88 tang_loc = -1;
89 }
91 void Mesh::set_xform(const Matrix4x4 &mat)
92 {
93 xform = mat;
94 }
96 const Matrix4x4 &Mesh::get_xform() const
97 {
98 return xform;
99 }
101 void Mesh::set_attrib_location(int attr, int loc)
102 {
103 if(attr == MESH_ATTR_TANGENT) {
104 tang_loc = loc;
105 }
106 }
108 int Mesh::get_attrib_location(int attr) const
109 {
110 return tang_loc;
111 }
113 void Mesh::draw() const
114 {
115 glMatrixMode(GL_MODELVIEW);
116 glPushMatrix();
117 mult_matrix(xform);
119 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
120 glVertexPointer(3, GL_FLOAT, 0, 0);
121 glEnableClientState(GL_VERTEX_ARRAY);
123 if(vbo[MESH_ATTR_NORMAL]) {
124 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_NORMAL]);
125 glNormalPointer(GL_FLOAT, 0, 0);
126 glEnableClientState(GL_NORMAL_ARRAY);
127 }
128 if(vbo[MESH_ATTR_TANGENT] && tang_loc >= 0) {
129 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TANGENT]);
130 glVertexAttribPointer(tang_loc, 3, GL_FLOAT, GL_FALSE, 0, 0);
131 glEnableVertexAttribArray(tang_loc);
132 }
133 if(vbo[MESH_ATTR_TEXCOORD]) {
134 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TEXCOORD]);
135 glTexCoordPointer(3, GL_FLOAT, 0, 0);
136 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
137 }
139 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
140 glDrawElements(GL_TRIANGLES, nfaces * 3, GL_UNSIGNED_INT, 0);
142 glDisableClientState(GL_VERTEX_ARRAY);
143 glDisableClientState(GL_NORMAL_ARRAY);
144 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
145 if(tang_loc >= 0) {
146 glDisableVertexAttribArray(tang_loc);
147 }
149 glPopMatrix();
150 }