From: Eleni Maria Stea Date: Sun, 27 Jan 2019 15:50:45 +0000 (+0200) Subject: Many fixes (credits Nuclear) X-Git-Url: http://git.mutantstargoat.com?p=hair;a=commitdiff_plain;h=8f59fd2bda5b48b7cb9137ca5ee141dd8f8382d1 Many fixes (credits Nuclear) 1- fixed memory leaks 2- added tex coords 3- fixed empty vbos bug 4- added tex opacity check --- diff --git a/Makefile b/Makefile index 8b94f2b..3792df5 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,9 @@ dbg = -g opt = -O0 inc = -Isrc -Isrc/shaders -Isrc/math CXX = g++ +CC = gcc CXXFLAGS = -pedantic -Wall $(dbg) $(opt) $(inc) +CFLAGS = -pedantic -Wall $(dbg) $(opt) $(inc) LDFLAGS = -lGL -lGLU -lglut -lGLEW -limago -lassimp -lgmath $(bin): $(obj) diff --git a/data/head.blend b/data/head.blend index 35f1e1e..6b4efad 100644 Binary files a/data/head.blend and b/data/head.blend differ diff --git a/data/head.fbx b/data/head.fbx index d1caf71..f7a4fe2 100644 Binary files a/data/head.fbx and b/data/head.fbx differ diff --git a/src/hair.cc b/src/hair.cc index de31ed8..a369465 100644 --- a/src/hair.cc +++ b/src/hair.cc @@ -110,6 +110,7 @@ bool Hair::init(const Mesh *m, int max_num_spawns, float thresh) if (res && !kd_res_end(res)) { Vec3 nearest; kd_res_item3f(res, &nearest.x, &nearest.y, &nearest.z); + kd_res_free(res); if(distance_sq(rpoint, nearest) < min_dist * min_dist) continue; } diff --git a/src/main.cc b/src/main.cc index 9720723..c409322 100644 --- a/src/main.cc +++ b/src/main.cc @@ -129,6 +129,7 @@ static void cleanup() for(size_t i=0; i +#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 indices; std::vector vertices; + std::vector texcoords; std::vector normals; std::vector colors;