#include <GL/glew.h>
+#include <assert.h>
+
#include <assimp/cimport.h>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
#include "mesh.h"
+static bool check_tex_opaque(unsigned int tex);
+
Mesh::Mesh()
{
vbo_vertices = 0;
vbo_normals = 0;
+ vbo_texcoords = 0;
vbo_colors = 0;
ibo = 0;
glDeleteBuffers(1, &vbo_vertices);
if(vbo_normals)
glDeleteBuffers(1, &vbo_normals);
+ if(vbo_texcoords)
+ glDeleteBuffers(1, &vbo_texcoords);
if(vbo_colors)
glDeleteBuffers(1, &vbo_colors);
if(ibo)
vertices.clear();
normals.clear();
+ texcoords.clear();
colors.clear();
}
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, mtl.shininess);
+ glPushAttrib(GL_ENABLE_BIT);
if(mtl.tex) {
glBindTexture(GL_TEXTURE_2D, mtl.tex);
glEnable(GL_TEXTURE_2D);
+
+ if(!mtl.tex_opaque) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
}
glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
glEnableClientState(GL_NORMAL_ARRAY);
}
+ if(vbo_texcoords) {
+ glBindBuffer(GL_ARRAY_BUFFER, vbo_texcoords);
+ glTexCoordPointer(2, GL_FLOAT, 0, 0);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+
if(vbo_colors) {
glBindBuffer(GL_ARRAY_BUFFER, vbo_colors);
glColorPointer(3, GL_FLOAT, 0, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
-
- if(mtl.tex)
- glDisable(GL_TEXTURE_2D);
+ glPopAttrib();
}
void Mesh::update_vbo(unsigned int which)
{
- if(which & MESH_NORMAL) {
+ if((which & MESH_NORMAL) && !normals.empty()) {
if(!vbo_normals) {
glGenBuffers(1, &vbo_normals);
}
}
}
- if(which & MESH_COLOR) {
+ if((which & MESH_TEXCOORDS) && !texcoords.empty()) {
+ if(!vbo_texcoords) {
+ glGenBuffers(1, &vbo_texcoords);
+ }
+ glBindBuffer(GL_ARRAY_BUFFER, vbo_texcoords);
+ if(num_vertices != (int)texcoords.size()) {
+ glBufferData(GL_ARRAY_BUFFER, texcoords.size() * 2 * sizeof(float),
+ &texcoords[0], GL_STATIC_DRAW);
+ }
+ else {
+ glBufferSubData(GL_ARRAY_BUFFER, 0, texcoords.size() * 2 * sizeof(float),
+ &texcoords[0]);
+ }
+ }
+
+ if((which & MESH_COLOR) && !colors.empty()) {
if(!vbo_colors) {
glGenBuffers(1, &vbo_colors);
}
if(which & MESH_VERTEX) {
+ assert(!vertices.empty());
if(!vbo_vertices) {
glGenBuffers(1, &vbo_vertices);
}
num_vertices = vertices.size();
}
- if(which & MESH_INDEX) {
+ if((which & MESH_INDEX) && !indices.empty()) {
if(!ibo) {
glGenBuffers(1, &ibo);
}
amesh->mVertices[i].z);
mesh->vertices.push_back(vertex);
}
+ printf(" %u vertices\n", amesh->mNumVertices);
if(amesh->HasNormals()) {
for(unsigned int i=0; i<amesh->mNumVertices; i++) {
}
}
+ if(amesh->HasTextureCoords(0)) {
+ for(unsigned int i=0; i<amesh->mNumVertices; i++) {
+ Vec2 tc = Vec2(amesh->mTextureCoords[0][i].x,
+ 1.0f - amesh->mTextureCoords[0][i].y);
+ mesh->texcoords.push_back(tc);
+ }
+ }
+
if(amesh->HasVertexColors(0)) {
for(unsigned int i=0; i<amesh->mNumVertices; i++) {
Vec3 color = Vec3(amesh->mColors[0][i].r,
mesh->indices.push_back(amesh->mFaces[i].mIndices[j]);
}
}
+ printf(" %d faces\n", amesh->mNumFaces);
aiColor4D acol;
aiGetMaterialColor(amtl, AI_MATKEY_COLOR_DIFFUSE, &acol);
aiGetMaterialColor(amtl, AI_MATKEY_COLOR_SPECULAR, &acol);
mesh->mtl.specular = sstr * Vec3(acol.r, acol.g, acol.b) * 0.3;
- printf("mtl sstr: %f\n", sstr);
- printf("mtl spec: %f %f %f\n", acol.r, acol.g, acol.b);
float shin;
aiGetMaterialFloat(amtl, AI_MATKEY_SHININESS, &shin);
mesh->mtl.shininess = shin * 6;
- printf("mtl shin: %f\n", mesh->mtl.shininess);
aiString astr;
if(aiGetMaterialTexture(amtl, aiTextureType_DIFFUSE, 0, &astr) == 0) {
path = new char[strlen(fname) + 6];
sprintf(path, "data/%s", fname);
if(!(mesh->mtl.tex = img_gltexture_load(path))) {
- fprintf(stderr, "Failed to load texture %s\n", fname);
+ fprintf(stderr, "Failed to load texture %s\n", path);
+ } else {
+ mesh->mtl.tex_opaque = check_tex_opaque(mesh->mtl.tex);
+ printf(" texture: %s (%s)\n", path, mesh->mtl.tex_opaque ? "opaque" : "transparent");
}
delete [] path;
}
meshes.push_back(mesh);
}
+ aiReleaseImport(scene);
return meshes;
}
}
}
}
+
+static bool check_tex_opaque(unsigned int tex)
+{
+ int xsz, ysz;
+ uint32_t *pixels, *pptr;
+
+ glBindTexture(GL_TEXTURE_2D, tex);
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &xsz);
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &ysz);
+ assert(xsz > 0 && ysz > 0);
+
+ pptr = pixels = new uint32_t[xsz * ysz];
+ glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+ for(int i=0; i<xsz * ysz; i++) {
+ if((*pptr++ & 0xff000000) != 0xff000000) {
+ delete [] pixels;
+ return false;
+ }
+ }
+ delete [] pixels;
+ return true;
+}