Do not segfault when the scene does not contain texture images. Fixes #251

This commit is contained in:
Syoyo Fujita 2020-04-06 22:11:16 +09:00
parent 40982716f9
commit 5f603c56dc
2 changed files with 48 additions and 32 deletions

View File

@ -19,3 +19,7 @@ $ make
Plese use solution file located at `basic` folder. 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).

View File

@ -100,42 +100,49 @@ std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos,
std::cout << "vaa missing: " << attrib.first << std::endl; std::cout << "vaa missing: " << attrib.first << std::endl;
} }
GLuint texid; if (model.textures.size() > 0) {
glGenTextures(1, &texid); // fixme: Use material's baseColor
tinygltf::Texture &tex = model.textures[0];
tinygltf::Texture &tex = model.textures[0]; if (tex.source > -1) {
tinygltf::Image &image = model.images[tex.source];
glBindTexture(GL_TEXTURE_2D, texid); GLuint texid;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenTextures(1, &texid);
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; tinygltf::Image &image = model.images[tex.source];
if (image.component == 1) { glBindTexture(GL_TEXTURE_2D, texid);
format = GL_RED; glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
} else if (image.component == 2) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
format = GL_RG; glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
} else if (image.component == 3) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
format = GL_RGB; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
} else {
// ??? 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; return vbos;
@ -144,8 +151,12 @@ std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos,
// bind models // bind models
void bindModelNodes(std::map<int, GLuint> vbos, tinygltf::Model &model, void bindModelNodes(std::map<int, GLuint> vbos, tinygltf::Model &model,
tinygltf::Node &node) { 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++) { 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]]); 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]; const tinygltf::Scene &scene = model.scenes[model.defaultScene];
for (size_t i = 0; i < scene.nodes.size(); ++i) { 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]]); bindModelNodes(vbos, model, model.nodes[scene.nodes[i]]);
} }