3 #include <assimp/cimport.h>
4 #include <assimp/postprocess.h>
5 #include <assimp/scene.h>
6 #include <assimp/mesh.h>
24 mtl.diffuse = Vec3(1, 1, 1);
31 glDeleteBuffers(1, &vbo_vertices);
33 glDeleteBuffers(1, &vbo_normals);
35 glDeleteBuffers(1, &vbo_colors);
37 glDeleteBuffers(1, &ibo);
44 void Mesh::draw() const
48 mtl.diffuse.x, mtl.diffuse.y, mtl.diffuse.z, 1.0
50 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, diff);
53 mtl.specular.x, mtl.specular.y, mtl.specular.z, 1.0
55 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
57 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, mtl.shininess);
60 glBindTexture(GL_TEXTURE_2D, mtl.tex);
61 glEnable(GL_TEXTURE_2D);
64 glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
65 glVertexPointer(3, GL_FLOAT, 0, 0);
68 glBindBuffer(GL_ARRAY_BUFFER, vbo_normals);
69 glNormalPointer(GL_FLOAT, 0, 0);
70 glEnableClientState(GL_NORMAL_ARRAY);
74 glBindBuffer(GL_ARRAY_BUFFER, vbo_colors);
75 glColorPointer(3, GL_FLOAT, 0, 0);
76 glEnableClientState(GL_COLOR_ARRAY);
79 glBindBuffer(GL_ARRAY_BUFFER, 0);
81 glEnableClientState(GL_VERTEX_ARRAY);
84 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
85 glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, 0);
86 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
88 glDrawArrays(GL_TRIANGLES, 0, num_vertices);
91 glDisableClientState(GL_VERTEX_ARRAY);
92 glDisableClientState(GL_NORMAL_ARRAY);
93 glDisableClientState(GL_COLOR_ARRAY);
97 glDisable(GL_TEXTURE_2D);
100 void Mesh::update_vbo(unsigned int which)
102 if(which & MESH_NORMAL) {
104 glGenBuffers(1, &vbo_normals);
106 glBindBuffer(GL_ARRAY_BUFFER, vbo_normals);
107 if(num_vertices != (int)normals.size()) {
108 glBufferData(GL_ARRAY_BUFFER, normals.size() * 3 * sizeof(float),
109 &normals[0], GL_STATIC_DRAW);
112 glBufferSubData(GL_ARRAY_BUFFER, 0, normals.size() * 3 * sizeof(float),
117 if(which & MESH_COLOR) {
119 glGenBuffers(1, &vbo_colors);
121 glBindBuffer(GL_ARRAY_BUFFER, vbo_colors);
122 if(num_vertices != (int)colors.size()) {
123 glBufferData(GL_ARRAY_BUFFER, colors.size() * 3 * sizeof(float),
124 &colors[0], GL_STATIC_DRAW);
127 glBufferSubData(GL_ARRAY_BUFFER, 0, colors.size() * 3 * sizeof(float),
133 if(which & MESH_VERTEX) {
135 glGenBuffers(1, &vbo_vertices);
137 glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
138 if(num_vertices != (int)vertices.size()) {
139 glBufferData(GL_ARRAY_BUFFER, vertices.size() * 3 * sizeof(float),
140 &vertices[0], GL_STATIC_DRAW);
143 glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * 3 * sizeof(float),
146 num_vertices = vertices.size();
149 if(which & MESH_INDEX) {
151 glGenBuffers(1, &ibo);
153 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
154 if(num_indices != (int)indices.size()) {
155 glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * 2,
156 &indices[0], GL_STATIC_DRAW);
159 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indices.size() * 2,
162 num_indices = indices.size();
166 std::vector<Mesh*> load_meshes(const char *fname)
168 std::vector<Mesh*> meshes;
169 unsigned int ai_flags = aiProcessPreset_TargetRealtime_Quality;
170 const aiScene *scene = aiImportFile(fname, ai_flags);
172 for(unsigned int j=0; j<scene->mNumMeshes; j++) {
173 aiMesh *amesh = scene->mMeshes[j];
174 aiMaterial *amtl = scene->mMaterials[amesh->mMaterialIndex];
176 if(!amesh->HasPositions() || !amesh->mNumFaces)
179 Mesh *mesh = new Mesh;
180 mesh->name = std::string(amesh->mName.C_Str());
181 printf("loading mesh: %s\n", mesh->name.c_str());
183 for(unsigned int i=0; i<amesh->mNumVertices; i++) {
184 Vec3 vertex = Vec3(amesh->mVertices[i].x,
185 amesh->mVertices[i].y,
186 amesh->mVertices[i].z);
187 mesh->vertices.push_back(vertex);
190 if(amesh->HasNormals()) {
191 for(unsigned int i=0; i<amesh->mNumVertices; i++) {
192 Vec3 normal = Vec3(amesh->mNormals[i].x,
193 amesh->mNormals[i].y,
194 amesh->mNormals[i].z);
195 mesh->normals.push_back(normal);
199 if(amesh->HasVertexColors(0)) {
200 for(unsigned int i=0; i<amesh->mNumVertices; i++) {
201 Vec3 color = Vec3(amesh->mColors[0][i].r,
202 amesh->mColors[0][i].g,
203 amesh->mColors[0][i].b);
204 mesh->colors.push_back(color);
208 for(unsigned int i=0; i<amesh->mNumFaces; i++) {
209 for(int j=0; j<3; j++) {
210 mesh->indices.push_back(amesh->mFaces[i].mIndices[j]);
215 aiGetMaterialColor(amtl, AI_MATKEY_COLOR_DIFFUSE, &acol);
216 mesh->mtl.diffuse = Vec3(acol.r, acol.g, acol.b);
219 aiGetMaterialFloat(amtl, AI_MATKEY_SHININESS_STRENGTH, &sstr);
221 aiGetMaterialColor(amtl, AI_MATKEY_COLOR_SPECULAR, &acol);
222 mesh->mtl.specular = sstr * Vec3(acol.r, acol.g, acol.b) * 0.3;
223 printf("mtl sstr: %f\n", sstr);
224 printf("mtl spec: %f %f %f\n", acol.r, acol.g, acol.b);
227 aiGetMaterialFloat(amtl, AI_MATKEY_SHININESS, &shin);
228 mesh->mtl.shininess = shin * 6;
229 printf("mtl shin: %f\n", mesh->mtl.shininess);
232 if(aiGetMaterialTexture(amtl, aiTextureType_DIFFUSE, 0, &astr) == 0) {
233 char *fname = astr.data;
237 if((slash = strrchr(fname, '/'))) {
240 if((slash = strrchr(fname, '\\'))) {
243 path = new char[strlen(fname) + 6];
244 sprintf(path, "data/%s", fname);
245 if(!(mesh->mtl.tex = img_gltexture_load(path))) {
246 fprintf(stderr, "Failed to load texture %s\n", fname);
251 meshes.push_back(mesh);
257 void Mesh::calc_bbox()
259 if (vertices.empty()) {
260 bbox.v0 = Vec3(0, 0, 0);
261 bbox.v1 = Vec3(0, 0, 0);
266 bbox.v0 = Vec3(FLT_MAX, FLT_MAX, FLT_MAX);
269 for(size_t i=0; i<vertices.size(); i++) {
270 for(int j=0; j<3; j++) {
271 if(vertices[i][j] < bbox.v0[j])
272 bbox.v0[j] = vertices[i][j];
273 if(vertices[i][j] > bbox.v1[j])
274 bbox.v1[j] = vertices[i][j];