Compare commits

...
365 Commits
Author SHA1 Message Date
Syoyo Fujita 147a00a601 Prevent duplicated key generation when serializing lights + RapidJSON backend. Fixes #420 2023-06-04 05:45:24 +09:00
Syoyo Fujita 350c296802 Merge pull request #418 from agnat/fix_get_file_size_bug
[Bugfix] Actually invoke the user-supplied function instead of subtracting from a pointer...
2023-04-26 19:28:58 +09:00
David Siegel cc93e1fd25 Fix: Actually invoke the user-supplied function 2023-04-26 12:13:41 +02:00
Syoyo Fujita 59cc44ad4f Merge pull request #417 from syoyo/filesize-check
Fix to #416
2023-04-23 23:15:07 +09:00
Syoyo Fujita 1a5046e06b Fix MSVC compile failure on AppVeyor CI. 2023-04-23 23:08:41 +09:00
Syoyo Fujita 877d856e71 Format error message.
Add regression test of issue-416.
2023-04-23 21:47:31 +09:00
Syoyo Fujita b534b6b0d8 Fix syntax. 2023-04-23 21:40:23 +09:00
Syoyo Fujita ecfd37dee2 - Add GetFileSizeInBytes Filesystem Callback
- Add feature to limit file size for external resources(images, buffers)
- Use strlen to correctly retrieve a string from a string which contains multiple null-characters.
- Return fail when opening a directory(Posix only). Fixes #416
2023-04-23 21:31:30 +09:00
Syoyo Fujita 5c06b7d03b Merge pull request #415 from louwaque/release
Fix serialization of AnimationChannel::target_node when it is zero
2023-04-19 05:17:06 +09:00
Loïc Escales a75355b018 Fix serialization of AnimationChannel::target_node when it is zero 2023-04-18 21:03:39 +02:00
Syoyo Fujita a977f7a16f Merge pull request #412 from agnat/add_char_pointer_ctor
Fix #411 by adding a Value(const char *) constructor.
2023-04-10 19:11:35 +09:00
Syoyo Fujita 5a6c55870e Deprecate ubuntu-18.04 image and update CI build configuration. 2023-04-10 18:51:29 +09:00
David Siegel 49caa65177 Fix #411 by adding a Value(const char *) constructor.
Avoid implicit conversion of pointers to bool. Closes #411.
2023-04-08 23:44:53 +02:00
Syoyo Fujita d71c6f61f3 Merge pull request #409 from NeilBickford-NV/nbickford/update-stb-image
Updates stb_image and stb_image_write
2023-03-30 18:13:12 +09:00
Neil Bickford b5d27fd151 stb_image: Apply https://github.com/nothings/stb/pull/1443 2023-03-29 12:00:24 -07:00
Neil Bickford af4456ba68 stb_image: Apply https://github.com/nothings/stb/pull/1454 2023-03-29 11:57:27 -07:00
Neil Bickford 344669ddf6 Update stb_image and stb_image_write to latest nothings/stb dev branch: https://github.com/nothings/stb/commit/9f1776a36d2a3d63c52f705c3a84b372cfed4340 2023-03-29 11:56:13 -07:00
Syoyo Fujita 967c98dd90 Merge pull request #408 from marco-langer/feature/ostream_error_handling
Added error checking to ostream writing
2023-03-13 21:18:02 +09:00
Marco Langer 7658624bb4 Added error handling to ostream writing 2023-03-12 19:26:05 +01:00
Syoyo Fujita 84a83d39f5 Merge pull request #407 from DavidSM64/release
Added detail namespace to prevent json namespace conflicts
2023-02-19 02:08:19 +09:00
David 03ad33cc8d Fixed global namespace issue 2023-02-15 23:35:51 -06:00
David 3831802717 Fix RapidJSON implementation (hopefully) 2023-02-15 23:21:09 -06:00
David 1f9a4b97a3 Added detail namespace to prevent namespace conflicts 2023-02-15 22:56:18 -06:00
Syoyo Fujita 6dba104c54 Merge pull request #405 from tioez326/patch-2
Fix typo
2023-02-10 21:00:27 +09:00
tioez326 b5e1b35ef1 Fix typo 2023-02-10 12:09:12 +01:00
Syoyo Fujita 52b73c7f0b Update README.md 2023-01-16 05:46:11 +09:00
Syoyo Fujita 98adbb3fb3 Merge pull request #401 from jmousseau/animation-channel-node-optionality
Fix animation channel target node optionality
2023-01-16 05:33:40 +09:00
Jack Mousseau 283b552a4e Fix animation channel target node optionality 2023-01-15 11:45:45 -08:00
Syoyo Fujita c2ca97b38b v2.8.1 2023-01-13 18:15:21 +09:00
Syoyo Fujita f051892c55 Merge pull request #399 from e2e4e6/texture_sampler_name_fix
Missed serialization texture sampler name fixed.
2023-01-13 18:13:12 +09:00
s00665032 137a7ca999 Missed serialization texture sampler name fixed.
According to the glTF 2.0 specification it exists, the internal tinygltf structure contains 'name' field as well.
2023-01-13 12:52:08 +07:00
Syoyo Fujita 477d977fea Merge pull request #398 from nicolas-raoul/patch-1
Fixed typo
2023-01-12 16:21:35 +09:00
Nicolas Raoul 8cd5e759d0 Fixed typo 2023-01-12 15:29:32 +09:00
Syoyo Fujita a6c3945ed3 Bump version 2.8.0. 2023-01-10 20:42:24 +09:00
Syoyo Fujita 6614bddef3 Merge pull request #397 from pknowlesnv/encode_image_uri
urlencode image urls
2023-01-10 20:31:39 +09:00
Pyarelal Knowles 385946dfd8 add URI encode/decode API
Tinygltf is able to write files defined by a URI, so it needs to be able
to decode it. Since it may also modify the path where the image is saved
it may need to re-encode the URI too. This patch provides an API to set
URI encoding and decoding callbacks and exposes the default decode
method.

Uses the existing dlib::urldecode as a decode default. The encode
callback is left null, matching existing behaviour.

Updates the WriteImageDataFunction signature to include
tinygltf::URICallbacks.

Decodes the image and buffer uris before using them as a filename.

If the encode callback is set, encodes the written image location in the
default WriteImageDataFunction and encodes generated buffer locations
when writing .bin files.

Adds a save+load step to the test image-uri-spaces to verify uri
encoding.
2023-01-09 20:54:29 -08:00
Syoyo Fujita 03bbe0921c Merge pull request #396 from pknowlesnv/image_write_failure
propagate image writing failures
2022-12-30 17:59:41 +09:00
Pyarelal Knowles a9121550b9 SerializeGltfImage: add missing & std::string ref
Hopefully the compiler would optimize this away but better to avoid the
copy in the first place.
2022-12-29 14:12:29 -08:00
Pyarelal Knowles d2b0af6915 propagate image writing failures
Modifies UpdateImageObject() so that Returning false from the
WriteImageDataFunction callback results in the WriteGltfScene*() call
returning false.

Does not call WriteImageDataFunction if there is no image data.

Adds test case serialize-image-failure to verify the callback return
code is able to cause an overall failure to save the gltf.
2022-12-29 13:50:17 -08:00
Syoyo Fujita 695608dd11 Update readme. 2022-12-29 21:50:47 +09:00
Syoyo Fujita 584f1dfbe4 Merge branch 'release' of github.com:syoyo/tinygltf into release 2022-12-29 21:13:48 +09:00
Syoyo Fujita a40ca4c5ab Merge pull request #393 from pknowlesnv/serialize_const
allow serializing a const Model
2022-12-29 21:00:24 +09:00
Pyarelal Knowles de75d87cfd allow serializing a const Model
Adds 'const' to all Serialize*() methods.

Updates WriteImageData callback to take a URI out pointer that was
previously being written to the Image::uri, which is now const.

This breaks the WriteImageData API and as a side effect, Image::uri will
no longer contain the written image URI after saving.

Adds test serialize-const-image, which verifies the model's image is not
changed (because it's const), but the uri written to the gltf json is
still correct.

Adds test serialize-image-callback that defines a WriteImageDataFunction
and also verifies the uri can be overwritten.
2022-12-28 17:20:09 -08:00
Syoyo Fujita cf11842e64 Merge pull request #395 from ethanpepro/cmake-export
Add CMake export configuration
2022-12-28 18:33:36 +09:00
James Luke 38003032e3 Add CMake export configuration 2022-12-27 21:12:54 -05:00
Syoyo Fujita 186016bf11 Merge branch 'release' of github.com:syoyo/tinygltf into release 2022-12-03 19:42:27 +09:00
Syoyo Fujita 5ee08f9274 Remove Python 2 description. 2022-12-03 19:40:50 +09:00
Syoyo Fujita aa613a1f57 Update README.md
Remove Python 2.x description
2022-12-03 19:40:45 +09:00
Syoyo Fujita 222454cc6d Create FUNDING.yml 2022-12-03 18:33:05 +09:00
Syoyo Fujita 16c2d3a8bf Merge pull request #390 from eduardodoria/patch-1
Added Supernova Engine to Projects using TinyGLTF
2022-11-07 21:18:50 +09:00
Eduardo Doria 186093657a Added Supernova Engine to Projects using TinyGLTF 2022-11-07 08:53:47 -03:00
Syoyo Fujita 9bdd256625 Merge pull request #388 from stromaster/patch-1
Avoid multiple asset_manager definitions on Android
2022-10-31 17:40:40 +09:00
Serdar Kocdemir 264ae4c131 Avoid multiple asset_manager definition on Android
Using TINYGLTF_IMPLEMENTATION to make the actual definition of the 'asset_manager' global variable.
2022-10-30 22:32:59 +00:00
Syoyo Fujita 091a1fcc1a Merge pull request #386 from geometrian/master
Fix Clang Compile Warnings/Errors (and Typos)
2022-10-08 19:08:22 +09:00
imallett 3a295887d6 Patch to fix previous commit for MinGW. 2022-10-07 11:20:39 -07:00
imallett d9ce9eb9d2 Fix a gazillion typos. 2022-10-07 10:37:09 -07:00
imallett 56e1098993 Fix various type mismatches and header include case (fixes compile warnings on Clang). 2022-10-07 10:35:16 -07:00
Syoyo Fujita 9bb5806df4 Merge pull request #385 from operatios/master
Fix UTF-8 filepath on LLVM MinGW
2022-09-25 05:35:36 +09:00
operatios 1668d1ecc5 Fix UTF-8 filepath on LLVM MinGW 2022-09-24 22:37:14 +03:00
Syoyo Fujita 6e8a858c45 Add WASI build procedure. 2022-09-22 04:36:58 +09:00
Syoyo Fujita e0b625561c v2.6.3 2022-09-19 03:36:58 +09:00
Syoyo Fujita 18450eafe7 Merge pull request #382 from syoyo/glb-zero-chunk
Fix parsing GLB file with empty Chunk1(BIN data).
2022-09-19 03:34:09 +09:00
Syoyo Fujita e9fbc03e2d Clear error/warn message. 2022-09-19 03:29:57 +09:00
Syoyo Fujita 612e57816f Fix handling <4 byte BIN data.
Fix handling GLB file with empty CHUNK1(BIN).
2022-09-18 21:01:39 +09:00
Kh4n a778c089d1 readd toplevel makefile 2022-09-17 15:39:28 -05:00
Kh4n 387fd61b83 update test to match gltf-validator 2022-09-17 13:02:39 -05:00
Kh4n 6514490090 update gitignore to remove test file
readd accidental removals in gitignore

undo autoformat

more undo autoformatting
2022-09-17 12:52:59 -05:00
Kh4n 6b7ec9f494 added tests to cover empty, empty buffer, and single byte buffer cases 2022-09-17 12:28:39 -05:00
Syoyo Fujita c670f08a3b Fix parsing GLB file with empty Chunk1(BIN data). 2022-09-17 19:52:25 +09:00
Syoyo Fujita eec4c98862 Add note on v2.6.2(Fix out-of-bounds access of accessors. PR#379) 2022-09-16 17:27:20 +09:00
Syoyo Fujita c7e911cf11 Merge pull request #380 from AlvaroBarua/master
Fixes compiler warning on VS (Unreachable code detected)
2022-09-11 17:56:55 +09:00
AlvaroBarua 43172238f7 Fixes compiler warning on VS (Unreachable code detected) 2022-09-11 00:41:43 +01:00
Syoyo Fujita 0cc23356dc Merge pull request #379 from nirmal/patch-1
Fix possible out of bounds index in LoadFromString
2022-09-07 01:52:55 +09:00
Nirmal Patel e413216722 Fix possible out of bounds index in LoadFromString 2022-09-06 09:16:31 -07:00
Syoyo Fujita 4581d37bec v2.6.1 2022-09-06 22:02:31 +09:00
Syoyo Fujita 966a9d0df7 Merge pull request #374 from syoyo/glb_chunk_check
Better GLB data size check when reading.
2022-09-06 21:35:47 +09:00
Syoyo Fujita 64452bb5fa Merge pull request #377 from zbendefy/master
Auto detect C++14 standard version
2022-09-06 14:01:26 +09:00
zbendefy 69eeea145b Auto detect C++14 standard version 2022-09-05 23:54:57 +02:00
Syoyo Fujita 24e539621d Merge pull request #376 from kacprzak/master
Read from moved object
2022-09-03 01:16:41 +09:00
Marcin Kacprzak f4f5c3cf3a Fix read from moved object. 2022-09-02 16:15:54 +02:00
Marcin Kacprzak b12a54ed15 Silence MS code analysis tool. 2022-09-02 16:13:11 +02:00
Syoyo Fujita 240d993f94 Create codeql-analysis.yml 2022-09-02 05:09:09 +09:00
Syoyo Fujita 46ee8b4276 GLB: Fix interger-overflow when calculating JSON Chunk size.
GLB: Check BIN Chunk size.
GLB: Chenk byte alignment of each chunk.
2022-08-26 22:06:53 +09:00
Syoyo Fujita 3bddc09af4 Update README. 2022-08-19 18:21:24 +09:00
Syoyo Fujita 9117abb45d Merge branch 'master' of github.com:syoyo/tinygltf 2022-08-16 20:11:52 +09:00
Syoyo Fujita 52ff00a384 Do not expand file path since its not necessary for glTF asset path(URI) and for security reason(wordexp). 2022-08-16 20:08:45 +09:00
Syoyo Fujita 0fa56e239c Merge pull request #367 from fynv/master
Sparse accessor: typo fix
2022-08-14 20:54:01 +09:00
Fei Yang 5c2dd83964 Merge branch 'syoyo:master' into master 2022-08-14 19:50:14 +08:00
feiy 1a8814d687 Sparse accessor serialization: typo fix. 2022-08-14 19:49:07 +08:00
Syoyo Fujita 666ab8661c Merge pull request #366 from fynv/master
Adding serialization code for sparse accessors.
2022-08-13 18:34:24 +09:00
feiy 0b31543098 Adding serialization code for sparse accessors. 2022-08-13 10:08:17 +08:00
Syoyo Fujita 81f7dbe53a Partial fix of issue 365 2022-08-02 01:05:34 +09:00
Syoyo Fujita 544969b732 Check the failure of RapidJson Accept(). Fixes #332
TODO: Better error reporting when Accept() failed.
2022-07-13 19:03:33 +09:00
Syoyo Fujita 3d4150419e Merge pull request #362 from hschwane/master
fix images not beeing embeded into stream
2022-06-29 20:16:35 +09:00
Hendrik Schwanekamp 41e1102e57 fix images not beeing embeded into stream 2022-06-29 12:22:40 +02:00
Syoyo Fujita b901dd62d8 Merge pull request #357 from eariassoto/fix-basic-example
Fix basic example
2022-05-15 20:06:17 +09:00
Syoyo Fujita bc03ceaac1 Merge pull request #358 from brlcad/patch-2
treat powerpc as big endian too
2022-05-15 20:02:28 +09:00
Christopher Sean Morrison 2c9b25642b treat powerpc as big endian too
added powerpc to the list of big endian types
2022-05-14 19:00:19 -04:00
Emmanuel Arias Soto a894904f11 Fix basic example
Context: When parsing a mesh with primitives that have indices pointing to different buffer views, the VAO will use the last GL_ELEMENT_ARRAY_BUFFER that was bound to it. In this scenario, the mesh will not be rendered properly.

When binding a mesh, return VAO and EBOs so that primitives can bind to the proper element array buffer.
2022-05-14 19:54:03 +02:00
Syoyo Fujita 912856823d Add Open3D to "projects using TinyGLTF". 2022-05-07 01:35:14 +09:00
Syoyo Fujita 1a7c7d2001 Merge pull request #353 from mgerhardy/master
Fixed find_last_of call in GetBaseFilename
2022-03-14 14:50:32 +09:00
Martin Gerhardy fae6543b7a Fixed find_last_of call in GetBaseFilename
this leads to a stack overflow on linux - it looks like this magically works on msvc though...
2022-03-13 18:42:39 +01:00
Syoyo Fujita 6ed7c39d71 Add note on componentType double type. 2022-03-03 16:40:54 +09:00
Syoyo Fujita 5a90ab76ee Merge pull request #350 from tsmaster/master
Examples/glview - apply translation, rotation, scale in that order
2022-03-03 03:16:29 +09:00
Dave LeCompte 0ffdc4334a Examples/glview - apply translation, rotation, scale in that order
Tested on the Kenney.nl CarKit models: https://www.kenney.nl/assets/car-kit
2022-03-02 07:01:34 -08:00
Syoyo Fujita 53338352f2 Merge pull request #349 from tsmaster/master
Fix examples/glview rotations
2022-03-02 02:55:15 +09:00
Dave LeCompte d642c80a86 Fix examples/glview rotations
GLtf defines rotations as quaternions, glRotated expects angle/axis, with angle in degrees.
2022-03-01 08:11:22 -08:00
Syoyo Fujita a1952053ee Merge pull request #347 from syoyo/jmousseau-sparse-accessor-optionality
Jmousseau sparse accessor optionality
2022-02-26 21:27:35 +09:00
Syoyo Fujita cbd3885049 Check required attribute exists for SparseAccessor. 2022-02-26 21:19:15 +09:00
Jack Mousseau 9471517c1e Fix byte offset optionality for sparse accessor indices and values 2022-02-24 14:25:37 -08:00
Syoyo Fujita e59028d68f Merge pull request #345 from syoyo/github-actions-ci-fix
GitHub actions ci fix
2022-02-25 02:07:46 +09:00
Syoyo Fujita cfab524125 VS2019 seems gone. Use VS2022. 2022-02-25 01:39:02 +09:00
Syoyo Fujita 9229971bcb Print cmake help 2022-02-25 01:25:15 +09:00
Syoyo Fujita 051149311c Specify x64 for MSVC build. 2022-02-25 01:11:51 +09:00
Syoyo Fujita 0c7789b1e5 Merge pull request #344 from epajarre/fix-wrapS
Added missing comparison for wrapS
2022-02-24 21:52:43 +09:00
Eero Pajarre 51b12d2546 Added missing comparison for wrapS 2022-02-24 14:38:20 +02:00
Syoyo Fujita 4749b0989d Merge pull request #342 from brlcad/patch-1
add missing switch case for binary
2022-02-24 03:34:58 +09:00
Christopher Sean Morrison 0bfcb4f49e add missing switch case for binary
with warnings cranked up and warnings-as-errors enabled, the compiler throws an error due to this switch missing a case for binary.  this makes the ignore explicit in order for compilation to proceed.
2022-02-23 10:02:49 -05:00
Syoyo Fujita 17e6e310ce Merge pull request #341 from mushrom/loopfix
Fixing loop index
2022-02-14 17:10:31 +09:00
My Name 07ceb4c313 Fixing loop index 2022-02-13 16:31:27 -05:00
Syoyo Fujita e7f1ff5c59 Merge pull request #339 from yslking/yslking-update-json-hpp-3-10-4
update json.hpp to v3.10.4 to compile with c++20 compilers
2021-11-28 22:25:34 +09:00
yslking fd904063c9 update json.hpp to v3.10.4 2021-11-28 15:08:05 +08:00
Syoyo Fujita 38398cc2da Fix typo from PR #320 2021-11-21 18:59:10 +09:00
Syoyo Fujita ed1a294bc4 Merge branch 'master' of github.com:syoyo/tinygltf 2021-11-21 18:58:39 +09:00
Syoyo Fujita b86eb6c079 Merge pull request #331 from abwood/so-updates
Remove stackoverflow references from tinygltf.
2021-10-19 21:45:19 +09:00
Alexander Wood e4bc6c7bd4 - Remove clang warning suppression. I assume this stackoverflow reference can just be removed as it isn't a code snippet but a repost of clang documentation of ignoring warning levels.
- Remove stackoverflow reference that recommends the use of dlib. There's no source that was pulled from this s.o. post, only a recommendation on a library, I wouldn't think a link to s.o. is necessary here. Per the Boost License, I've included a copy of the license along with the snippet
2021-10-14 08:54:59 -04:00
Alexander Wood 13803659f8 Build fix. 2021-10-08 20:13:07 -04:00
Alexander Wood a3d5d5d1c9 Build fix. 2021-10-08 20:09:08 -04:00
Alexander Wood 9e3d1f6db5 Build fix. 2021-10-08 16:57:56 -04:00
Alexander Wood 190382aecd GetBaseFilename contained a logic error in that a filename that does not contain a path separator would result in a crash.
Removed the roundUp lambda, as this generalization is not necessary; the caller always attempts 4 byte alignment.
2021-10-08 12:19:13 -04:00
Syoyo Fujita c6501530e3 Merge branch 'master' of github.com:syoyo/tinygltf 2021-09-24 17:11:07 +09:00
Syoyo Fujita ed48224f4b Describe current status(its stable) 2021-09-24 17:10:29 +09:00
Syoyo Fujita 19a41d20ec Merge pull request #330 from cgdae/master
Fix for OpenBSD - wordexp.h not available.
2021-08-25 20:25:03 +09:00
Julian Smith 0598a20cce Fix for OpenBSD - wordexp.h not available. 2021-08-25 12:06:08 +01:00
Syoyo Fujita 514167b475 Merge pull request #329 from syoyo/cmake-add-subdirectory
Cmake add subdirectory
2021-07-03 22:09:26 +09:00
Syoyo Fujita 0f76561ebf Add readme to use tinygtf through cmake + add_subdirectory. 2021-07-03 22:06:29 +09:00
Syoyo Fujita f3dc4acaa4 Merge branch 'master' into cmake-add-subdirectory 2021-07-03 22:01:46 +09:00
Syoyo Fujita 1588e75e26 Merge branch 'master' of github.com:syoyo/tinygltf 2021-06-09 21:23:57 +09:00
Syoyo Fujita d1453b5e5e GLEW_LIBRARY -> GLEW_LIBRARIES 2021-06-09 21:23:37 +09:00
Syoyo Fujita 7e83ef9fb4 Merge pull request #327 from CppProgrammer23/master
update enum Type
2021-05-20 20:44:16 +09:00
Idriss Chaouch 425195bf9c update enum Type
the first element in an enum is 0, so it's not necessarily to affect values from 0 to 7.
2021-05-20 12:11:00 +01:00
Syoyo Fujita ce3a30e612 Merge pull request #326 from xzrunner/master
Fix comment on minFilter
2021-05-14 15:06:07 +09:00
zz 8a35b8f6fe Fix comment on minFilter 2021-05-14 13:49:33 +08:00
Syoyo Fujita f66f3bfeb3 Merge pull request #325 from iceydee/scene-extras
Store scene extras and extensions on the scene
2021-05-11 19:01:25 +09:00
Mio Nilsson e29ba7c49a 🐛 Store scene extras and exteions on the scene
This was being stored in the wrong place
2021-05-11 11:50:35 +02:00
Syoyo Fujita bc753d4ac5 Merge pull request #322 from syoyo/fix-negative-skeleton-id
Do not serialize skeleton id -1
2021-04-29 16:20:42 +09:00
Syoyo Fujita 688ba8a60e Add regression test for issue 321 2021-04-29 16:04:52 +09:00
Syoyo Fujita d07b976d59 Do not write negative skeleton id(skeleton is not assigned).
Also ensure `inverseBindMatrices` should not be -2 or other negative values.
2021-04-28 19:15:16 +09:00
Syoyo Fujita 08a7dd8dad Merge pull request #317 from Snowapril/master
Delete unused variable initialization code
2021-03-30 03:15:26 +09:00
snowapril 87da1e775f Delete unused variable initialization code
Line 4536 in tinygltf.h file, there is unused variable initialization code like below.
```c++
    const auto pBuffer = pAttribute->buffer();
```

gcc compiler complain about that unused variable. 

I found there is no side-effect in  `pAttribute->buffer()` call and also pBuffer variable is never used. Therefore I delete that line entirely.
2021-03-30 00:16:04 +09:00
Syoyo Fujita 151495558e Merge pull request #314 from Snowapril/master
Add (void)err for handling unused variable warning
2021-03-20 19:59:44 +09:00
snowapril 84e15260ba add (void)err for handling unused variable warning
I saw in the `ParseExtensionsProperty`(3667) function,
unused variable err argument is wrapped with (void) keword.

I think err argument in the `ParseDracoExtension`(4472) is exactly
same situation with the above one.

For consistency, I think it need to be added (void)err in the
`ParseDracoExtension` function.
2021-03-20 19:25:58 +09:00
Syoyo Fujita 03cdef430d Merge pull request #312 from AlvaroBarua/no_include_rapidjson
Added TINYGLTF_NO_INCLUDE_RAPIDJSON
2021-03-19 14:32:35 +09:00
AlvaroBarua fb4bd82e2c Updated Readme.md 2021-03-18 18:40:09 +00:00
Alvaro Barua 3ddf8301f6 Added TINYGLTF_NO_INCLUDE_RAPIDJSON for consistency and because my project already used rapidjson/ 2021-03-18 00:21:23 +00:00
Syoyo Fujita 298c37a954 Merge pull request #310 from syoyo/write-assert-version
`asset.version` is a required field
2021-03-03 00:35:55 +09:00
Syoyo Fujita b702de755f asset.version is a required field so write "2.0" when asset.version is empty. Fixes #308 2021-03-02 19:08:29 +09:00
Syoyo Fujita 58ceed1d89 Add CMake file and Makefile for examples/build-gltf 2021-02-26 18:34:00 +09:00
Dov Grobgeld d1b6b3a5aa Add example for creating a triangle gltf file from scratch 2021-02-26 09:30:05 +02:00
Syoyo Fujita c56d069726 Merge pull request #306 from mahiuchun/const
Drop an unnecessary 'const'.
2021-02-21 16:07:51 +09:00
Hill Ma d1e32865f1 Drop an unnecessary 'const'. 2021-02-20 22:30:44 -08:00
Syoyo Fujita 869a9d273c Merge pull request #305 from Selmar/patch-2
check correct `extensionsUsed` for serialization
2021-02-02 14:17:34 +09:00
Selmar 1208f057d6 check correct extensionsUsed for serialization 2021-02-01 19:24:41 +01:00
Syoyo Fujita f684dde9f1 Merge pull request #303 from syoyo/int-minmax-serialize
Issue #301. Serialize accessor min/vax value as int
2021-01-22 03:40:52 +09:00
Syoyo Fujita 7905a5b4dc Issue #301. Serialize accessor min/vax value as int if its component type is an integer. 2021-01-21 20:33:11 +09:00
Syoyo Fujita f161782001 Merge pull request #299 from DethRaid/patch-1
Add my project to the README
2020-12-23 15:46:32 +09:00
David Dubois 654bcf733c Add my project to the README
My personal project uses tinygltf so i want to add it to the "Projects using TinyGLTF" section of the README
2020-12-22 22:32:59 -08:00
syoyo 001c870051 Make cmake script add_subdirectory friendly. 2020-12-18 01:10:21 +09:00
Syoyo Fujita 2c521b3432 Remove sampler.wrapR parameter(unused tinygltf extension). Fixes #287
Suppress clang `-Wdocumentation-unknown-command` warning.
2020-12-04 00:50:46 +09:00
Syoyo Fujita a159945db9 Add document for TinyGLTF::SetPreserveimageChannels. 2020-10-31 19:40:33 +09:00
Syoyo Fujita 010ee9c67b Add SetPreserveImageChannels feature(preserve image channels in stored image file. Only effective when using builtin ImageLoad function(STB image load)). 2020-10-31 19:35:55 +09:00
Syoyo Fujita a23971c603 Merge pull request #295 from syoyo/empty-material
Empty material
2020-10-23 04:05:19 +09:00
Syoyo Fujita 1923067982 Fix build when using RapidJSON backend. 2020-10-22 22:38:56 +09:00
Syoyo Fujita 68adc4ba5e Serialize empty JSON object when material has all default parameters. Fixes #294 . 2020-10-22 22:27:12 +09:00
Syoyo Fujita 42a8cd50ff Merge branch 'master' of github.com:syoyo/tinygltf 2020-10-22 21:51:01 +09:00
Syoyo Fujita 0543640a83 Merge pull request #290 from Coast-Coader/master
Minor change to the example of usage with opengl (basic example)
2020-09-29 14:28:47 +09:00
Eschemann 9c59a0b64c Deleted unnessecary stuff2 2020-09-28 16:06:31 +02:00
Eschemann 452541a231 Deleted unnessecary stuff 2020-09-28 16:04:14 +02:00
Eschemann 78fe8d9b89 Fixed segfault in example basic on inter graphics hd and corrected path to model 2020-09-28 15:50:45 +02:00
Syoyo Fujita 51e5508fa0 Add note on sajson branch. 2020-08-09 21:18:28 +09:00
Syoyo Fujita 91da299729 Fix inequality. Should allow 0 for bufferView. 2020-07-15 13:52:39 +09:00
Syoyo Fujita 50ae8a31a8 Merge branch 'master' of github.com:syoyo/tinygltf 2020-07-14 22:05:28 +09:00
Syoyo Fujita 0af0435ef1 Renamed directory name. 2020-07-14 22:04:26 +09:00
Syoyo Fujita 7c342533e9 Add scene date for issue 280 2020-07-14 22:02:51 +09:00
Syoyo Fujita 7842c1276f Merge pull request #281 from rbsheth/sparse_morph_fix
Fix sparse morph targets
2020-07-14 15:35:37 +09:00
Rahul Sheth 125e4a2033 Fix sparse morph targets 2020-07-13 13:56:50 -04:00
Syoyo Fujita c9d6c5b9b4 Merge pull request #278 from rbsheth/string_fix
Use std::string for GetKey function
2020-07-11 03:41:11 +09:00
Rahul Sheth 96a8b2c69b Run clang-format 2020-07-10 14:27:46 -04:00
Rahul Sheth 01d54380ac Use std::string instead of const char* for GetKey function 2020-07-10 14:27:37 -04:00
Syoyo Fujita 6cd8fdb2c8 Merge pull request #274 from daemyung/dxview
Add dxview
2020-07-04 16:48:08 +09:00
daemyung jang fe01af2f01 Add README.md for dxview 2020-07-04 09:24:00 +09:00
daemyung jang efdd2b04dc Add dxview 2020-07-04 01:29:41 +09:00
Syoyo Fujita 2e642b3322 Merge pull request #273 from daemyung/dxview
Initialize member variables
2020-07-03 15:38:46 +09:00
daemyung jang 1739d025a9 Initialize member variables 2020-07-03 13:27:39 +09:00
Syoyo 39418e5728 Disable blank issue. 2020-06-26 02:01:16 +09:00
Syoyo Fujita 5622d2762d Update issue templates 2020-06-19 16:31:37 +09:00
Syoyo Fujita 3d939fd3ee Add comment on tinygltf::ExpandFilePath() 2020-06-06 18:13:15 +09:00
Syoyo Fujita fbbeb4d6a9 Use nullptr instead of NULL. 2020-06-06 17:11:50 +09:00
Syoyo Fujita cef1787ef8 Add regression test for PR-266. 2020-06-06 17:10:49 +09:00
cwbhhjl 2f5aa9f13b fix an error occurred while expanding utf8 path 2020-06-04 10:40:38 +08:00
Syoyo Fujita 28bafe4b11 Add GitHub Actions badge. 2020-05-30 17:06:45 +09:00
Syoyo Fujita 34894a6325 Build validator for MSVC build. 2020-05-30 02:28:58 +09:00
Syoyo Fujita 2e7006797b Separrate build of examples. 2020-05-30 02:27:25 +09:00
Syoyo Fujita d9c03d041a Build examples for VS2019 build job. 2020-05-30 02:21:07 +09:00
Syoyo Fujita 50a3061ddf Fix path to rapidjson headers 2020-05-30 02:19:47 +09:00
Syoyo Fujita 014dce27f4 Add VS2019 build job. 2020-05-30 02:16:41 +09:00
Syoyo Fujita c046769054 Add mingw build job 2020-05-30 02:12:48 +09:00
Syoyo Fujita c43266fdc9 Add argument to loader_example run 2020-05-30 02:07:00 +09:00
Syoyo Fujita aca196e8d3 add aarch64 cross compile and macos build job. 2020-05-30 02:04:06 +09:00
Syoyo Fujita b48c027c9a Fix yaml syntax. 2020-05-30 02:00:03 +09:00
Syoyo Fujita db5c3bea45 Add gcc-4.8 build job. 2020-05-30 01:59:02 +09:00
Syoyo Fujita ddfa1f2f0b Fix workflow 2020-05-30 01:56:35 +09:00
Syoyo Fujita 7b69c778fe Add rapidjson build job 2020-05-29 22:21:24 +09:00
Syoyo Fujita 73e73bf3c1 Create github actions workflow 2020-05-29 20:57:39 +09:00
Syoyo Fujita 35d664e417 Merge pull request #265 from ivovandongen/ivd_rapidjson_size_t
cast size_t to uint_64_t for rapidjson serialization
2020-05-29 18:19:07 +09:00
Ivo van Dongen 272a9dfa5f cast size_t to uint_64_t for rapidjson serialization 2020-05-29 11:24:11 +03:00
Syoyo f3bf6ee78e Add TDME2 2020-05-22 01:25:03 +09:00
Syoyo Fujita aba57bb907 Support llvm-mingw(clang + libcxx) to open UTF-8 path in ifstream. 2020-05-18 20:50:45 +09:00
Syoyo Fujita 6fad7adb9c Fix existing "extensions" were overwritten in serialization when the scene contains lights(serialized as "KHR_light_punctual")
Append "KHR_light_punctual" to `extensionsUsed` if not exist in serialization.
Apply clang-format.
Fixes #261
2020-05-15 21:32:06 +09:00
Syoyo Fujita 3dad303bea Only serialize light.range when range > 0. Fixes #260 2020-05-13 21:22:23 +09:00
Syoyo Fujita ff0a2e9fb4 Return type must be int for GetNumberAsInt(). Fixes #258 2020-05-11 19:07:00 +09:00
Syoyo fe77cc5cdd Serialize extension and extras for Camera. Fixes #257 2020-05-09 02:41:07 +09:00
Syoyo Fujita 18f0e20a11 Fix float and int comparison. 2020-04-29 19:16:35 +09:00
Syoyo Fujita 978adee547 Include cmath for std::fabs 2020-04-29 17:33:48 +09:00
Syoyo Fujita 73c4cce303 Return false for zero-sized asset. Fixes #255 2020-04-28 01:06:34 +09:00
Syoyo Fujita 925b83627a Merge pull request #254 from LHLaurini/master
Fix write functions so they work with MinGW
2020-04-14 01:40:00 +09:00
Luiz Henrique Laurini 92c23725ae Fix write functions so they work with MinGW 2020-04-12 16:00:33 -03:00
Syoyo Fujita af750a5104 Merge pull request #252 from freddiehonohan/master
Fixed small error if node has no mesh in examples/basic.
2020-04-10 02:04:12 +09:00
root ff48fa0ff4 Fixed small error if node has no mesh. 2020-04-09 10:42:41 -04:00
Syoyo Fujita ec45334d3d Merge branch 'master' of github.com:syoyo/tinygltf 2020-04-06 22:12:39 +09:00
Syoyo Fujita 5f603c56dc Do not segfault when the scene does not contain texture images. Fixes #251 2020-04-06 22:11:16 +09:00
Syoyo Fujita 063b8586f1 Merge pull request #250 from FsiGuy00015623/prevent-cloning-buffer-images
Prevent cloning of images in buffers
2020-03-10 14:53:13 +09:00
FsiGuy00015623 db855c6794 Prevent cloning of images in buffers
Now, in UpdateImageObject, if an image has no URI but had a valid bufferView, it will no longer change the image object or copy the buffer object to an outside file at baseDir. 
(When saving files from streams, this function would previously save textures in buffers as "#.png" in the program's working directory instead of the model file's directory, and create a broken link in the updated image object if the two locations were different.)
2020-03-09 16:57:21 -05:00
Syoyo Fujita e391f6b03e Merge pull request #249 from CesiumGS/accessor-index-fix
Ensures only valid bufferViews are mentioned in accessor
2020-03-05 23:59:23 +09:00
Sanjeet Suhag 5ecede71f0 Ensures only valid bufferViews are mentioned in accessor 2020-03-04 17:40:10 -05:00
Syoyo Fujita 40982716f9 Merge branch 'uri-decode' 2020-03-03 18:49:27 +09:00
Syoyo Fujita 4bdc96fb9b Update copyright year.
Add note on the result from fuzzer test.
2020-02-24 01:36:24 +09:00
Syoyo Fujita 96ecea080a Merge pull request #243 from mfpgs/reading_copyright
Reading copyright field in ParseAsset()
2020-02-20 23:42:14 +09:00
Miguel Sousa 22bfc843ee Reading copyright field in ParseAsset() 2020-02-20 14:16:58 +01:00
Syoyo Fujita eaa25a307a Merge pull request #242 from Selmar/some_empty_array_fixes
Some empty array fixes
2020-01-29 01:27:44 +09:00
Selmar Kok ab600b8e72 Merge remote-tracking branch 'origin/master' into some_empty_array_fixes 2020-01-28 13:46:22 +01:00
Selmar Kok eb9d29c06e dont serialize a couple of empty arrays 2020-01-28 13:45:38 +01:00
Syoyo Fujita 57356933c5 Merge pull request #240 from kacprzak/master
Set target for bufferView used by MorphTargets
2020-01-22 22:32:41 +09:00
Marcin Kacprzak c3d6716c56 Set target for bufferView used by MorphTargets 2020-01-22 13:13:35 +01:00
Syoyo Fujita ac5e09f8c3 Merge pull request #239 from Selmar/channel_target_extensions
Channel target extensions
2020-01-22 03:52:20 +09:00
Selmar Kok e2c3fe1c0b Merge remote-tracking branch 'origin/master' into channel_target_extensions 2020-01-21 18:46:58 +01:00
Selmar Kok 973d9b3394 add channel.target extensions 2020-01-21 18:45:24 +01:00
Syoyo Fujita 28ad4ab7b8 Add clang fuzzer tester. 2020-01-18 20:31:54 +09:00
Syoyo Fujita 0227ae5d9b Merge pull request #238 from sammyKhan/patch-1
Initialize defaultScene to -1
2020-01-17 21:58:00 +09:00
sammyKhan a0a62bde1c Initialize defaultScene to -1
To prevent undefined behavior if the model is serialized without defaultScene being set explicitly.
2020-01-17 13:41:16 +01:00
Syoyo Fujita 23d1ff2880 Possible fix for error: invalid path 'models/CubeImageUriSpaces/ 2x2 image has multiple spaces.png ' on Windows(NTFS? dislikes extra white space after the file extension ) 2020-01-17 16:15:03 +09:00
Syoyo Fujita bcf2ce586e Merge pull request #237 from FrankGalligan/fix_image_uri_with_spaces
Fix loading images with spaces on Linux
2020-01-14 18:00:48 +09:00
Frank Galligan aa3c5a1cad Fix loading images with spaces on Linux
This change quotes the string before it is passed into wordexp.

This addresses issue https://github.com/syoyo/tinygltf/issues/236
2020-01-13 15:06:56 -08:00
Syoyo Fujita db2fbeec9d Add dlib license. 2020-01-08 02:39:46 +09:00
Syoyo Fujita c4166e4c60 Initial support of decoding percent-encoding URI. 2020-01-08 02:38:01 +09:00
Syoyo Fujita 1cf179d377 Merge pull request #235 from ziocleto/master
BufferView ctor now uses correct members order.
2020-01-08 00:52:09 +09:00
Syoyo Fujita ddc14f8ba6 Merge pull request #233 from 8i/fix-animation-sampler-serialization
Reserve space for animation samplers in serialization
2020-01-08 00:47:41 +09:00
Syoyo Fujita 72f4a55edd Suppress clang warnings. Fixes #234 2020-01-08 00:40:41 +09:00
Dado 379bb612f1 BufferView ctor now uses correct members order.
tiny_gltf.h line 815 
(Moved target(0) to second to last)
2020-01-07 14:41:12 +00:00
Jacek 1da4e5d633 Reserve space for animation samplers in serialization 2020-01-06 15:15:21 -06:00
Syoyo Fujita 4e47bc7799 Fill BufferView variables with initial/invalid values just in case. 2020-01-02 22:07:25 +09:00
Syoyo Fujita 9cc3e91968 Merge pull request #232 from kacprzak/master
Do not set target on bufferView pointing to animation data
2020-01-02 21:53:53 +09:00
Marcin Kacprzak d09788d10f Do not set target on bufferView pointing to animation data 2020-01-02 13:00:48 +01:00
Syoyo Fujita a11f6e1939 Allow empty buffer when serializing glTF buffer data. 2019-12-19 14:20:01 +09:00
Syoyo Fujita 8ced108571 Merge pull request #230 from itainter/fix-primitive-extension
Fix the issue that the extension of primitive written as extension of mesh.
2019-12-18 13:33:46 +09:00
zhaozhiquan 3eb65e269a Fix the issue that the extension of primitive written as extension of mesh. 2019-12-18 11:28:57 +08:00
Syoyo Fujita 1322c7bf09 Merge branch 'master' of github.com:syoyo/tinygltf 2019-11-24 20:50:50 +09:00
Syoyo Fujita 49651fe3d9 Update READE. 2019-11-24 20:50:35 +09:00
Syoyo Fujita db93a87c4a Merge pull request #226 from epajarre/glb-bin-blob
Glb bin blob
2019-11-19 01:30:10 +09:00
Eero Pajarre 7b0d81bf12 Added support for BIN chunk when saving in glb format
If saving in glb (binary) format the first buffer in
model is saved as gbl chunk number 1 in binary format.
This operation is not performed if the first buffer
as an url specified.
2019-11-18 14:15:48 +02:00
Eero Pajarre 2e8a115d7e Only serialize Accessor.normalized if it is true 2019-11-18 13:09:25 +02:00
Eero Pajarre ae9364902a Added Accessor initializers
Added Accessor intializers
Now byteOffset and normalized are initialized to their default
values. componentType and Type are initialized to bad values
on purpose, they must be set when loading or creating the model.
2019-11-18 12:59:05 +02:00
Syoyo Fujita 06d2fbdae6 not is alternative keyword and not recommended to use. Fixes #225 2019-11-17 02:11:59 +09:00
Syoyo Fujita d5ff5cbfb1 Merge branch 'master' of github.com:syoyo/tinygltf 2019-11-16 17:00:42 +09:00
Syoyo Fujita 1d20520680 Correct computation of padding size. Fixes #224. 2019-11-16 17:00:17 +09:00
Syoyo Fujita 4ab0386d09 Fix MinGW code path reused linux code path. 2019-11-10 15:31:17 +09:00
Syoyo Fujita a471770f38 Merge pull request #223 from syoyo/mingw-fix
Mingw fix
2019-11-10 02:03:18 +09:00
Syoyo Fujita 125d8e50a9 fopen_s -> fopen in linux(posix) code path. 2019-11-09 20:52:56 +09:00
Syoyo Fujita 45cac78709 Fix utf8 filepath on MinGW based on PR 222. 2019-11-09 20:42:55 +09:00
Syoyo Fujita a9d86c1af4 Add URL of Vulkan-Samples. 2019-11-08 14:45:16 +09:00
Syoyo Fujita 2f26eddac4 Merge pull request #220 from Selmar/doublesided_default_serialization
Doublesided default serialization
2019-11-01 13:39:36 +09:00
Selmar Kok a0939550ca Merge branch 'master' of github.com:syoyo/tinygltf into doublesided_default_serialization 2019-10-31 15:10:03 +01:00
Selmar Kok 58ab95be2f only serialize doublesided if it is not the default value 2019-10-31 15:08:03 +01:00
Syoyo Fujita bf0e4f8e45 Merge pull request #219 from syoyo/travis-gcc-4.8
Travis gcc 4.8
2019-10-31 19:34:33 +09:00
Syoyo Fujita 30f333c607 Fix travis script. 2019-10-31 02:17:22 +09:00
Syoyo Fujita 419162716e Introduce TINYGLTF_BUILD_EXAMPLES option to CMakeLists.txt. Fixes #218 2019-10-31 01:55:57 +09:00
Syoyo Fujita 9533c352a1 Add gcc-4.8 build on Travis. 2019-10-31 01:02:43 +09:00
Syoyo Fujita 9ff3d93084 Merge pull request #217 from syoyo/store-json-string-for-extras-and-extensions
Add feature to store original JSON string for extras and extensions
2019-10-30 19:08:08 +09:00
Syoyo Fujita aea514a975 Merge pull request #216 from harokyang/feature/utf8_path
Feature/utf8 path
2019-10-30 17:40:22 +09:00
Harokyang 05a4456948 fix build error on C++11/C++14 2019-10-30 16:30:00 +08:00
Syoyo Fujita 6e08b17ce3 Add feature to store original JSON string for extras and extensions(for user-specific JSON parsing). # Fixes 215
Fix some glTF object(e.g. Skin) does not have extras and/or extensions property.
2019-10-30 17:25:38 +09:00
Harokyang fb256609f2 support writing with utf-8 filepath 2019-10-30 16:14:10 +08:00
Harokyang 5cecef2b92 Treat all filepath string as utf-8 encoded
On Windows, convert utf-8 to wchar string before interact with filepath
2019-10-30 15:17:09 +08:00
Syoyo Fujita 1100f0f1eb Allow parsing integer number value as double(For example, glTF-Sample-Models/2.0/Cameras/glTF has zfar number property with integer value, which trigerred a parsing failure). 2019-10-30 15:18:55 +09:00
Syoyo Fujita 2b66c81f67 Merge pull request #212 from Selmar/move_operator
Move semantics
2019-10-30 15:11:26 +09:00
Selmar Kok f29375f59b revert some local modifications, oops.... >_> 2019-10-29 16:25:37 +01:00
Selmar Kok 79e3df26a8 replace TINYGLTF_USE_NO_EXCEPT with GNU compiler version check 2019-10-29 16:22:07 +01:00
Selmar Kok e3cf5edb94 Merge remote-tracking branch 'origin/Selmar-move_operator' into move_operator 2019-10-29 16:09:40 +01:00
Selmar Kok b74fadef8e TINYGLTF_USE_NOEXCEPT 2019-10-29 16:09:32 +01:00
Syoyo Fujita a11709a9ff Merge pull request #213 from dmuir/master
Validate model_length against length in LoadBinaryFromMemory.
2019-10-29 02:20:31 +09:00
Doug Muir cf668683f9 Fix check for invalid glTF to consider invalid length/model_length combinations. 2019-10-28 09:51:13 -07:00
Syoyo Fujita 817bbcfb58 Show clang version in Travis build. 2019-10-23 00:41:40 +09:00
Selmar Kok 23467959ca pbrMetallicRoughnes default noexcept move operator 2019-10-21 19:23:15 +02:00
Selmar Kok 6f08785e9f Merge remote-tracking branch 'origin/master' into move_operator 2019-10-21 17:58:57 +02:00
Selmar Kok ff2b1f92dd use default noexcept move constructor / operator 2019-10-21 17:58:09 +02:00
Syoyo Fujita e886247329 Fix parsing a glTF file with 2GB+ or lareger size. 2019-10-20 17:47:50 +09:00
Syoyo Fujita 83bb1a48d7 Merge pull request #211 from Selmar/add_missing_serialization
small serialization additions
2019-10-19 15:18:19 +09:00
Selmar Kok c3353e1acd set default values for baseColorFactor so that it has correct values when parsing a material without a pbrMetallicRoughness struct 2019-10-18 18:22:35 +02:00
Selmar Kok 81b672bcc2 add some missing serialization // add mesh==() weights comparison // use const iterator for extension serialization 2019-10-18 16:08:44 +02:00
Syoyo Fujita cece6ee6d2 Merge pull request #209 from patriciogonzalezvivo/master
Adding glslViewer
2019-10-08 19:21:51 +09:00
Patricio Gonzalez Vivo 31f875ddbc adding glslViewer 2019-10-08 03:07:58 -07:00
Syoyo Fujita 8dccf9bf4e Merge pull request #208 from toshiks/patch-1
Added project to Readme.md (QuickLook GLTF plugin)
2019-09-15 14:50:06 +09:00
Anton Klochkov 508dcfa2e6 Added project to Readme.md (QuickLook GLTF plugin) 2019-09-15 01:25:47 +03:00
Syoyo Fujita 7e009041e3 Do not serialize pbrMetallicRoughness when they have all default values. Fixes #204 2019-09-13 15:32:22 +09:00
Syoyo Fujita 14977937c2 Add a link to Lighthouse 2. 2019-09-09 20:07:54 +09:00
Syoyo Fujita 8bb18fbd9c Merge pull request #202 from Ybalrid/fix_copy_assignment_operator
Fix broken copy-assignment operators
2019-09-06 13:58:54 +09:00
Arthur Brainville (Ybalrid) 9eeaf20133 Fix copy-assignment operator
When manual move constructor are declared, C++ compilers deletes the
copy constructor and copy-assign operator.

Most of these structures recently got a move ctor added, and copy ctor
re-enabled ( = default ). But copy-assignment are missing, thus in some
context, breaking instantiations of templates like std::vector<>.
2019-09-05 13:02:05 +02:00
Syoyo Fujita a34aa8ea77 Suppress variable-is-shadowed warnings.
Apply clang-format.
Add note on RapidJSON and C++14 compilation flags.
2019-09-05 14:40:32 +09:00
Syoyo Fujita 59b2966f81 Merge branch 'master' of https://github.com/jrkoonce/tinygltf into jrkoonce-master 2019-09-05 14:22:51 +09:00
jrkoonce 7481011fd9 Removing RapidJSON toggle 2019-09-04 13:46:59 -05:00
jrkoonce 0d2b6efa6f Removing warnings 2019-09-04 13:46:45 -05:00
jrkoonce ce7fa7419b Support simultaneous gltf load/saves
Added support for RapidJSON's CrtAllocator which is stateless and allows multiple documents to be in use at once, removing that restriction on default documents.  Enable with TINYGLTF_USE_RAPIDJSON_CRTALLOCATOR
2019-09-04 13:31:44 -05:00
jrkoonce 906f98fa74 Revert "Support simultaneous gltf load/saves"
This reverts commit d2a2703ec5.
2019-09-04 13:30:02 -05:00
jrkoonce d2a2703ec5 Support simultaneous gltf load/saves
Added support for RapidJSON's CrtAllocator which is stateless and allows multiple documents to be in use at once, removing that restriction on default documents.  Enable with TINYGLTF_USE_RAPIDJSON_CRTALLOCATOR
2019-09-04 12:19:27 -05:00
jrkoonce 95f05757d6 Revert "Support simultaneous gltf load/saves (TINYGLTF_USE_RAPIDJSON_CRTALLOCATOR)"
This reverts commit ab63db6318.
2019-09-04 12:15:51 -05:00
jrkoonce ab63db6318 Support simultaneous gltf load/saves (TINYGLTF_USE_RAPIDJSON_CRTALLOCATOR)
This allows multiple gltf's to be loaded/saved in parallel.  It removes the restriction of a single JsonDocument active at once which is default behavior.  Enable with TINYGLTF_USE_RAPIDJSON_CRTALLOCATOR
2019-09-04 12:01:39 -05:00
jrkoonce 6ff95392b0 Fix Compiler Warnings 2019-09-04 10:50:55 -05:00
Syoyo Fujita c29bd3d9ce Use const reference for Buffer to fix compilation.
Removed UTF BOM?
2019-09-04 14:26:58 +09:00
jrkoonce 63419a11e1 Revert accidental committed change
Put "JsonX" helpers back in anonymous namespace to keep them inside local translation unit.
2019-09-03 17:06:41 -05:00
jrkoonce 06c30c4d04 Fixed Bugs/Unit Tests Pass
Fixed bugs found by unit tests and got unit tests running with RapidJSON as well as nlohmann.
2019-09-03 15:56:48 -05:00
jrkoonce 67e6160a9a Fixed move bugs 2019-09-03 10:42:39 -05:00
jrkoonce a3b8b355ae Merge branch 'pr/1' 2019-09-03 10:30:19 -05:00
jrkoonce 5145394239 Made C++14 optional, default off. 2019-09-03 09:48:30 -05:00
Syoyo Fujita 67aa2ca75e Merge pull request #200 from ux3d/feature/allow-scenes-without-nodes
allow scenes without nodes
2019-09-02 22:12:15 +09:00
Benjamin Schmithüsen ce25385eab remove extra parenthesis 2019-09-02 13:43:24 +02:00
Benjamin Schmithüsen 6143c6662b don't fail if a scene has no nodes property (which is not required) 2019-09-02 13:41:59 +02:00
Syoyo Fujita 81d75df48a Rename typeSizeInBytes to numComponents. 2019-08-30 19:19:52 +09:00
DingboDingboDingbo 83ccb9f28d GetTypeSizeInBytes not returning Type Size In Bytes
Changed name to be less misleading.
2019-08-29 18:49:15 -04:00
jrkoonce 9b6f52e98a Fix bug in ParseNumberArrayProperty()
Only doubles were being accepted instead of any number (including ordinals)
2019-08-29 13:56:58 -05:00
jrkoonce 5cecc41db9 More cleanup
1. Reserve array memory when converting JSON to Value for heap efficiency.
2. Grouped more JSON abstraction functions together and put in anonymous namespace instead of making each static.
2019-08-29 11:45:04 -05:00
jrkoonce 208c3058bf Remove test code accidentally commited 2019-08-29 11:28:07 -05:00
jrkoonce cba5d6caae RapidJson 1.1 support + More move semantics
*Support for RapidJson 1.1, use TINYGLTF_USE_RAPIDJSON to toggle between RapidJson and nlohmann

*Lot more move semantics enabled.  All parsing and serialization now move all json objects with far fewer copies
2019-08-29 11:26:22 -05:00
jrkoonce d1e1472992 Update tiny_gltf.h
Add/Enable move semantics to most all structs/classes
2019-08-27 11:51:02 -05:00
Syoyo Fujita ff51570c26 Apply clang format.
Remove `const static std::string` global variable.
2019-08-24 16:29:14 +09:00
Syoyo Fujita a472a3fa0f Add Set/Get SerializeDefaultValues method(W.I.P.) 2019-08-21 14:23:00 +09:00
Syoyo Fujita 1f160d5b8f Merge pull request #195 from ux3d/fix/parse-int-as-double
(also) parse int as double
2019-08-20 19:33:20 +09:00
Syoyo Fujita 5150a46072 Merge branch 'master' of github.com:syoyo/tinygltf 2019-08-20 17:11:29 +09:00
Syoyo Fujita cea69e37a5 Suppress clang warnings. 2019-08-20 17:10:30 +09:00
Syoyo Fujita 8b56c016ab Merge pull request #193 from Selmar/emissiveFactor_defaults
Emissive factor defaults
2019-08-20 13:13:12 +09:00
Benjamin Schmithüsen c7e205be87 when parsing a number from an int, also set the 'real value' to the value 2019-08-19 16:16:43 +02:00
Selmar Kok 6dba6c6aac [emissiveFactor] correct default values 2019-08-19 11:23:31 +02:00
Selmar Kok 6df800d2b6 [emissiveFactor] fix inconsistency with baseColorFactor where default values were set only for baseColorFactor and not emissiveFactor 2019-08-19 11:05:28 +02:00
Syoyo Fujita 2f044e77f1 Merge pull request #191 from Selmar/animation_extension_properties
Animation extension properties
2019-08-17 01:09:34 +09:00
Selmar Kok af5a5ef026 Merge branch 'master' of github.com:syoyo/tinygltf into animation_extension_properties 2019-08-16 17:54:14 +02:00
Syoyo Fujita 6591ba4461 Merge pull request #190 from ux3d/feature/parse-node-weights
parse/serialize node weights
2019-08-16 22:21:48 +09:00
Benjamin Schmithüsen 74c3c10121 serialize node weights 2019-08-16 14:24:26 +02:00
Benjamin Schmithüsen ad63bf748b parse node weights 2019-08-16 14:19:27 +02:00
Selmar Kok 5d43cf8e64 Merge branch 'master' of github.com:syoyo/tinygltf 2019-08-16 14:08:31 +02:00
Selmar Kok 4e2988eebd add extension property for Animation and AnimationChannel 2019-08-16 14:08:08 +02:00
Syoyo Fujita ee179b2cb6 Set default value of minFilter and magFilter in Sampler to -1(unset), since glTF 2.0 spec does not declare default values for it.
Fixes #186
2019-08-16 13:11:30 +09:00
Syoyo Fujita 4ebd6368fb Fix inequality of texture index check when serializing texture of material.
Texture info was written even if it have invalid index(-1). Fixes #189
2019-08-15 12:25:50 +09:00
Syoyo Fujita 67d3d2504d Merge pull request #188 from ux3d/fix/alphaMode
Fixed saving of alphaMode if not OPAQUE
2019-08-14 21:40:07 +09:00
Patrick Härtl d9a468bbb4 Fixed saving of alphaMode if not OPAQUE
Removed duplicated code for alphaCutoff
2019-08-14 14:14:07 +02:00
Syoyo Fujita c7bae71f7f Merge pull request #185 from DerouineauNicolas/endif
remove extra #endif in examples/basic app
2019-08-14 03:09:53 +09:00
nicolasDEROUINEAU f93642c196 remove extra #endif in examples/basic app 2019-08-13 15:08:01 +02:00
51 changed files with 77100 additions and 8115 deletions
+13
View File
@@ -0,0 +1,13 @@
# These are supported funding model platforms
github: syoyo
#patreon: # Replace with a single Patreon username
#open_collective: # Replace with a single Open Collective username
#ko_fi: # Replace with a single Ko-fi username
#tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
#community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
#liberapay: # Replace with a single Liberapay username
#issuehunt: # Replace with a single IssueHunt username
#otechie: # Replace with a single Otechie username
#lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
#custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
+1
View File
@@ -0,0 +1 @@
blank_issues_enabled: false
+30
View File
@@ -0,0 +1,30 @@
---
name: Issue report
about: Create a report
title: ''
labels: ''
assignees: ''
---
**Describe the issue**
A clear and concise description of what the issue is.
**To Reproduce**
- OS
- Compiler, compiler version, compile options
- Please attach minimal and reproducible .glTF file if you got an issue related to .glTF data
**Expected behaviour**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.
+169
View File
@@ -0,0 +1,169 @@
name: C/C++ CI
on: [push, pull_request]
jobs:
# gcc4.8 is too old and ubuntu-18.04 image is not supported in GitHub Actions anymore,
# so disable this build.
## 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-latest
name: Build with MinGW gcc cross
steps:
- name: Checkout
uses: actions/checkout@v2
- 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 2022 build
# Assume windows-latest have VS2022 installed
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 --help
cmake -G "Visual Studio 17 2022" -A x64 -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-latest
name: Build on cross aarch64
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Build
run: |
sudo apt-get update
sudo apt-get install -y build-essential
sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
git clone https://github.com/Tencent/rapidjson
aarch64-linux-gnu-g++ -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
+72
View File
@@ -0,0 +1,72 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ "master" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "master" ]
schedule:
- cron: '21 20 * * 5'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'cpp', 'python' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
+7
View File
@@ -68,4 +68,11 @@ loader_example
tests/tester
tests/tester_noexcept
tests/issue-97.gltf
tests/issue-261.gltf
# unignore
!Makefile
!examples/build-gltf/Makefile
!examples/raytrace/cornellbox_suzanne.obj
!tests/Makefile
!tools/windows/premake5.exe
+12
View File
@@ -31,6 +31,17 @@ matrix:
- addons: *1
compiler: clang
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:
- ./.travis-before-install.sh
@@ -43,6 +54,7 @@ script:
- ${CXX} ${EXTRA_CXXFLAGS} -std=c++11 -Wall -g -o loader_example loader_example.cc
- ./loader_example ./models/Cube/Cube.gltf
- cd tests
- clang++ -v
- make
- ./tester
- ./tester_noexcept
+66 -18
View File
@@ -2,27 +2,75 @@ cmake_minimum_required(VERSION 3.6)
PROJECT (tinygltf)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
SET(CMAKE_CXX_STANDARD 11)
ADD_EXECUTABLE ( loader_example
loader_example.cc
option(TINYGLTF_BUILD_LOADER_EXAMPLE "Build loader_example(load glTF and dump infos)" ON)
option(TINYGLTF_BUILD_GL_EXAMPLES "Build GL exampels(requires glfw, OpenGL, etc)" OFF)
option(TINYGLTF_BUILD_VALIDATOR_EXAMPLE "Build validator exampe" OFF)
option(TINYGLTF_BUILD_BUILDER_EXAMPLE "Build glTF builder example" OFF)
option(TINYGLTF_HEADER_ONLY "On: header-only mode. Off: create tinygltf library(No TINYGLTF_IMPLEMENTATION required in your project)" OFF)
option(TINYGLTF_INSTALL "Install tinygltf files during install step. Usually set to OFF if you include tinygltf through add_subdirectory()" ON)
if (TINYGLTF_BUILD_LOADER_EXAMPLE)
ADD_EXECUTABLE ( loader_example
loader_example.cc
)
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)
if (TINYGLTF_BUILD_BUILDER_EXAMPLE)
ADD_SUBDIRECTORY ( examples/build-gltf )
endif (TINYGLTF_BUILD_BUILDER_EXAMPLE)
#
# for add_subdirectory and standalone build
#
if (TINYGLTF_HEADER_ONLY)
add_library(tinygltf INTERFACE)
target_include_directories(tinygltf
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
ADD_SUBDIRECTORY ( examples/gltfutil )
ADD_SUBDIRECTORY ( examples/glview )
ADD_SUBDIRECTORY ( examples/validator )
else (TINYGLTF_HEADER_ONLY)
add_library(tinygltf)
target_sources(tinygltf PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/tiny_gltf.cc)
target_include_directories(tinygltf
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
endif (TINYGLTF_HEADER_ONLY)
INSTALL ( FILES
json.hpp
stb_image.h
stb_image_write.h
tiny_gltf.h
DESTINATION
include
)
if (TINYGLTF_INSTALL)
install(TARGETS tinygltf EXPORT tinygltfTargets)
install(EXPORT tinygltfTargets NAMESPACE tinygltf:: FILE TinyGLTFTargets.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/TinyGLTFConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/TinyGLTFConfig.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/TinyGLTFConfig.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
# Do not install .lib even if !TINYGLTF_HEADER_ONLY
INSTALL ( FILES
cmake/TinyGLTFConfig.cmake
DESTINATION
cmake
)
INSTALL ( FILES
json.hpp
stb_image.h
stb_image_write.h
tiny_gltf.h
${TINYGLTF_EXTRA_SOUECES}
DESTINATION
include
)
endif(TINYGLTF_INSTALL)
+92 -8
View File
@@ -2,24 +2,40 @@
`TinyGLTF` is a header only C++11 glTF 2.0 https://github.com/KhronosGroup/glTF library.
`TinyGLTF` uses Niels Lohmann's json library(https://github.com/nlohmann/json), so now it requires C++11 compiler.
If you are looking for old, C++03 version, please use `devel-picojson` branch.
`TinyGLTF` uses Niels Lohmann's json library (https://github.com/nlohmann/json), so now it requires C++11 compiler.
(Also, you can use RadpidJSON as an JSON backend)
If you are looking for old, C++03 version, please use `devel-picojson` branch (but not maintained anymore).
## Status
Currently TinyGLTF is stable and maintenance mode. No drastic changes and feature additions planned.
- v2.8.0 Add URICallbacks for custom URI handling in Buffer and Image. PR#397
- v2.7.0 Change WriteImageDataFunction user callback function signature. PR#393
- v2.6.0 Support serializing sparse accessor(Thanks to @fynv).
- v2.5.0 Add SetPreserveImageChannels() option to load image data as is.
- v2.4.0 Experimental RapidJSON support. Experimental C++14 support(C++14 may give better performance)
- 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.1.0 release(Draco support)
- v2.1.0 release(Draco decoding support)
- v2.0.0 release(22 Aug, 2018)!
### Branches
* `sajson` : Use sajson to parse JSON. Parsing only but faster compile time(2x reduction compared to json.hpp and RapidJson), but not well maintained.
## Builds
[![Build Status](https://travis-ci.org/syoyo/tinygltf.svg?branch=devel)](https://travis-ci.org/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
Probably mostly feature-complete. Last missing feature is Draco encoding: https://github.com/syoyo/tinygltf/issues/207
* Written in portable C++. C++-11 with STL dependency only.
* [x] macOS + clang(LLVM)
* [x] iOS + clang
@@ -33,8 +49,11 @@ If you are looking for old, C++03 version, please use `devel-picojson` branch.
* Moderate parsing time and memory consumption.
* glTF specification v2.0.0
* [x] ASCII glTF
* [x] Load
* [x] Save
* [x] Binary glTF(GLB)
* [x] PBR material description
* [x] Load
* [x] Save(.bin embedded .glb)
* Buffers
* [x] Parse BASE64 encoded embedded buffer data(DataURI).
* [x] Load `.bin` file.
@@ -54,6 +73,7 @@ If you are looking for old, C++03 version, please use `devel-picojson` branch.
* [x] Image save
* Extensions
* [x] Draco mesh decoding
* [ ] Draco mesh encoding
## Note on extension property
@@ -66,6 +86,13 @@ In extension(`ExtensionMap`), JSON number value is parsed as int or float(number
* [glview](examples/glview) : Simple glTF geometry viewer.
* [validator](examples/validator) : Simple glTF validator with JSON schema.
* [basic](examples/basic) : Basic glTF viewer with texturing support.
* [build-gltf](examples/build-gltf) : Build simple glTF scene from a scratch.
### WASI/WASM build
Users who want to run TinyGLTF securely and safely(e.g. need to handle malcious glTF file to serve online glTF conver),
I recommend to build TinyGLTF for WASM target.
WASI build example is located in [wasm](wasm) .
## Projects using TinyGLTF
@@ -74,11 +101,19 @@ 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
* [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
* 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
* [SanityEngine](https://github.com/DethRaid/SanityEngine) - A C++/D3D12 renderer focused on the personal and professional development of its developer
* [Open3D](http://www.open3d.org/) - A Modern Library for 3D Data Processing
* [Supernova Engine](https://github.com/supernovaengine/supernova) - Game engine for 2D and 3D projects with Lua or C++ in data oriented design.
* Your projects here! (Please send PR)
## TODOs
* [ ] Write C++ code generator which emits C++ code from JSON schema for robust parsing.
* [ ] Robust URI decoding/encoding. https://github.com/syoyo/tinygltf/issues/369
* [ ] Mesh Compression/decompression(Open3DGC, etc)
* [x] Load Draco compressed mesh
* [ ] Save Draco compressed mesh
@@ -89,6 +124,10 @@ In extension(`ExtensionMap`), JSON number value is parsed as int or float(number
* [ ] 16bit PNG support in Serialization
* [ ] Write example and tests for `animation` and `skin`
### Optional
* [ ] Write C++ code generator which emits C++ code from JSON schema for robust parsing?
## Licenses
TinyGLTF is licensed under MIT license.
@@ -139,6 +178,10 @@ if (!ret) {
}
```
#### Loader options
* `TinyGLTF::SetPreserveimageChannels(bool onoff)`. `true` to preserve image channels as stored in image file for loaded image. `false` by default for backward compatibility(image channels are widen to `RGBA` 4 channels). Effective only when using builtin image loader(STB image loader).
## Compile options
* `TINYGLTF_NOEXCEPTION` : Disable C++ exception in JSON parsing. You can use `-fno-exceptions` or by defining the symbol `JSON_NOEXCEPTION` and `TINYGLTF_NOEXCEPTION` to fully remove C++ exception codes when compiling TinyGLTF.
@@ -148,19 +191,51 @@ if (!ret) {
* `TINYGLTF_ANDROID_LOAD_FROM_ASSETS`: Load all files from packaged app assets instead of the regular file system. **Note:** You must pass a valid asset manager from your android app to `tinygltf::asset_manager` beforehand.
* `TINYGLTF_ENABLE_DRACO`: Enable Draco compression. User must provide include path and link correspnding libraries in your project file.
* `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_RAPIDJSON `: Disable including RapidJson's header files 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_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 feature.
* `TINYGLTF_USE_CPP14` : Use C++14 feature(requires C++14 compiler). This may give better performance than C++11.
### Wuffs image loader option(faster and secure JPEG/PNG deocoding)
You can use `wuffs` image loader to load JPEG and PNG in fast and securely.
(`stb_image` has some security issues, whereas `wuffs` is well fuzz tested)
Not that some uncommon JPEG format is unsupported in `wuffs` `std/jpeg` decoder.
* `TINYGLTF_USE_WUFFS_IMAGE_LOADER` : Use `wuffs` to load images. `stb_image` related stuff will be disabled.
* `TINYGLTF_NO_STB_IMAGE` supercedes `wuffs` macros. i.e. when `TINYGLTF_NO_STB_IMAGE` is defined, both `stb_image` and `wuffs` are disabled.
* `TINYGLTF_NO_WUFFS_IMPLEMENTATION` : Do not define `WUFFS_IMPLEMENTATION` inside `tiny_gltf.h`. Define this macro if you use `wuffs` in another C/C++ file.
## CMake options
You can add tinygltf using `add_subdirectory` feature.
If you add tinygltf to your project using `add_subdirectory`, it would be better to set `TINYGLTF_HEADER_ONLY` on(just add an include path to tinygltf) and `TINYGLTF_INSTALL` off(Which does not install tinygltf files).
```
// Your project's CMakeLists.txt
...
set(TINYGLTF_HEADER_ONLY ON CACHE INTERNAL "" FORCE)
set(TINYGLTF_INSTALL OFF CACHE INTERNAL "" FORCE)
add_subdirectory(/path/to/tinygltf)
```
### Saving gltTF 2.0 model
* [ ] Buffers.
* Buffers.
* [x] To file
* [x] Embedded
* [ ] Draco compressed?
* [x] Images
* [x] To file
* [x] Embedded
* [ ] Binary(.glb)
* Binary(.glb)
* [x] .bin embedded single .glb
* [ ] External .bin
## Running tests.
@@ -168,7 +243,7 @@ if (!ret) {
#### Setup
Python 2.6 or 2.7 required.
Python required.
Git clone https://github.com/KhronosGroup/glTF-Sample-Models to your local dir.
#### Run parsing test
@@ -188,8 +263,17 @@ $ ./tester
$ ./tester_noexcept
```
### Fuzzing 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.
* 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
-15
View File
@@ -1,15 +0,0 @@
# -*- cmake -*-
# - Find TinyGLTF
# TinyGLTF_INCLUDE_DIR TinyGLTF's include directory
FIND_PACKAGE ( PackageHandleStandardArgs )
SET ( TinyGLTF_INCLUDE_DIR "${TinyGLTF_DIR}/../include" CACHE STRING "TinyGLTF include directory")
FIND_FILE ( TinyGLTF_HEADER tiny_gltf.h PATHS ${TinyGLTF_INCLUDE_DIR} )
IF (NOT TinyGLTF_HEADER)
MESSAGE ( FATAL_ERROR "Unable to find tiny_gltf.h, TinyGLTF_INCLUDE_DIR = ${TinyGLTF_INCLUDE_DIR}")
ENDIF ()
+3
View File
@@ -0,0 +1,3 @@
@PACKAGE_INIT@
include(${CMAKE_CURRENT_LIST_DIR}/TinyGLTFTargets.cmake)
+1
View File
@@ -1,5 +1,6 @@
.vs
Debug
Release
x64
packages
+4
View File
@@ -19,3 +19,7 @@ $ make
Plese use solution file located at `basic` folder.
## Limitation
There are so many limitations in this example(e.g. no PBR shader. the shader only shows texture of textures[0] if available).
+5 -5
View File
@@ -22,32 +22,32 @@
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{0589AC44-0CF3-40D8-8D89-68393CFD40F3}</ProjectGuid>
<RootNamespace>basic</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
+394 -365
View File
@@ -1,365 +1,394 @@
#include <fstream>
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/gtc/matrix_transform.hpp>
#include "shaders.h"
#include "window.h"
#define TINYGLTF_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#define TINYGLTF_NOEXCEPTION
#define JSON_NOEXCEPTION
#include "../../tiny_gltf.h"
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
bool loadModel(tinygltf::Model &model, const char *filename) {
tinygltf::TinyGLTF loader;
std::string err;
std::string warn;
bool res = loader.LoadASCIIFromFile(&model, &err, &warn, filename);
if (!warn.empty()) {
std::cout << "WARN: " << warn << std::endl;
}
if (!err.empty()) {
std::cout << "ERR: " << err << std::endl;
}
if (!res)
std::cout << "Failed to load glTF: " << filename << std::endl;
else
std::cout << "Loaded glTF: " << filename << std::endl;
return res;
}
std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos,
tinygltf::Model &model, tinygltf::Mesh &mesh) {
for (size_t i = 0; i < model.bufferViews.size(); ++i) {
const tinygltf::BufferView &bufferView = model.bufferViews[i];
if (bufferView.target == 0) { // TODO impl drawarrays
std::cout << "WARN: bufferView.target is zero" << std::endl;
continue; // Unsupported bufferView.
/*
From spec2.0 readme:
https://github.com/KhronosGroup/glTF/tree/master/specification/2.0
... 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
primitive).
*/
}
tinygltf::Buffer buffer = model.buffers[bufferView.buffer];
std::cout << "bufferview.target " << bufferView.target << std::endl;
GLuint vbo;
glGenBuffers(1, &vbo);
vbos[i] = vbo;
glBindBuffer(bufferView.target, vbo);
std::cout << "buffer.data.size = " << buffer.data.size()
<< ", bufferview.byteOffset = " << bufferView.byteOffset
<< std::endl;
glBufferData(bufferView.target, bufferView.byteLength,
&buffer.data.at(0) + bufferView.byteOffset, GL_STATIC_DRAW);
}
for (size_t i = 0; i < mesh.primitives.size(); ++i) {
tinygltf::Primitive primitive = mesh.primitives[i];
tinygltf::Accessor indexAccessor = model.accessors[primitive.indices];
for (auto &attrib : primitive.attributes) {
tinygltf::Accessor accessor = model.accessors[attrib.second];
int byteStride =
accessor.ByteStride(model.bufferViews[accessor.bufferView]);
glBindBuffer(GL_ARRAY_BUFFER, vbos[accessor.bufferView]);
int size = 1;
if (accessor.type != TINYGLTF_TYPE_SCALAR) {
size = accessor.type;
}
int vaa = -1;
if (attrib.first.compare("POSITION") == 0) vaa = 0;
if (attrib.first.compare("NORMAL") == 0) vaa = 1;
if (attrib.first.compare("TEXCOORD_0") == 0) vaa = 2;
if (vaa > -1) {
glEnableVertexAttribArray(vaa);
glVertexAttribPointer(vaa, size, accessor.componentType,
accessor.normalized ? GL_TRUE : GL_FALSE,
byteStride, BUFFER_OFFSET(accessor.byteOffset));
} else
std::cout << "vaa missing: " << attrib.first << std::endl;
}
GLuint texid;
glGenTextures(1, &texid);
tinygltf::Texture &tex = model.textures[0];
tinygltf::Image &image = model.images[tex.source];
glBindTexture(GL_TEXTURE_2D, texid);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
GLenum format = GL_RGBA;
if (image.component == 1) {
format = GL_RED;
} else if (image.component == 2) {
format = GL_RG;
} else if (image.component == 3) {
format = GL_RGB;
} else {
// ???
}
GLenum type = GL_UNSIGNED_BYTE;
if (image.bits == 8) {
// ok
} else if (image.bits == 16) {
type = GL_UNSIGNED_SHORT;
} else {
// ???
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0,
format, type, &image.image.at(0));
}
return vbos;
}
// bind models
void bindModelNodes(std::map<int, GLuint> vbos, tinygltf::Model &model,
tinygltf::Node &node) {
bindMesh(vbos, model, model.meshes[node.mesh]);
for (size_t i = 0; i < node.children.size(); i++) {
bindModelNodes(vbos, model, model.nodes[node.children[i]]);
}
}
GLuint bindModel(tinygltf::Model &model) {
std::map<int, GLuint> vbos;
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
const tinygltf::Scene &scene = model.scenes[model.defaultScene];
for (size_t i = 0; i < scene.nodes.size(); ++i) {
bindModelNodes(vbos, model, model.nodes[scene.nodes[i]]);
}
glBindVertexArray(0);
// cleanup vbos
for (size_t i = 0; i < vbos.size(); ++i) {
glDeleteBuffers(1, &vbos[i]);
}
return vao;
}
void drawMesh(tinygltf::Model &model, tinygltf::Mesh &mesh) {
for (size_t i = 0; i < mesh.primitives.size(); ++i) {
tinygltf::Primitive primitive = mesh.primitives[i];
tinygltf::Accessor indexAccessor = model.accessors[primitive.indices];
glDrawElements(primitive.mode, indexAccessor.count,
indexAccessor.componentType,
BUFFER_OFFSET(indexAccessor.byteOffset));
}
}
// recursively draw node and children nodes of model
void drawModelNodes(tinygltf::Model &model, tinygltf::Node &node) {
drawMesh(model, model.meshes[node.mesh]);
for (size_t i = 0; i < node.children.size(); i++) {
drawModelNodes(model, model.nodes[node.children[i]]);
}
}
void drawModel(GLuint vao, tinygltf::Model &model) {
glBindVertexArray(vao);
const tinygltf::Scene &scene = model.scenes[model.defaultScene];
for (size_t i = 0; i < scene.nodes.size(); ++i) {
drawModelNodes(model, model.nodes[scene.nodes[i]]);
}
glBindVertexArray(0);
}
void dbgModel(tinygltf::Model &model) {
for (auto &mesh : model.meshes) {
std::cout << "mesh : " << mesh.name << std::endl;
for (auto &primitive : mesh.primitives) {
const tinygltf::Accessor &indexAccessor =
model.accessors[primitive.indices];
std::cout << "indexaccessor: count " << indexAccessor.count << ", type "
<< indexAccessor.componentType << std::endl;
tinygltf::Material &mat = model.materials[primitive.material];
for (auto &mats : mat.values) {
std::cout << "mat : " << mats.first.c_str() << std::endl;
}
for (auto &image : model.images) {
std::cout << "image name : " << image.uri << std::endl;
std::cout << " size : " << image.image.size() << std::endl;
std::cout << " w/h : " << image.width << "/" << image.height
<< std::endl;
}
std::cout << "indices : " << primitive.indices << std::endl;
std::cout << "mode : "
<< "(" << primitive.mode << ")" << std::endl;
for (auto &attrib : primitive.attributes) {
std::cout << "attribute : " << attrib.first.c_str() << std::endl;
}
}
}
}
glm::mat4 genView(glm::vec3 pos, glm::vec3 lookat) {
// Camera matrix
glm::mat4 view = glm::lookAt(
pos, // Camera in World Space
lookat, // and looks at the origin
glm::vec3(0, 1, 0) // Head is up (set to 0,-1,0 to look upside-down)
);
return view;
}
glm::mat4 genMVP(glm::mat4 view_mat, glm::mat4 model_mat, float fov, int w,
int h) {
glm::mat4 Projection =
glm::perspective(glm::radians(fov), (float)w / (float)h, 0.01f, 1000.0f);
// 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
glm::mat4 mvp = Projection * view_mat * model_mat;
return mvp;
}
void displayLoop(Window &window, const std::string &filename) {
Shaders shader = Shaders();
glUseProgram(shader.pid);
// grab uniforms to modify
GLuint MVP_u = glGetUniformLocation(shader.pid, "MVP");
GLuint sun_position_u = glGetUniformLocation(shader.pid, "sun_position");
GLuint sun_color_u = glGetUniformLocation(shader.pid, "sun_color");
tinygltf::Model model;
if (!loadModel(model, filename.c_str())) return;
GLuint vao = bindModel(model);
// dbgModel(model); return;
// Model matrix : an identity matrix (model will be at the origin)
glm::mat4 model_mat = glm::mat4(1.0f);
glm::mat4 model_rot = glm::mat4(1.0f);
glm::vec3 model_pos = glm::vec3(-3, 0, -3);
// generate a camera view, based on eye-position and lookAt world-position
glm::mat4 view_mat = genView(glm::vec3(2, 2, 20), model_pos);
glm::vec3 sun_position = glm::vec3(3.0, 10.0, -5.0);
glm::vec3 sun_color = glm::vec3(1.0);
while (!window.Close()) {
window.Resize();
glClearColor(0.2, 0.2, 0.2, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 trans =
glm::translate(glm::mat4(1.0f), model_pos); // reposition model
model_rot = glm::rotate(model_rot, glm::radians(0.8f),
glm::vec3(0, 1, 0)); // rotate model on y axis
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);
}
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;
// Force create OpenGL 3.3
// NOTE(syoyo): Linux + NVIDIA driver segfaults for some reason? commenting out glfwWindowHint will work.
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
#endif
Window window = Window(800, 600, "TinyGLTF basic example");
glfwMakeContextCurrent(window.window);
#ifdef __APPLE__
// https://stackoverflow.com/questions/50192625/openggl-segmentation-fault
glewExperimental = GL_TRUE;
#endif
glewInit();
std::cout << glGetString(GL_RENDERER) << ", " << glGetString(GL_VERSION)
<< std::endl;
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;
}
#include <fstream>
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/gtc/matrix_transform.hpp>
#include "shaders.h"
#include "window.h"
#define TINYGLTF_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#define TINYGLTF_NOEXCEPTION
#define JSON_NOEXCEPTION
#include "../../tiny_gltf.h"
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
bool loadModel(tinygltf::Model &model, const char *filename) {
tinygltf::TinyGLTF loader;
std::string err;
std::string warn;
bool res = loader.LoadASCIIFromFile(&model, &err, &warn, filename);
if (!warn.empty()) {
std::cout << "WARN: " << warn << std::endl;
}
if (!err.empty()) {
std::cout << "ERR: " << err << std::endl;
}
if (!res)
std::cout << "Failed to load glTF: " << filename << std::endl;
else
std::cout << "Loaded glTF: " << filename << std::endl;
return res;
}
void bindMesh(std::map<int, GLuint>& vbos,
tinygltf::Model &model, tinygltf::Mesh &mesh) {
for (size_t i = 0; i < model.bufferViews.size(); ++i) {
const tinygltf::BufferView &bufferView = model.bufferViews[i];
if (bufferView.target == 0) { // TODO impl drawarrays
std::cout << "WARN: bufferView.target is zero" << std::endl;
continue; // Unsupported bufferView.
/*
From spec2.0 readme:
https://github.com/KhronosGroup/glTF/tree/master/specification/2.0
... 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
primitive).
*/
}
const tinygltf::Buffer &buffer = model.buffers[bufferView.buffer];
std::cout << "bufferview.target " << bufferView.target << std::endl;
GLuint vbo;
glGenBuffers(1, &vbo);
vbos[i] = vbo;
glBindBuffer(bufferView.target, vbo);
std::cout << "buffer.data.size = " << buffer.data.size()
<< ", bufferview.byteOffset = " << bufferView.byteOffset
<< std::endl;
glBufferData(bufferView.target, bufferView.byteLength,
&buffer.data.at(0) + bufferView.byteOffset, GL_STATIC_DRAW);
}
for (size_t i = 0; i < mesh.primitives.size(); ++i) {
tinygltf::Primitive primitive = mesh.primitives[i];
tinygltf::Accessor indexAccessor = model.accessors[primitive.indices];
for (auto &attrib : primitive.attributes) {
tinygltf::Accessor accessor = model.accessors[attrib.second];
int byteStride =
accessor.ByteStride(model.bufferViews[accessor.bufferView]);
glBindBuffer(GL_ARRAY_BUFFER, vbos[accessor.bufferView]);
int size = 1;
if (accessor.type != TINYGLTF_TYPE_SCALAR) {
size = accessor.type;
}
int vaa = -1;
if (attrib.first.compare("POSITION") == 0) vaa = 0;
if (attrib.first.compare("NORMAL") == 0) vaa = 1;
if (attrib.first.compare("TEXCOORD_0") == 0) vaa = 2;
if (vaa > -1) {
glEnableVertexAttribArray(vaa);
glVertexAttribPointer(vaa, size, accessor.componentType,
accessor.normalized ? GL_TRUE : GL_FALSE,
byteStride, BUFFER_OFFSET(accessor.byteOffset));
} else
std::cout << "vaa missing: " << attrib.first << std::endl;
}
if (model.textures.size() > 0) {
// fixme: Use material's baseColor
tinygltf::Texture &tex = model.textures[0];
if (tex.source > -1) {
GLuint texid;
glGenTextures(1, &texid);
tinygltf::Image &image = model.images[tex.source];
glBindTexture(GL_TEXTURE_2D, texid);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
GLenum format = GL_RGBA;
if (image.component == 1) {
format = GL_RED;
} else if (image.component == 2) {
format = GL_RG;
} else if (image.component == 3) {
format = GL_RGB;
} else {
// ???
}
GLenum type = GL_UNSIGNED_BYTE;
if (image.bits == 8) {
// ok
} else if (image.bits == 16) {
type = GL_UNSIGNED_SHORT;
} else {
// ???
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0,
format, type, &image.image.at(0));
}
}
}
}
// bind models
void bindModelNodes(std::map<int, GLuint>& vbos, tinygltf::Model &model,
tinygltf::Node &node) {
if ((node.mesh >= 0) && (node.mesh < model.meshes.size())) {
bindMesh(vbos, model, model.meshes[node.mesh]);
}
for (size_t i = 0; i < node.children.size(); i++) {
assert((node.children[i] >= 0) && (node.children[i] < model.nodes.size()));
bindModelNodes(vbos, model, model.nodes[node.children[i]]);
}
}
std::pair<GLuint, std::map<int, GLuint>> bindModel(tinygltf::Model &model) {
std::map<int, GLuint> vbos;
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
const tinygltf::Scene &scene = model.scenes[model.defaultScene];
for (size_t i = 0; i < scene.nodes.size(); ++i) {
assert((scene.nodes[i] >= 0) && (scene.nodes[i] < model.nodes.size()));
bindModelNodes(vbos, model, model.nodes[scene.nodes[i]]);
}
glBindVertexArray(0);
// cleanup vbos but do not delete index buffers yet
for (auto it = vbos.cbegin(); it != vbos.cend();) {
tinygltf::BufferView bufferView = model.bufferViews[it->first];
if (bufferView.target != GL_ELEMENT_ARRAY_BUFFER) {
glDeleteBuffers(1, &vbos[it->first]);
vbos.erase(it++);
}
else {
++it;
}
}
return {vao, vbos};
}
void drawMesh(const std::map<int, GLuint>& vbos,
tinygltf::Model &model, tinygltf::Mesh &mesh) {
for (size_t i = 0; i < mesh.primitives.size(); ++i) {
tinygltf::Primitive primitive = mesh.primitives[i];
tinygltf::Accessor indexAccessor = model.accessors[primitive.indices];
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbos.at(indexAccessor.bufferView));
glDrawElements(primitive.mode, indexAccessor.count,
indexAccessor.componentType,
BUFFER_OFFSET(indexAccessor.byteOffset));
}
}
// recursively draw node and children nodes of model
void drawModelNodes(const std::pair<GLuint, std::map<int, GLuint>>& vaoAndEbos,
tinygltf::Model &model, tinygltf::Node &node) {
if ((node.mesh >= 0) && (node.mesh < model.meshes.size())) {
drawMesh(vaoAndEbos.second, model, model.meshes[node.mesh]);
}
for (size_t i = 0; i < node.children.size(); i++) {
drawModelNodes(vaoAndEbos, model, model.nodes[node.children[i]]);
}
}
void drawModel(const std::pair<GLuint, std::map<int, GLuint>>& vaoAndEbos,
tinygltf::Model &model) {
glBindVertexArray(vaoAndEbos.first);
const tinygltf::Scene &scene = model.scenes[model.defaultScene];
for (size_t i = 0; i < scene.nodes.size(); ++i) {
drawModelNodes(vaoAndEbos, model, model.nodes[scene.nodes[i]]);
}
glBindVertexArray(0);
}
void dbgModel(tinygltf::Model &model) {
for (auto &mesh : model.meshes) {
std::cout << "mesh : " << mesh.name << std::endl;
for (auto &primitive : mesh.primitives) {
const tinygltf::Accessor &indexAccessor =
model.accessors[primitive.indices];
std::cout << "indexaccessor: count " << indexAccessor.count << ", type "
<< indexAccessor.componentType << std::endl;
tinygltf::Material &mat = model.materials[primitive.material];
for (auto &mats : mat.values) {
std::cout << "mat : " << mats.first.c_str() << std::endl;
}
for (auto &image : model.images) {
std::cout << "image name : " << image.uri << std::endl;
std::cout << " size : " << image.image.size() << std::endl;
std::cout << " w/h : " << image.width << "/" << image.height
<< std::endl;
}
std::cout << "indices : " << primitive.indices << std::endl;
std::cout << "mode : "
<< "(" << primitive.mode << ")" << std::endl;
for (auto &attrib : primitive.attributes) {
std::cout << "attribute : " << attrib.first.c_str() << std::endl;
}
}
}
}
glm::mat4 genView(glm::vec3 pos, glm::vec3 lookat) {
// Camera matrix
glm::mat4 view = glm::lookAt(
pos, // Camera in World Space
lookat, // and looks at the origin
glm::vec3(0, 1, 0) // Head is up (set to 0,-1,0 to look upside-down)
);
return view;
}
glm::mat4 genMVP(glm::mat4 view_mat, glm::mat4 model_mat, float fov, int w,
int h) {
glm::mat4 Projection =
glm::perspective(glm::radians(fov), (float)w / (float)h, 0.01f, 1000.0f);
// 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
glm::mat4 mvp = Projection * view_mat * model_mat;
return mvp;
}
void displayLoop(Window &window, const std::string &filename) {
Shaders shader = Shaders();
glUseProgram(shader.pid);
// grab uniforms to modify
GLuint MVP_u = glGetUniformLocation(shader.pid, "MVP");
GLuint sun_position_u = glGetUniformLocation(shader.pid, "sun_position");
GLuint sun_color_u = glGetUniformLocation(shader.pid, "sun_color");
tinygltf::Model model;
if (!loadModel(model, filename.c_str())) return;
std::pair<GLuint, std::map<int, GLuint>> vaoAndEbos = bindModel(model);
// dbgModel(model); return;
// Model matrix : an identity matrix (model will be at the origin)
glm::mat4 model_mat = glm::mat4(1.0f);
glm::mat4 model_rot = glm::mat4(1.0f);
glm::vec3 model_pos = glm::vec3(-3, 0, -3);
// generate a camera view, based on eye-position and lookAt world-position
glm::mat4 view_mat = genView(glm::vec3(2, 2, 20), model_pos);
glm::vec3 sun_position = glm::vec3(3.0, 10.0, -5.0);
glm::vec3 sun_color = glm::vec3(1.0);
while (!window.Close()) {
window.Resize();
glClearColor(0.2, 0.2, 0.2, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 trans =
glm::translate(glm::mat4(1.0f), model_pos); // reposition model
model_rot = glm::rotate(model_rot, glm::radians(0.8f),
glm::vec3(0, 1, 0)); // rotate model on y axis
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(vaoAndEbos, model);
glfwSwapBuffers(window.window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &vaoAndEbos.first);
}
static void error_callback(int error, const char *description) {
(void)error;
fprintf(stderr, "Error: %s\n", description);
}
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;
// Force create OpenGL 3.3
// NOTE(syoyo): Linux + NVIDIA driver segfaults for some reason? commenting out glfwWindowHint will work.
// Note (PE): On laptops with intel hd graphics card you can overcome the segfault by enabling experimental, see below (tested on lenovo thinkpad)
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glewExperimental = GL_TRUE;
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
Window window = Window(800, 600, "TinyGLTF basic example");
glfwMakeContextCurrent(window.window);
#ifdef __APPLE__
// https://stackoverflow.com/questions/50192625/openggl-segmentation-fault
glewExperimental = GL_TRUE;
#endif
glewInit();
std::cout << glGetString(GL_RENDERER) << ", " << glGetString(GL_VERSION)
<< std::endl;
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;
}
+2
View File
@@ -0,0 +1,2 @@
all:
$(CXX) -o create_triangle_gltf -I../../ create_triangle_gltf.cpp
@@ -0,0 +1,121 @@
// An example of how to generate a gltf file from scratch. This example
// was translated from the pygltlib documentation in the pypi project page,
// which in turn is based on the Khronos Sample Models at:
//
// https://github.com/KhronosGroup/glTF-Sample-Models
//
// This example is released under the MIT license.
//
// 2021-02-25 Thu
// Dov Grobgeld <dov.grobgeld@gmail.com>
// Define these only in *one* .cc file.
#define TINYGLTF_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
// #define TINYGLTF_NOEXCEPTION // optional. disable exception handling.
#include "tiny_gltf.h"
int main(int argc, char **argv)
{
// Create a model with a single mesh and save it as a gltf file
tinygltf::Model m;
tinygltf::Scene scene;
tinygltf::Mesh mesh;
tinygltf::Primitive primitive;
tinygltf::Node node;
tinygltf::Buffer buffer;
tinygltf::BufferView bufferView1;
tinygltf::BufferView bufferView2;
tinygltf::Accessor accessor1;
tinygltf::Accessor accessor2;
tinygltf::Asset asset;
// This is the raw data buffer.
buffer.data = {
// 6 bytes of indices and two bytes of padding
0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x00,
// 36 bytes of floating point numbers
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3f,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3f,
0x00,0x00,0x00,0x00};
// "The indices of the vertices (ELEMENT_ARRAY_BUFFER) take up 6 bytes in the
// start of the buffer.
bufferView1.buffer = 0;
bufferView1.byteOffset=0;
bufferView1.byteLength=6;
bufferView1.target = TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER;
// The vertices take up 36 bytes (3 vertices * 3 floating points * 4 bytes)
// at position 8 in the buffer and are of type ARRAY_BUFFER
bufferView2.buffer = 0;
bufferView2.byteOffset=8;
bufferView2.byteLength=36;
bufferView2.target = TINYGLTF_TARGET_ARRAY_BUFFER;
// Describe the layout of bufferView1, the indices of the vertices
accessor1.bufferView = 0;
accessor1.byteOffset = 0;
accessor1.componentType = TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT;
accessor1.count = 3;
accessor1.type = TINYGLTF_TYPE_SCALAR;
accessor1.maxValues.push_back(2);
accessor1.minValues.push_back(0);
// Describe the layout of bufferView2, the vertices themself
accessor2.bufferView = 1;
accessor2.byteOffset = 0;
accessor2.componentType = TINYGLTF_COMPONENT_TYPE_FLOAT;
accessor2.count = 3;
accessor2.type = TINYGLTF_TYPE_VEC3;
accessor2.maxValues = {1.0, 1.0, 0.0};
accessor2.minValues = {0.0, 0.0, 0.0};
// Build the mesh primitive and add it to the mesh
primitive.indices = 0; // The index of the accessor for the vertex indices
primitive.attributes["POSITION"] = 1; // The index of the accessor for positions
primitive.material = 0;
primitive.mode = TINYGLTF_MODE_TRIANGLES;
mesh.primitives.push_back(primitive);
// Other tie ups
node.mesh = 0;
scene.nodes.push_back(0); // Default scene
// Define the asset. The version is required
asset.version = "2.0";
asset.generator = "tinygltf";
// Now all that remains is to tie back all the loose objects into the
// our single model.
m.scenes.push_back(scene);
m.meshes.push_back(mesh);
m.nodes.push_back(node);
m.buffers.push_back(buffer);
m.bufferViews.push_back(bufferView1);
m.bufferViews.push_back(bufferView2);
m.accessors.push_back(accessor1);
m.accessors.push_back(accessor2);
m.asset = asset;
// Create a simple material
tinygltf::Material mat;
mat.pbrMetallicRoughness.baseColorFactor = {1.0f, 0.9f, 0.9f, 1.0f};
mat.doubleSided = true;
m.materials.push_back(mat);
// Save it to a file
tinygltf::TinyGLTF gltf;
gltf.WriteGltfSceneToFile(&m, "triangle.gltf",
true, // embedImages
true, // embedBuffers
true, // pretty print
false); // write binary
exit(0);
}
+36
View File
@@ -0,0 +1,36 @@
cmake_minimum_required(VERSION 3.5)
project(dxview)
find_package(glfw3 CONFIG REQUIRED)
find_package(spdlog CONFIG REQUIRED)
add_executable(dxview
src/Viewer.h
src/Viewer.cc
src/dxview.cc
)
target_include_directories(dxview
PRIVATE
../../
)
target_compile_definitions(dxview
PRIVATE
DXVIEW_SWAP_CHAIN_BUFFER_COUNT=3
DXVIEW_RES_DIR=L"${PROJECT_SOURCE_DIR}/res"
)
target_link_libraries(dxview
PRIVATE
dxgi
d3dcompiler
d3d12
glfw
spdlog::spdlog
)
set_target_properties(dxview
PROPERTIES
CXX_STANDARD 17
)
+37
View File
@@ -0,0 +1,37 @@
# DirectX glTF Viewer
## Overview
This project was motivated by a lack of sample code demonstrating the graphics API agnostic nature of the glTF specification. The sample code is written using modern C++ and DirectX 12 for the client application.
## Features
* [x] DirectX 12
* [ ] Loader
* [ ] Animation
* [ ] Morph Target
* [ ] Physical Base Rendering
* [ ] Environment Map
## Dependencies
* [CMake](https://github.com/Kitware/CMake)
* [Vcpkg](https://github.com/Microsoft/vcpkg)
* [GLFW](https://github.com/glfw/glfw)
* [spdlog](https://github.com/gabime/spdlog)
## Building
### Install dependencies
```
vcpkg install glfw3:x64-windows
vcpkg install spdlog:x64-windows
```
### Generate Project Files
```
mkdir build
cmake . -B build -DCMAKE_TOOLCHAIN_FILE=${VCPKG_DIR}/script/buildsystem/vcpkg.cmake
```
+3
View File
@@ -0,0 +1,3 @@
float4 main() : SV_Target {
return float4(0.5, 0.5, 0.5, 1.0);
}
+52
View File
@@ -0,0 +1,52 @@
struct RS2PS {
float4 position : SV_POSITION;
#ifdef HAS_TEXCOORD_0
float2 texcoord_0: TEXCOORD_0;
#endif
};
struct TextureInfo {
uint textureIndex;
uint samplerIndex;
};
struct PBRMetallicRoughness {
float4 baseColorFactor;
TextureInfo baseColorTexture;
float metallicFactor;
float roughnessFactor;
TextureInfo metallicRoughnessTexture;
};
cbuffer Material : register(b2) {
PBRMetallicRoughness pbrMetallicRoughness;
};
Texture2D textures[5] : register(t0);
SamplerState samplerState[5] : register(s0);
float4 getBaseColor(float2 uv) {
float4 baseColor = pbrMetallicRoughness.baseColorFactor;
#ifdef HAS_TEXCOORD_0
TextureInfo baseColorTexture = pbrMetallicRoughness.baseColorTexture;
if (baseColorTexture.textureIndex >= 0) {
baseColor *= textures[baseColorTexture.textureIndex].Sample(samplerState[baseColorTexture.samplerIndex], uv);
}
#endif
return baseColor;
}
float4 main(RS2PS input) : SV_Target {
float2 uv = float2(0.0, 0.0);
#ifdef HAS_TEXCOORD_0
uv = input.texcoord_0;
#endif
float4 color = getBaseColor(uv);
return color;
}
+46
View File
@@ -0,0 +1,46 @@
struct IA2VS {
float3 position : POSITION;
#ifdef HAS_NORMAL
float3 normal : NORMAL;
#endif
#ifdef HAS_TANGENT
float4 tangent : TANGENT;
#endif
#ifdef HAS_TEXCOORD_0
float2 texcoord_0: TEXCOORD_0;
#endif
};
struct VS2RS {
float4 position : SV_POSITION;
#ifdef HAS_TEXCOORD_0
float2 texcoord_0: TEXCOORD_0;
#endif
};
cbuffer Camera : register(b0) {
float4x4 V;
float4x4 P;
float4x4 VP;
};
cbuffer Node : register(b1) {
float4x4 M;
};
VS2RS main(IA2VS input) {
VS2RS output;
output.position = mul(float4(input.position, 1.0), M);
output.position = mul(output.position, V);
output.position = mul(output.position, P);
#ifdef HAS_TEXCOORD_0
output.texcoord_0 = input.texcoord_0;
#endif
return output;
}
File diff suppressed because it is too large Load Diff
+130
View File
@@ -0,0 +1,130 @@
#ifndef DXVIEW_VIEWER_GUARD
#define DXVIEW_VIEWER_GUARD
#include <DirectXMath.h>
#include <d3d12.h>
#include <dxgi1_6.h>
#include <tiny_gltf.h>
#include <wrl.h>
#include <filesystem>
#include <map>
#include <string>
#include <vector>
using Microsoft::WRL::ComPtr;
enum RenderPassType { RENDER_PASS_TYPE_PRESENT = 0, RENDER_PASS_TYPE_COUNT };
struct RenderTarget {
ComPtr<ID3D12Resource> pTexture;
D3D12_CPU_DESCRIPTOR_HANDLE viewDescriptor;
};
struct TextureInfo {
int32_t textureIndex;
int32_t samplerIndex;
};
struct PBRMetallicRoughness {
DirectX::XMFLOAT4 baseColorFactor;
TextureInfo baseColorTexture;
float metallicFactor;
float roughnessFactor;
TextureInfo metallicRoughnessTexture;
};
struct Material {
std::string name;
D3D12_BLEND_DESC blendDesc;
D3D12_RASTERIZER_DESC rasterizerDesc;
ComPtr<ID3D12Resource> pBuffer;
void* pBufferData;
ComPtr<ID3D12DescriptorHeap> pSRVDescriptorHeap;
ComPtr<ID3D12DescriptorHeap> pSamplerDescriptorHeap;
};
struct Attribute {
std::string name;
DXGI_FORMAT format;
D3D12_VERTEX_BUFFER_VIEW vertexBufferView;
};
struct Primitive {
std::vector<Attribute> attributes;
uint32_t vertexCount;
D3D12_PRIMITIVE_TOPOLOGY primitiveTopology;
D3D12_INDEX_BUFFER_VIEW indexBufferView;
uint32_t indexCount;
Material* pMaterial;
ComPtr<ID3D12RootSignature> pRootSignature;
ComPtr<ID3D12PipelineState> pPipelineState;
};
struct Mesh {
std::string name;
std::vector<Primitive> primitives;
};
struct Node {
DirectX::XMFLOAT4X4 M;
};
struct Camera {
DirectX::XMFLOAT4X4 V;
DirectX::XMFLOAT4X4 P;
DirectX::XMFLOAT4X4 VP;
};
class Viewer {
public:
Viewer(HWND window, tinygltf::Model* pModel);
void update(double deltaTime);
void render(double deltaTime);
private:
void initDirectX(HWND window);
void buildRenderTargets();
void buildResources();
void buildBuffers(std::vector<ComPtr<ID3D12Resource> >* pStagingResources);
void buildImages(std::vector<ComPtr<ID3D12Resource> >* pStagingResources);
void buildSamplerDescs();
void buildMaterials();
void buildMeshes();
void buildNodes();
void drawNode(uint64_t nodeIndex);
private:
tinygltf::Model* pModel_;
ComPtr<IDXGIFactory1> pFactory_;
ComPtr<IDXGIAdapter1> pAdapter_;
ComPtr<ID3D12Device> pDevice_;
ComPtr<ID3D12CommandQueue> pDirectCommandQueue_;
UINT64 directFenceValue_;
ComPtr<ID3D12Fence> pDirectFence_;
ComPtr<ID3D12CommandQueue> pCopyCommandQueue_;
UINT64 copyFenceValue_;
ComPtr<ID3D12Fence> pCopyFence_;
ComPtr<IDXGISwapChain3> pSwapChain_;
ComPtr<ID3D12Resource> pSwapChainBuffers_[DXVIEW_SWAP_CHAIN_BUFFER_COUNT];
ComPtr<ID3D12CommandAllocator>
pDirectCommandAllocators_[DXVIEW_SWAP_CHAIN_BUFFER_COUNT];
ComPtr<ID3D12GraphicsCommandList> pDirectCommandList_;
ComPtr<ID3D12CommandAllocator> pCopyCommandAllocator_;
ComPtr<ID3D12GraphicsCommandList> pCopyCommandList_;
UINT descriptorIncrementSize_[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES];
ComPtr<ID3D12DescriptorHeap>
pRTVDescriptorHeaps_[DXVIEW_SWAP_CHAIN_BUFFER_COUNT];
std::vector<RenderTarget> renderTargets_[DXVIEW_SWAP_CHAIN_BUFFER_COUNT];
std::vector<ComPtr<ID3D12Resource> > pBuffers_;
std::vector<ComPtr<ID3D12Resource> > pTextures_;
std::vector<D3D12_SAMPLER_DESC> samplerDescs_;
std::vector<Material> materials_;
std::vector<Mesh> meshes_;
std::vector<ComPtr<ID3D12Resource> > pNodeBuffers_;
ComPtr<ID3D12Resource> pCameraBuffer_;
};
#endif
+90
View File
@@ -0,0 +1,90 @@
#define GLFW_EXPOSE_NATIVE_WIN32
#define TINYGLTF_IMPLEMENTATION
#define STBI_MSC_SECURE_CRT
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include <GLFW/glfw3.h>
#include <GLFW/glfw3native.h>
#include <spdlog/spdlog.h>
#include <tiny_gltf.h>
#undef GLFW_EXPOSE_NATIVE_WIN32
#undef TINYGLTF_IMPLEMENTATION
#undef STBI_MSC_SECURE_CRT
#undef STB_IMAGE_IMPLEMENTATION
#undef STB_IMAGE_WRITE_IMPLEMENTATION
#include <iostream>
#include <string>
#include "Viewer.h"
static void onError(int error, const char* message) {
spdlog::error("[{}] {}", error, message);
}
static void onRender(Viewer* pViewer, double deltaTime) {
pViewer->update(deltaTime);
pViewer->render(deltaTime);
}
int main(int argc, char* argv[]) {
tinygltf::TinyGLTF context;
tinygltf::Model model;
std::string error;
std::string warning;
if (!context.LoadASCIIFromFile(&model, &error, &warning, argv[1])) {
if (!error.empty()) {
spdlog::error("{}", error);
}
if (!warning.empty()) {
spdlog::warn("{}", warning);
}
exit(EXIT_FAILURE);
}
GLFWwindow* pWindow;
glfwSetErrorCallback(onError);
if (!glfwInit()) {
spdlog::error("Fail to initialize GLFW!!!");
exit(EXIT_FAILURE);
}
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
pWindow = glfwCreateWindow(512, 512, "dxview", nullptr, nullptr);
if (!pWindow) {
spdlog::error("Fail to create GLFWwindow!!!");
glfwTerminate();
exit(EXIT_FAILURE);
}
auto pViewer = std::make_unique<Viewer>(glfwGetWin32Window(pWindow), &model);
if (!pViewer) {
spdlog::error("Fail to create Viewer");
glfwDestroyWindow(pWindow);
glfwTerminate();
exit(EXIT_FAILURE);
}
auto prevTimeStamp = glfwGetTime();
while (!glfwWindowShouldClose(pWindow)) {
auto currTimeStamp = glfwGetTime();
onRender(pViewer.get(), currTimeStamp - prevTimeStamp);
prevTimeStamp = currTimeStamp;
glfwPollEvents();
}
glfwDestroyWindow(pWindow);
glfwTerminate();
exit(EXIT_SUCCESS);
}
+3 -3
View File
@@ -29,7 +29,7 @@ if (DEFINED DRACO_DIR)
# TODO(syoyo): better CMake script for draco
add_definitions(-DTINYGLTF_ENABLE_DRACO)
include_directories(${DRACO_DIR}/include)
link_directories(${DRACO_DIR}/lib)
set(DRACO_LIBRARY draco)
endif ()
@@ -49,9 +49,9 @@ add_executable(glview
)
target_link_libraries ( glview
${DRACO_LIBRARY}
${DRACO_LIBRARY}
${GLFW3_UNIX_LINK_LIBRARIES}
${GLEW_LIBRARY}
${GLEW_LIBRARIES}
${GLFW3_glfw_LIBRARY}
${OPENGL_gl_LIBRARY}
${OPENGL_glu_LIBRARY}
+37 -9
View File
@@ -771,6 +771,30 @@ static void DrawCurves(tinygltf::Scene &scene, const tinygltf::Mesh &mesh) {
}
#endif
static void QuatToAngleAxis(const std::vector<double> quaternion,
double &outAngleDegrees,
double *axis) {
double qx = quaternion[0];
double qy = quaternion[1];
double qz = quaternion[2];
double qw = quaternion[3];
double angleRadians = 2 * acos(qw);
if (angleRadians == 0.0) {
outAngleDegrees = 0.0;
axis[0] = 0.0;
axis[1] = 0.0;
axis[2] = 1.0;
return;
}
double denom = sqrt(1-qw*qw);
outAngleDegrees = angleRadians * 180.0 / M_PI;
axis[0] = qx / denom;
axis[1] = qy / denom;
axis[2] = qz / denom;
}
// Hierarchically draw nodes
static void DrawNode(tinygltf::Model &model, const tinygltf::Node &node) {
// Apply xform
@@ -781,18 +805,22 @@ static void DrawNode(tinygltf::Model &model, const tinygltf::Node &node) {
glMultMatrixd(node.matrix.data());
} else {
// Assume Trans x Rotate x Scale order
if (node.scale.size() == 3) {
glScaled(node.scale[0], node.scale[1], node.scale[2]);
}
if (node.rotation.size() == 4) {
glRotated(node.rotation[0], node.rotation[1], node.rotation[2],
node.rotation[3]);
}
if (node.translation.size() == 3) {
glTranslated(node.translation[0], node.translation[1],
node.translation[2]);
}
if (node.rotation.size() == 4) {
double angleDegrees;
double axis[3];
QuatToAngleAxis(node.rotation, angleDegrees, axis);
glRotated(angleDegrees, axis[0], axis[1], axis[2]);
}
if (node.scale.size() == 3) {
glScaled(node.scale[0], node.scale[1], node.scale[2]);
}
}
+12480 -6133
View File
File diff suppressed because it is too large Load Diff
+168 -8
View File
@@ -322,6 +322,15 @@ 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) {
std::cout << Indent(indent) << "material : " << primitive.material
<< std::endl;
@@ -333,19 +342,23 @@ static void DumpPrimitive(const tinygltf::Primitive &primitive, int indent) {
<< std::endl;
DumpStringIntMap(primitive.attributes, indent + 1);
DumpExtensions(primitive.extensions, indent);
std::cout << Indent(indent) << "extras :" << std::endl
<< PrintValue("extras", primitive.extras, indent + 1) << std::endl;
}
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;
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 DumpTextureInfo(const tinygltf::TextureInfo &texinfo,
const int indent) {
std::cout << Indent(indent) << "index : " << texinfo.index << "\n";
@@ -353,6 +366,17 @@ static void DumpTextureInfo(const tinygltf::TextureInfo &texinfo,
<< "\n";
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,
@@ -500,7 +524,7 @@ static void Dump(const tinygltf::Model &model) {
<< std::endl;
std::cout << Indent(1) << "channels : [ " << std::endl;
for (size_t j = 0; i < animation.channels.size(); i++) {
for (size_t j = 0; j < animation.channels.size(); j++) {
std::cout << Indent(2)
<< "sampler : " << animation.channels[j].sampler
<< std::endl;
@@ -546,6 +570,21 @@ static void Dump(const tinygltf::Model &model) {
std::cout << Indent(2)
<< "target : " << PrintTarget(bufferView.target)
<< 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";
}
}
}
@@ -556,6 +595,21 @@ static void Dump(const tinygltf::Model &model) {
std::cout << Indent(1) << "name : " << buffer.name << std::endl;
std::cout << Indent(2) << "byteLength : " << buffer.data.size()
<< 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";
}
}
}
@@ -602,6 +656,17 @@ static void Dump(const tinygltf::Model &model) {
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";
}
}
}
@@ -625,6 +690,18 @@ static void Dump(const tinygltf::Model &model) {
std::cout << Indent(2) << "height : " << image.height << std::endl;
std::cout << Indent(2) << "component : " << image.component << std::endl;
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";
}
}
}
@@ -637,6 +714,18 @@ static void Dump(const tinygltf::Model &model) {
std::cout << Indent(1) << "source : " << texture.source
<< std::endl;
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";
}
}
}
@@ -658,6 +747,20 @@ static void Dump(const tinygltf::Model &model) {
std::cout << Indent(2)
<< "wrapT : " << PrintWrapMode(sampler.wrapT)
<< 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";
}
}
}
@@ -690,6 +793,54 @@ static void Dump(const tinygltf::Model &model) {
<< "znear : " << camera.orthographic.znear
<< 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";
}
}
}
@@ -707,6 +858,12 @@ int main(int argc, char **argv) {
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::TinyGLTF gltf_ctx;
std::string err;
@@ -714,6 +871,9 @@ int main(int argc, char **argv) {
std::string input_filename(argv[1]);
std::string ext = GetFilePathExtension(input_filename);
gltf_ctx.SetStoreOriginalJSONForExtrasAndExtensions(
store_original_json_for_extras_and_extensions);
bool ret = false;
if (ext.compare("glb") == 0) {
std::cout << "Reading binary glTF" << std::endl;
Binary file not shown.

After

Width:  |  Height:  |  Size: 79 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 B

@@ -0,0 +1,171 @@
{
"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"
}
]
}
Binary file not shown.
@@ -0,0 +1,171 @@
{
"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"
}
]
}
Binary file not shown.
@@ -0,0 +1,376 @@
{
"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
]
}
]
}
File diff suppressed because one or more lines are too long
+701 -224
View File
File diff suppressed because it is too large Load Diff
+221 -118
View File
@@ -1,4 +1,4 @@
/* stb_image_write - v1.11 - public domain - http://nothings.org/stb/stb_image_write.h
/* stb_image_write - v1.16 - public domain - http://nothings.org/stb
writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015
no warranty implied; use at your own risk
@@ -10,11 +10,6 @@
Will probably not work correctly with strict-aliasing optimizations.
If using a modern Microsoft Compiler, non-safe versions of CRT calls may cause
compilation warnings or even errors. To avoid this, also before #including,
#define STBI_MSC_SECURE_CRT
ABOUT:
This header file is a library for writing images to C stdio or a callback.
@@ -110,7 +105,7 @@ USAGE:
TGA supports RLE or non-RLE compressed data. To use non-RLE-compressed
data, set the global variable 'stbi_write_tga_with_rle' to 0.
JPEG does ignore alpha channels in input data; quality is between 1 and 100.
Higher quality looks better but results in a bigger image.
JPEG baseline (no JPEG progressive).
@@ -118,7 +113,7 @@ USAGE:
CREDITS:
Sean Barrett - PNG/BMP/TGA
Sean Barrett - PNG/BMP/TGA
Baldur Karlsson - HDR
Jean-Sebastien Guay - TGA monochrome
Tim Kelsey - misc enhancements
@@ -145,6 +140,7 @@ CREDITS:
Ivan Tikhonov
github:ignotion
Adam Schackart
Andrew Kensler
LICENSE
@@ -171,9 +167,9 @@ LICENSE
#endif
#ifndef STB_IMAGE_WRITE_STATIC // C++ forbids static forward declarations
extern int stbi_write_tga_with_rle;
extern int stbi_write_png_compression_level;
extern int stbi_write_force_png_filter;
STBIWDEF int stbi_write_tga_with_rle;
STBIWDEF int stbi_write_png_compression_level;
STBIWDEF int stbi_write_force_png_filter;
#endif
#ifndef STBI_WRITE_NO_STDIO
@@ -183,7 +179,7 @@ STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const
STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality);
#ifdef STBI_WINDOWS_UTF8
#ifdef STBIW_WINDOWS_UTF8
STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input);
#endif
#endif
@@ -252,17 +248,17 @@ STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean);
#define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff)
#ifdef STB_IMAGE_WRITE_STATIC
static int stbi__flip_vertically_on_write=0;
static int stbi_write_png_compression_level = 8;
static int stbi_write_tga_with_rle = 1;
static int stbi_write_force_png_filter = -1;
#else
int stbi_write_png_compression_level = 8;
int stbi__flip_vertically_on_write=0;
int stbi_write_tga_with_rle = 1;
int stbi_write_force_png_filter = -1;
#endif
static int stbi__flip_vertically_on_write = 0;
STBIWDEF void stbi_flip_vertically_on_write(int flag)
{
stbi__flip_vertically_on_write = flag;
@@ -272,6 +268,8 @@ typedef struct
{
stbi_write_func *func;
void *context;
unsigned char buffer[64];
int buf_used;
} stbi__write_context;
// initialize a callback-based context
@@ -288,7 +286,7 @@ static void stbi__stdio_write(void *context, void *data, int size)
fwrite(data,1,size,(FILE*) context);
}
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
#if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8)
#ifdef __cplusplus
#define STBIW_EXTERN extern "C"
#else
@@ -299,25 +297,25 @@ STBIW_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned in
STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input)
{
return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, bufferlen, NULL, NULL);
return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
}
#endif
static FILE *stbiw__fopen(char const *filename, char const *mode)
{
FILE *f;
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
#if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8)
wchar_t wMode[64];
wchar_t wFilename[1024];
if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)))
return 0;
if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)))
if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename)))
return 0;
#if _MSC_VER >= 1400
if (0 != _wfopen_s(&f, wFilename, wMode))
f = 0;
if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode)))
return 0;
#if defined(_MSC_VER) && _MSC_VER >= 1400
if (0 != _wfopen_s(&f, wFilename, wMode))
f = 0;
#else
f = _wfopen(wFilename, wMode);
#endif
@@ -385,16 +383,36 @@ static void stbiw__writef(stbi__write_context *s, const char *fmt, ...)
va_end(v);
}
static void stbiw__write_flush(stbi__write_context *s)
{
if (s->buf_used) {
s->func(s->context, &s->buffer, s->buf_used);
s->buf_used = 0;
}
}
static void stbiw__putc(stbi__write_context *s, unsigned char c)
{
s->func(s->context, &c, 1);
}
static void stbiw__write1(stbi__write_context *s, unsigned char a)
{
if ((size_t)s->buf_used + 1 > sizeof(s->buffer))
stbiw__write_flush(s);
s->buffer[s->buf_used++] = a;
}
static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c)
{
unsigned char arr[3];
arr[0] = a, arr[1] = b, arr[2] = c;
s->func(s->context, arr, 3);
int n;
if ((size_t)s->buf_used + 3 > sizeof(s->buffer))
stbiw__write_flush(s);
n = s->buf_used;
s->buf_used = n+3;
s->buffer[n+0] = a;
s->buffer[n+1] = b;
s->buffer[n+2] = c;
}
static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d)
@@ -403,7 +421,7 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in
int k;
if (write_alpha < 0)
s->func(s->context, &d[comp - 1], 1);
stbiw__write1(s, d[comp - 1]);
switch (comp) {
case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case
@@ -411,7 +429,7 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in
if (expand_mono)
stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp
else
s->func(s->context, d, 1); // monochrome TGA
stbiw__write1(s, d[0]); // monochrome TGA
break;
case 4:
if (!write_alpha) {
@@ -427,7 +445,7 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in
break;
}
if (write_alpha > 0)
s->func(s->context, &d[comp - 1], 1);
stbiw__write1(s, d[comp - 1]);
}
static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad, int expand_mono)
@@ -441,16 +459,18 @@ static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, i
if (stbi__flip_vertically_on_write)
vdir *= -1;
if (vdir < 0)
j_end = -1, j = y-1;
else
j_end = y, j = 0;
if (vdir < 0) {
j_end = -1; j = y-1;
} else {
j_end = y; j = 0;
}
for (; j != j_end; j += vdir) {
for (i=0; i < x; ++i) {
unsigned char *d = (unsigned char *) data + (j*x+i)*comp;
stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d);
}
stbiw__write_flush(s);
s->func(s->context, &zero, scanline_pad);
}
}
@@ -471,16 +491,27 @@ static int stbiw__outfile(stbi__write_context *s, int rgb_dir, int vdir, int x,
static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data)
{
int pad = (-x*3) & 3;
return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad,
"11 4 22 4" "4 44 22 444444",
'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header
40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header
if (comp != 4) {
// write RGB bitmap
int pad = (-x*3) & 3;
return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad,
"11 4 22 4" "4 44 22 444444",
'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header
40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header
} else {
// RGBA bitmaps need a v4 header
// use BI_BITFIELDS mode with 32bpp and alpha mask
// (straight BI_RGB with alpha mask doesn't work in most readers)
return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *)data,1,0,
"11 4 22 4" "4 44 22 444444 4444 4 444 444 444 444",
'B', 'M', 14+108+x*y*4, 0, 0, 14+108, // file header
108, x,y, 1,32, 3,0,0,0,0,0, 0xff0000,0xff00,0xff,0xff000000u, 0, 0,0,0, 0,0,0, 0,0,0, 0,0,0); // bitmap V4 header
}
}
STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
{
stbi__write_context s;
stbi__write_context s = { 0 };
stbi__start_write_callbacks(&s, func, context);
return stbi_write_bmp_core(&s, x, y, comp, data);
}
@@ -488,7 +519,7 @@ STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x,
#ifndef STBI_WRITE_NO_STDIO
STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data)
{
stbi__write_context s;
stbi__write_context s = { 0 };
if (stbi__start_write_file(&s,filename)) {
int r = stbi_write_bmp_core(&s, x, y, comp, data);
stbi__end_write_file(&s);
@@ -561,24 +592,25 @@ static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, v
if (diff) {
unsigned char header = STBIW_UCHAR(len - 1);
s->func(s->context, &header, 1);
stbiw__write1(s, header);
for (k = 0; k < len; ++k) {
stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp);
}
} else {
unsigned char header = STBIW_UCHAR(len - 129);
s->func(s->context, &header, 1);
stbiw__write1(s, header);
stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin);
}
}
}
stbiw__write_flush(s);
}
return 1;
}
STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
{
stbi__write_context s;
stbi__write_context s = { 0 };
stbi__start_write_callbacks(&s, func, context);
return stbi_write_tga_core(&s, x, y, comp, (void *) data);
}
@@ -586,7 +618,7 @@ STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x,
#ifndef STBI_WRITE_NO_STDIO
STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data)
{
stbi__write_context s;
stbi__write_context s = { 0 };
if (stbi__start_write_file(&s,filename)) {
int r = stbi_write_tga_core(&s, x, y, comp, (void *) data);
stbi__end_write_file(&s);
@@ -602,6 +634,8 @@ STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const
#define stbiw__max(a, b) ((a) > (b) ? (a) : (b))
#ifndef STBI_WRITE_NO_STDIO
static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
{
int exponent;
@@ -736,8 +770,8 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f
char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
s->func(s->context, header, sizeof(header)-1);
#ifdef STBI_MSC_SECURE_CRT
len = sprintf_s(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
#ifdef __STDC_LIB_EXT1__
len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
#else
len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
#endif
@@ -752,15 +786,14 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f
STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data)
{
stbi__write_context s;
stbi__write_context s = { 0 };
stbi__start_write_callbacks(&s, func, context);
return stbi_write_hdr_core(&s, x, y, comp, (float *) data);
}
#ifndef STBI_WRITE_NO_STDIO
STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data)
{
stbi__write_context s;
stbi__write_context s = { 0 };
if (stbi__start_write_file(&s,filename)) {
int r = stbi_write_hdr_core(&s, x, y, comp, (float *) data);
stbi__end_write_file(&s);
@@ -778,7 +811,7 @@ STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const
#ifndef STBIW_ZLIB_COMPRESS
// stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
#define stbiw__sbraw(a) ((int *) (a) - 2)
#define stbiw__sbraw(a) ((int *) (void *) (a) - 2)
#define stbiw__sbm(a) stbiw__sbraw(a)[0]
#define stbiw__sbn(a) stbiw__sbraw(a)[1]
@@ -872,7 +905,7 @@ STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, i
unsigned int bitbuf=0;
int i,j, bitcount=0;
unsigned char *out = NULL;
unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(char**));
unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(unsigned char**));
if (hash_table == NULL)
return NULL;
if (quality < 5) quality = 5;
@@ -895,7 +928,7 @@ STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, i
for (j=0; j < n; ++j) {
if (hlist[j]-data > i-32768) { // if entry lies within window
int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i);
if (d >= best) best=d,bestloc=hlist[j];
if (d >= best) { best=d; bestloc=hlist[j]; }
}
}
// when hash table entry is too long, delete half the entries
@@ -948,14 +981,31 @@ STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, i
(void) stbiw__sbfree(hash_table[i]);
STBIW_FREE(hash_table);
// store uncompressed instead if compression was worse
if (stbiw__sbn(out) > data_len + 2 + ((data_len+32766)/32767)*5) {
stbiw__sbn(out) = 2; // truncate to DEFLATE 32K window and FLEVEL = 1
for (j = 0; j < data_len;) {
int blocklen = data_len - j;
if (blocklen > 32767) blocklen = 32767;
stbiw__sbpush(out, data_len - j == blocklen); // BFINAL = ?, BTYPE = 0 -- no compression
stbiw__sbpush(out, STBIW_UCHAR(blocklen)); // LEN
stbiw__sbpush(out, STBIW_UCHAR(blocklen >> 8));
stbiw__sbpush(out, STBIW_UCHAR(~blocklen)); // NLEN
stbiw__sbpush(out, STBIW_UCHAR(~blocklen >> 8));
memcpy(out+stbiw__sbn(out), data+j, blocklen);
stbiw__sbn(out) += blocklen;
j += blocklen;
}
}
{
// compute adler32 on input
unsigned int s1=1, s2=0;
int blocklen = (int) (data_len % 5552);
j=0;
while (j < data_len) {
for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1;
s1 %= 65521, s2 %= 65521;
for (i=0; i < blocklen; ++i) { s1 += data[j+i]; s2 += s1; }
s1 %= 65521; s2 %= 65521;
j += blocklen;
blocklen = 5552;
}
@@ -1048,13 +1098,13 @@ static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int
int type = mymap[filter_type];
unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height-1-y : y);
int signed_stride = stbi__flip_vertically_on_write ? -stride_bytes : stride_bytes;
if (type==0) {
memcpy(line_buffer, z, width*n);
return;
}
// first loop isn't optimized since it's just one pixel
// first loop isn't optimized since it's just one pixel
for (i = 0; i < n; ++i) {
switch (type) {
case 1: line_buffer[i] = z[i]; break;
@@ -1275,26 +1325,31 @@ static void stbiw__jpg_calcBits(int val, unsigned short bits[2]) {
bits[0] = val & ((1<<bits[1])-1);
}
static int stbiw__jpg_processDU(stbi__write_context *s, int *bitBuf, int *bitCnt, float *CDU, float *fdtbl, int DC, const unsigned short HTDC[256][2], const unsigned short HTAC[256][2]) {
static int stbiw__jpg_processDU(stbi__write_context *s, int *bitBuf, int *bitCnt, float *CDU, int du_stride, float *fdtbl, int DC, const unsigned short HTDC[256][2], const unsigned short HTAC[256][2]) {
const unsigned short EOB[2] = { HTAC[0x00][0], HTAC[0x00][1] };
const unsigned short M16zeroes[2] = { HTAC[0xF0][0], HTAC[0xF0][1] };
int dataOff, i, diff, end0pos;
int dataOff, i, j, n, diff, end0pos, x, y;
int DU[64];
// DCT rows
for(dataOff=0; dataOff<64; dataOff+=8) {
for(dataOff=0, n=du_stride*8; dataOff<n; dataOff+=du_stride) {
stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff+1], &CDU[dataOff+2], &CDU[dataOff+3], &CDU[dataOff+4], &CDU[dataOff+5], &CDU[dataOff+6], &CDU[dataOff+7]);
}
// DCT columns
for(dataOff=0; dataOff<8; ++dataOff) {
stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff+8], &CDU[dataOff+16], &CDU[dataOff+24], &CDU[dataOff+32], &CDU[dataOff+40], &CDU[dataOff+48], &CDU[dataOff+56]);
stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff+du_stride], &CDU[dataOff+du_stride*2], &CDU[dataOff+du_stride*3], &CDU[dataOff+du_stride*4],
&CDU[dataOff+du_stride*5], &CDU[dataOff+du_stride*6], &CDU[dataOff+du_stride*7]);
}
// Quantize/descale/zigzag the coefficients
for(i=0; i<64; ++i) {
float v = CDU[i]*fdtbl[i];
// DU[stbiw__jpg_ZigZag[i]] = (int)(v < 0 ? ceilf(v - 0.5f) : floorf(v + 0.5f));
// ceilf() and floorf() are C99, not C89, but I /think/ they're not needed here anyway?
DU[stbiw__jpg_ZigZag[i]] = (int)(v < 0 ? v - 0.5f : v + 0.5f);
for(y = 0, j=0; y < 8; ++y) {
for(x = 0; x < 8; ++x,++j) {
float v;
i = y*du_stride+x;
v = CDU[i]*fdtbl[j];
// DU[stbiw__jpg_ZigZag[j]] = (int)(v < 0 ? ceilf(v - 0.5f) : floorf(v + 0.5f));
// ceilf() and floorf() are C99, not C89, but I /think/ they're not needed here anyway?
DU[stbiw__jpg_ZigZag[j]] = (int)(v < 0 ? v - 0.5f : v + 0.5f);
}
}
// Encode DC
@@ -1409,10 +1464,10 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
37,56,68,109,103,77,24,35,55,64,81,104,113,92,49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99};
static const int UVQT[] = {17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99,
99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99};
static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f,
static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f,
1.0f * 2.828427125f, 0.785694958f * 2.828427125f, 0.541196100f * 2.828427125f, 0.275899379f * 2.828427125f };
int row, col, i, k;
int row, col, i, k, subsample;
float fdtbl_Y[64], fdtbl_UV[64];
unsigned char YTable[64], UVTable[64];
@@ -1421,6 +1476,7 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
}
quality = quality ? quality : 90;
subsample = quality <= 90 ? 1 : 0;
quality = quality < 1 ? 1 : quality > 100 ? 100 : quality;
quality = quality < 50 ? 5000 / quality : 200 - quality * 2;
@@ -1443,7 +1499,7 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
static const unsigned char head0[] = { 0xFF,0xD8,0xFF,0xE0,0,0x10,'J','F','I','F',0,1,1,0,0,1,0,1,0,0,0xFF,0xDB,0,0x84,0 };
static const unsigned char head2[] = { 0xFF,0xDA,0,0xC,3,1,0,2,0x11,3,0x11,0,0x3F,0 };
const unsigned char head1[] = { 0xFF,0xC0,0,0x11,8,(unsigned char)(height>>8),STBIW_UCHAR(height),(unsigned char)(width>>8),STBIW_UCHAR(width),
3,1,0x11,0,2,0x11,1,3,0x11,1,0xFF,0xC4,0x01,0xA2,0 };
3,1,(unsigned char)(subsample?0x22:0x11),0,2,0x11,1,3,0x11,1,0xFF,0xC4,0x01,0xA2,0 };
s->func(s->context, (void*)head0, sizeof(head0));
s->func(s->context, (void*)YTable, sizeof(YTable));
stbiw__putc(s, 1);
@@ -1466,36 +1522,74 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
// Encode 8x8 macroblocks
{
static const unsigned short fillBits[] = {0x7F, 7};
const unsigned char *imageData = (const unsigned char *)data;
int DCY=0, DCU=0, DCV=0;
int bitBuf=0, bitCnt=0;
// comp == 2 is grey+alpha (alpha is ignored)
int ofsG = comp > 2 ? 1 : 0, ofsB = comp > 2 ? 2 : 0;
const unsigned char *dataR = (const unsigned char *)data;
const unsigned char *dataG = dataR + ofsG;
const unsigned char *dataB = dataR + ofsB;
int x, y, pos;
for(y = 0; y < height; y += 8) {
for(x = 0; x < width; x += 8) {
float YDU[64], UDU[64], VDU[64];
for(row = y, pos = 0; row < y+8; ++row) {
// row >= height => use last input row
int clamped_row = (row < height) ? row : height - 1;
int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp;
for(col = x; col < x+8; ++col, ++pos) {
float r, g, b;
// if col >= width => use pixel from last input column
int p = base_p + ((col < width) ? col : (width-1))*comp;
if(subsample) {
for(y = 0; y < height; y += 16) {
for(x = 0; x < width; x += 16) {
float Y[256], U[256], V[256];
for(row = y, pos = 0; row < y+16; ++row) {
// row >= height => use last input row
int clamped_row = (row < height) ? row : height - 1;
int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp;
for(col = x; col < x+16; ++col, ++pos) {
// if col >= width => use pixel from last input column
int p = base_p + ((col < width) ? col : (width-1))*comp;
float r = dataR[p], g = dataG[p], b = dataB[p];
Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128;
U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b;
V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b;
}
}
DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+0, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+8, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+128, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+136, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
r = imageData[p+0];
g = imageData[p+ofsG];
b = imageData[p+ofsB];
YDU[pos]=+0.29900f*r+0.58700f*g+0.11400f*b-128;
UDU[pos]=-0.16874f*r-0.33126f*g+0.50000f*b;
VDU[pos]=+0.50000f*r-0.41869f*g-0.08131f*b;
// subsample U,V
{
float subU[64], subV[64];
int yy, xx;
for(yy = 0, pos = 0; yy < 8; ++yy) {
for(xx = 0; xx < 8; ++xx, ++pos) {
int j = yy*32+xx*2;
subU[pos] = (U[j+0] + U[j+1] + U[j+16] + U[j+17]) * 0.25f;
subV[pos] = (V[j+0] + V[j+1] + V[j+16] + V[j+17]) * 0.25f;
}
}
DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subU, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subV, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
}
}
}
} else {
for(y = 0; y < height; y += 8) {
for(x = 0; x < width; x += 8) {
float Y[64], U[64], V[64];
for(row = y, pos = 0; row < y+8; ++row) {
// row >= height => use last input row
int clamped_row = (row < height) ? row : height - 1;
int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp;
for(col = x; col < x+8; ++col, ++pos) {
// if col >= width => use pixel from last input column
int p = base_p + ((col < width) ? col : (width-1))*comp;
float r = dataR[p], g = dataG[p], b = dataB[p];
Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128;
U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b;
V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b;
}
}
DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT);
DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y, 8, fdtbl_Y, DCY, YDC_HT, YAC_HT);
DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, U, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, V, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
}
}
}
@@ -1512,7 +1606,7 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality)
{
stbi__write_context s;
stbi__write_context s = { 0 };
stbi__start_write_callbacks(&s, func, context);
return stbi_write_jpg_core(&s, x, y, comp, (void *) data, quality);
}
@@ -1521,7 +1615,7 @@ STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x,
#ifndef STBI_WRITE_NO_STDIO
STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality)
{
stbi__write_context s;
stbi__write_context s = { 0 };
if (stbi__start_write_file(&s,filename)) {
int r = stbi_write_jpg_core(&s, x, y, comp, data, quality);
stbi__end_write_file(&s);
@@ -1534,8 +1628,17 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
#endif // STB_IMAGE_WRITE_IMPLEMENTATION
/* Revision history
1.16 (2021-07-11)
make Deflate code emit uncompressed blocks when it would otherwise expand
support writing BMPs with alpha channel
1.15 (2020-07-13) unknown
1.14 (2020-02-02) updated JPEG writer to downsample chroma channels
1.13
1.12
1.11 (2019-08-11)
1.10 (2019-02-07)
support utf8 filenames in Windows; fix warnings and platform ifdefs
support utf8 filenames in Windows; fix warnings and platform ifdefs
1.09 (2018-02-11)
fix typo in zlib quality API, improve STB_I_W_STATIC in C++
1.08 (2018-01-29)
@@ -1566,7 +1669,7 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
add HDR output
fix monochrome BMP
0.95 (2014-08-17)
add monochrome TGA output
add monochrome TGA output
0.94 (2014-05-31)
rename private functions to avoid conflicts with stb_image.h
0.93 (2014-05-27)
@@ -1584,38 +1687,38 @@ This software is available under 2 licenses -- choose whichever you prefer.
------------------------------------------------------------------------------
ALTERNATIVE A - MIT License
Copyright (c) 2017 Sean Barrett
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
------------------------------------------------------------------------------
ALTERNATIVE B - Public Domain (www.unlicense.org)
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------
*/
-2
View File
@@ -1,7 +1,5 @@
#!/usr/bin/env python
# Assume python 2.6 or 2.7
import glob
import os
import subprocess
+46
View File
@@ -0,0 +1,46 @@
# 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
```
+33
View File
@@ -0,0 +1,33 @@
#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;
}
+9
View File
@@ -0,0 +1,9 @@
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' )
+1
View File
@@ -0,0 +1 @@
{"images":[{"uri":"%!QAAAQAAA5"}],"asset":{"version":""}}
+463 -21
View File
@@ -3,6 +3,9 @@
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "tiny_gltf.h"
// Nlohmann json(include ../json.hpp)
#include "json.hpp"
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
#include "catch.hpp"
@@ -13,6 +16,14 @@
#include <sstream>
#include <fstream>
static tinygltf::detail::JsonDocument JsonConstruct(const char* str)
{
tinygltf::detail::JsonDocument doc;
tinygltf::detail::JsonParse(doc, str, strlen(str));
return doc;
}
TEST_CASE("parse-error", "[parse]") {
tinygltf::Model model;
@@ -20,7 +31,7 @@ TEST_CASE("parse-error", "[parse]") {
std::string err;
std::string warn;
bool ret = ctx.LoadASCIIFromString(&model, &err, &warn, "bora", strlen("bora"), /* basedir*/ "");
bool ret = ctx.LoadASCIIFromString(&model, &err, &warn, "bora", static_cast<int>(strlen("bora")), /* basedir*/ "");
REQUIRE(false == ret);
@@ -85,6 +96,59 @@ 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]") {
tinygltf::Model model;
tinygltf::TinyGLTF ctx;
@@ -167,12 +231,12 @@ TEST_CASE("parse-integer", "[bounds-checking]") {
SECTION("parses valid numbers") {
std::string err;
int result = 123;
CHECK(tinygltf::ParseIntegerProperty(&result, &err, {{"zero", 0}}, "zero",
CHECK(tinygltf::ParseIntegerProperty(&result, &err, JsonConstruct("{\"zero\" : 0}"), "zero",
true));
REQUIRE(err == "");
REQUIRE(result == 0);
CHECK(tinygltf::ParseIntegerProperty(&result, &err, {{"int", -1234}}, "int",
CHECK(tinygltf::ParseIntegerProperty(&result, &err, JsonConstruct("{\"int\": -1234}"), "int",
true));
REQUIRE(err == "");
REQUIRE(result == -1234);
@@ -181,7 +245,7 @@ TEST_CASE("parse-integer", "[bounds-checking]") {
SECTION("detects missing properties") {
std::string err;
int result = -1;
CHECK_FALSE(tinygltf::ParseIntegerProperty(&result, &err, {}, "int", true));
CHECK_FALSE(tinygltf::ParseIntegerProperty(&result, &err, JsonConstruct(""), "int", true));
REQUIRE_THAT(err, Catch::Contains("'int' property is missing"));
REQUIRE(result == -1);
}
@@ -190,7 +254,7 @@ TEST_CASE("parse-integer", "[bounds-checking]") {
std::string err;
int result = -1;
CHECK_FALSE(
tinygltf::ParseIntegerProperty(&result, &err, {}, "int", false));
tinygltf::ParseIntegerProperty(&result, &err, JsonConstruct(""), "int", false));
REQUIRE(err == "");
REQUIRE(result == -1);
}
@@ -199,21 +263,26 @@ TEST_CASE("parse-integer", "[bounds-checking]") {
std::string err;
int result = -1;
CHECK_FALSE(tinygltf::ParseIntegerProperty(&result, &err, {{"int", 0.5}},
"int", true));
CHECK_FALSE(tinygltf::ParseIntegerProperty(&result, &err, JsonConstruct("{\"int\": 0.5}"),
"int", true));
REQUIRE_THAT(err, Catch::Contains("not an integer type"));
// Excessively large values and NaN aren't allowed either.
err.clear();
CHECK_FALSE(tinygltf::ParseIntegerProperty(&result, &err, {{"int", 1e300}},
"int", true));
CHECK_FALSE(tinygltf::ParseIntegerProperty(&result, &err, JsonConstruct("{\"int\": 1e300}"),
"int", true));
REQUIRE_THAT(err, Catch::Contains("not an integer type"));
err.clear();
CHECK_FALSE(tinygltf::ParseIntegerProperty(
&result, &err, {{"int", std::numeric_limits<double>::quiet_NaN()}},
{
tinygltf::detail::JsonDocument o;
double nan = std::numeric_limits<double>::quiet_NaN();
tinygltf::detail::JsonAddMember(o, "int", tinygltf::detail::json(nan));
CHECK_FALSE(tinygltf::ParseIntegerProperty(
&result, &err, o,
"int", true));
REQUIRE_THAT(err, Catch::Contains("not an integer type"));
REQUIRE_THAT(err, Catch::Contains("not an integer type"));
}
}
}
@@ -221,7 +290,7 @@ TEST_CASE("parse-unsigned", "[bounds-checking]") {
SECTION("parses valid unsigned integers") {
// Use string-based parsing here, using the initializer list syntax doesn't
// parse 0 as unsigned.
json zero_obj = json::parse("{\"zero\": 0}");
auto zero_obj = JsonConstruct("{\"zero\": 0}");
std::string err;
size_t result = 123;
@@ -235,26 +304,31 @@ TEST_CASE("parse-unsigned", "[bounds-checking]") {
std::string err;
size_t result = -1;
CHECK_FALSE(tinygltf::ParseUnsignedProperty(&result, &err, {{"int", -1234}},
CHECK_FALSE(tinygltf::ParseUnsignedProperty(&result, &err, JsonConstruct("{\"int\": -1234}"),
"int", true));
REQUIRE_THAT(err, Catch::Contains("not a positive integer"));
err.clear();
CHECK_FALSE(tinygltf::ParseUnsignedProperty(&result, &err, {{"int", 0.5}},
CHECK_FALSE(tinygltf::ParseUnsignedProperty(&result, &err, JsonConstruct("{\"int\": 0.5}"),
"int", true));
REQUIRE_THAT(err, Catch::Contains("not a positive integer"));
// Excessively large values and NaN aren't allowed either.
err.clear();
CHECK_FALSE(tinygltf::ParseUnsignedProperty(&result, &err, {{"int", 1e300}},
CHECK_FALSE(tinygltf::ParseUnsignedProperty(&result, &err, JsonConstruct("{\"int\": 1e300}"),
"int", true));
REQUIRE_THAT(err, Catch::Contains("not a positive integer"));
err.clear();
CHECK_FALSE(tinygltf::ParseUnsignedProperty(
&result, &err, {{"int", std::numeric_limits<double>::quiet_NaN()}},
{
tinygltf::detail::JsonDocument o;
double nan = std::numeric_limits<double>::quiet_NaN();
tinygltf::detail::JsonAddMember(o, "int", tinygltf::detail::json(nan));
CHECK_FALSE(tinygltf::ParseUnsignedProperty(
&result, &err, o,
"int", true));
REQUIRE_THAT(err, Catch::Contains("not a positive integer"));
REQUIRE_THAT(err, Catch::Contains("not a positive integer"));
}
}
}
@@ -263,7 +337,7 @@ TEST_CASE("parse-integer-array", "[bounds-checking]") {
std::string err;
std::vector<int> result;
CHECK(tinygltf::ParseIntegerArrayProperty(&result, &err,
{{"x", {-1, 2, 3}}}, "x", true));
JsonConstruct("{\"x\": [-1, 2, 3]}"), "x", true));
REQUIRE(err == "");
REQUIRE(result.size() == 3);
REQUIRE(result[0] == -1);
@@ -275,7 +349,7 @@ TEST_CASE("parse-integer-array", "[bounds-checking]") {
std::string err;
std::vector<int> result;
CHECK_FALSE(tinygltf::ParseIntegerArrayProperty(
&result, &err, {{"x", {-1, 1e300, 3}}}, "x", true));
&result, &err, JsonConstruct("{\"x\": [-1, 1e300, 3]}"), "x", true));
REQUIRE_THAT(err, Catch::Contains("not an integer type"));
}
}
@@ -315,3 +389,371 @@ TEST_CASE("pbr-khr-texture-transform", "[material]") {
REQUIRE(scale[1] == Approx(-1.0));
}
TEST_CASE("image-uri-spaces", "[issue-236]") {
tinygltf::TinyGLTF ctx;
std::string err;
std::string warn;
// Test image file with single spaces.
{
tinygltf::Model model;
bool ret = ctx.LoadASCIIFromFile(
&model, &err, &warn,
"../models/CubeImageUriSpaces/CubeImageUriSpaces.gltf");
if (!warn.empty()) {
std::cerr << warn << std::endl;
}
if (!err.empty()) {
std::cerr << err << std::endl;
}
REQUIRE(true == ret);
REQUIRE(warn.empty());
REQUIRE(err.empty());
REQUIRE(model.images.size() == 1);
REQUIRE(model.images[0].uri.find(' ') != std::string::npos);
}
// Test image file with a beginning space, trailing space, and greater than
// one consecutive spaces.
tinygltf::Model model;
bool ret = ctx.LoadASCIIFromFile(
&model, &err, &warn,
"../models/CubeImageUriSpaces/CubeImageUriMultipleSpaces.gltf");
if (!warn.empty()) {
std::cerr << warn << std::endl;
}
if (!err.empty()) {
std::cerr << err << std::endl;
}
REQUIRE(true == ret);
REQUIRE(warn.empty());
REQUIRE(err.empty());
REQUIRE(model.images.size() == 1);
REQUIRE(model.images[0].uri.size() > 1);
REQUIRE(model.images[0].uri[0] == ' ');
// Test the URI encoding API by saving and re-load the file, without embedding
// the image.
// TODO(syoyo): create temp directory.
{
// Encoder that only replaces spaces with "%20".
auto uriencode = [](const std::string &in_uri,
const std::string &object_type, std::string *out_uri,
void *user_data) -> bool {
(void)user_data;
bool imageOrBuffer = object_type == "image" || object_type == "buffer";
REQUIRE(true == imageOrBuffer);
*out_uri = {};
for (char c : in_uri) {
if (c == ' ')
*out_uri += "%20";
else
*out_uri += c;
}
return true;
};
// Remove the buffer URI, so a new one is generated based on the gltf
// filename and then encoded with the above callback.
model.buffers[0].uri.clear();
tinygltf::URICallbacks uri_cb{uriencode, tinygltf::URIDecode, nullptr};
ctx.SetURICallbacks(uri_cb);
ret = ctx.WriteGltfSceneToFile(&model, " issue-236.gltf", false, false);
REQUIRE(true == ret);
// read back serialized glTF
tinygltf::Model saved;
bool ret = ctx.LoadASCIIFromFile(&saved, &err, &warn, " issue-236.gltf");
if (!err.empty()) {
std::cerr << err << std::endl;
}
REQUIRE(true == ret);
REQUIRE(err.empty());
REQUIRE(!warn.empty()); // relative image path won't exist in tests/
REQUIRE(saved.images.size() == model.images.size());
// The image uri in CubeImageUriMultipleSpaces.gltf is not encoded and
// should be different after encoding spaces with %20.
REQUIRE(model.images[0].uri != saved.images[0].uri);
// Verify the image path remains the same after uri decoding
std::string image_uri, image_uri_saved;
(void)tinygltf::URIDecode(model.images[0].uri, &image_uri, nullptr);
(void)tinygltf::URIDecode(saved.images[0].uri, &image_uri_saved, nullptr);
REQUIRE(image_uri == image_uri_saved);
// Verify the buffer's generated and encoded URI
REQUIRE(saved.buffers.size() == model.buffers.size());
REQUIRE(saved.buffers[0].uri == "%20issue-236.bin");
}
}
TEST_CASE("serialize-empty-material", "[issue-294]") {
tinygltf::Model m;
tinygltf::Material mat;
mat.pbrMetallicRoughness.baseColorFactor = {1.0f, 1.0f, 1.0f, 1.0f}; // default baseColorFactor
m.materials.push_back(mat);
std::stringstream os;
tinygltf::TinyGLTF ctx;
bool ret = ctx.WriteGltfSceneToStream(&m, os, false, false);
REQUIRE(true == ret);
// use nlohmann json
nlohmann::json j = nlohmann::json::parse(os.str());
REQUIRE(1 == j["materials"].size());
REQUIRE(j["materials"][0].is_object());
}
TEST_CASE("empty-skeleton-id", "[issue-321]") {
tinygltf::Model model;
tinygltf::TinyGLTF ctx;
std::string err;
std::string warn;
bool ret = ctx.LoadASCIIFromFile(&model, &err, &warn, "../models/regression/unassigned-skeleton.gltf");
if (!err.empty()) {
std::cerr << err << std::endl;
}
REQUIRE(true == ret);
REQUIRE(model.skins.size() == 1);
REQUIRE(model.skins[0].skeleton == -1); // unassigned
std::stringstream os;
ret = ctx.WriteGltfSceneToStream(&model, os, false, false);
REQUIRE(true == ret);
// use nlohmann json
nlohmann::json j = nlohmann::json::parse(os.str());
// Ensure `skeleton` property is not written to .gltf(was serialized as -1)
REQUIRE(1 == j["skins"].size());
REQUIRE(j["skins"][0].is_object());
REQUIRE(j["skins"][0].count("skeleton") == 0);
}
#ifndef TINYGLTF_NO_FS
TEST_CASE("expandpath-utf-8", "[pr-226]") {
std::string s1 = "\xe5\xaf\xb9"; // utf-8 string
std::string ret = tinygltf::ExpandFilePath(s1, /* userdata */nullptr);
// expected: E5 AF B9
REQUIRE(3 == ret.size());
REQUIRE(0xe5 == static_cast<uint8_t>(ret[0]));
REQUIRE(0xaf == static_cast<uint8_t>(ret[1]));
REQUIRE(0xb9 == static_cast<uint8_t>(ret[2]));
}
#endif
TEST_CASE("empty-bin-buffer", "[issue-382]") {
tinygltf::Model model;
tinygltf::TinyGLTF ctx;
std::string err;
std::string warn;
tinygltf::Model model_empty;
std::stringstream stream;
bool ret = ctx.WriteGltfSceneToStream(&model_empty, stream, false, true);
REQUIRE(ret == true);
std::string str = stream.str();
const unsigned char* bytes = (unsigned char*)str.data();
ret = ctx.LoadBinaryFromMemory(&model, &err, &warn, bytes, str.size());
if (!err.empty()) {
std::cerr << err << std::endl;
}
REQUIRE(true == ret);
err.clear();
warn.clear();
tinygltf::Model model_empty_buffer;
model_empty_buffer.buffers.push_back(tinygltf::Buffer());
stream = std::stringstream();
ret = ctx.WriteGltfSceneToStream(&model_empty_buffer, stream, false, true);
REQUIRE(ret == true);
str = stream.str();
bytes = (unsigned char*)str.data();
ret = ctx.LoadBinaryFromMemory(&model, &err, &warn, bytes, str.size());
if (err.empty()) {
std::cerr << "there should have been an error reported" << std::endl;
}
REQUIRE(false == ret);
err.clear();
warn.clear();
tinygltf::Model model_single_byte_buffer;
tinygltf::Buffer buffer;
buffer.data.push_back(0);
model_single_byte_buffer.buffers.push_back(buffer);
stream = std::stringstream();
ret = ctx.WriteGltfSceneToStream(&model_single_byte_buffer, stream, false, true);
REQUIRE(ret == true);
str = stream.str();
{
std::ofstream ofs("tmp.glb");
ofs.write(str.data(), str.size());
}
bytes = (unsigned char*)str.data();
ret = ctx.LoadBinaryFromMemory(&model_single_byte_buffer, &err, &warn, bytes, str.size());
if (!err.empty()) {
std::cerr << err << std::endl;
}
REQUIRE(true == ret);
}
TEST_CASE("serialize-const-image", "[issue-394]") {
tinygltf::Model m;
tinygltf::Image i;
i.width = 1;
i.height = 1;
i.component = 4;
i.bits = 8;
i.pixel_type = TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE;
i.image = {255, 255, 255, 255};
i.uri = "image.png";
m.images.push_back(i);
std::stringstream os;
tinygltf::TinyGLTF ctx;
bool ret = ctx.WriteGltfSceneToStream(const_cast<const tinygltf::Model *>(&m), os, false,
false);
REQUIRE(true == ret);
REQUIRE(m.images[0].uri == i.uri);
// use nlohmann json
nlohmann::json j = nlohmann::json::parse(os.str());
REQUIRE(1 == j["images"].size());
REQUIRE(j["images"][0].is_object());
REQUIRE(j["images"][0]["uri"].get<std::string>() != i.uri);
REQUIRE(j["images"][0]["uri"].get<std::string>().rfind("data:", 0) == 0);
}
TEST_CASE("serialize-image-callback", "[issue-394]") {
tinygltf::Model m;
tinygltf::Image i;
i.width = 1;
i.height = 1;
i.bits = 32;
i.image = {255, 255, 255, 255};
i.uri = "foo";
m.images.push_back(i);
std::stringstream os;
auto writer = [](const std::string *basepath, const std::string *filename,
const tinygltf::Image *image, bool embedImages,
const tinygltf::URICallbacks *uri_cb, std::string *out_uri,
void *user_pointer) -> bool {
(void)basepath;
(void)image;
(void)uri_cb;
REQUIRE(*filename == "foo");
REQUIRE(embedImages == true);
REQUIRE(user_pointer == (void *)0xba5e1e55);
*out_uri = "bar";
return true;
};
tinygltf::TinyGLTF ctx;
ctx.SetImageWriter(writer, (void *)0xba5e1e55);
bool result = ctx.WriteGltfSceneToStream(const_cast<const tinygltf::Model *>(&m), os, false,
false);
// use nlohmann json
nlohmann::json j = nlohmann::json::parse(os.str());
REQUIRE(true == result);
REQUIRE(1 == j["images"].size());
REQUIRE(j["images"][0].is_object());
REQUIRE(j["images"][0]["uri"].get<std::string>() == "bar");
}
TEST_CASE("serialize-image-failure", "[issue-394]") {
tinygltf::Model m;
tinygltf::Image i;
// Set some data so the ImageWriter callback will be called
i.image = {255, 255, 255, 255};
m.images.push_back(i);
std::stringstream os;
auto writer = [](const std::string *basepath, const std::string *filename,
const tinygltf::Image *image, bool embedImages,
const tinygltf::URICallbacks *uri_cb, std::string *out_uri,
void *user_pointer) -> bool {
(void)basepath;
(void)filename;
(void)image;
(void)embedImages;
(void)uri_cb;
(void)out_uri;
(void)user_pointer;
return false;
};
tinygltf::TinyGLTF ctx;
ctx.SetImageWriter(writer, (void *)0xba5e1e55);
bool result = ctx.WriteGltfSceneToStream(const_cast<const tinygltf::Model *>(&m), os, false,
false);
REQUIRE(false == result);
REQUIRE(os.str().size() == 0);
}
TEST_CASE("filesize-check", "[issue-416]") {
tinygltf::Model model;
tinygltf::TinyGLTF ctx;
std::string err;
std::string warn;
ctx.SetMaxExternalFileSize(10); // 10 bytes. will fail to load texture image.
bool ret = ctx.LoadASCIIFromFile(&model, &err, &warn, "../models/Cube/Cube.gltf");
if (!err.empty()) {
std::cerr << err << std::endl;
}
REQUIRE(false == ret);
}
TEST_CASE("load-issue-416-model", "[issue-416]") {
tinygltf::Model model;
tinygltf::TinyGLTF ctx;
std::string err;
std::string warn;
bool ret = ctx.LoadASCIIFromFile(&model, &err, &warn, "issue-416.gltf");
if (!warn.empty()) {
std::cout << "WARN:" << warn << std::endl;
}
if (!err.empty()) {
std::cerr << "ERR:" << err << std::endl;
}
// external file load fails, but reading glTF itself is ok.
REQUIRE(true == ret);
}
+4
View File
@@ -0,0 +1,4 @@
#define TINYGLTF_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "tiny_gltf.h"
+3399 -1186
View File
File diff suppressed because it is too large Load Diff
+11
View File
@@ -0,0 +1,11 @@
WASI_VERSION=16
WASI_VERSION_FULL=${WASI_VERSION}.0
WASI_SDK_PATH=$(HOME)/local/wasi-sdk-${WASI_VERSION_FULL}
CC=${WASI_SDK_PATH}/bin/clang
CXX=${WASI_SDK_PATH}/bin/clang++
CXXFLAGS=-fno-rtti -fno-exceptions -g -Os
all:
$(CXX) ../loader_example.cc $(CXXFLAGS) -I../
+31
View File
@@ -0,0 +1,31 @@
Experimental WASI/WASM build
## Build
Download wasi-sdk https://github.com/WebAssembly/wasi-sdk
Compile tinygltf without C++ exceptions and threads. See `Makefile` for details
(NOTE: TinyGLTF itself does not use RTTI and threading feature(C++ threads, posix, win32 thread))
## Build examples and Run
Build `loader_example.cc`
```
$ /path/to/wasi-sdk-16.0/bin/clang++ ../loader_example.cc -fno-rtti -fno-exceptions -g -Os -I../ -o loader_example.wasi
```
Tested with wasmtime. https://github.com/bytecodealliance/wasmtime
Set a folder containing .gltf file to `--dir`
```
$ wasmtime --dir=../models loader_example.wasi ../models/Cube/Cube.gltf
```
## Emscripen
T.B.W. ...
EoL.
File diff suppressed because it is too large Load Diff