From c2474e27ab05a6db067dfa5dafbc62397cb4ea50 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Mon, 24 Oct 2016 23:58:33 +0900 Subject: [PATCH] Fix seg fault when no material assigned to object in viewer example. Bump version v1.0.2. --- examples/viewer/viewer.cc | 30 ++++++++++++++++++++---------- loader_example.cc | 14 +++++++------- tiny_obj_loader.h | 2 ++ 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/examples/viewer/viewer.cc b/examples/viewer/viewer.cc index 323faac..09fcb67 100644 --- a/examples/viewer/viewer.cc +++ b/examples/viewer/viewer.cc @@ -209,6 +209,9 @@ bool LoadObjAndConvert(float bmin[3], float bmax[3], printf("# of materials = %d\n", (int)materials.size()); printf("# of shapes = %d\n", (int)shapes.size()); + // Append `default` material + materials.push_back(tinyobj::material_t()); + // Load diffuse textures { for (size_t m = 0; m < materials.size(); m++) { @@ -248,11 +251,6 @@ bool LoadObjAndConvert(float bmin[3], float bmax[3], { for (size_t s = 0; s < shapes.size(); s++) { - size_t current_material_id = 0; - if (shapes[s].mesh.material_ids.size() > 0 && shapes[s].mesh.material_ids.size() > s) { - // Base case - current_material_id = shapes[s].mesh.material_ids[s]; - } DrawObject o; std::vector vb; // pos(3float), normal(3float), color(3float) for (size_t f = 0; f < shapes[s].mesh.indices.size() / 3; f++) { @@ -260,12 +258,16 @@ bool LoadObjAndConvert(float bmin[3], float bmax[3], tinyobj::index_t idx1 = shapes[s].mesh.indices[3 * f + 1]; tinyobj::index_t idx2 = shapes[s].mesh.indices[3 * f + 2]; - current_material_id = shapes[s].mesh.material_ids[f]; + int current_material_id = shapes[s].mesh.material_ids[f]; - if (current_material_id >= materials.size()) { - std::cerr << "Invalid material index: " << current_material_id << std::endl; + if ((current_material_id < 0) || (current_material_id >= static_cast(materials.size()))) { + // Invaid material ID. Use default material. + current_material_id = materials.size() - 1; // Default material is added to the last item in `materials`. } - + //if (current_material_id >= materials.size()) { + // std::cerr << "Invalid material index: " << current_material_id << std::endl; + //} + // float diffuse[3]; for (size_t i = 0; i < 3; i++) { diffuse[i] = materials[current_material_id].diffuse[i]; @@ -364,7 +366,15 @@ bool LoadObjAndConvert(float bmin[3], float bmax[3], o.vb = 0; o.numTriangles = 0; - o.material_id = current_material_id; + + // OpenGL viewer does not support texturing with per-face material. + if (shapes[s].mesh.material_ids.size() > 0 && shapes[s].mesh.material_ids.size() > s) { + // Base case + o.material_id = shapes[s].mesh.material_ids[s]; + } else { + o.material_id = materials.size() - 1; // = ID for default material. + } + if (vb.size() > 0) { glGenBuffers(1, &o.vb); glBindBuffer(GL_ARRAY_BUFFER, o.vb); diff --git a/loader_example.cc b/loader_example.cc index 076ab3d..df74a6c 100644 --- a/loader_example.cc +++ b/loader_example.cc @@ -236,13 +236,13 @@ static void PrintInfo(const tinyobj::attrib_t& attrib, printf(" material.map_d = %s\n", materials[i].alpha_texname.c_str()); printf(" material.disp = %s\n", materials[i].displacement_texname.c_str()); printf(" <>\n"); - printf(" material.Pr = %f\n", materials[i].roughness); - printf(" material.Pm = %f\n", materials[i].metallic); - printf(" material.Ps = %f\n", materials[i].sheen); - printf(" material.Pc = %f\n", materials[i].clearcoat_thickness); - printf(" material.Pcr = %f\n", materials[i].clearcoat_thickness); - printf(" material.aniso = %f\n", materials[i].anisotropy); - printf(" material.anisor = %f\n", materials[i].anisotropy_rotation); + printf(" material.Pr = %f\n", static_cast(materials[i].roughness)); + printf(" material.Pm = %f\n", static_cast(materials[i].metallic)); + printf(" material.Ps = %f\n", static_cast(materials[i].sheen)); + printf(" material.Pc = %f\n", static_cast(materials[i].clearcoat_thickness)); + printf(" material.Pcr = %f\n", static_cast(materials[i].clearcoat_thickness)); + printf(" material.aniso = %f\n", static_cast(materials[i].anisotropy)); + printf(" material.anisor = %f\n", static_cast(materials[i].anisotropy_rotation)); printf(" material.map_Ke = %s\n", materials[i].emissive_texname.c_str()); printf(" material.map_Pr = %s\n", materials[i].roughness_texname.c_str()); printf(" material.map_Pm = %s\n", materials[i].metallic_texname.c_str()); diff --git a/tiny_obj_loader.h b/tiny_obj_loader.h index a46b590..9c9f77d 100644 --- a/tiny_obj_loader.h +++ b/tiny_obj_loader.h @@ -23,6 +23,7 @@ THE SOFTWARE. */ // +// version 1.0.2 : Improve parsing speed by about a factor of 2 for large files(#105) // version 1.0.1 : Fixes a shape is lost if obj ends with a 'usemtl'(#104) // version 1.0.0 : Change data structure. Change license from BSD to MIT. // @@ -75,6 +76,7 @@ typedef struct { float clearcoat_roughness; // [0, 1] default 0 float anisotropy; // aniso. [0, 1] default 0 float anisotropy_rotation; // anisor. [0, 1] default 0 + float pad0; std::string roughness_texname; // map_Pr std::string metallic_texname; // map_Pm std::string sheen_texname; // map_Ps