dungeon_crawler

view prototype/src/mesh.cc @ 10:22562582c82d

foo
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 18 Aug 2012 03:47:13 +0300
parents 8fb37db44fd8
children e5567ddbf2ef
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "mesh.h"
4 #include "opengl.h"
6 /*
7 #define DBG_NORMALS
8 #define NSZ 0.1
9 */
11 Mesh::Mesh()
12 {
13 nverts = nfaces = 0;
14 for(int i=0; i<NUM_MESH_ATTR; i++) {
15 vbo[i] = 0;
16 }
17 ibo = 0;
18 tang_loc = -1;
19 }
21 Mesh::~Mesh()
22 {
23 destroy();
24 }
26 void Mesh::set_name(const char *name)
27 {
28 this->name = name;
29 }
31 const char *Mesh::get_name() const
32 {
33 return name.c_str();
34 }
36 bool Mesh::create(const aiScene *scn, aiMesh *aim)
37 {
38 if(vbo[MESH_ATTR_VERTEX]) {
39 destroy();
40 }
42 name = aim->mName.data;
44 nverts = aim->mNumVertices;
45 nfaces = aim->mNumFaces;
47 glGenBuffers(1, vbo + MESH_ATTR_VERTEX);
48 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
49 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mVertices, aim->mVertices, GL_STATIC_DRAW);
51 if(aim->mNormals) {
52 glGenBuffers(1, vbo + MESH_ATTR_NORMAL);
53 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_NORMAL]);
54 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mNormals, aim->mNormals, GL_STATIC_DRAW);
55 }
56 if(aim->mTangents) {
57 glGenBuffers(1, vbo + MESH_ATTR_TANGENT);
58 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TANGENT]);
59 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mTangents, aim->mTangents, GL_STATIC_DRAW);
60 }
61 if(aim->mTextureCoords[0]) {
62 glGenBuffers(1, vbo + MESH_ATTR_TEXCOORD);
63 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TEXCOORD]);
64 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mTextureCoords[0], aim->mTextureCoords[0], GL_STATIC_DRAW);
65 }
67 glGenBuffers(1, &ibo);
68 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
69 glBufferData(GL_ELEMENT_ARRAY_BUFFER, nfaces * 3 * sizeof *aim->mFaces[0].mIndices, 0, GL_STATIC_DRAW);
71 /* map the buffer and fill it up */
72 unsigned int *iptr = (unsigned int*)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
74 for(int i=0; i<(int)nfaces; i++) {
75 for(int j=0; j<3; j++) {
76 *iptr++ = aim->mFaces[i].mIndices[j];
77 }
78 }
79 glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
80 return true;
81 }
83 void Mesh::destroy()
84 {
85 for(int i=0; i<NUM_MESH_ATTR; i++) {
86 if(vbo[i]) {
87 glDeleteBuffers(1, vbo + i);
88 vbo[i] = 0;
89 }
90 }
91 glDeleteBuffers(1, &ibo);
92 ibo = 0;
94 nverts = nfaces = 0;
95 tang_loc = -1;
96 }
98 void Mesh::set_xform(const Matrix4x4 &mat)
99 {
100 xform = mat;
101 }
103 const Matrix4x4 &Mesh::get_xform() const
104 {
105 return xform;
106 }
108 void Mesh::set_attrib_location(int attr, int loc)
109 {
110 if(attr == MESH_ATTR_TANGENT) {
111 tang_loc = loc;
112 }
113 }
115 int Mesh::get_attrib_location(int attr) const
116 {
117 return tang_loc;
118 }
120 void Mesh::draw() const
121 {
122 glMatrixMode(GL_MODELVIEW);
123 glPushMatrix();
124 mult_matrix(xform);
126 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
127 glVertexPointer(3, GL_FLOAT, 0, 0);
128 glEnableClientState(GL_VERTEX_ARRAY);
130 if(vbo[MESH_ATTR_NORMAL]) {
131 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_NORMAL]);
132 glNormalPointer(GL_FLOAT, 0, 0);
133 glEnableClientState(GL_NORMAL_ARRAY);
134 }
135 if(vbo[MESH_ATTR_TANGENT] && tang_loc >= 0) {
136 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TANGENT]);
137 glVertexAttribPointer(tang_loc, 3, GL_FLOAT, GL_FALSE, 0, 0);
138 glEnableVertexAttribArray(tang_loc);
139 }
140 if(vbo[MESH_ATTR_TEXCOORD]) {
141 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TEXCOORD]);
142 glTexCoordPointer(3, GL_FLOAT, 0, 0);
143 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
144 }
146 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
147 glDrawElements(GL_TRIANGLES, nfaces * 3, GL_UNSIGNED_INT, 0);
149 glDisableClientState(GL_VERTEX_ARRAY);
150 glDisableClientState(GL_NORMAL_ARRAY);
151 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
152 if(tang_loc >= 0) {
153 glDisableVertexAttribArray(tang_loc);
154 }
156 #ifdef DBG_NORMALS
157 glPushAttrib(GL_ENABLE_BIT);
158 glDisable(GL_LIGHTING);
160 int prog;
161 glGetIntegerv(GL_CURRENT_PROGRAM, &prog);
162 glUseProgram(0);
164 Vector3 *varr, *narr;
166 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
167 varr = (Vector3*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
169 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_NORMAL]);
170 narr = (Vector3*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
172 glBegin(GL_LINES);
173 for(unsigned int i=0; i<nverts; i++) {
174 glColor3f(0, 1, 0);
175 glVertex3f(varr->x, varr->y, varr->z);
176 glVertex3f(varr->x + narr->x * NSZ, varr->y + narr->y * NSZ, varr->z + narr->z * NSZ);
177 varr++;
178 narr++;
179 }
180 glEnd();
182 glUnmapBuffer(GL_ARRAY_BUFFER);
183 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
184 glUnmapBuffer(GL_ARRAY_BUFFER);
186 glUseProgram(prog);
187 glPopAttrib();
188 #endif
190 glPopMatrix();
191 }