mirror of
https://github.com/syoyo/tinygltf.git
synced 2026-06-13 18:58:53 +00:00
Compare commits
4 Commits
textureinf
...
tinyktx
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98eef6ee75 | ||
|
|
c7bf800075 | ||
|
|
006ab90c67 | ||
|
|
6f7518255f |
25
LICENSE.tinyktx
Normal file
25
LICENSE.tinyktx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
BSD 2-Clause License
|
||||||
|
|
||||||
|
Copyright (c) 2019, DeanoC
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
23
README.md
23
README.md
@@ -7,7 +7,7 @@ If you are looking for old, C++03 version, please use `devel-picojson` branch.
|
|||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
- v2.3.0 Modified Material representation according to glTF 2.0 schema(and introduced TextureInfo class)
|
- v2.3.0 release(Support loading KTX image through tiny_ktx)
|
||||||
- v2.2.0 release(Support loading 16bit PNG. Sparse accessor support)
|
- v2.2.0 release(Support loading 16bit PNG. Sparse accessor support)
|
||||||
- v2.1.0 release(Draco support)
|
- v2.1.0 release(Draco support)
|
||||||
- v2.0.0 release(22 Aug, 2018)!
|
- v2.0.0 release(22 Aug, 2018)!
|
||||||
@@ -53,13 +53,8 @@ If you are looking for old, C++03 version, please use `devel-picojson` branch.
|
|||||||
* [x] Image load
|
* [x] Image load
|
||||||
* [x] Image save
|
* [x] Image save
|
||||||
* Extensions
|
* Extensions
|
||||||
* [x] Draco mesh decoding
|
* [x] Draco mesh decoding(`TINYGLTF_ENABLE_DRACO` required)
|
||||||
|
* [x] KTX image support(no mipmap. `TINYGLTF_ENABLE_KTX` required)
|
||||||
## Note on extension property
|
|
||||||
|
|
||||||
In extension(`ExtensionMap`), JSON number value is parsed as int or float(number) and stored as `tinygltf::Value` object. If you want a floating point value from `tinygltf::Value`, use `GetNumberAsDouble()` method.
|
|
||||||
|
|
||||||
`IsNumber()` returns true if the underlying value is an int value or a floating point value.
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
@@ -83,11 +78,12 @@ In extension(`ExtensionMap`), JSON number value is parsed as int or float(number
|
|||||||
* [x] Load Draco compressed mesh
|
* [x] Load Draco compressed mesh
|
||||||
* [ ] Save Draco compressed mesh
|
* [ ] Save Draco compressed mesh
|
||||||
* [ ] Open3DGC?
|
* [ ] Open3DGC?
|
||||||
* [x] Support `extensions` and `extras` property
|
* [ ] Support `extensions` and `extras` property
|
||||||
* [ ] HDR image?
|
* [ ] HDR image?
|
||||||
* [ ] OpenEXR extension through TinyEXR.
|
* [ ] OpenEXR extension through TinyEXR.
|
||||||
* [ ] 16bit PNG support in Serialization
|
* [ ] 16bit PNG support in Serialization
|
||||||
* [ ] Write example and tests for `animation` and `skin`
|
* [ ] Write example and tests for `animation` and `skin`
|
||||||
|
* [ ] mipmap support for KTX image.
|
||||||
|
|
||||||
## Licenses
|
## Licenses
|
||||||
|
|
||||||
@@ -99,12 +95,15 @@ TinyGLTF uses the following third party libraries.
|
|||||||
* base64 : Copyright (C) 2004-2008 René Nyffenegger
|
* base64 : Copyright (C) 2004-2008 René Nyffenegger
|
||||||
* stb_image.h : v2.08 - public domain image loader - [Github link](https://github.com/nothings/stb/blob/master/stb_image.h)
|
* stb_image.h : v2.08 - public domain image loader - [Github link](https://github.com/nothings/stb/blob/master/stb_image.h)
|
||||||
* stb_image_write.h : v1.09 - public domain image writer - [Github link](https://github.com/nothings/stb/blob/master/stb_image_write.h)
|
* stb_image_write.h : v1.09 - public domain image writer - [Github link](https://github.com/nothings/stb/blob/master/stb_image_write.h)
|
||||||
|
* tinyktx.h : Copyright (c) 2019, DeanoC. Licensed under 2 clause BSD license.
|
||||||
|
|
||||||
|
|
||||||
## Build and example
|
## Build and example
|
||||||
|
|
||||||
Copy `stb_image.h`, `stb_image_write.h`, `json.hpp` and `tiny_gltf.h` to your project.
|
Copy `stb_image.h`, `stb_image_write.h`, `json.hpp` and `tiny_gltf.h` to your project.
|
||||||
|
|
||||||
|
If you enable KTX support(`TINYGLTF_ENABLE_KTX`), Copy `tinyktx.h` to your project.
|
||||||
|
|
||||||
### Loading glTF 2.0 model
|
### Loading glTF 2.0 model
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
@@ -150,6 +149,8 @@ if (!ret) {
|
|||||||
* `TINYGLTF_NO_INCLUDE_JSON `: Disable including `json.hpp` from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`.
|
* `TINYGLTF_NO_INCLUDE_JSON `: Disable including `json.hpp` from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`.
|
||||||
* `TINYGLTF_NO_INCLUDE_STB_IMAGE `: Disable including `stb_image.h` from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`.
|
* `TINYGLTF_NO_INCLUDE_STB_IMAGE `: Disable including `stb_image.h` from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`.
|
||||||
* `TINYGLTF_NO_INCLUDE_STB_IMAGE_WRITE `: Disable including `stb_image_write.h` from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`.
|
* `TINYGLTF_NO_INCLUDE_STB_IMAGE_WRITE `: Disable including `stb_image_write.h` from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`.
|
||||||
|
* `TINYGLTF_ENABLE_KTX` : Enable loading KTX images( https://www.khronos.org/opengles/sdk/tools/KTX/ ) using `tiny_ktx.h`. Supported MIME is `image/ktx` ( https://github.com/KhronosGroup/glTF/issues/835 ). See `models/Cube-KTX` for details. Application also defined `TINYKTX_IMPLEMENTATION` in **one** .cc file.
|
||||||
|
* `TINYGLTF_NO_INCLUDE_TINYKTX` : Disable including `tinyktx.h` from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`.
|
||||||
|
|
||||||
|
|
||||||
### Saving gltTF 2.0 model
|
### Saving gltTF 2.0 model
|
||||||
@@ -188,8 +189,6 @@ $ ./tester
|
|||||||
$ ./tester_noexcept
|
$ ./tester_noexcept
|
||||||
```
|
```
|
||||||
|
|
||||||
## Third party licenses
|
## Third party licenses used in unit tests
|
||||||
|
|
||||||
* json.hpp : Licensed under the MIT License <http://opensource.org/licenses/MIT>. Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
|
||||||
* stb_image : Public domain.
|
|
||||||
* catch : Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. Distributed under the Boost Software License, Version 1.0.
|
* catch : Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. Distributed under the Boost Software License, Version 1.0.
|
||||||
|
|||||||
@@ -1,365 +1,460 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
#include "shaders.h"
|
#include "shaders.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
#define TINYGLTF_IMPLEMENTATION
|
#ifdef __clang__
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#pragma clang diagnostic push
|
||||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
#pragma clang diagnostic ignored "-Weverything"
|
||||||
#define TINYGLTF_NOEXCEPTION
|
#endif
|
||||||
#define JSON_NOEXCEPTION
|
|
||||||
#include "../../tiny_gltf.h"
|
// Inlude tinyktx.h before tiny_gltf.h
|
||||||
|
// to get TKTX_*** definitions
|
||||||
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
#define TINYKTX_IMPLEMENTATION
|
||||||
|
#include "../../tinyktx.h"
|
||||||
bool loadModel(tinygltf::Model &model, const char *filename) {
|
|
||||||
tinygltf::TinyGLTF loader;
|
#ifdef __clang__
|
||||||
std::string err;
|
#pragma clang diagnostic pop
|
||||||
std::string warn;
|
#endif
|
||||||
|
|
||||||
bool res = loader.LoadASCIIFromFile(&model, &err, &warn, filename);
|
#define TINYGLTF_IMPLEMENTATION
|
||||||
if (!warn.empty()) {
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
std::cout << "WARN: " << warn << std::endl;
|
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||||
}
|
#define TINYGLTF_NOEXCEPTION
|
||||||
|
#define JSON_NOEXCEPTION
|
||||||
if (!err.empty()) {
|
#define TINYGLTF_ENABLE_KTX
|
||||||
std::cout << "ERR: " << err << std::endl;
|
// tinyktx.h is already included above,
|
||||||
}
|
// so let tiny_gltf.h know do not include tinyktx.h anymore
|
||||||
|
#define TINYGLTF_NO_INCLUDE_TINY_KTX
|
||||||
if (!res)
|
#include "../../tiny_gltf.h"
|
||||||
std::cout << "Failed to load glTF: " << filename << std::endl;
|
|
||||||
else
|
//#define BUFFER_OFFSET(i) ((char *)nullptr + (i))
|
||||||
std::cout << "Loaded glTF: " << filename << std::endl;
|
#define BUFFER_OFFSET(i) \
|
||||||
|
(reinterpret_cast<void *>(i)) // TODO(syoyo): Is this right way?
|
||||||
return res;
|
|
||||||
}
|
bool loadModel(tinygltf::Model &model, const char *filename) {
|
||||||
|
tinygltf::TinyGLTF loader;
|
||||||
std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos,
|
std::string err;
|
||||||
tinygltf::Model &model, tinygltf::Mesh &mesh) {
|
std::string warn;
|
||||||
for (size_t i = 0; i < model.bufferViews.size(); ++i) {
|
|
||||||
const tinygltf::BufferView &bufferView = model.bufferViews[i];
|
bool res = loader.LoadASCIIFromFile(&model, &err, &warn, filename);
|
||||||
if (bufferView.target == 0) { // TODO impl drawarrays
|
if (!warn.empty()) {
|
||||||
std::cout << "WARN: bufferView.target is zero" << std::endl;
|
std::cout << "WARN: " << warn << std::endl;
|
||||||
continue; // Unsupported bufferView.
|
}
|
||||||
/*
|
|
||||||
From spec2.0 readme:
|
if (!err.empty()) {
|
||||||
https://github.com/KhronosGroup/glTF/tree/master/specification/2.0
|
std::cout << "ERR: " << err << std::endl;
|
||||||
... drawArrays function should be used with a count equal to
|
}
|
||||||
the count property of any of the accessors referenced by the
|
|
||||||
attributes property (they are all equal for a given
|
if (!res)
|
||||||
primitive).
|
std::cout << "Failed to load glTF: " << filename << std::endl;
|
||||||
*/
|
else
|
||||||
}
|
std::cout << "Loaded glTF: " << filename << std::endl;
|
||||||
|
|
||||||
tinygltf::Buffer buffer = model.buffers[bufferView.buffer];
|
return res;
|
||||||
std::cout << "bufferview.target " << bufferView.target << std::endl;
|
}
|
||||||
|
|
||||||
GLuint vbo;
|
static bool GetOpenGLFormatFromKTX(int ktx_fmt, GLint *internal_format, GLenum *format, GLenum *type) {
|
||||||
glGenBuffers(1, &vbo);
|
#if defined(TINYGLTF_ENABLE_KTX)
|
||||||
vbos[i] = vbo;
|
bool ret = true;
|
||||||
glBindBuffer(bufferView.target, vbo);
|
|
||||||
|
std::cout << "fmt = " << ktx_fmt << ", rgb8 fmt = " << TKTX_R8G8B8_UNORM << "\n";
|
||||||
std::cout << "buffer.data.size = " << buffer.data.size()
|
|
||||||
<< ", bufferview.byteOffset = " << bufferView.byteOffset
|
if (ktx_fmt == TKTX_R8G8B8_UNORM) {
|
||||||
<< std::endl;
|
(*internal_format) = GL_RGB;
|
||||||
|
(*format) = GL_RGB;
|
||||||
glBufferData(bufferView.target, bufferView.byteLength,
|
(*type) = GL_UNSIGNED_BYTE;
|
||||||
&buffer.data.at(0) + bufferView.byteOffset, GL_STATIC_DRAW);
|
} else {
|
||||||
}
|
// TODO(syoyo): Support more KTX formats.
|
||||||
|
ret = false;
|
||||||
for (size_t i = 0; i < mesh.primitives.size(); ++i) {
|
}
|
||||||
tinygltf::Primitive primitive = mesh.primitives[i];
|
|
||||||
tinygltf::Accessor indexAccessor = model.accessors[primitive.indices];
|
return ret;
|
||||||
|
#else
|
||||||
for (auto &attrib : primitive.attributes) {
|
(void)fmt;
|
||||||
tinygltf::Accessor accessor = model.accessors[attrib.second];
|
(void)internal_format;
|
||||||
int byteStride =
|
(void)internal_format;
|
||||||
accessor.ByteStride(model.bufferViews[accessor.bufferView]);
|
return false;
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbos[accessor.bufferView]);
|
#endif
|
||||||
|
}
|
||||||
int size = 1;
|
|
||||||
if (accessor.type != TINYGLTF_TYPE_SCALAR) {
|
std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos,
|
||||||
size = accessor.type;
|
tinygltf::Model &model, tinygltf::Mesh &mesh) {
|
||||||
}
|
for (size_t i = 0; i < model.bufferViews.size(); ++i) {
|
||||||
|
const tinygltf::BufferView &bufferView = model.bufferViews[i];
|
||||||
int vaa = -1;
|
if (bufferView.target == 0) { // TODO impl drawarrays
|
||||||
if (attrib.first.compare("POSITION") == 0) vaa = 0;
|
std::cout << "WARN: bufferView.target is zero" << std::endl;
|
||||||
if (attrib.first.compare("NORMAL") == 0) vaa = 1;
|
continue; // Unsupported bufferView.
|
||||||
if (attrib.first.compare("TEXCOORD_0") == 0) vaa = 2;
|
/*
|
||||||
if (vaa > -1) {
|
From spec2.0 readme:
|
||||||
glEnableVertexAttribArray(vaa);
|
https://github.com/KhronosGroup/glTF/tree/master/specification/2.0
|
||||||
glVertexAttribPointer(vaa, size, accessor.componentType,
|
... drawArrays function should be used with a count equal to
|
||||||
accessor.normalized ? GL_TRUE : GL_FALSE,
|
the count property of any of the accessors referenced by the
|
||||||
byteStride, BUFFER_OFFSET(accessor.byteOffset));
|
attributes property (they are all equal for a
|
||||||
} else
|
given primitive).
|
||||||
std::cout << "vaa missing: " << attrib.first << std::endl;
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint texid;
|
tinygltf::Buffer buffer = model.buffers[bufferView.buffer];
|
||||||
glGenTextures(1, &texid);
|
std::cout << "bufferview.target " << bufferView.target << std::endl;
|
||||||
|
|
||||||
tinygltf::Texture &tex = model.textures[0];
|
GLuint vbo;
|
||||||
tinygltf::Image &image = model.images[tex.source];
|
glGenBuffers(1, &vbo);
|
||||||
|
vbos[i] = vbo;
|
||||||
glBindTexture(GL_TEXTURE_2D, texid);
|
glBindBuffer(bufferView.target, vbo);
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
std::cout << "buffer.data.size = " << buffer.data.size()
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
<< ", bufferview.byteOffset = " << bufferView.byteOffset
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
<< std::endl;
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
||||||
|
glBufferData(bufferView.target, bufferView.byteLength,
|
||||||
GLenum format = GL_RGBA;
|
&buffer.data.at(0) + bufferView.byteOffset, GL_STATIC_DRAW);
|
||||||
|
}
|
||||||
if (image.component == 1) {
|
|
||||||
format = GL_RED;
|
for (size_t i = 0; i < mesh.primitives.size(); ++i) {
|
||||||
} else if (image.component == 2) {
|
tinygltf::Primitive primitive = mesh.primitives[i];
|
||||||
format = GL_RG;
|
tinygltf::Accessor indexAccessor = model.accessors[primitive.indices];
|
||||||
} else if (image.component == 3) {
|
|
||||||
format = GL_RGB;
|
for (auto &attrib : primitive.attributes) {
|
||||||
} else {
|
tinygltf::Accessor accessor = model.accessors[attrib.second];
|
||||||
// ???
|
int byteStride =
|
||||||
}
|
accessor.ByteStride(model.bufferViews[accessor.bufferView]);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vbos[accessor.bufferView]);
|
||||||
GLenum type = GL_UNSIGNED_BYTE;
|
|
||||||
if (image.bits == 8) {
|
int size = 1;
|
||||||
// ok
|
if (accessor.type != TINYGLTF_TYPE_SCALAR) {
|
||||||
} else if (image.bits == 16) {
|
size = accessor.type;
|
||||||
type = GL_UNSIGNED_SHORT;
|
}
|
||||||
} else {
|
|
||||||
// ???
|
int vaa = -1;
|
||||||
}
|
if (attrib.first.compare("POSITION") == 0) vaa = 0;
|
||||||
|
if (attrib.first.compare("NORMAL") == 0) vaa = 1;
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0,
|
if (attrib.first.compare("TEXCOORD_0") == 0) vaa = 2;
|
||||||
format, type, &image.image.at(0));
|
if (vaa > -1) {
|
||||||
}
|
glEnableVertexAttribArray(vaa);
|
||||||
|
glVertexAttribPointer(vaa, size, accessor.componentType,
|
||||||
return vbos;
|
accessor.normalized ? GL_TRUE : GL_FALSE,
|
||||||
}
|
byteStride, BUFFER_OFFSET(accessor.byteOffset));
|
||||||
|
} else
|
||||||
// bind models
|
std::cout << "Unsupported vertex attribute: " << attrib.first << std::endl;
|
||||||
void bindModelNodes(std::map<int, GLuint> vbos, tinygltf::Model &model,
|
}
|
||||||
tinygltf::Node &node) {
|
|
||||||
bindMesh(vbos, model, model.meshes[node.mesh]);
|
GLuint texid;
|
||||||
for (size_t i = 0; i < node.children.size(); i++) {
|
glGenTextures(1, &texid);
|
||||||
bindModelNodes(vbos, model, model.nodes[node.children[i]]);
|
|
||||||
}
|
tinygltf::Texture &tex = model.textures[0];
|
||||||
}
|
tinygltf::Image &image = model.images[tex.source];
|
||||||
GLuint bindModel(tinygltf::Model &model) {
|
|
||||||
std::map<int, GLuint> vbos;
|
glBindTexture(GL_TEXTURE_2D, texid);
|
||||||
GLuint vao;
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
glGenVertexArrays(1, &vao);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glBindVertexArray(vao);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
const tinygltf::Scene &scene = model.scenes[model.defaultScene];
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
for (size_t i = 0; i < scene.nodes.size(); ++i) {
|
|
||||||
bindModelNodes(vbos, model, model.nodes[scene.nodes[i]]);
|
GLint internal_format = GL_RGBA;
|
||||||
}
|
GLenum format = GL_RGBA;
|
||||||
|
GLenum type = GL_UNSIGNED_BYTE;
|
||||||
glBindVertexArray(0);
|
|
||||||
// cleanup vbos
|
bool valid = false;
|
||||||
for (size_t i = 0; i < vbos.size(); ++i) {
|
|
||||||
glDeleteBuffers(1, &vbos[i]);
|
// KTX extension
|
||||||
}
|
if (image.extras.Has("ktx_format")) {
|
||||||
|
|
||||||
return vao;
|
valid = GetOpenGLFormatFromKTX(image.extras.Get("ktx_format").Get<int>(), &internal_format, &format, &type);
|
||||||
}
|
|
||||||
|
if (valid) {
|
||||||
void drawMesh(tinygltf::Model &model, tinygltf::Mesh &mesh) {
|
|
||||||
for (size_t i = 0; i < mesh.primitives.size(); ++i) {
|
std::cout << "ktx_format: " << image.extras.Get("ktx_format").Get<int>() << std::endl;
|
||||||
tinygltf::Primitive primitive = mesh.primitives[i];
|
std::cout << "ktx image size: " << image.width << ", " << image.height << std::endl;
|
||||||
tinygltf::Accessor indexAccessor = model.accessors[primitive.indices];
|
}
|
||||||
|
|
||||||
glDrawElements(primitive.mode, indexAccessor.count,
|
} else {
|
||||||
indexAccessor.componentType,
|
|
||||||
BUFFER_OFFSET(indexAccessor.byteOffset));
|
valid = true;
|
||||||
}
|
|
||||||
}
|
if (image.component == 1) {
|
||||||
|
format = GL_RED;
|
||||||
// recursively draw node and children nodes of model
|
} else if (image.component == 2) {
|
||||||
void drawModelNodes(tinygltf::Model &model, tinygltf::Node &node) {
|
format = GL_RG;
|
||||||
drawMesh(model, model.meshes[node.mesh]);
|
} else if (image.component == 3) {
|
||||||
for (size_t i = 0; i < node.children.size(); i++) {
|
format = GL_RGB;
|
||||||
drawModelNodes(model, model.nodes[node.children[i]]);
|
} else if (image.component == 4) {
|
||||||
}
|
format = GL_RGBA;
|
||||||
}
|
} else {
|
||||||
void drawModel(GLuint vao, tinygltf::Model &model) {
|
valid = false;
|
||||||
glBindVertexArray(vao);
|
}
|
||||||
|
|
||||||
const tinygltf::Scene &scene = model.scenes[model.defaultScene];
|
if (image.bits == 8) {
|
||||||
for (size_t i = 0; i < scene.nodes.size(); ++i) {
|
type = GL_UNSIGNED_BYTE;
|
||||||
drawModelNodes(model, model.nodes[scene.nodes[i]]);
|
} else if (image.bits == 16) {
|
||||||
}
|
type = GL_UNSIGNED_SHORT;
|
||||||
|
} else {
|
||||||
glBindVertexArray(0);
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dbgModel(tinygltf::Model &model) {
|
}
|
||||||
for (auto &mesh : model.meshes) {
|
|
||||||
std::cout << "mesh : " << mesh.name << std::endl;
|
if (valid) {
|
||||||
for (auto &primitive : mesh.primitives) {
|
|
||||||
const tinygltf::Accessor &indexAccessor =
|
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, image.width, image.height, 0,
|
||||||
model.accessors[primitive.indices];
|
format, type, &image.image.at(0));
|
||||||
|
}
|
||||||
std::cout << "indexaccessor: count " << indexAccessor.count << ", type "
|
}
|
||||||
<< indexAccessor.componentType << std::endl;
|
|
||||||
|
return vbos;
|
||||||
tinygltf::Material &mat = model.materials[primitive.material];
|
}
|
||||||
for (auto &mats : mat.values) {
|
|
||||||
std::cout << "mat : " << mats.first.c_str() << std::endl;
|
// bind models
|
||||||
}
|
void bindModelNodes(std::map<int, GLuint> vbos, tinygltf::Model &model,
|
||||||
|
tinygltf::Node &node) {
|
||||||
for (auto &image : model.images) {
|
bindMesh(vbos, model, model.meshes[node.mesh]);
|
||||||
std::cout << "image name : " << image.uri << std::endl;
|
for (size_t i = 0; i < node.children.size(); i++) {
|
||||||
std::cout << " size : " << image.image.size() << std::endl;
|
bindModelNodes(vbos, model, model.nodes[node.children[i]]);
|
||||||
std::cout << " w/h : " << image.width << "/" << image.height
|
}
|
||||||
<< std::endl;
|
}
|
||||||
}
|
GLuint bindModel(tinygltf::Model &model) {
|
||||||
|
std::map<int, GLuint> vbos;
|
||||||
std::cout << "indices : " << primitive.indices << std::endl;
|
GLuint vao;
|
||||||
std::cout << "mode : "
|
glGenVertexArrays(1, &vao);
|
||||||
<< "(" << primitive.mode << ")" << std::endl;
|
glBindVertexArray(vao);
|
||||||
|
|
||||||
for (auto &attrib : primitive.attributes) {
|
const tinygltf::Scene &scene = model.scenes[model.defaultScene];
|
||||||
std::cout << "attribute : " << attrib.first.c_str() << std::endl;
|
for (size_t i = 0; i < scene.nodes.size(); ++i) {
|
||||||
}
|
bindModelNodes(vbos, model, model.nodes[scene.nodes[i]]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
glBindVertexArray(0);
|
||||||
|
// cleanup vbos
|
||||||
glm::mat4 genView(glm::vec3 pos, glm::vec3 lookat) {
|
for (size_t i = 0; i < vbos.size(); ++i) {
|
||||||
// Camera matrix
|
glDeleteBuffers(1, &vbos[i]);
|
||||||
glm::mat4 view = glm::lookAt(
|
}
|
||||||
pos, // Camera in World Space
|
|
||||||
lookat, // and looks at the origin
|
return vao;
|
||||||
glm::vec3(0, 1, 0) // Head is up (set to 0,-1,0 to look upside-down)
|
}
|
||||||
);
|
|
||||||
|
void drawMesh(tinygltf::Model &model, tinygltf::Mesh &mesh) {
|
||||||
return view;
|
for (size_t i = 0; i < mesh.primitives.size(); ++i) {
|
||||||
}
|
tinygltf::Primitive primitive = mesh.primitives[i];
|
||||||
|
tinygltf::Accessor indexAccessor = model.accessors[primitive.indices];
|
||||||
glm::mat4 genMVP(glm::mat4 view_mat, glm::mat4 model_mat, float fov, int w,
|
|
||||||
int h) {
|
glDrawElements(primitive.mode, indexAccessor.count,
|
||||||
glm::mat4 Projection =
|
indexAccessor.componentType,
|
||||||
glm::perspective(glm::radians(fov), (float)w / (float)h, 0.01f, 1000.0f);
|
BUFFER_OFFSET(indexAccessor.byteOffset));
|
||||||
|
}
|
||||||
// Or, for an ortho camera :
|
}
|
||||||
// glm::mat4 Projection = glm::ortho(-10.0f,10.0f,-10.0f,10.0f,0.0f,100.0f);
|
|
||||||
// // In world coordinates
|
// recursively draw node and children nodes of model
|
||||||
|
void drawModelNodes(tinygltf::Model &model, tinygltf::Node &node) {
|
||||||
glm::mat4 mvp = Projection * view_mat * model_mat;
|
drawMesh(model, model.meshes[node.mesh]);
|
||||||
|
for (size_t i = 0; i < node.children.size(); i++) {
|
||||||
return mvp;
|
drawModelNodes(model, model.nodes[node.children[i]]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
void displayLoop(Window &window, const std::string &filename) {
|
void drawModel(GLuint vao, tinygltf::Model &model) {
|
||||||
Shaders shader = Shaders();
|
glBindVertexArray(vao);
|
||||||
glUseProgram(shader.pid);
|
|
||||||
|
const tinygltf::Scene &scene = model.scenes[model.defaultScene];
|
||||||
// grab uniforms to modify
|
for (size_t i = 0; i < scene.nodes.size(); ++i) {
|
||||||
GLuint MVP_u = glGetUniformLocation(shader.pid, "MVP");
|
drawModelNodes(model, model.nodes[scene.nodes[i]]);
|
||||||
GLuint sun_position_u = glGetUniformLocation(shader.pid, "sun_position");
|
}
|
||||||
GLuint sun_color_u = glGetUniformLocation(shader.pid, "sun_color");
|
|
||||||
|
glBindVertexArray(0);
|
||||||
tinygltf::Model model;
|
}
|
||||||
if (!loadModel(model, filename.c_str())) return;
|
|
||||||
|
void dbgModel(tinygltf::Model &model) {
|
||||||
GLuint vao = bindModel(model);
|
for (auto &mesh : model.meshes) {
|
||||||
// dbgModel(model); return;
|
std::cout << "mesh : " << mesh.name << std::endl;
|
||||||
|
for (auto &primitive : mesh.primitives) {
|
||||||
// Model matrix : an identity matrix (model will be at the origin)
|
const tinygltf::Accessor &indexAccessor =
|
||||||
glm::mat4 model_mat = glm::mat4(1.0f);
|
model.accessors[primitive.indices];
|
||||||
glm::mat4 model_rot = glm::mat4(1.0f);
|
|
||||||
glm::vec3 model_pos = glm::vec3(-3, 0, -3);
|
std::cout << "indexaccessor: count " << indexAccessor.count << ", type "
|
||||||
|
<< indexAccessor.componentType << std::endl;
|
||||||
// generate a camera view, based on eye-position and lookAt world-position
|
|
||||||
glm::mat4 view_mat = genView(glm::vec3(2, 2, 20), model_pos);
|
tinygltf::Material &mat = model.materials[primitive.material];
|
||||||
|
for (auto &mats : mat.values) {
|
||||||
glm::vec3 sun_position = glm::vec3(3.0, 10.0, -5.0);
|
std::cout << "mat : " << mats.first.c_str() << std::endl;
|
||||||
glm::vec3 sun_color = glm::vec3(1.0);
|
}
|
||||||
|
|
||||||
while (!window.Close()) {
|
for (auto &image : model.images) {
|
||||||
window.Resize();
|
std::cout << "image name : " << image.uri << std::endl;
|
||||||
|
std::cout << " size : " << image.image.size() << std::endl;
|
||||||
glClearColor(0.2, 0.2, 0.2, 1.0);
|
std::cout << " w/h : " << image.width << "/" << image.height
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
<< std::endl;
|
||||||
|
}
|
||||||
glm::mat4 trans =
|
|
||||||
glm::translate(glm::mat4(1.0f), model_pos); // reposition model
|
std::cout << "indices : " << primitive.indices << std::endl;
|
||||||
model_rot = glm::rotate(model_rot, glm::radians(0.8f),
|
std::cout << "mode : "
|
||||||
glm::vec3(0, 1, 0)); // rotate model on y axis
|
<< "(" << primitive.mode << ")" << std::endl;
|
||||||
model_mat = trans * model_rot;
|
|
||||||
|
for (auto &attrib : primitive.attributes) {
|
||||||
// build a model-view-projection
|
std::cout << "attribute : " << attrib.first.c_str() << std::endl;
|
||||||
GLint w, h;
|
}
|
||||||
glfwGetWindowSize(window.window, &w, &h);
|
}
|
||||||
glm::mat4 mvp = genMVP(view_mat, model_mat, 45.0f, w, h);
|
}
|
||||||
glUniformMatrix4fv(MVP_u, 1, GL_FALSE, &mvp[0][0]);
|
}
|
||||||
|
|
||||||
glUniform3fv(sun_position_u, 1, &sun_position[0]);
|
glm::mat4 genView(glm::vec3 pos, glm::vec3 lookat) {
|
||||||
glUniform3fv(sun_color_u, 1, &sun_color[0]);
|
// Camera matrix
|
||||||
|
glm::mat4 view = glm::lookAt(
|
||||||
drawModel(vao, model);
|
pos, // Camera in World Space
|
||||||
glfwSwapBuffers(window.window);
|
lookat, // and looks at the origin
|
||||||
glfwPollEvents();
|
glm::vec3(0, 1, 0) // Head is up (set to 0,-1,0 to look upside-down)
|
||||||
}
|
);
|
||||||
}
|
|
||||||
|
return view;
|
||||||
static void error_callback(int error, const char *description) {
|
}
|
||||||
(void)error;
|
|
||||||
fprintf(stderr, "Error: %s\n", description);
|
glm::mat4 genMVP(glm::mat4 view_mat, glm::mat4 model_mat, float fov, int w,
|
||||||
}
|
int h) {
|
||||||
|
glm::mat4 Projection =
|
||||||
int main(int argc, char **argv) {
|
glm::perspective(glm::radians(fov), (float)w / (float)h, 0.01f, 1000.0f);
|
||||||
std::string filename = "../../models/Cube/Cube.gltf";
|
|
||||||
|
// Or, for an ortho camera :
|
||||||
if (argc > 1) {
|
// glm::mat4 Projection = glm::ortho(-10.0f,10.0f,-10.0f,10.0f,0.0f,100.0f);
|
||||||
filename = argv[1];
|
// // In world coordinates
|
||||||
}
|
|
||||||
|
glm::mat4 mvp = Projection * view_mat * model_mat;
|
||||||
glfwSetErrorCallback(error_callback);
|
|
||||||
|
return mvp;
|
||||||
if (!glfwInit()) return -1;
|
}
|
||||||
|
|
||||||
// Force create OpenGL 3.3
|
void displayLoop(Window &window, const std::string &filename) {
|
||||||
// NOTE(syoyo): Linux + NVIDIA driver segfaults for some reason? commenting out glfwWindowHint will work.
|
Shaders shader = Shaders();
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
glUseProgram(shader.pid);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
// grab uniforms to modify
|
||||||
#ifdef __APPLE__
|
GLuint MVP_u = glGetUniformLocation(shader.pid, "MVP");
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
GLuint sun_position_u = glGetUniformLocation(shader.pid, "sun_position");
|
||||||
#endif
|
GLuint sun_color_u = glGetUniformLocation(shader.pid, "sun_color");
|
||||||
#endif
|
|
||||||
|
tinygltf::Model model;
|
||||||
Window window = Window(800, 600, "TinyGLTF basic example");
|
if (!loadModel(model, filename.c_str())) return;
|
||||||
glfwMakeContextCurrent(window.window);
|
|
||||||
|
GLuint vao = bindModel(model);
|
||||||
#ifdef __APPLE__
|
// dbgModel(model); return;
|
||||||
// https://stackoverflow.com/questions/50192625/openggl-segmentation-fault
|
|
||||||
glewExperimental = GL_TRUE;
|
// Model matrix : an identity matrix (model will be at the origin)
|
||||||
#endif
|
glm::mat4 model_mat = glm::mat4(1.0f);
|
||||||
|
glm::mat4 model_rot = glm::mat4(1.0f);
|
||||||
glewInit();
|
glm::vec3 model_pos = glm::vec3(-3, 0, -3);
|
||||||
std::cout << glGetString(GL_RENDERER) << ", " << glGetString(GL_VERSION)
|
|
||||||
<< std::endl;
|
// generate a camera view, based on eye-position and lookAt world-position
|
||||||
|
glm::mat4 view_mat = genView(glm::vec3(2, 2, 20), model_pos);
|
||||||
if (!GLEW_VERSION_3_3) {
|
|
||||||
std::cerr << "OpenGL 3.3 is required to execute this app." << std::endl;
|
glm::vec3 sun_position = glm::vec3(3.0, 10.0, -5.0);
|
||||||
return EXIT_FAILURE;
|
glm::vec3 sun_color = glm::vec3(1.0);
|
||||||
}
|
|
||||||
|
while (!window.Close()) {
|
||||||
glEnable(GL_DEPTH_TEST);
|
window.Resize();
|
||||||
glDepthFunc(GL_LESS);
|
|
||||||
|
glClearColor(0.2, 0.2, 0.2, 1.0);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
glEnable(GL_BLEND);
|
|
||||||
|
glm::mat4 trans =
|
||||||
displayLoop(window, filename);
|
glm::translate(glm::mat4(1.0f), model_pos); // reposition model
|
||||||
|
model_rot = glm::rotate(model_rot, glm::radians(0.8f),
|
||||||
glfwTerminate();
|
glm::vec3(0, 1, 0)); // rotate model on y axis
|
||||||
return 0;
|
model_mat = trans * model_rot;
|
||||||
}
|
|
||||||
|
// build a model-view-projection
|
||||||
|
GLint w, h;
|
||||||
|
glfwGetWindowSize(window.window, &w, &h);
|
||||||
|
glm::mat4 mvp = genMVP(view_mat, model_mat, 45.0f, w, h);
|
||||||
|
glUniformMatrix4fv(MVP_u, 1, GL_FALSE, &mvp[0][0]);
|
||||||
|
|
||||||
|
glUniform3fv(sun_position_u, 1, &sun_position[0]);
|
||||||
|
glUniform3fv(sun_color_u, 1, &sun_color[0]);
|
||||||
|
|
||||||
|
drawModel(vao, model);
|
||||||
|
glfwSwapBuffers(window.window);
|
||||||
|
glfwPollEvents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void error_callback(int error, const char *description) {
|
||||||
|
(void)error;
|
||||||
|
fprintf(stderr, "Error: %s\n", description);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drop_callback(GLFWwindow *window, int num, const char **paths) {
|
||||||
|
(void)window;
|
||||||
|
printf("dropCB %d\n", num);
|
||||||
|
for (int i = 0; i < num; i++) {
|
||||||
|
printf("%s\n", paths[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
std::string filename = "../../models/Cube/Cube.gltf";
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
filename = argv[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwSetErrorCallback(error_callback);
|
||||||
|
|
||||||
|
if (!glfwInit()) return -1;
|
||||||
|
|
||||||
|
// NOTE(syoyo): For some reason, Linux + NVIDIA driver + apt-installed
|
||||||
|
// glew(1.13) cannot initialize some ARB functions when CONTEXT_VERSION are
|
||||||
|
// explicitly given. Proably we need to compile app with recent glfw and
|
||||||
|
// glew(or use glad) package
|
||||||
|
#if !defined(__linux__)
|
||||||
|
// Try to create OpenGL 3.3 context on Windows and macOS
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||||
|
#ifdef __APPLE__
|
||||||
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Window window = Window(800, 600, "TinyGLTF basic example");
|
||||||
|
|
||||||
|
glfwSetDropCallback(window.window, drop_callback);
|
||||||
|
|
||||||
|
glfwMakeContextCurrent(window.window);
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
// https://stackoverflow.com/questions/50192625/openggl-segmentation-fault
|
||||||
|
glewExperimental = GL_TRUE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (glewInit() != GLEW_OK) {
|
||||||
|
std::cerr << "Failed to initialie glew." << std::endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << glGetString(GL_RENDERER) << ", " << glGetString(GL_VERSION)
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
if (!GLEW_ARB_vertex_array_object) {
|
||||||
|
std::cerr << "GLEW_ARB_vertex_array_object was not available." << std::endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GLEW_VERSION_3_3) {
|
||||||
|
std::cerr << "OpenGL 3.3 is required to execute this app." << std::endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glDepthFunc(GL_LESS);
|
||||||
|
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
|
||||||
|
displayLoop(window, filename);
|
||||||
|
|
||||||
|
glfwTerminate();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -175,10 +175,7 @@ static std::string PrintIntArray(const std::vector<int> &arr) {
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "[ ";
|
ss << "[ ";
|
||||||
for (size_t i = 0; i < arr.size(); i++) {
|
for (size_t i = 0; i < arr.size(); i++) {
|
||||||
ss << arr[i];
|
ss << arr[i] << ((i != arr.size() - 1) ? ", " : "");
|
||||||
if (i != arr.size() - 1) {
|
|
||||||
ss << ", ";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ss << " ]";
|
ss << " ]";
|
||||||
|
|
||||||
@@ -193,10 +190,7 @@ static std::string PrintFloatArray(const std::vector<double> &arr) {
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "[ ";
|
ss << "[ ";
|
||||||
for (size_t i = 0; i < arr.size(); i++) {
|
for (size_t i = 0; i < arr.size(); i++) {
|
||||||
ss << arr[i];
|
ss << arr[i] << ((i != arr.size() - 1) ? ", " : "");
|
||||||
if (i != arr.size() - 1) {
|
|
||||||
ss << ", ";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ss << " ]";
|
ss << " ]";
|
||||||
|
|
||||||
@@ -249,36 +243,35 @@ static std::string PrintValue(const std::string &name,
|
|||||||
if (tag) {
|
if (tag) {
|
||||||
ss << Indent(indent) << name << " : " << value.Get<std::string>();
|
ss << Indent(indent) << name << " : " << value.Get<std::string>();
|
||||||
} else {
|
} else {
|
||||||
ss << Indent(indent) << value.Get<std::string>() << " ";
|
ss << " " << value.Get<std::string>() << " ";
|
||||||
}
|
}
|
||||||
} else if (value.IsBool()) {
|
} else if (value.IsBool()) {
|
||||||
if (tag) {
|
if (tag) {
|
||||||
ss << Indent(indent) << name << " : " << value.Get<bool>();
|
ss << Indent(indent) << name << " : " << value.Get<bool>();
|
||||||
} else {
|
} else {
|
||||||
ss << Indent(indent) << value.Get<bool>() << " ";
|
ss << " " << value.Get<bool>() << " ";
|
||||||
}
|
}
|
||||||
} else if (value.IsNumber()) {
|
} else if (value.IsNumber()) {
|
||||||
if (tag) {
|
if (tag) {
|
||||||
ss << Indent(indent) << name << " : " << value.Get<double>();
|
ss << Indent(indent) << name << " : " << value.Get<double>();
|
||||||
} else {
|
} else {
|
||||||
ss << Indent(indent) << value.Get<double>() << " ";
|
ss << " " << value.Get<double>() << " ";
|
||||||
}
|
}
|
||||||
} else if (value.IsInt()) {
|
} else if (value.IsInt()) {
|
||||||
if (tag) {
|
if (tag) {
|
||||||
ss << Indent(indent) << name << " : " << value.Get<int>();
|
ss << Indent(indent) << name << " : " << value.Get<int>();
|
||||||
} else {
|
} else {
|
||||||
ss << Indent(indent) << value.Get<int>() << " ";
|
ss << " " << value.Get<int>() << " ";
|
||||||
}
|
}
|
||||||
} else if (value.IsArray()) {
|
} else if (value.IsArray()) {
|
||||||
// TODO(syoyo): Better pretty printing of array item
|
ss << Indent(indent) << name << " [ ";
|
||||||
ss << Indent(indent) << name << " [ \n";
|
|
||||||
for (size_t i = 0; i < value.Size(); i++) {
|
for (size_t i = 0; i < value.Size(); i++) {
|
||||||
ss << PrintValue("", value.Get(int(i)), indent + 1, /* tag */ false);
|
ss << PrintValue("", value.Get(int(i)), indent + 1, /* tag */ false);
|
||||||
if (i != (value.ArrayLen() - 1)) {
|
if (i != (value.ArrayLen() - 1)) {
|
||||||
ss << ", \n";
|
ss << ", ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ss << "\n" << Indent(indent) << "] ";
|
ss << Indent(indent) << "] ";
|
||||||
}
|
}
|
||||||
|
|
||||||
// @todo { binary }
|
// @todo { binary }
|
||||||
@@ -346,54 +339,6 @@ static void DumpExtensions(const tinygltf::ExtensionMap &extension,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DumpTextureInfo(const tinygltf::TextureInfo &texinfo,
|
|
||||||
const int indent) {
|
|
||||||
std::cout << Indent(indent) << "index : " << texinfo.index << "\n";
|
|
||||||
std::cout << Indent(indent) << "texCoord : TEXCOORD_" << texinfo.texCoord
|
|
||||||
<< "\n";
|
|
||||||
DumpExtensions(texinfo.extensions, indent + 1);
|
|
||||||
std::cout << PrintValue("extras", texinfo.extras, indent + 1) << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DumpNormalTextureInfo(const tinygltf::NormalTextureInfo &texinfo,
|
|
||||||
const int indent) {
|
|
||||||
std::cout << Indent(indent) << "index : " << texinfo.index << "\n";
|
|
||||||
std::cout << Indent(indent) << "texCoord : TEXCOORD_" << texinfo.texCoord
|
|
||||||
<< "\n";
|
|
||||||
std::cout << Indent(indent) << "scale : " << texinfo.scale << "\n";
|
|
||||||
DumpExtensions(texinfo.extensions, indent + 1);
|
|
||||||
std::cout << PrintValue("extras", texinfo.extras, indent + 1) << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DumpOcclusionTextureInfo(
|
|
||||||
const tinygltf::OcclusionTextureInfo &texinfo, const int indent) {
|
|
||||||
std::cout << Indent(indent) << "index : " << texinfo.index << "\n";
|
|
||||||
std::cout << Indent(indent) << "texCoord : TEXCOORD_" << texinfo.texCoord
|
|
||||||
<< "\n";
|
|
||||||
std::cout << Indent(indent) << "strength : " << texinfo.strength << "\n";
|
|
||||||
DumpExtensions(texinfo.extensions, indent + 1);
|
|
||||||
std::cout << PrintValue("extras", texinfo.extras, indent + 1) << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DumpPbrMetallicRoughness(const tinygltf::PbrMetallicRoughness &pbr,
|
|
||||||
const int indent) {
|
|
||||||
std::cout << Indent(indent)
|
|
||||||
<< "baseColorFactor : " << PrintFloatArray(pbr.baseColorFactor)
|
|
||||||
<< "\n";
|
|
||||||
std::cout << Indent(indent) << "baseColorTexture :\n";
|
|
||||||
DumpTextureInfo(pbr.baseColorTexture, indent + 1);
|
|
||||||
|
|
||||||
std::cout << Indent(indent) << "metallicFactor : " << pbr.metallicFactor
|
|
||||||
<< "\n";
|
|
||||||
std::cout << Indent(indent) << "roughnessFactor : " << pbr.roughnessFactor
|
|
||||||
<< "\n";
|
|
||||||
|
|
||||||
std::cout << Indent(indent) << "metallicRoughnessTexture :\n";
|
|
||||||
DumpTextureInfo(pbr.metallicRoughnessTexture, indent + 1);
|
|
||||||
DumpExtensions(pbr.extensions, indent + 1);
|
|
||||||
std::cout << PrintValue("extras", pbr.extras, indent + 1) << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Dump(const tinygltf::Model &model) {
|
static void Dump(const tinygltf::Model &model) {
|
||||||
std::cout << "=== Dump glTF ===" << std::endl;
|
std::cout << "=== Dump glTF ===" << std::endl;
|
||||||
std::cout << "asset.copyright : " << model.asset.copyright
|
std::cout << "asset.copyright : " << model.asset.copyright
|
||||||
@@ -564,44 +509,16 @@ static void Dump(const tinygltf::Model &model) {
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
for (size_t i = 0; i < model.materials.size(); i++) {
|
for (size_t i = 0; i < model.materials.size(); i++) {
|
||||||
const tinygltf::Material &material = model.materials[i];
|
const tinygltf::Material &material = model.materials[i];
|
||||||
std::cout << Indent(1) << "name : " << material.name
|
std::cout << Indent(1) << "name : " << material.name << std::endl;
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
std::cout << Indent(1) << "alphaMode : " << material.alphaMode
|
|
||||||
<< std::endl;
|
|
||||||
std::cout << Indent(1)
|
|
||||||
<< "alphaCutoff : " << material.alphaCutoff
|
|
||||||
<< std::endl;
|
|
||||||
std::cout << Indent(1) << "doubleSided : "
|
|
||||||
<< (material.doubleSided ? "true" : "false") << std::endl;
|
|
||||||
std::cout << Indent(1) << "emissiveFactor : "
|
|
||||||
<< PrintFloatArray(material.emissiveFactor) << std::endl;
|
|
||||||
|
|
||||||
std::cout << Indent(1) << "pbrMetallicRoughness :\n";
|
|
||||||
DumpPbrMetallicRoughness(material.pbrMetallicRoughness, 2);
|
|
||||||
|
|
||||||
std::cout << Indent(1) << "normalTexture :\n";
|
|
||||||
DumpNormalTextureInfo(material.normalTexture, 2);
|
|
||||||
|
|
||||||
std::cout << Indent(1) << "occlusionTexture :\n";
|
|
||||||
DumpOcclusionTextureInfo(material.occlusionTexture, 2);
|
|
||||||
|
|
||||||
std::cout << Indent(1) << "emissiveTexture :\n";
|
|
||||||
DumpTextureInfo(material.emissiveTexture, 2);
|
|
||||||
|
|
||||||
std::cout << Indent(1) << "---- legacy material parameter ----\n";
|
|
||||||
std::cout << Indent(1) << "values(items=" << material.values.size() << ")"
|
std::cout << Indent(1) << "values(items=" << material.values.size() << ")"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
tinygltf::ParameterMap::const_iterator p(material.values.begin());
|
tinygltf::ParameterMap::const_iterator p(material.values.begin());
|
||||||
tinygltf::ParameterMap::const_iterator pEnd(material.values.end());
|
tinygltf::ParameterMap::const_iterator pEnd(material.values.end());
|
||||||
for (; p != pEnd; p++) {
|
for (; p != pEnd; p++) {
|
||||||
std::cout << Indent(2) << p->first << ": "
|
std::cout << Indent(2) << p->first << ": "
|
||||||
<< PrintParameterValue(p->second) << std::endl;
|
<< PrintParameterValue(p->second) << std::endl;
|
||||||
}
|
}
|
||||||
std::cout << Indent(1) << "-------------------------------------\n";
|
|
||||||
|
|
||||||
DumpExtensions(material.extensions, 1);
|
|
||||||
std::cout << PrintValue("extras", material.extras, 2) << std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
193
models/Cube-KTX/Cube.gltf
Normal file
193
models/Cube-KTX/Cube.gltf
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
{
|
||||||
|
"accessors" : [
|
||||||
|
{
|
||||||
|
"bufferView" : 0,
|
||||||
|
"byteOffset" : 0,
|
||||||
|
"componentType" : 5123,
|
||||||
|
"count" : 36,
|
||||||
|
"max" : [
|
||||||
|
35
|
||||||
|
],
|
||||||
|
"min" : [
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"type" : "SCALAR"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView" : 1,
|
||||||
|
"byteOffset" : 0,
|
||||||
|
"componentType" : 5126,
|
||||||
|
"count" : 36,
|
||||||
|
"max" : [
|
||||||
|
1.000000,
|
||||||
|
1.000000,
|
||||||
|
1.000001
|
||||||
|
],
|
||||||
|
"min" : [
|
||||||
|
-1.000000,
|
||||||
|
-1.000000,
|
||||||
|
-1.000000
|
||||||
|
],
|
||||||
|
"type" : "VEC3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView" : 2,
|
||||||
|
"byteOffset" : 0,
|
||||||
|
"componentType" : 5126,
|
||||||
|
"count" : 36,
|
||||||
|
"max" : [
|
||||||
|
1.000000,
|
||||||
|
1.000000,
|
||||||
|
1.000000
|
||||||
|
],
|
||||||
|
"min" : [
|
||||||
|
-1.000000,
|
||||||
|
-1.000000,
|
||||||
|
-1.000000
|
||||||
|
],
|
||||||
|
"type" : "VEC3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView" : 3,
|
||||||
|
"byteOffset" : 0,
|
||||||
|
"componentType" : 5126,
|
||||||
|
"count" : 36,
|
||||||
|
"max" : [
|
||||||
|
1.000000,
|
||||||
|
-0.000000,
|
||||||
|
-0.000000,
|
||||||
|
1.000000
|
||||||
|
],
|
||||||
|
"min" : [
|
||||||
|
0.000000,
|
||||||
|
-0.000000,
|
||||||
|
-1.000000,
|
||||||
|
-1.000000
|
||||||
|
],
|
||||||
|
"type" : "VEC4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView" : 4,
|
||||||
|
"byteOffset" : 0,
|
||||||
|
"componentType" : 5126,
|
||||||
|
"count" : 36,
|
||||||
|
"max" : [
|
||||||
|
1.000000,
|
||||||
|
1.000000
|
||||||
|
],
|
||||||
|
"min" : [
|
||||||
|
-1.000000,
|
||||||
|
-1.000000
|
||||||
|
],
|
||||||
|
"type" : "VEC2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"asset" : {
|
||||||
|
"generator" : "VKTS glTF 2.0 exporter",
|
||||||
|
"version" : "2.0"
|
||||||
|
},
|
||||||
|
"bufferViews" : [
|
||||||
|
{
|
||||||
|
"buffer" : 0,
|
||||||
|
"byteLength" : 72,
|
||||||
|
"byteOffset" : 0,
|
||||||
|
"target" : 34963
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer" : 0,
|
||||||
|
"byteLength" : 432,
|
||||||
|
"byteOffset" : 72,
|
||||||
|
"target" : 34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer" : 0,
|
||||||
|
"byteLength" : 432,
|
||||||
|
"byteOffset" : 504,
|
||||||
|
"target" : 34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer" : 0,
|
||||||
|
"byteLength" : 576,
|
||||||
|
"byteOffset" : 936,
|
||||||
|
"target" : 34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer" : 0,
|
||||||
|
"byteLength" : 288,
|
||||||
|
"byteOffset" : 1512,
|
||||||
|
"target" : 34962
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buffers" : [
|
||||||
|
{
|
||||||
|
"byteLength" : 1800,
|
||||||
|
"uri" : "Cube.bin"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"uri" : "Cube_BaseColor.ktx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uri" : "Cube_MetallicRoughness.ktx"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"materials" : [
|
||||||
|
{
|
||||||
|
"name" : "Cube",
|
||||||
|
"pbrMetallicRoughness" : {
|
||||||
|
"baseColorTexture" : {
|
||||||
|
"index" : 0
|
||||||
|
},
|
||||||
|
"metallicRoughnessTexture" : {
|
||||||
|
"index" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meshes" : [
|
||||||
|
{
|
||||||
|
"name" : "Cube",
|
||||||
|
"primitives" : [
|
||||||
|
{
|
||||||
|
"attributes" : {
|
||||||
|
"NORMAL" : 2,
|
||||||
|
"POSITION" : 1,
|
||||||
|
"TANGENT" : 3,
|
||||||
|
"TEXCOORD_0" : 4
|
||||||
|
},
|
||||||
|
"indices" : 0,
|
||||||
|
"material" : 0,
|
||||||
|
"mode" : 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nodes" : [
|
||||||
|
{
|
||||||
|
"mesh" : 0,
|
||||||
|
"name" : "Cube"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"samplers" : [
|
||||||
|
{}
|
||||||
|
],
|
||||||
|
"scene" : 0,
|
||||||
|
"scenes" : [
|
||||||
|
{
|
||||||
|
"nodes" : [
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"textures" : [
|
||||||
|
{
|
||||||
|
"sampler" : 0,
|
||||||
|
"source" : 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sampler" : 0,
|
||||||
|
"source" : 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
models/Cube-KTX/Cube_BaseColor.ktx
Normal file
BIN
models/Cube-KTX/Cube_BaseColor.ktx
Normal file
Binary file not shown.
BIN
models/Cube-KTX/Cube_MetallicRoughness.ktx
Normal file
BIN
models/Cube-KTX/Cube_MetallicRoughness.ktx
Normal file
Binary file not shown.
12
models/Cube-KTX/README.md
Normal file
12
models/Cube-KTX/README.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
License: Donated by Norbert Nopper for glTF testing.
|
||||||
|
|
||||||
|
https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/Cube
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
Converted .png to .ktx image by Syoyo Fujita.
|
||||||
|
|
||||||
|
.png -> .ppm using image magic(resize with 25% to reduce file size)
|
||||||
|
.ppm -> .ktx using `toktx` in KTX-Software https://github.com/KhronosGroup/KTX-Software
|
||||||
|
|
||||||
@@ -1,224 +0,0 @@
|
|||||||
{
|
|
||||||
"accessors": [
|
|
||||||
{
|
|
||||||
"bufferView": 0,
|
|
||||||
"byteOffset": 0,
|
|
||||||
"componentType": 5123,
|
|
||||||
"count": 36,
|
|
||||||
"max": [
|
|
||||||
35
|
|
||||||
],
|
|
||||||
"min": [
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"type": "SCALAR"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"bufferView": 1,
|
|
||||||
"byteOffset": 0,
|
|
||||||
"componentType": 5126,
|
|
||||||
"count": 36,
|
|
||||||
"max": [
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1.000001
|
|
||||||
],
|
|
||||||
"min": [
|
|
||||||
-1,
|
|
||||||
-1,
|
|
||||||
-1
|
|
||||||
],
|
|
||||||
"type": "VEC3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"bufferView": 2,
|
|
||||||
"byteOffset": 0,
|
|
||||||
"componentType": 5126,
|
|
||||||
"count": 36,
|
|
||||||
"max": [
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1
|
|
||||||
],
|
|
||||||
"min": [
|
|
||||||
-1,
|
|
||||||
-1,
|
|
||||||
-1
|
|
||||||
],
|
|
||||||
"type": "VEC3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"bufferView": 3,
|
|
||||||
"byteOffset": 0,
|
|
||||||
"componentType": 5126,
|
|
||||||
"count": 36,
|
|
||||||
"max": [
|
|
||||||
1,
|
|
||||||
-0,
|
|
||||||
-0,
|
|
||||||
1
|
|
||||||
],
|
|
||||||
"min": [
|
|
||||||
0,
|
|
||||||
-0,
|
|
||||||
-1,
|
|
||||||
-1
|
|
||||||
],
|
|
||||||
"type": "VEC4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"bufferView": 4,
|
|
||||||
"byteOffset": 0,
|
|
||||||
"componentType": 5126,
|
|
||||||
"count": 36,
|
|
||||||
"max": [
|
|
||||||
1,
|
|
||||||
1
|
|
||||||
],
|
|
||||||
"min": [
|
|
||||||
-1,
|
|
||||||
-1
|
|
||||||
],
|
|
||||||
"type": "VEC2"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"asset": {
|
|
||||||
"generator": "VKTS glTF 2.0 exporter",
|
|
||||||
"version": "2.0"
|
|
||||||
},
|
|
||||||
"bufferViews": [
|
|
||||||
{
|
|
||||||
"buffer": 0,
|
|
||||||
"byteLength": 72,
|
|
||||||
"byteOffset": 0,
|
|
||||||
"target": 34963
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"buffer": 0,
|
|
||||||
"byteLength": 432,
|
|
||||||
"byteOffset": 72,
|
|
||||||
"target": 34962
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"buffer": 0,
|
|
||||||
"byteLength": 432,
|
|
||||||
"byteOffset": 504,
|
|
||||||
"target": 34962
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"buffer": 0,
|
|
||||||
"byteLength": 576,
|
|
||||||
"byteOffset": 936,
|
|
||||||
"target": 34962
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"buffer": 0,
|
|
||||||
"byteLength": 288,
|
|
||||||
"byteOffset": 1512,
|
|
||||||
"target": 34962
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"buffers": [
|
|
||||||
{
|
|
||||||
"byteLength": 1800,
|
|
||||||
"uri": "Cube.bin"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"images": [
|
|
||||||
{
|
|
||||||
"0comment": "Use Cube_MetallicRoughness.png to reduce scene filesize",
|
|
||||||
"uri": "Cube_MetallicRoughness.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"uri": "Cube_MetallicRoughness.png"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"materials": [
|
|
||||||
{
|
|
||||||
"emissiveTexture": {
|
|
||||||
"index": 0,
|
|
||||||
"extensions": {
|
|
||||||
"KHR_texture_transform": {
|
|
||||||
"offset": [
|
|
||||||
0,
|
|
||||||
1
|
|
||||||
],
|
|
||||||
"scale": [
|
|
||||||
1,
|
|
||||||
-1
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Cube",
|
|
||||||
"pbrMetallicRoughness": {
|
|
||||||
"baseColorTexture": {
|
|
||||||
"index": 0
|
|
||||||
},
|
|
||||||
"metallicRoughnessTexture": {
|
|
||||||
"index": 1,
|
|
||||||
"extensions": {
|
|
||||||
"KHR_texture_transform": {
|
|
||||||
"offset": [
|
|
||||||
0,
|
|
||||||
1
|
|
||||||
],
|
|
||||||
"rotation": 1.57079632679,
|
|
||||||
"scale": [
|
|
||||||
0.5,
|
|
||||||
0.5
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"meshes": [
|
|
||||||
{
|
|
||||||
"name": "Cube",
|
|
||||||
"primitives": [
|
|
||||||
{
|
|
||||||
"attributes": {
|
|
||||||
"NORMAL": 2,
|
|
||||||
"POSITION": 1,
|
|
||||||
"TANGENT": 3,
|
|
||||||
"TEXCOORD_0": 4
|
|
||||||
},
|
|
||||||
"indices": 0,
|
|
||||||
"material": 0,
|
|
||||||
"mode": 4
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nodes": [
|
|
||||||
{
|
|
||||||
"mesh": 0,
|
|
||||||
"name": "Cube"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"samplers": [
|
|
||||||
{}
|
|
||||||
],
|
|
||||||
"scene": 0,
|
|
||||||
"scenes": [
|
|
||||||
{
|
|
||||||
"nodes": [
|
|
||||||
0
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"textures": [
|
|
||||||
{
|
|
||||||
"sampler": 0,
|
|
||||||
"source": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sampler": 0,
|
|
||||||
"source": 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 319 B |
@@ -1,6 +0,0 @@
|
|||||||
Added KHR_texture_transform property to Cube scene.
|
|
||||||
|
|
||||||
License: Donated by Norbert Nopper for glTF testing.
|
|
||||||
|
|
||||||
https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/Cube
|
|
||||||
|
|
||||||
@@ -279,39 +279,3 @@ TEST_CASE("parse-integer-array", "[bounds-checking]") {
|
|||||||
REQUIRE_THAT(err, Catch::Contains("not an integer type"));
|
REQUIRE_THAT(err, Catch::Contains("not an integer type"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("pbr-khr-texture-transform", "[material]") {
|
|
||||||
tinygltf::Model model;
|
|
||||||
tinygltf::TinyGLTF ctx;
|
|
||||||
std::string err;
|
|
||||||
std::string warn;
|
|
||||||
|
|
||||||
// Loading is expected to fail, but not crash.
|
|
||||||
bool ret = ctx.LoadASCIIFromFile(
|
|
||||||
&model, &err, &warn,
|
|
||||||
"../models/Cube-texture-ext/Cube-textransform.gltf");
|
|
||||||
REQUIRE(ret == true);
|
|
||||||
|
|
||||||
REQUIRE(model.materials.size() == 2);
|
|
||||||
REQUIRE(model.materials[0].emissiveTexture.extensions.count("KHR_texture_transform") == 1);
|
|
||||||
REQUIRE(model.materials[0].emissiveTexture.extensions["KHR_texture_transform"].IsObject());
|
|
||||||
|
|
||||||
tinygltf::Value::Object &texform = model.materials[0].emissiveTexture.extensions["KHR_texture_transform"].Get<tinygltf::Value::Object>();
|
|
||||||
|
|
||||||
REQUIRE(texform.count("scale"));
|
|
||||||
|
|
||||||
REQUIRE(texform["scale"].IsArray());
|
|
||||||
|
|
||||||
// Note: It looks json.hpp parse integer JSON number as integer, not floating point.
|
|
||||||
// IsNumber return true either value is int or floating point.
|
|
||||||
REQUIRE(texform["scale"].Get(0).IsNumber());
|
|
||||||
REQUIRE(texform["scale"].Get(1).IsNumber());
|
|
||||||
|
|
||||||
double scale[2];
|
|
||||||
scale[0] = texform["scale"].Get(0).GetNumberAsDouble();
|
|
||||||
scale[1] = texform["scale"].Get(1).GetNumberAsDouble();
|
|
||||||
|
|
||||||
REQUIRE(scale[0] == Approx(1.0));
|
|
||||||
REQUIRE(scale[1] == Approx(-1.0));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
1324
tiny_gltf.h
1324
tiny_gltf.h
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user