From 5f603c56dc6930c355a5b51389c7fcb05dea3777 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Mon, 6 Apr 2020 22:11:16 +0900 Subject: [PATCH] Do not segfault when the scene does not contain texture images. Fixes #251 --- examples/basic/README.md | 4 +++ examples/basic/main.cpp | 76 +++++++++++++++++++++++----------------- 2 files changed, 48 insertions(+), 32 deletions(-) diff --git a/examples/basic/README.md b/examples/basic/README.md index 67da089..dd68e0a 100644 --- a/examples/basic/README.md +++ b/examples/basic/README.md @@ -19,3 +19,7 @@ $ make Plese use solution file located at `basic` folder. +## Limitation + +There are so many limitations in this example(e.g. no PBR shader. the shader only shows texture of textures[0] if available). + diff --git a/examples/basic/main.cpp b/examples/basic/main.cpp index 1d196ae..e4e059e 100644 --- a/examples/basic/main.cpp +++ b/examples/basic/main.cpp @@ -100,42 +100,49 @@ std::map bindMesh(std::map vbos, std::cout << "vaa missing: " << attrib.first << std::endl; } - GLuint texid; - glGenTextures(1, &texid); + if (model.textures.size() > 0) { + // fixme: Use material's baseColor + tinygltf::Texture &tex = model.textures[0]; - tinygltf::Texture &tex = model.textures[0]; - tinygltf::Image &image = model.images[tex.source]; + if (tex.source > -1) { - glBindTexture(GL_TEXTURE_2D, texid); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + GLuint texid; + glGenTextures(1, &texid); - GLenum format = GL_RGBA; + tinygltf::Image &image = model.images[tex.source]; - if (image.component == 1) { - format = GL_RED; - } else if (image.component == 2) { - format = GL_RG; - } else if (image.component == 3) { - format = GL_RGB; - } else { - // ??? + glBindTexture(GL_TEXTURE_2D, texid); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + GLenum format = GL_RGBA; + + if (image.component == 1) { + format = GL_RED; + } else if (image.component == 2) { + format = GL_RG; + } else if (image.component == 3) { + format = GL_RGB; + } else { + // ??? + } + + GLenum type = GL_UNSIGNED_BYTE; + if (image.bits == 8) { + // ok + } else if (image.bits == 16) { + type = GL_UNSIGNED_SHORT; + } else { + // ??? + } + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0, + format, type, &image.image.at(0)); + } } - - GLenum type = GL_UNSIGNED_BYTE; - if (image.bits == 8) { - // ok - } else if (image.bits == 16) { - type = GL_UNSIGNED_SHORT; - } else { - // ??? - } - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0, - format, type, &image.image.at(0)); } return vbos; @@ -144,8 +151,12 @@ std::map bindMesh(std::map vbos, // bind models void bindModelNodes(std::map vbos, tinygltf::Model &model, tinygltf::Node &node) { - bindMesh(vbos, model, model.meshes[node.mesh]); + if ((node.mesh >= 0) && (node.mesh < model.meshes.size())) { + bindMesh(vbos, model, model.meshes[node.mesh]); + } + for (size_t i = 0; i < node.children.size(); i++) { + assert((node.children[i] >= 0) && (node.children[i] < model.nodes.size())); bindModelNodes(vbos, model, model.nodes[node.children[i]]); } } @@ -157,6 +168,7 @@ GLuint bindModel(tinygltf::Model &model) { const tinygltf::Scene &scene = model.scenes[model.defaultScene]; for (size_t i = 0; i < scene.nodes.size(); ++i) { + assert((scene.nodes[i] >= 0) && (scene.nodes[i] < model.nodes.size())); bindModelNodes(vbos, model, model.nodes[scene.nodes[i]]); }