Compare commits

..

4 Commits

Author SHA1 Message Date
Syoyo Fujita
98eef6ee75 Fix non-KTX texture was not handled correctly.
Experience file drop API of glfw(not working yet).
2019-07-06 15:13:13 +09:00
Syoyo Fujita
c7bf800075 Support KTX texture of R8G8B8 format in basic example. 2019-07-05 16:20:53 +09:00
Syoyo Fujita
006ab90c67 Initial support of KTX texture load using TinyKTX. 2019-07-04 14:30:28 +09:00
Syoyo Fujita
6f7518255f Add tinyktx.
Add workaround for OpenGL3 context creation in `basic` example.
2019-07-03 16:41:11 +09:00
29 changed files with 3257 additions and 4889 deletions

View File

@@ -1,165 +0,0 @@
name: C/C++ CI
on: [push, pull_request]
jobs:
# compile with older gcc4.8
build-gcc48:
runs-on: ubuntu-18.04
name: Build with gcc 4.8
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Build
run: |
sudo apt-get update
sudo apt-get install -y build-essential
sudo apt-get install -y gcc-4.8 g++-4.8
g++-4.8 -std=c++11 -o loader_example loader_example.cc
- name: NoexceptBuild
run: |
g++-4.8 -DTINYGLTF_NOEXCEPTION -std=c++11 -o loader_example loader_example.cc
- name: RapidjsonBuild
run: |
git clone https://github.com/Tencent/rapidjson
g++-4.8 -DTINYGLTF_USE_RAPIDJSON -I./rapidjson/include/rapidjson -std=c++11 -o loader_example loader_example.cc
# compile with mingw gcc cross
build-mingw-cross:
runs-on: ubuntu-18.04
name: Build with MinGW gcc cross
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Build
run: |
sudo apt-get update
sudo apt-get install -y build-essential
sudo apt-get install -y mingw-w64
x86_64-w64-mingw32-g++ -std=c++11 -o loader_example loader_example.cc
# Windows(x64) + Visual Studio 2019 build
build-windows-msvc:
runs-on: windows-latest
name: Build for Windows(x64, MSVC)
# Use system installed cmake
# https://help.github.com/en/actions/reference/software-installed-on-github-hosted-runners
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Configure
run: |
mkdir build
cd build
cmake -G "Visual Studio 16 2019" -DTINYGLTF_BUILD_LOADER_EXAMPLE=On -DTINYGLTF_BUILD_GL_EXAMPLES=Off -DTINYGLTF_BUILD_VALIDATOR_EXAMPLE=On ..
cd ..
- name: Build
run: cmake --build build --config Release
build-linux:
runs-on: ubuntu-latest
name: Buld with gcc
steps:
- uses: actions/checkout@v2
- name: build
run: |
g++ -std=c++11 -o loader_example loader_example.cc
- name: test
run: |
./loader_example models/Cube/Cube.gltf
- name: tests
run: |
cd tests
g++ -I../ -std=c++11 -g -O0 -o tester tester.cc
./tester
cd ..
- name: noexcept_tests
run: |
cd tests
g++ -DTINYGLTF_NOEXCEPTION -I../ -std=c++11 -g -O0 -o tester_noexcept tester.cc
./tester_noexcept
cd ..
build-rapidjson-linux:
runs-on: ubuntu-latest
name: Buld with gcc + rapidjson
steps:
- uses: actions/checkout@v2
- name: build
run: |
git clone https://github.com/Tencent/rapidjson
g++ -v
g++ -DTINYGLTF_USE_RAPIDJSON -I./rapidjson/include/rapidjson -std=c++11 -o loader_example loader_example.cc
- name: loader_example_test
run: |
./loader_example models/Cube/Cube.gltf
- name: tests
run: |
cd tests
g++ -DTINYGLTF_USE_RAPIDJSON -I../rapidjson/include/rapidjson -I../ -std=c++11 -g -O0 -o tester tester.cc
./tester
cd ..
- name: noexcept_tests
run: |
cd tests
g++ -DTINYGLTF_USE_RAPIDJSON -I../rapidjson/include/rapidjson -DTINYGLTF_NOEXCEPTION -I../ -std=c++11 -g -O0 -o tester_noexcept tester.cc
./tester_noexcept
cd ..
# Cross-compile for aarch64 linux target
build-cross-aarch64:
runs-on: ubuntu-18.04
name: Build on cross aarch64
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Build
run: |
sudo apt-get update
sudo apt-get install -y build-essential
sudo apt-get install -y gcc-8-aarch64-linux-gnu g++-8-aarch64-linux-gnu
git clone https://github.com/Tencent/rapidjson
aarch64-linux-gnu-g++-8 -DTINYGLTF_USE_RAPIDJSON -I./rapidjson/include/rapidjson -std=c++11 -g -O0 -o loader_example loader_example.cc
# macOS clang
build-macos:
runs-on: macos-latest
name: Build on macOS
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Build
run: |
clang++ -std=c++11 -g -O0 -o loader_example loader_example.cc
./loader_example models/Cube/Cube.gltf
git clone https://github.com/Tencent/rapidjson
clang++ -DTINYGLTF_USE_RAPIDJSON -I./rapidjson/include/rapidjson -std=c++11 -g -O0 -o loader_example loader_example.cc

View File

@@ -31,17 +31,6 @@ matrix:
- addons: *1 - addons: *1
compiler: clang compiler: clang
env: COMPILER_VERSION=3.9 BUILD_TYPE=Debug CFLAGS="-O0" CXXFLAGS="-O0" env: COMPILER_VERSION=3.9 BUILD_TYPE=Debug CFLAGS="-O0" CXXFLAGS="-O0"
- addons: &3
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8
compiler: gcc
env: COMPILER_VERSION=4.8 BUILD_TYPE=Debug
- addons: *3
compiler: gcc
env: COMPILER_VERSION=4.8 BUILD_TYPE=Release
before_install: before_install:
- ./.travis-before-install.sh - ./.travis-before-install.sh
@@ -54,7 +43,6 @@ script:
- ${CXX} ${EXTRA_CXXFLAGS} -std=c++11 -Wall -g -o loader_example loader_example.cc - ${CXX} ${EXTRA_CXXFLAGS} -std=c++11 -Wall -g -o loader_example loader_example.cc
- ./loader_example ./models/Cube/Cube.gltf - ./loader_example ./models/Cube/Cube.gltf
- cd tests - cd tests
- clang++ -v
- make - make
- ./tester - ./tester
- ./tester_noexcept - ./tester_noexcept

View File

@@ -4,27 +4,14 @@ PROJECT (tinygltf)
SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CXX_STANDARD 11)
option(TINYGLTF_BUILD_LOADER_EXAMPLE "Build loader_example" ON) ADD_EXECUTABLE ( loader_example
option(TINYGLTF_BUILD_GL_EXAMPLES "Build GL exampels(requires glfw, OpenGL, etc)" OFF) loader_example.cc
option(TINYGLTF_BUILD_VALIDATOR_EXAMPLE "Build validator exampe" OFF) )
if (TINYGLTF_BUILD_LOADER_EXAMPLE) ADD_SUBDIRECTORY ( examples/gltfutil )
ADD_EXECUTABLE ( loader_example ADD_SUBDIRECTORY ( examples/glview )
loader_example.cc ADD_SUBDIRECTORY ( examples/validator )
)
endif (TINYGLTF_BUILD_LOADER_EXAMPLE)
if (TINYGLTF_BUILD_GL_EXAMPLES)
ADD_SUBDIRECTORY ( examples/gltfutil )
ADD_SUBDIRECTORY ( examples/glview )
endif (TINYGLTF_BUILD_GL_EXAMPLES)
if (TINYGLTF_BUILD_VALIDATOR_EXAMPLE)
ADD_SUBDIRECTORY ( examples/validator )
endif (TINYGLTF_BUILD_VALIDATOR_EXAMPLE)
#
# TinuGLTF is a header-only library, so no library build. just install header files.
#
INSTALL ( FILES INSTALL ( FILES
json.hpp json.hpp
stb_image.h stb_image.h

25
LICENSE.tinyktx Normal file
View 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.

View File

@@ -7,8 +7,7 @@ If you are looking for old, C++03 version, please use `devel-picojson` branch.
## Status ## Status
- v2.4.0 Experimental RapidJSON support. Experimental C++14 support(C++14 may give better performance) - v2.3.0 release(Support loading KTX image through tiny_ktx)
- v2.3.0 Modified Material representation according to glTF 2.0 schema(and introduced TextureInfo class)
- 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)!
@@ -19,8 +18,6 @@ If you are looking for old, C++03 version, please use `devel-picojson` branch.
[![Build status](https://ci.appveyor.com/api/projects/status/warngenu9wjjhlm8?svg=true)](https://ci.appveyor.com/project/syoyo/tinygltf) [![Build status](https://ci.appveyor.com/api/projects/status/warngenu9wjjhlm8?svg=true)](https://ci.appveyor.com/project/syoyo/tinygltf)
![C/C++ CI](https://github.com/syoyo/tinygltf/workflows/C/C++%20CI/badge.svg)
## Features ## Features
* Written in portable C++. C++-11 with STL dependency only. * Written in portable C++. C++-11 with STL dependency only.
@@ -36,11 +33,8 @@ If you are looking for old, C++03 version, please use `devel-picojson` branch.
* Moderate parsing time and memory consumption. * Moderate parsing time and memory consumption.
* glTF specification v2.0.0 * glTF specification v2.0.0
* [x] ASCII glTF * [x] ASCII glTF
* [x] Load
* [x] Save
* [x] Binary glTF(GLB) * [x] Binary glTF(GLB)
* [x] Load * [x] PBR material description
* [x] Save(.bin embedded .glb)
* Buffers * Buffers
* [x] Parse BASE64 encoded embedded buffer data(DataURI). * [x] Parse BASE64 encoded embedded buffer data(DataURI).
* [x] Load `.bin` file. * [x] Load `.bin` file.
@@ -59,14 +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)
* [ ] Draco mesh encoding * [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
@@ -81,11 +69,6 @@ In extension(`ExtensionMap`), JSON number value is parsed as int or float(number
* GLTF loader plugin for OGRE 2.1. Support for PBR materials via HLMS/PBS https://github.com/Ybalrid/Ogre_glTF * GLTF loader plugin for OGRE 2.1. Support for PBR materials via HLMS/PBS https://github.com/Ybalrid/Ogre_glTF
* [TinyGltfImporter](http://doc.magnum.graphics/magnum/classMagnum_1_1Trade_1_1TinyGltfImporter.html) plugin for [Magnum](https://github.com/mosra/magnum), a lightweight and modular C++11/C++14 graphics middleware for games and data visualization. * [TinyGltfImporter](http://doc.magnum.graphics/magnum/classMagnum_1_1Trade_1_1TinyGltfImporter.html) plugin for [Magnum](https://github.com/mosra/magnum), a lightweight and modular C++11/C++14 graphics middleware for games and data visualization.
* [Diligent Engine](https://github.com/DiligentGraphics/DiligentEngine) - A modern cross-platform low-level graphics library and rendering framework * [Diligent Engine](https://github.com/DiligentGraphics/DiligentEngine) - A modern cross-platform low-level graphics library and rendering framework
* Lighthouse 2: a rendering framework for real-time ray tracing / path tracing experiments. https://github.com/jbikker/lighthouse2
* [QuickLook GLTF](https://github.com/toshiks/glTF-quicklook) - quicklook plugin for macos. Also SceneKit wrapper for tinygltf.
* [GlslViewer](https://github.com/patriciogonzalezvivo/glslViewer) - live GLSL coding for MacOS and Linux
* [Vulkan-Samples](https://github.com/KhronosGroup/Vulkan-Samples) - The Vulkan Samples is collection of resources to help you develop optimized Vulkan applications.
* [TDME2](https://github.com/andreasdr/tdme2) - TDME2 - ThreeDeeMiniEngine2 is a lightweight 3D engine including tools suited for 3D game development using C++11
* Your projects here! (Please send PR) * Your projects here! (Please send PR)
## TODOs ## TODOs
@@ -95,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
@@ -111,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++
@@ -162,22 +149,19 @@ 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_USE_RAPIDJSON` : Use RapidJSON as a JSON parser/serializer. RapidJSON files are not included in TinyGLTF repo. Please set an include path to RapidJSON if you enable this featrure. * `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_USE_CPP14` : Use C++14 feature(requires C++14 compiler). This may give better performance than C++11. * `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
* [ ] Buffers.
* Buffers.
* [x] To file * [x] To file
* [x] Embedded * [x] Embedded
* [ ] Draco compressed? * [ ] Draco compressed?
* [x] Images * [x] Images
* [x] To file * [x] To file
* [x] Embedded * [x] Embedded
* Binary(.glb) * [ ] Binary(.glb)
* [x] .bin embedded single .glb
* [ ] External .bin
## Running tests. ## Running tests.
@@ -205,17 +189,6 @@ $ ./tester
$ ./tester_noexcept $ ./tester_noexcept
``` ```
### Fuzzing tests ## Third party licenses used in unit tests
See `tests/fuzzer` for details.
After running fuzzer on Ryzen9 3950X a week, at least `LoadASCIIFromString` looks safe except for out-of-memory error in Fuzzer.
We may be better to introduce bounded memory size checking when parsing glTF data.
## Third party licenses
* 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.
* RapidJSON : Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. http://rapidjson.org/
* dlib(uridecode, uriencode) : Copyright (C) 2003 Davis E. King Boost Software License 1.0. http://dlib.net/dlib/server/server_http.cpp.html

View File

@@ -19,7 +19,3 @@ $ 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

@@ -8,14 +8,34 @@
#include "shaders.h" #include "shaders.h"
#include "window.h" #include "window.h"
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Weverything"
#endif
// Inlude tinyktx.h before tiny_gltf.h
// to get TKTX_*** definitions
#define TINYKTX_IMPLEMENTATION
#include "../../tinyktx.h"
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#define TINYGLTF_IMPLEMENTATION #define TINYGLTF_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION #define STB_IMAGE_WRITE_IMPLEMENTATION
#define TINYGLTF_NOEXCEPTION #define TINYGLTF_NOEXCEPTION
#define JSON_NOEXCEPTION #define JSON_NOEXCEPTION
#define TINYGLTF_ENABLE_KTX
// tinyktx.h is already included above,
// so let tiny_gltf.h know do not include tinyktx.h anymore
#define TINYGLTF_NO_INCLUDE_TINY_KTX
#include "../../tiny_gltf.h" #include "../../tiny_gltf.h"
#define BUFFER_OFFSET(i) ((char *)NULL + (i)) //#define BUFFER_OFFSET(i) ((char *)nullptr + (i))
#define BUFFER_OFFSET(i) \
(reinterpret_cast<void *>(i)) // TODO(syoyo): Is this right way?
bool loadModel(tinygltf::Model &model, const char *filename) { bool loadModel(tinygltf::Model &model, const char *filename) {
tinygltf::TinyGLTF loader; tinygltf::TinyGLTF loader;
@@ -39,6 +59,30 @@ bool loadModel(tinygltf::Model &model, const char *filename) {
return res; return res;
} }
static bool GetOpenGLFormatFromKTX(int ktx_fmt, GLint *internal_format, GLenum *format, GLenum *type) {
#if defined(TINYGLTF_ENABLE_KTX)
bool ret = true;
std::cout << "fmt = " << ktx_fmt << ", rgb8 fmt = " << TKTX_R8G8B8_UNORM << "\n";
if (ktx_fmt == TKTX_R8G8B8_UNORM) {
(*internal_format) = GL_RGB;
(*format) = GL_RGB;
(*type) = GL_UNSIGNED_BYTE;
} else {
// TODO(syoyo): Support more KTX formats.
ret = false;
}
return ret;
#else
(void)fmt;
(void)internal_format;
(void)internal_format;
return false;
#endif
}
std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos, std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos,
tinygltf::Model &model, tinygltf::Mesh &mesh) { tinygltf::Model &model, tinygltf::Mesh &mesh) {
for (size_t i = 0; i < model.bufferViews.size(); ++i) { for (size_t i = 0; i < model.bufferViews.size(); ++i) {
@@ -51,12 +95,12 @@ std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos,
https://github.com/KhronosGroup/glTF/tree/master/specification/2.0 https://github.com/KhronosGroup/glTF/tree/master/specification/2.0
... drawArrays function should be used with a count equal to ... drawArrays function should be used with a count equal to
the count property of any of the accessors referenced by the the count property of any of the accessors referenced by the
attributes property (they are all equal for a given attributes property (they are all equal for a
primitive). given primitive).
*/ */
} }
const tinygltf::Buffer &buffer = model.buffers[bufferView.buffer]; tinygltf::Buffer buffer = model.buffers[bufferView.buffer];
std::cout << "bufferview.target " << bufferView.target << std::endl; std::cout << "bufferview.target " << bufferView.target << std::endl;
GLuint vbo; GLuint vbo;
@@ -97,51 +141,69 @@ std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos,
accessor.normalized ? GL_TRUE : GL_FALSE, accessor.normalized ? GL_TRUE : GL_FALSE,
byteStride, BUFFER_OFFSET(accessor.byteOffset)); byteStride, BUFFER_OFFSET(accessor.byteOffset));
} else } else
std::cout << "vaa missing: " << attrib.first << std::endl; std::cout << "Unsupported vertex attribute: " << attrib.first << std::endl;
} }
if (model.textures.size() > 0) { GLuint texid;
// fixme: Use material's baseColor glGenTextures(1, &texid);
tinygltf::Texture &tex = model.textures[0];
if (tex.source > -1) { tinygltf::Texture &tex = model.textures[0];
tinygltf::Image &image = model.images[tex.source];
GLuint texid; glBindTexture(GL_TEXTURE_2D, texid);
glGenTextures(1, &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);
tinygltf::Image &image = model.images[tex.source]; GLint internal_format = GL_RGBA;
GLenum format = GL_RGBA;
GLenum type = GL_UNSIGNED_BYTE;
glBindTexture(GL_TEXTURE_2D, texid); bool valid = false;
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; // KTX extension
if (image.extras.Has("ktx_format")) {
if (image.component == 1) { valid = GetOpenGLFormatFromKTX(image.extras.Get("ktx_format").Get<int>(), &internal_format, &format, &type);
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 (valid) {
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, std::cout << "ktx_format: " << image.extras.Get("ktx_format").Get<int>() << std::endl;
format, type, &image.image.at(0)); std::cout << "ktx image size: " << image.width << ", " << image.height << std::endl;
} }
} else {
valid = true;
if (image.component == 1) {
format = GL_RED;
} else if (image.component == 2) {
format = GL_RG;
} else if (image.component == 3) {
format = GL_RGB;
} else if (image.component == 4) {
format = GL_RGBA;
} else {
valid = false;
}
if (image.bits == 8) {
type = GL_UNSIGNED_BYTE;
} else if (image.bits == 16) {
type = GL_UNSIGNED_SHORT;
} else {
valid = false;
}
}
if (valid) {
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, image.width, image.height, 0,
format, type, &image.image.at(0));
} }
} }
@@ -151,12 +213,8 @@ 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) {
if ((node.mesh >= 0) && (node.mesh < model.meshes.size())) { bindMesh(vbos, model, model.meshes[node.mesh]);
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]]);
} }
} }
@@ -168,7 +226,6 @@ 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]]);
} }
@@ -194,9 +251,7 @@ void drawMesh(tinygltf::Model &model, tinygltf::Mesh &mesh) {
// recursively draw node and children nodes of model // recursively draw node and children nodes of model
void drawModelNodes(tinygltf::Model &model, tinygltf::Node &node) { void drawModelNodes(tinygltf::Model &model, tinygltf::Node &node) {
if ((node.mesh >= 0) && (node.mesh < model.meshes.size())) { drawMesh(model, model.meshes[node.mesh]);
drawMesh(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++) {
drawModelNodes(model, model.nodes[node.children[i]]); drawModelNodes(model, model.nodes[node.children[i]]);
} }
@@ -328,6 +383,14 @@ static void error_callback(int error, const char *description) {
fprintf(stderr, "Error: %s\n", description); 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) { int main(int argc, char **argv) {
std::string filename = "../../models/Cube/Cube.gltf"; std::string filename = "../../models/Cube/Cube.gltf";
@@ -339,16 +402,26 @@ int main(int argc, char **argv) {
if (!glfwInit()) return -1; if (!glfwInit()) return -1;
// Force create OpenGL 3.3 // NOTE(syoyo): For some reason, Linux + NVIDIA driver + apt-installed
// NOTE(syoyo): Linux + NVIDIA driver segfaults for some reason? commenting out glfwWindowHint will work. // 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_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); #endif
// glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#ifdef __APPLE__ #ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif #endif
Window window = Window(800, 600, "TinyGLTF basic example"); Window window = Window(800, 600, "TinyGLTF basic example");
glfwSetDropCallback(window.window, drop_callback);
glfwMakeContextCurrent(window.window); glfwMakeContextCurrent(window.window);
#ifdef __APPLE__ #ifdef __APPLE__
@@ -356,10 +429,19 @@ int main(int argc, char **argv) {
glewExperimental = GL_TRUE; glewExperimental = GL_TRUE;
#endif #endif
glewInit(); if (glewInit() != GLEW_OK) {
std::cerr << "Failed to initialie glew." << std::endl;
return EXIT_FAILURE;
}
std::cout << glGetString(GL_RENDERER) << ", " << glGetString(GL_VERSION) std::cout << glGetString(GL_RENDERER) << ", " << glGetString(GL_VERSION)
<< std::endl; << 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) { if (!GLEW_VERSION_3_3) {
std::cerr << "OpenGL 3.3 is required to execute this app." << std::endl; std::cerr << "OpenGL 3.3 is required to execute this app." << std::endl;
return EXIT_FAILURE; return EXIT_FAILURE;

View File

@@ -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 }
@@ -322,15 +315,6 @@ static void DumpStringIntMap(const std::map<std::string, int> &m, int indent) {
} }
} }
static void DumpExtensions(const tinygltf::ExtensionMap &extension,
const int indent) {
// TODO(syoyo): pritty print Value
for (auto &e : extension) {
std::cout << Indent(indent) << e.first << std::endl;
std::cout << PrintValue("extensions", e.second, indent + 1) << std::endl;
}
}
static void DumpPrimitive(const tinygltf::Primitive &primitive, int indent) { static void DumpPrimitive(const tinygltf::Primitive &primitive, int indent) {
std::cout << Indent(indent) << "material : " << primitive.material std::cout << Indent(indent) << "material : " << primitive.material
<< std::endl; << std::endl;
@@ -342,80 +326,17 @@ static void DumpPrimitive(const tinygltf::Primitive &primitive, int indent) {
<< std::endl; << std::endl;
DumpStringIntMap(primitive.attributes, indent + 1); DumpStringIntMap(primitive.attributes, indent + 1);
DumpExtensions(primitive.extensions, indent);
std::cout << Indent(indent) << "extras :" << std::endl std::cout << Indent(indent) << "extras :" << std::endl
<< PrintValue("extras", primitive.extras, indent + 1) << std::endl; << PrintValue("extras", primitive.extras, indent + 1) << std::endl;
if (!primitive.extensions_json_string.empty()) {
std::cout << Indent(indent + 1) << "extensions(JSON string) = "
<< primitive.extensions_json_string << "\n";
}
if (!primitive.extras_json_string.empty()) {
std::cout << Indent(indent + 1)
<< "extras(JSON string) = " << primitive.extras_json_string
<< "\n";
}
} }
static void DumpExtensions(const tinygltf::ExtensionMap &extension,
static void DumpTextureInfo(const tinygltf::TextureInfo &texinfo, const int indent) {
const int indent) { // TODO(syoyo): pritty print Value
std::cout << Indent(indent) << "index : " << texinfo.index << "\n"; for (auto &e : extension) {
std::cout << Indent(indent) << "texCoord : TEXCOORD_" << texinfo.texCoord std::cout << Indent(indent) << e.first << std::endl;
<< "\n"; std::cout << PrintValue("extensions", e.second, indent + 1) << std::endl;
DumpExtensions(texinfo.extensions, indent + 1);
std::cout << PrintValue("extras", texinfo.extras, indent + 1) << "\n";
if (!texinfo.extensions_json_string.empty()) {
std::cout << Indent(indent)
<< "extensions(JSON string) = " << texinfo.extensions_json_string
<< "\n";
} }
if (!texinfo.extras_json_string.empty()) {
std::cout << Indent(indent)
<< "extras(JSON string) = " << texinfo.extras_json_string << "\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) {
@@ -570,21 +491,6 @@ static void Dump(const tinygltf::Model &model) {
std::cout << Indent(2) std::cout << Indent(2)
<< "target : " << PrintTarget(bufferView.target) << "target : " << PrintTarget(bufferView.target)
<< std::endl; << std::endl;
std::cout << Indent(1) << "-------------------------------------\n";
DumpExtensions(bufferView.extensions, 1);
std::cout << PrintValue("extras", bufferView.extras, 2) << std::endl;
if (!bufferView.extensions_json_string.empty()) {
std::cout << Indent(2) << "extensions(JSON string) = "
<< bufferView.extensions_json_string << "\n";
}
if (!bufferView.extras_json_string.empty()) {
std::cout << Indent(2)
<< "extras(JSON string) = " << bufferView.extras_json_string
<< "\n";
}
} }
} }
@@ -595,21 +501,6 @@ static void Dump(const tinygltf::Model &model) {
std::cout << Indent(1) << "name : " << buffer.name << std::endl; std::cout << Indent(1) << "name : " << buffer.name << std::endl;
std::cout << Indent(2) << "byteLength : " << buffer.data.size() std::cout << Indent(2) << "byteLength : " << buffer.data.size()
<< std::endl; << std::endl;
std::cout << Indent(1) << "-------------------------------------\n";
DumpExtensions(buffer.extensions, 1);
std::cout << PrintValue("extras", buffer.extras, 2) << std::endl;
if (!buffer.extensions_json_string.empty()) {
std::cout << Indent(2) << "extensions(JSON string) = "
<< buffer.extensions_json_string << "\n";
}
if (!buffer.extras_json_string.empty()) {
std::cout << Indent(2)
<< "extras(JSON string) = " << buffer.extras_json_string
<< "\n";
}
} }
} }
@@ -618,55 +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;
if (!material.extensions_json_string.empty()) {
std::cout << Indent(2) << "extensions(JSON string) = "
<< material.extensions_json_string << "\n";
}
if (!material.extras_json_string.empty()) {
std::cout << Indent(2)
<< "extras(JSON string) = " << material.extras_json_string
<< "\n";
}
} }
} }
@@ -690,18 +542,6 @@ static void Dump(const tinygltf::Model &model) {
std::cout << Indent(2) << "height : " << image.height << std::endl; std::cout << Indent(2) << "height : " << image.height << std::endl;
std::cout << Indent(2) << "component : " << image.component << std::endl; std::cout << Indent(2) << "component : " << image.component << std::endl;
DumpExtensions(image.extensions, 1); DumpExtensions(image.extensions, 1);
std::cout << PrintValue("extras", image.extras, 2) << std::endl;
if (!image.extensions_json_string.empty()) {
std::cout << Indent(2) << "extensions(JSON string) = "
<< image.extensions_json_string << "\n";
}
if (!image.extras_json_string.empty()) {
std::cout << Indent(2)
<< "extras(JSON string) = " << image.extras_json_string
<< "\n";
}
} }
} }
@@ -714,18 +554,6 @@ static void Dump(const tinygltf::Model &model) {
std::cout << Indent(1) << "source : " << texture.source std::cout << Indent(1) << "source : " << texture.source
<< std::endl; << std::endl;
DumpExtensions(texture.extensions, 1); DumpExtensions(texture.extensions, 1);
std::cout << PrintValue("extras", texture.extras, 2) << std::endl;
if (!texture.extensions_json_string.empty()) {
std::cout << Indent(2) << "extensions(JSON string) = "
<< texture.extensions_json_string << "\n";
}
if (!texture.extras_json_string.empty()) {
std::cout << Indent(2)
<< "extras(JSON string) = " << texture.extras_json_string
<< "\n";
}
} }
} }
@@ -747,20 +575,6 @@ static void Dump(const tinygltf::Model &model) {
std::cout << Indent(2) std::cout << Indent(2)
<< "wrapT : " << PrintWrapMode(sampler.wrapT) << "wrapT : " << PrintWrapMode(sampler.wrapT)
<< std::endl; << std::endl;
DumpExtensions(sampler.extensions, 1);
std::cout << PrintValue("extras", sampler.extras, 2) << std::endl;
if (!sampler.extensions_json_string.empty()) {
std::cout << Indent(2) << "extensions(JSON string) = "
<< sampler.extensions_json_string << "\n";
}
if (!sampler.extras_json_string.empty()) {
std::cout << Indent(2)
<< "extras(JSON string) = " << sampler.extras_json_string
<< "\n";
}
} }
} }
@@ -793,54 +607,6 @@ static void Dump(const tinygltf::Model &model) {
<< "znear : " << camera.orthographic.znear << "znear : " << camera.orthographic.znear
<< std::endl; << std::endl;
} }
std::cout << Indent(1) << "-------------------------------------\n";
DumpExtensions(camera.extensions, 1);
std::cout << PrintValue("extras", camera.extras, 2) << std::endl;
if (!camera.extensions_json_string.empty()) {
std::cout << Indent(2) << "extensions(JSON string) = "
<< camera.extensions_json_string << "\n";
}
if (!camera.extras_json_string.empty()) {
std::cout << Indent(2)
<< "extras(JSON string) = " << camera.extras_json_string
<< "\n";
}
}
}
{
std::cout << "skins(items=" << model.skins.size() << ")" << std::endl;
for (size_t i = 0; i < model.skins.size(); i++) {
const tinygltf::Skin &skin = model.skins[i];
std::cout << Indent(1) << "name : " << skin.name << std::endl;
std::cout << Indent(2)
<< "inverseBindMatrices : " << skin.inverseBindMatrices
<< std::endl;
std::cout << Indent(2) << "skeleton : " << skin.skeleton
<< std::endl;
std::cout << Indent(2)
<< "joints : " << PrintIntArray(skin.joints)
<< std::endl;
std::cout << Indent(1) << "-------------------------------------\n";
DumpExtensions(skin.extensions, 1);
std::cout << PrintValue("extras", skin.extras, 2) << std::endl;
if (!skin.extensions_json_string.empty()) {
std::cout << Indent(2)
<< "extensions(JSON string) = " << skin.extensions_json_string
<< "\n";
}
if (!skin.extras_json_string.empty()) {
std::cout << Indent(2)
<< "extras(JSON string) = " << skin.extras_json_string
<< "\n";
}
} }
} }
@@ -858,12 +624,6 @@ int main(int argc, char **argv) {
exit(1); exit(1);
} }
// Store original JSON string for `extras` and `extensions`
bool store_original_json_for_extras_and_extensions = false;
if (argc > 2) {
store_original_json_for_extras_and_extensions = true;
}
tinygltf::Model model; tinygltf::Model model;
tinygltf::TinyGLTF gltf_ctx; tinygltf::TinyGLTF gltf_ctx;
std::string err; std::string err;
@@ -871,9 +631,6 @@ int main(int argc, char **argv) {
std::string input_filename(argv[1]); std::string input_filename(argv[1]);
std::string ext = GetFilePathExtension(input_filename); std::string ext = GetFilePathExtension(input_filename);
gltf_ctx.SetStoreOriginalJSONForExtrasAndExtensions(
store_original_json_for_extras_and_extensions);
bool ret = false; bool ret = false;
if (ext.compare("glb") == 0) { if (ext.compare("glb") == 0) {
std::cout << "Reading binary glTF" << std::endl; std::cout << "Reading binary glTF" << std::endl;

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

193
models/Cube-KTX/Cube.gltf Normal file
View 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
}
]
}

Binary file not shown.

Binary file not shown.

12
models/Cube-KTX/README.md Normal file
View 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

View File

@@ -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

View File

@@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 B

View File

@@ -1,171 +0,0 @@
{
"asset": {
"version": "2.0"
},
"scenes": [
{
"nodes": [
0
]
}
],
"scene": 0,
"nodes": [
{
"mesh": 0
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"NORMAL": 2,
"POSITION": 1,
"TEXCOORD_0": 3
},
"indices": 0,
"mode": 4,
"material": 0
}
]
}
],
"materials": [
{
"pbrMetallicRoughness": {
"baseColorTexture": {
"index": 0,
"texCoord": 0
},
"baseColorFactor": [
1,
1,
1,
1
],
"metallicFactor": 1,
"roughnessFactor": 1
},
"emissiveFactor": [
0,
0,
0
],
"alphaMode": "OPAQUE"
}
],
"textures": [
{
"source": 0,
"sampler": 0
}
],
"samplers": [
{
"wrapS": 33071,
"wrapT": 33071
}
],
"images": [
{
"uri": " 2x2 image has multiple spaces.png"
}
],
"accessors": [
{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5121,
"count": 36,
"normalized": false,
"max": [
23
],
"min": [
0
],
"type": "SCALAR"
},
{
"bufferView": 1,
"byteOffset": 0,
"componentType": 5126,
"count": 24,
"normalized": false,
"max": [
0.5,
0.5,
0.5
],
"min": [
-0.5,
-0.5,
-0.5
],
"type": "VEC3"
},
{
"bufferView": 2,
"byteOffset": 0,
"componentType": 5126,
"count": 24,
"normalized": false,
"max": [
1,
1,
1
],
"min": [
-1,
-1,
-1
],
"type": "VEC3"
},
{
"bufferView": 3,
"byteOffset": 0,
"componentType": 5126,
"count": 24,
"normalized": false,
"max": [
1,
1
],
"min": [
0,
0
],
"type": "VEC2"
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 36
},
{
"buffer": 0,
"byteOffset": 36,
"byteLength": 288
},
{
"buffer": 0,
"byteOffset": 324,
"byteLength": 288
},
{
"buffer": 0,
"byteOffset": 612,
"byteLength": 192
}
],
"buffers": [
{
"byteLength": 804,
"uri": "CubeImageUriSpaces.bin"
}
]
}

View File

@@ -1,171 +0,0 @@
{
"asset": {
"version": "2.0"
},
"scenes": [
{
"nodes": [
0
]
}
],
"scene": 0,
"nodes": [
{
"mesh": 0
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"NORMAL": 2,
"POSITION": 1,
"TEXCOORD_0": 3
},
"indices": 0,
"mode": 4,
"material": 0
}
]
}
],
"materials": [
{
"pbrMetallicRoughness": {
"baseColorTexture": {
"index": 0,
"texCoord": 0
},
"baseColorFactor": [
1,
1,
1,
1
],
"metallicFactor": 1,
"roughnessFactor": 1
},
"emissiveFactor": [
0,
0,
0
],
"alphaMode": "OPAQUE"
}
],
"textures": [
{
"source": 0,
"sampler": 0
}
],
"samplers": [
{
"wrapS": 33071,
"wrapT": 33071
}
],
"images": [
{
"uri": "2x2 image has spaces.png"
}
],
"accessors": [
{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5121,
"count": 36,
"normalized": false,
"max": [
23
],
"min": [
0
],
"type": "SCALAR"
},
{
"bufferView": 1,
"byteOffset": 0,
"componentType": 5126,
"count": 24,
"normalized": false,
"max": [
0.5,
0.5,
0.5
],
"min": [
-0.5,
-0.5,
-0.5
],
"type": "VEC3"
},
{
"bufferView": 2,
"byteOffset": 0,
"componentType": 5126,
"count": 24,
"normalized": false,
"max": [
1,
1,
1
],
"min": [
-1,
-1,
-1
],
"type": "VEC3"
},
{
"bufferView": 3,
"byteOffset": 0,
"componentType": 5126,
"count": 24,
"normalized": false,
"max": [
1,
1
],
"min": [
0,
0
],
"type": "VEC2"
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 36
},
{
"buffer": 0,
"byteOffset": 36,
"byteLength": 288
},
{
"buffer": 0,
"byteOffset": 324,
"byteLength": 288
},
{
"buffer": 0,
"byteOffset": 612,
"byteLength": 192
}
],
"buffers": [
{
"byteLength": 804,
"uri": "CubeImageUriSpaces.bin"
}
]
}

View File

@@ -1,376 +0,0 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 8,
"max": [
0.5,
0.5,
0.5
],
"min": [
-0.5,
-0.5,
-0.5
],
"type": "VEC3"
},
{
"bufferView": 1,
"componentType": 5125,
"count": 36,
"type": "SCALAR"
}
],
"asset": {
"copyright": "NVIDIA Corporation",
"generator": "Iray glTF plugin",
"version": "2.0"
},
"bufferViews": [
{
"buffer": 0,
"byteLength": 96,
"byteStride": 12
},
{
"buffer": 0,
"byteLength": 144,
"byteOffset": 96
}
],
"buffers": [
{
"byteLength": 240,
"uri": "issue-261.bin"
}
],
"cameras": [
{
"extensions": {
"NV_Iray": {
"mip_burn_highlights": 0.699999988079071,
"mip_burn_highlights_per_component": false,
"mip_camera_shutter": 4.0,
"mip_cm2_factor": 1.0,
"mip_crush_blacks": 0.5,
"mip_f_number": 1.0,
"mip_film_iso": 100.0,
"mip_gamma": 2.200000047683716,
"mip_saturation": 1.0,
"mip_vignetting": 0.00019999999494757503,
"mip_whitepoint": [
1.0,
1.0,
1.0,
1.0
],
"tm_enable_tonemapper": true,
"tm_tonemapper": "mia_exposure_photographic"
}
},
"extras": {
"resolution": [
640,
480
]
},
"name": "default",
"perspective": {
"aspectRatio": 1.3333333730697632,
"yfov": 0.9272952079772949,
"zfar": 1000.0,
"znear": 0.1
},
"type": "perspective"
}
],
"extensions": {
"KHR_lights_punctual": {
"lights": [
{
"color": [
1.0,
1.0,
1.0
],
"intensity": 1000.0,
"name": "light",
"type": "point"
}
]
},
"NV_MDL": {
"modules": [
"mdl::base",
"mdl::nvidia::core_definitions",
"mdl::state"
],
"shaders": [
{
"definition": "mdl::base::environment_spherical(texture_2d)",
"name": "env_shd"
},
{
"arguments": {
"base_color": [
0.0055217444896698,
0.36859095096588135,
0.0041161770932376385
],
"normal=": 2
},
"definition": "mdl::nvidia::core_definitions::flex_material",
"name": "cube_instance_material"
},
{
"definition": "mdl::state::normal()",
"name": "mdl::state::normal_341"
},
{
"arguments": {
"base_color": [
0.0055217444896698,
0.36859095096588135,
0.0041161770932376385
],
"normal=": 4
},
"definition": "mdl::nvidia::core_definitions::flex_material",
"name": "cube_instance_material"
},
{
"definition": "mdl::state::normal()",
"name": "mdl::state::normal_341"
}
]
}
},
"extensionsUsed": [
"NV_MDL",
"NV_Iray",
"KHR_lights_punctual"
],
"materials": [
{
"doubleSided": true,
"extras": {
"mdl_shader": 1
},
"name": "cube_instance_material",
"pbrMetallicRoughness": {
"baseColorFactor": [
0.0055217444896698,
0.36859095096588135,
0.0041161770932376385,
1.0
]
}
}
],
"meshes": [
{
"name": "cube",
"primitives": [
{
"attributes": {
"POSITION": 0
},
"indices": 1,
"material": 0,
"mode": 4
}
]
}
],
"nodes": [
{
"camera": 0,
"extensions": {
"NV_Iray": {
"iview:fkey": -1,
"iview:fov": 53.130104064941406,
"iview:interest": [
0.1342654824256897,
-0.14356137812137604,
0.037264324724674225
],
"iview:position": [
0.9729073643684387,
1.2592438459396362,
2.4199187755584717
],
"iview:roll": 0.0,
"iview:up": [
0.0,
1.0,
0.0
]
}
},
"matrix": [
0.9432751389105357,
-1.1769874756875739e-16,
-0.3320120665176343,
0.0,
-0.16119596696756341,
0.8742297945345237,
-0.45797175303889276,
0.0,
0.290254840694694,
0.48551237507207207,
0.8246392308792816,
0.0,
0.9729073377709113,
1.2592438262175363,
2.419918748461627,
1.0
],
"name": "CamInst"
},
{
"extensions": {
"NV_Iray": {
"caustic": true,
"caustic_cast": true,
"caustic_recv": true,
"face_back": true,
"face_front": true,
"finalgather": true,
"finalgather_cast": true,
"finalgather_recv": true,
"globillum": true,
"globillum_cast": true,
"globillum_recv": true,
"material=": 3,
"pickable": true,
"reflection_cast": true,
"reflection_recv": true,
"refraction_cast": true,
"refraction_recv": true,
"shadow_cast": true,
"shadow_recv": true,
"transparency_cast": true,
"transparency_recv": true,
"visible": true
}
},
"mesh": 0,
"name": "cube_instance"
},
{
"extensions": {
"KHR_lights_punctual": {
"light": 0
},
"NV_Iray": {
"shadow_cast": true,
"visible": false
}
},
"matrix": [
0.6988062355563571,
-7.76042172309776e-17,
-0.7153110128800992,
-0.0,
-0.4276881690736487,
0.8015668284138362,
-0.41781987700564616,
-0.0,
0.57336957992379,
0.5979051928078428,
0.5601398979107212,
0.0,
2.3640632834071384,
2.465226204472449,
2.309515908392224,
1.0
],
"name": "light_inst"
}
],
"scene": 0,
"scenes": [
{
"extensions": {
"NV_Iray": {
"CP_canny_threshold1": 40,
"CP_canny_threshold2": 120,
"CP_color_quantization": 8,
"IVP_color": [
1.0,
0.0,
0.0,
1.0
],
"TM_drago_bias": 0.8500000238418579,
"TM_drago_gamma2": 2.200000047683716,
"TM_drago_saturation": 1.0,
"TM_durand_contrast": 4.0,
"TM_durand_gamma": 2.200000047683716,
"TM_durand_saturation": 1.0,
"TM_durand_sigma_color": 2.0,
"TM_durand_sigma_space": 2.0,
"TM_linear_gamma": 2.200000047683716,
"TM_reinhard_color_adapt": 0.8999999761581421,
"TM_reinhard_gamma": 1.0,
"TM_reinhard_intensity": 0.0,
"TM_reinhard_light_adapt": 1.0,
"TM_reye_Ywhite": 1000000.0,
"TM_reye_bsize": 2,
"TM_reye_bthres": 3.0,
"TM_reye_gamma": 2.200000047683716,
"TM_reye_key": 0.5,
"TM_reye_saturation": 1.0,
"TM_reye_whitebalance": [
1.0,
0.9965101480484009,
0.9805564880371094,
0.0
],
"environment_dome_depth": 200.0,
"environment_dome_height": 200.0,
"environment_dome_mode": "infinite",
"environment_dome_position": [
0.0,
0.0,
0.0
],
"environment_dome_radius": 100.0,
"environment_dome_rotation_angle": 0.0,
"environment_dome_width": 200.0,
"environment_function=": 0,
"environment_function_intensity": 1.9900000095367432,
"iray_instancing": "off",
"iview::inline_color": [
1.0,
0.0,
0.0,
1.0
],
"iview::inline_width": 1.0,
"iview::magnifier_size": 300,
"iview::offset": 10.0,
"iview::outline_color": [
0.0,
0.0,
0.0,
1.0
],
"iview::outline_width": 2.0,
"iview::overview": true,
"iview::zoom_factor": 1.0,
"samples": 4.0,
"shadow_cast": true,
"shadow_recv": true
}
},
"nodes": [
0,
1,
2
]
}
]
}

View File

@@ -1,46 +0,0 @@
# Fuzzing test
Do fuzzing test for TinyGLTF API.
## Supported API
* [x] LoadASCIIFromMemory
* [ ] LoadBinaryFromMemory
## Requirements
* meson
* clang with fuzzer support(`-fsanitize=fuzzer`. at least clang 8.0 should work)
## Setup
### Ubuntu 18.04
```
$ sudo apt install clang++-8
$ sudo apt install libfuzzer-8-dev
```
Optionally, if you didn't set `update-alternatives` you can set `clang++` to point to `clang++8`
```
$ sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-8 10
$ sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-8 10
```
## How to compile
```
$ CXX=clang++ CC=clang meson build
$ cd build
$ ninja
```
## How to run
Increase memory limit. e.g. `-rss_limit_mb=50000`
```
$ ./fuzz_gltf -rss_limit_mb=20000 -jobs 4
```

View File

@@ -1,33 +0,0 @@
#include <cstdint>
#include <cstring>
#include <memory>
#include <vector>
#include <iostream>
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#define TINYGLTF_IMPLEMENTATION
#include "tiny_gltf.h"
static void parse_intCoding4(const uint8_t *data, size_t size)
{
tinygltf::Model model;
tinygltf::TinyGLTF ctx;
std::string err;
std::string warn;
const char *str = reinterpret_cast<const char *>(data);
bool ret = ctx.LoadASCIIFromString(&model, &err, &warn, str, size, /* base_dir */"" );
(void)ret;
}
extern "C"
int LLVMFuzzerTestOneInput(std::uint8_t const* data, std::size_t size)
{
parse_intCoding4(data, size);
return 0;
}

View File

@@ -1,9 +0,0 @@
project('fuzz_tinygltf', 'cpp', default_options : ['cpp_std=c++11'])
incdirs = include_directories('../../')
executable('fuzz_gltf',
'fuzz_gltf.cc',
include_directories : incdirs,
cpp_args : '-fsanitize=address,fuzzer',
link_args : '-fsanitize=address,fuzzer' )

View File

@@ -13,14 +13,6 @@
#include <sstream> #include <sstream>
#include <fstream> #include <fstream>
static JsonDocument JsonConstruct(const char* str)
{
JsonDocument doc;
JsonParse(doc, str, strlen(str));
return doc;
}
TEST_CASE("parse-error", "[parse]") { TEST_CASE("parse-error", "[parse]") {
tinygltf::Model model; tinygltf::Model model;
@@ -28,7 +20,7 @@ TEST_CASE("parse-error", "[parse]") {
std::string err; std::string err;
std::string warn; std::string warn;
bool ret = ctx.LoadASCIIFromString(&model, &err, &warn, "bora", static_cast<int>(strlen("bora")), /* basedir*/ ""); bool ret = ctx.LoadASCIIFromString(&model, &err, &warn, "bora", strlen("bora"), /* basedir*/ "");
REQUIRE(false == ret); REQUIRE(false == ret);
@@ -93,59 +85,6 @@ TEST_CASE("extension-with-empty-object", "[issue-97]") {
} }
TEST_CASE("extension-overwrite", "[issue-261]") {
tinygltf::Model model;
tinygltf::TinyGLTF ctx;
std::string err;
std::string warn;
bool ret = ctx.LoadASCIIFromFile(&model, &err, &warn, "../models/Extensions-overwrite-issue261/issue-261.gltf");
if (!err.empty()) {
std::cerr << err << std::endl;
}
REQUIRE(true == ret);
REQUIRE(model.extensionsUsed.size() == 3);
{
bool has_ext_lights = false;
has_ext_lights |= (model.extensionsUsed[0].compare("KHR_lights_punctual") == 0);
has_ext_lights |= (model.extensionsUsed[1].compare("KHR_lights_punctual") == 0);
has_ext_lights |= (model.extensionsUsed[2].compare("KHR_lights_punctual") == 0);
REQUIRE(true == has_ext_lights);
}
{
REQUIRE(model.extensions.size() == 2);
REQUIRE(model.extensions.count("NV_MDL"));
REQUIRE(model.extensions.count("KHR_lights_punctual"));
}
// TODO(syoyo): create temp directory.
{
ret = ctx.WriteGltfSceneToFile(&model, "issue-261.gltf", true, true);
REQUIRE(true == ret);
tinygltf::Model m;
// read back serialized glTF
bool ret = ctx.LoadASCIIFromFile(&m, &err, &warn, "issue-261.gltf");
if (!err.empty()) {
std::cerr << err << std::endl;
}
REQUIRE(true == ret);
REQUIRE(m.extensionsUsed.size() == 3);
REQUIRE(m.extensions.size() == 2);
REQUIRE(m.extensions.count("NV_MDL"));
REQUIRE(m.extensions.count("KHR_lights_punctual"));
}
}
TEST_CASE("invalid-primitive-indices", "[bounds-checking]") { TEST_CASE("invalid-primitive-indices", "[bounds-checking]") {
tinygltf::Model model; tinygltf::Model model;
tinygltf::TinyGLTF ctx; tinygltf::TinyGLTF ctx;
@@ -228,12 +167,12 @@ TEST_CASE("parse-integer", "[bounds-checking]") {
SECTION("parses valid numbers") { SECTION("parses valid numbers") {
std::string err; std::string err;
int result = 123; int result = 123;
CHECK(tinygltf::ParseIntegerProperty(&result, &err, JsonConstruct("{\"zero\" : 0}"), "zero", CHECK(tinygltf::ParseIntegerProperty(&result, &err, {{"zero", 0}}, "zero",
true)); true));
REQUIRE(err == ""); REQUIRE(err == "");
REQUIRE(result == 0); REQUIRE(result == 0);
CHECK(tinygltf::ParseIntegerProperty(&result, &err, JsonConstruct("{\"int\": -1234}"), "int", CHECK(tinygltf::ParseIntegerProperty(&result, &err, {{"int", -1234}}, "int",
true)); true));
REQUIRE(err == ""); REQUIRE(err == "");
REQUIRE(result == -1234); REQUIRE(result == -1234);
@@ -242,7 +181,7 @@ TEST_CASE("parse-integer", "[bounds-checking]") {
SECTION("detects missing properties") { SECTION("detects missing properties") {
std::string err; std::string err;
int result = -1; int result = -1;
CHECK_FALSE(tinygltf::ParseIntegerProperty(&result, &err, JsonConstruct(""), "int", true)); CHECK_FALSE(tinygltf::ParseIntegerProperty(&result, &err, {}, "int", true));
REQUIRE_THAT(err, Catch::Contains("'int' property is missing")); REQUIRE_THAT(err, Catch::Contains("'int' property is missing"));
REQUIRE(result == -1); REQUIRE(result == -1);
} }
@@ -251,7 +190,7 @@ TEST_CASE("parse-integer", "[bounds-checking]") {
std::string err; std::string err;
int result = -1; int result = -1;
CHECK_FALSE( CHECK_FALSE(
tinygltf::ParseIntegerProperty(&result, &err, JsonConstruct(""), "int", false)); tinygltf::ParseIntegerProperty(&result, &err, {}, "int", false));
REQUIRE(err == ""); REQUIRE(err == "");
REQUIRE(result == -1); REQUIRE(result == -1);
} }
@@ -260,26 +199,21 @@ TEST_CASE("parse-integer", "[bounds-checking]") {
std::string err; std::string err;
int result = -1; int result = -1;
CHECK_FALSE(tinygltf::ParseIntegerProperty(&result, &err, JsonConstruct("{\"int\": 0.5}"), CHECK_FALSE(tinygltf::ParseIntegerProperty(&result, &err, {{"int", 0.5}},
"int", true)); "int", true));
REQUIRE_THAT(err, Catch::Contains("not an integer type")); REQUIRE_THAT(err, Catch::Contains("not an integer type"));
// Excessively large values and NaN aren't allowed either. // Excessively large values and NaN aren't allowed either.
err.clear(); err.clear();
CHECK_FALSE(tinygltf::ParseIntegerProperty(&result, &err, JsonConstruct("{\"int\": 1e300}"), CHECK_FALSE(tinygltf::ParseIntegerProperty(&result, &err, {{"int", 1e300}},
"int", true)); "int", true));
REQUIRE_THAT(err, Catch::Contains("not an integer type")); REQUIRE_THAT(err, Catch::Contains("not an integer type"));
err.clear(); err.clear();
{ CHECK_FALSE(tinygltf::ParseIntegerProperty(
JsonDocument o; &result, &err, {{"int", std::numeric_limits<double>::quiet_NaN()}},
double nan = std::numeric_limits<double>::quiet_NaN();
tinygltf::JsonAddMember(o, "int", json(nan));
CHECK_FALSE(tinygltf::ParseIntegerProperty(
&result, &err, o,
"int", true)); "int", true));
REQUIRE_THAT(err, Catch::Contains("not an integer type")); REQUIRE_THAT(err, Catch::Contains("not an integer type"));
}
} }
} }
@@ -287,7 +221,7 @@ TEST_CASE("parse-unsigned", "[bounds-checking]") {
SECTION("parses valid unsigned integers") { SECTION("parses valid unsigned integers") {
// Use string-based parsing here, using the initializer list syntax doesn't // Use string-based parsing here, using the initializer list syntax doesn't
// parse 0 as unsigned. // parse 0 as unsigned.
auto zero_obj = JsonConstruct("{\"zero\": 0}"); json zero_obj = json::parse("{\"zero\": 0}");
std::string err; std::string err;
size_t result = 123; size_t result = 123;
@@ -301,31 +235,26 @@ TEST_CASE("parse-unsigned", "[bounds-checking]") {
std::string err; std::string err;
size_t result = -1; size_t result = -1;
CHECK_FALSE(tinygltf::ParseUnsignedProperty(&result, &err, JsonConstruct("{\"int\": -1234}"), CHECK_FALSE(tinygltf::ParseUnsignedProperty(&result, &err, {{"int", -1234}},
"int", true)); "int", true));
REQUIRE_THAT(err, Catch::Contains("not a positive integer")); REQUIRE_THAT(err, Catch::Contains("not a positive integer"));
err.clear(); err.clear();
CHECK_FALSE(tinygltf::ParseUnsignedProperty(&result, &err, JsonConstruct("{\"int\": 0.5}"), CHECK_FALSE(tinygltf::ParseUnsignedProperty(&result, &err, {{"int", 0.5}},
"int", true)); "int", true));
REQUIRE_THAT(err, Catch::Contains("not a positive integer")); REQUIRE_THAT(err, Catch::Contains("not a positive integer"));
// Excessively large values and NaN aren't allowed either. // Excessively large values and NaN aren't allowed either.
err.clear(); err.clear();
CHECK_FALSE(tinygltf::ParseUnsignedProperty(&result, &err, JsonConstruct("{\"int\": 1e300}"), CHECK_FALSE(tinygltf::ParseUnsignedProperty(&result, &err, {{"int", 1e300}},
"int", true)); "int", true));
REQUIRE_THAT(err, Catch::Contains("not a positive integer")); REQUIRE_THAT(err, Catch::Contains("not a positive integer"));
err.clear(); err.clear();
{ CHECK_FALSE(tinygltf::ParseUnsignedProperty(
JsonDocument o; &result, &err, {{"int", std::numeric_limits<double>::quiet_NaN()}},
double nan = std::numeric_limits<double>::quiet_NaN();
tinygltf::JsonAddMember(o, "int", json(nan));
CHECK_FALSE(tinygltf::ParseUnsignedProperty(
&result, &err, o,
"int", true)); "int", true));
REQUIRE_THAT(err, Catch::Contains("not a positive integer")); REQUIRE_THAT(err, Catch::Contains("not a positive integer"));
}
} }
} }
@@ -334,7 +263,7 @@ TEST_CASE("parse-integer-array", "[bounds-checking]") {
std::string err; std::string err;
std::vector<int> result; std::vector<int> result;
CHECK(tinygltf::ParseIntegerArrayProperty(&result, &err, CHECK(tinygltf::ParseIntegerArrayProperty(&result, &err,
JsonConstruct("{\"x\": [-1, 2, 3]}"), "x", true)); {{"x", {-1, 2, 3}}}, "x", true));
REQUIRE(err == ""); REQUIRE(err == "");
REQUIRE(result.size() == 3); REQUIRE(result.size() == 3);
REQUIRE(result[0] == -1); REQUIRE(result[0] == -1);
@@ -346,69 +275,7 @@ TEST_CASE("parse-integer-array", "[bounds-checking]") {
std::string err; std::string err;
std::vector<int> result; std::vector<int> result;
CHECK_FALSE(tinygltf::ParseIntegerArrayProperty( CHECK_FALSE(tinygltf::ParseIntegerArrayProperty(
&result, &err, JsonConstruct("{\"x\": [-1, 1e300, 3]}"), "x", true)); &result, &err, {{"x", {-1, 1e300, 3}}}, "x", true));
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));
}
TEST_CASE("image-uri-spaces", "[issue-236]") {
tinygltf::Model model;
tinygltf::TinyGLTF ctx;
std::string err;
std::string warn;
// Test image file with single spaces.
bool ret = ctx.LoadASCIIFromFile(&model, &err, &warn, "../models/CubeImageUriSpaces/CubeImageUriSpaces.gltf");
if (!err.empty()) {
std::cerr << err << std::endl;
}
REQUIRE(true == ret);
// Test image file with a beginning space, trailing space, and greater than
// one consecutive spaces.
ret = ctx.LoadASCIIFromFile(&model, &err, &warn, "../models/CubeImageUriSpaces/CubeImageUriMultipleSpaces.gltf");
if (!err.empty()) {
std::cerr << err << std::endl;
}
REQUIRE(true == ret);
}

File diff suppressed because it is too large Load Diff

1600
tinyktx.h Normal file

File diff suppressed because it is too large Load Diff