dungeon_crawler

view prototype/src/mesh.cc @ 21:0588f8a1a351

converting LIGHT meshes to lights
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 21 Aug 2012 06:33:36 +0300
parents e5567ddbf2ef
children cbf86e5198a9
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_material(const Material &mat)
109 {
110 this->mat = mat;
111 }
113 const Material &Mesh::get_material() const
114 {
115 return mat;
116 }
118 void Mesh::set_attrib_location(int attr, int loc)
119 {
120 if(attr == MESH_ATTR_TANGENT) {
121 tang_loc = loc;
122 }
123 }
125 int Mesh::get_attrib_location(int attr) const
126 {
127 return tang_loc;
128 }
130 void Mesh::draw() const
131 {
132 mat.setup();
134 glMatrixMode(GL_MODELVIEW);
135 glPushMatrix();
136 mult_matrix(xform);
138 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
139 glVertexPointer(3, GL_FLOAT, 0, 0);
140 glEnableClientState(GL_VERTEX_ARRAY);
142 if(vbo[MESH_ATTR_NORMAL]) {
143 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_NORMAL]);
144 glNormalPointer(GL_FLOAT, 0, 0);
145 glEnableClientState(GL_NORMAL_ARRAY);
146 }
147 if(vbo[MESH_ATTR_TANGENT] && tang_loc >= 0) {
148 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TANGENT]);
149 glVertexAttribPointer(tang_loc, 3, GL_FLOAT, GL_FALSE, 0, 0);
150 glEnableVertexAttribArray(tang_loc);
151 }
152 if(vbo[MESH_ATTR_TEXCOORD]) {
153 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TEXCOORD]);
154 glTexCoordPointer(3, GL_FLOAT, 0, 0);
155 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
156 }
158 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
159 glDrawElements(GL_TRIANGLES, nfaces * 3, GL_UNSIGNED_INT, 0);
161 glDisableClientState(GL_VERTEX_ARRAY);
162 glDisableClientState(GL_NORMAL_ARRAY);
163 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
164 if(tang_loc >= 0) {
165 glDisableVertexAttribArray(tang_loc);
166 }
168 #ifdef DBG_NORMALS
169 glPushAttrib(GL_ENABLE_BIT);
170 glDisable(GL_LIGHTING);
172 int prog;
173 glGetIntegerv(GL_CURRENT_PROGRAM, &prog);
174 glUseProgram(0);
176 Vector3 *varr, *narr;
178 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
179 varr = (Vector3*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
181 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_NORMAL]);
182 narr = (Vector3*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
184 glBegin(GL_LINES);
185 for(unsigned int i=0; i<nverts; i++) {
186 glColor3f(0, 1, 0);
187 glVertex3f(varr->x, varr->y, varr->z);
188 glVertex3f(varr->x + narr->x * NSZ, varr->y + narr->y * NSZ, varr->z + narr->z * NSZ);
189 varr++;
190 narr++;
191 }
192 glEnd();
194 glUnmapBuffer(GL_ARRAY_BUFFER);
195 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
196 glUnmapBuffer(GL_ARRAY_BUFFER);
198 glUseProgram(prog);
199 glPopAttrib();
200 #endif
202 glPopMatrix();
203 }
206 void Mesh::calc_bsph()
207 {
208 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
209 Vector3 *varr = (Vector3*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
211 bsph_center = Vector3(0, 0, 0);
213 for(unsigned int i=0; i<nverts; i++) {
214 bsph_center += varr[i];
215 }
216 bsph_center /= (float)nverts;
218 // assume all vertices are equidistant from the center
219 bsph_rad = (varr[0] - bsph_center).length();
221 glUnmapBuffer(GL_ARRAY_BUFFER);
222 bsph_valid = true;
223 }
225 const Vector3 &Mesh::get_bsph_center() const
226 {
227 if(!bsph_valid) {
228 ((Mesh*)this)->calc_bsph();
229 }
230 return bsph_center;
231 }
233 float Mesh::get_bsph_radius() const
234 {
235 if(!bsph_valid) {
236 ((Mesh*)this)->calc_bsph();
237 }
238 return bsph_rad;
239 }