X-Git-Url: https://eleni.mutantstargoat.com/git/?p=hair;a=blobdiff_plain;f=src%2Fmesh.cc;h=da22d7801b01a5addb67e583fd7936f689877479;hp=ac18f526d9f964bb1793b313cbbe2012f276cc3f;hb=8f59fd2bda5b48b7cb9137ca5ee141dd8f8382d1;hpb=6b061e7aa1fcfad3e01eff29d5e4b2bed451e090 diff --git a/src/mesh.cc b/src/mesh.cc index ac18f52..da22d78 100644 --- a/src/mesh.cc +++ b/src/mesh.cc @@ -1,5 +1,7 @@ #include +#include + #include #include #include @@ -10,10 +12,13 @@ #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; @@ -31,6 +36,8 @@ Mesh::~Mesh() 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) @@ -38,6 +45,7 @@ Mesh::~Mesh() vertices.clear(); normals.clear(); + texcoords.clear(); colors.clear(); } @@ -56,9 +64,15 @@ void Mesh::draw() const 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); @@ -70,6 +84,12 @@ void Mesh::draw() const 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); @@ -90,16 +110,15 @@ void Mesh::draw() const 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); } @@ -114,7 +133,22 @@ void Mesh::update_vbo(unsigned int which) } } - 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); } @@ -131,6 +165,7 @@ void Mesh::update_vbo(unsigned int which) if(which & MESH_VERTEX) { + assert(!vertices.empty()); if(!vbo_vertices) { glGenBuffers(1, &vbo_vertices); } @@ -146,7 +181,7 @@ void Mesh::update_vbo(unsigned int which) num_vertices = vertices.size(); } - if(which & MESH_INDEX) { + if((which & MESH_INDEX) && !indices.empty()) { if(!ibo) { glGenBuffers(1, &ibo); } @@ -186,6 +221,7 @@ std::vector load_meshes(const char *fname) amesh->mVertices[i].z); mesh->vertices.push_back(vertex); } + printf(" %u vertices\n", amesh->mNumVertices); if(amesh->HasNormals()) { for(unsigned int i=0; imNumVertices; i++) { @@ -196,6 +232,14 @@ std::vector load_meshes(const char *fname) } } + if(amesh->HasTextureCoords(0)) { + for(unsigned int i=0; imNumVertices; 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; imNumVertices; i++) { Vec3 color = Vec3(amesh->mColors[0][i].r, @@ -210,6 +254,7 @@ std::vector load_meshes(const char *fname) mesh->indices.push_back(amesh->mFaces[i].mIndices[j]); } } + printf(" %d faces\n", amesh->mNumFaces); aiColor4D acol; aiGetMaterialColor(amtl, AI_MATKEY_COLOR_DIFFUSE, &acol); @@ -220,13 +265,10 @@ std::vector load_meshes(const char *fname) 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) { @@ -243,7 +285,10 @@ std::vector load_meshes(const char *fname) 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; } @@ -251,6 +296,7 @@ std::vector load_meshes(const char *fname) meshes.push_back(mesh); } + aiReleaseImport(scene); return meshes; } @@ -275,3 +321,26 @@ void Mesh::calc_bbox() } } } + +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