From 58fa260605fe380387ac08e59bdbff87add72857 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Wed, 20 Apr 2016 16:00:45 +0900 Subject: [PATCH] Show normal vector in viewer example. --- README.md | 8 +++-- examples/viewer/Makefile | 12 +++++--- examples/viewer/viewer.cc | 42 +++++++++++++++++++------- loader_example.cc | 3 ++ tiny_obj_loader.h | 62 ++++++++++++++++++++++++++------------- 5 files changed, 88 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 35dfd1e..838890f 100644 --- a/README.md +++ b/README.md @@ -79,12 +79,13 @@ Features TODO ---- -* [ ] Read .obj/.mtl from memory +* [ ] Read .obj/.mtl from memory. +* [ ] Fix Python binding. License ------- -Licensed under 2 clause BSD. +Licensed under MIT license. Usage ----- @@ -94,11 +95,12 @@ Usage #include "tiny_obj_loader.h" std::string inputfile = "cornell_box.obj"; +tinyobj::attrib_t attrib; std::vector shapes; std::vector materials; std::string err; -bool ret = tinyobj::LoadObj(shapes, materials, err, inputfile.c_str()); +bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &err, inputfile.c_str()); if (!err.empty()) { // `err` may contain warning message. std::cerr << err << std::endl; diff --git a/examples/viewer/Makefile b/examples/viewer/Makefile index 9c1f621..f06e3d0 100644 --- a/examples/viewer/Makefile +++ b/examples/viewer/Makefile @@ -1,12 +1,16 @@ GLFW_INC=-I/usr/local/include -# OSX -#GLFW_LIBS=-L/usr/local/lib -lglfw3 -lGLEW -#GL_LIBS=-framework OpenGL +UNAME=$(shell uname -s) -# Linux +ifeq ($(UNAME),Darwin) +# OSX +GLFW_LIBS=-L/usr/local/lib -lglfw3 -lGLEW +GL_LIBS=-framework OpenGL +else +# Assume Linux GLFW_LIBS=-L/usr/local/lib -lglfw3 -lGLEW GL_LIBS=-lGL -lGLU -lX11 -lXrandr -lXi -lXxf86vm -lXcursor -lXinerama -ldl -pthread +endif CXX_FLAGS=-Wno-deprecated-declarations diff --git a/examples/viewer/viewer.cc b/examples/viewer/viewer.cc index 2022168..a86c853 100644 --- a/examples/viewer/viewer.cc +++ b/examples/viewer/viewer.cc @@ -30,8 +30,8 @@ typedef struct { std::vector gDrawObjects; -int width = 512; -int height = 512; +int width = 768; +int height = 768; double prevMouseX, prevMouseY; bool mouseLeftPressed; @@ -92,8 +92,11 @@ bool LoadObjAndConvert(float bmin[3], float bmax[3], std::vector& dr return false; } + printf("# of vertices = %d\n", (int)(attrib.vertices.size()) / 3); + printf("# of normals = %d\n", (int)(attrib.normals.size()) / 3); + printf("# of texcoords = %d\n", (int)(attrib.texcoords.size()) / 2); printf("# of materials = %d\n", (int)materials.size()); - printf("# of shapes = %d\n", (int)shapes.size()); + printf("# of shapes = %d\n", (int)shapes.size()); bmin[0] = bmin[1] = bmin[2] = std::numeric_limits::max(); bmax[0] = bmax[1] = bmax[2] = -std::numeric_limits::max(); @@ -101,7 +104,7 @@ bool LoadObjAndConvert(float bmin[3], float bmax[3], std::vector& dr { for (size_t s = 0; s < shapes.size(); s++) { DrawObject o; - std::vector vb; // pos(3float), normal(3float) + std::vector vb; // pos(3float), normal(3float), color(3float) for (size_t f = 0; f < shapes[s].mesh.indices.size()/3; f++) { tinyobj::index_t idx0 = shapes[s].mesh.indices[3*f+0]; @@ -150,6 +153,19 @@ bool LoadObjAndConvert(float bmin[3], float bmax[3], std::vector& dr vb.push_back(n[k][0]); vb.push_back(n[k][1]); vb.push_back(n[k][2]); + // Use normal as color. + float c[3] = {n[k][0], n[k][1], n[k][2]}; + float len2 = c[0] * c[0] + c[1] * c[1] + c[2] * c[2]; + if (len2 > 0.0f) { + float len = sqrtf(len2); + + c[0] /= len; + c[1] /= len; + c[2] /= len; + } + vb.push_back(c[0] * 0.5 + 0.5); + vb.push_back(c[1] * 0.5 + 0.5); + vb.push_back(c[2] * 0.5 + 0.5); } } @@ -160,7 +176,8 @@ bool LoadObjAndConvert(float bmin[3], float bmax[3], std::vector& dr glGenBuffers(1, &o.vb); glBindBuffer(GL_ARRAY_BUFFER, o.vb); glBufferData(GL_ARRAY_BUFFER, vb.size() * sizeof(float), &vb.at(0), GL_STATIC_DRAW); - o.numTriangles = vb.size() / 6 / 3; + o.numTriangles = vb.size() / 9 / 3; + printf("shape[%d] # of triangles = %d\n", static_cast(s), o.numTriangles); } gDrawObjects.push_back(o); @@ -243,8 +260,8 @@ void motionFunc(GLFWwindow* window, double mouse_x, double mouse_y){ add_quats(prev_quat, curr_quat, curr_quat); } else if (mouseMiddlePressed) { - eye[0] += transScale * (mouse_x - prevMouseX) / (float)width; - lookat[0] += transScale * (mouse_x - prevMouseX) / (float)width; + eye[0] -= transScale * (mouse_x - prevMouseX) / (float)width; + lookat[0] -= transScale * (mouse_x - prevMouseX) / (float)width; eye[1] += transScale * (mouse_y - prevMouseY) / (float)height; lookat[1] += transScale * (mouse_y - prevMouseY) / (float)height; } else if (mouseRightPressed) { @@ -274,8 +291,10 @@ void Draw(const std::vector& drawObjects) glBindBuffer(GL_ARRAY_BUFFER, o.vb); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); - glVertexPointer(3, GL_FLOAT, 24, (const void*)0); - glNormalPointer(GL_FLOAT, 24, (const void*)(sizeof(float)*3)); + glEnableClientState(GL_COLOR_ARRAY); + glVertexPointer(3, GL_FLOAT, 36, (const void*)0); + glNormalPointer(GL_FLOAT, 36, (const void*)(sizeof(float)*3)); + glColorPointer(3, GL_FLOAT, 36, (const void*)(sizeof(float)*6)); glDrawArrays(GL_TRIANGLES, 0, 3 * o.numTriangles); CheckErrors("drawarrays"); @@ -296,8 +315,9 @@ void Draw(const std::vector& drawObjects) glBindBuffer(GL_ARRAY_BUFFER, o.vb); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); - glVertexPointer(3, GL_FLOAT, 24, (const void*)0); - glNormalPointer(GL_FLOAT, 24, (const void*)(sizeof(float)*3)); + glDisableClientState(GL_COLOR_ARRAY); + glVertexPointer(3, GL_FLOAT, 36, (const void*)0); + glNormalPointer(GL_FLOAT, 36, (const void*)(sizeof(float)*3)); glDrawArrays(GL_TRIANGLES, 0, 3 * o.numTriangles); CheckErrors("drawarrays"); diff --git a/loader_example.cc b/loader_example.cc index d91baaa..435684e 100644 --- a/loader_example.cc +++ b/loader_example.cc @@ -1,3 +1,6 @@ +// +// g++ loader_example.cc +// #define TINYOBJLOADER_IMPLEMENTATION #include "tiny_obj_loader.h" diff --git a/tiny_obj_loader.h b/tiny_obj_loader.h index 5db2bb8..8500fc9 100644 --- a/tiny_obj_loader.h +++ b/tiny_obj_loader.h @@ -1,11 +1,30 @@ -// -// Copyright 2012-2016, Syoyo Fujita. -// -// Licensed under 2-clause BSD license. -// +/* +The MIT License (MIT) + +Copyright (c) 2012-2016 Syoyo Fujita and many contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ // -// version devel : Change data structure. Support different index for +// version 1.0.0 : Change data structure. Change license from BSD to MIT. +// Support different index for // vertex/normal/texcoord(#73, #39) // version 0.9.20: Fixes creating per-face material using `usemtl`(#68) // version 0.9.17: Support n-polygon and crease tag(OpenSubdiv extension) @@ -117,8 +136,9 @@ typedef struct callback_t_ { void (*texcoord_cb)(void *user_data, float x, float y); // -2147483648 will be passed for undefined index void (*index_cb)(void *user_data, int v_idx, int vn_idx, int vt_idx); - // `name` material name, `materialId` = the array index of material_t[]. -1 if a material not found in .mtl - void (*usemtl_cb)(void *user_data, const char* name, int materialId); + // `name` material name, `materialId` = the array index of material_t[]. -1 if + // a material not found in .mtl + void (*usemtl_cb)(void *user_data, const char *name, int materialId); // `materials` = parsed material data. void (*mtllib_cb)(void *user_data, const material_t *materials, int num_materials); @@ -126,17 +146,16 @@ typedef struct callback_t_ { void (*group_cb)(void *user_data, const char **names, int num_names); void (*object_cb)(void *user_data, const char *name); - callback_t_() : - vertex_cb(NULL), - normal_cb(NULL), - texcoord_cb(NULL), - index_cb(NULL), - usemtl_cb(NULL), - mtllib_cb(NULL), - group_cb(NULL), - object_cb(NULL) { - } - + callback_t_() + : vertex_cb(NULL), + normal_cb(NULL), + texcoord_cb(NULL), + index_cb(NULL), + usemtl_cb(NULL), + mtllib_cb(NULL), + group_cb(NULL), + object_cb(NULL) {} + } callback_t; class MaterialReader { @@ -491,7 +510,8 @@ static vertex_index parseTriple(const char **token, int vsize, int vnsize, // Parse raw triples: i, i/j/k, i//k, i/j static vertex_index parseRawTriple(const char **token) { - vertex_index vi(static_cast(0x80000000)); // 0x80000000 = -2147483648 = invalid + vertex_index vi( + static_cast(0x80000000)); // 0x80000000 = -2147483648 = invalid vi.v_idx = atoi((*token)); (*token) += strcspn((*token), "/ \t\r"); @@ -1179,7 +1199,7 @@ bool LoadObjWithCallback(void *user_data, const callback_t &callback, // material std::map material_map; - int materialId = -1; // -1 = invalid + int materialId = -1; // -1 = invalid int maxchars = 8192; // Alloc enough size. std::vector buf(static_cast(maxchars)); // Alloc enough size.