mirror of
https://github.com/syoyo/tinygltf.git
synced 2026-06-08 19:23:50 +00:00
Compare commits
171 Commits
cwbhhjl-fi
...
v2.8.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98adbb3fb3 | ||
|
|
283b552a4e | ||
|
|
c2ca97b38b | ||
|
|
f051892c55 | ||
|
|
137a7ca999 | ||
|
|
477d977fea | ||
|
|
8cd5e759d0 | ||
|
|
a6c3945ed3 | ||
|
|
6614bddef3 | ||
|
|
385946dfd8 | ||
|
|
03bbe0921c | ||
|
|
a9121550b9 | ||
|
|
d2b0af6915 | ||
|
|
695608dd11 | ||
|
|
584f1dfbe4 | ||
|
|
a40ca4c5ab | ||
|
|
de75d87cfd | ||
|
|
cf11842e64 | ||
|
|
38003032e3 | ||
|
|
186016bf11 | ||
|
|
5ee08f9274 | ||
|
|
aa613a1f57 | ||
|
|
222454cc6d | ||
|
|
16c2d3a8bf | ||
|
|
186093657a | ||
|
|
9bdd256625 | ||
|
|
264ae4c131 | ||
|
|
091a1fcc1a | ||
|
|
3a295887d6 | ||
|
|
d9ce9eb9d2 | ||
|
|
56e1098993 | ||
|
|
9bb5806df4 | ||
|
|
1668d1ecc5 | ||
|
|
6e8a858c45 | ||
|
|
e0b625561c | ||
|
|
18450eafe7 | ||
|
|
e9fbc03e2d | ||
|
|
612e57816f | ||
|
|
a778c089d1 | ||
|
|
387fd61b83 | ||
|
|
6514490090 | ||
|
|
6b7ec9f494 | ||
|
|
c670f08a3b | ||
|
|
eec4c98862 | ||
|
|
c7e911cf11 | ||
|
|
43172238f7 | ||
|
|
0cc23356dc | ||
|
|
e413216722 | ||
|
|
4581d37bec | ||
|
|
966a9d0df7 | ||
|
|
64452bb5fa | ||
|
|
69eeea145b | ||
|
|
24e539621d | ||
|
|
f4f5c3cf3a | ||
|
|
b12a54ed15 | ||
|
|
240d993f94 | ||
|
|
46ee8b4276 | ||
|
|
3bddc09af4 | ||
|
|
9117abb45d | ||
|
|
52ff00a384 | ||
|
|
0fa56e239c | ||
|
|
5c2dd83964 | ||
|
|
1a8814d687 | ||
|
|
666ab8661c | ||
|
|
0b31543098 | ||
|
|
81f7dbe53a | ||
|
|
544969b732 | ||
|
|
3d4150419e | ||
|
|
41e1102e57 | ||
|
|
b901dd62d8 | ||
|
|
bc03ceaac1 | ||
|
|
2c9b25642b | ||
|
|
a894904f11 | ||
|
|
912856823d | ||
|
|
1a7c7d2001 | ||
|
|
fae6543b7a | ||
|
|
6ed7c39d71 | ||
|
|
5a90ab76ee | ||
|
|
0ffdc4334a | ||
|
|
53338352f2 | ||
|
|
d642c80a86 | ||
|
|
a1952053ee | ||
|
|
cbd3885049 | ||
|
|
9471517c1e | ||
|
|
e59028d68f | ||
|
|
cfab524125 | ||
|
|
9229971bcb | ||
|
|
051149311c | ||
|
|
0c7789b1e5 | ||
|
|
51b12d2546 | ||
|
|
4749b0989d | ||
|
|
0bfcb4f49e | ||
|
|
17e6e310ce | ||
|
|
07ceb4c313 | ||
|
|
e7f1ff5c59 | ||
|
|
fd904063c9 | ||
|
|
38398cc2da | ||
|
|
ed1a294bc4 | ||
|
|
b86eb6c079 | ||
|
|
e4bc6c7bd4 | ||
|
|
13803659f8 | ||
|
|
a3d5d5d1c9 | ||
|
|
9e3d1f6db5 | ||
|
|
190382aecd | ||
|
|
c6501530e3 | ||
|
|
ed48224f4b | ||
|
|
19a41d20ec | ||
|
|
0598a20cce | ||
|
|
514167b475 | ||
|
|
0f76561ebf | ||
|
|
f3dc4acaa4 | ||
|
|
1588e75e26 | ||
|
|
d1453b5e5e | ||
|
|
7e83ef9fb4 | ||
|
|
425195bf9c | ||
|
|
ce3a30e612 | ||
|
|
8a35b8f6fe | ||
|
|
f66f3bfeb3 | ||
|
|
e29ba7c49a | ||
|
|
bc753d4ac5 | ||
|
|
688ba8a60e | ||
|
|
d07b976d59 | ||
|
|
08a7dd8dad | ||
|
|
87da1e775f | ||
|
|
151495558e | ||
|
|
84e15260ba | ||
|
|
03cdef430d | ||
|
|
fb4bd82e2c | ||
|
|
3ddf8301f6 | ||
|
|
298c37a954 | ||
|
|
b702de755f | ||
|
|
58ceed1d89 | ||
|
|
d1b6b3a5aa | ||
|
|
c56d069726 | ||
|
|
d1e32865f1 | ||
|
|
869a9d273c | ||
|
|
1208f057d6 | ||
|
|
f684dde9f1 | ||
|
|
7905a5b4dc | ||
|
|
f161782001 | ||
|
|
654bcf733c | ||
|
|
001c870051 | ||
|
|
2c521b3432 | ||
|
|
a159945db9 | ||
|
|
010ee9c67b | ||
|
|
a23971c603 | ||
|
|
1923067982 | ||
|
|
68adc4ba5e | ||
|
|
42a8cd50ff | ||
|
|
0543640a83 | ||
|
|
9c59a0b64c | ||
|
|
452541a231 | ||
|
|
78fe8d9b89 | ||
|
|
51e5508fa0 | ||
|
|
91da299729 | ||
|
|
50ae8a31a8 | ||
|
|
0af0435ef1 | ||
|
|
7c342533e9 | ||
|
|
7842c1276f | ||
|
|
125e4a2033 | ||
|
|
c9d6c5b9b4 | ||
|
|
96a8b2c69b | ||
|
|
01d54380ac | ||
|
|
6cd8fdb2c8 | ||
|
|
fe01af2f01 | ||
|
|
efdd2b04dc | ||
|
|
2e642b3322 | ||
|
|
1739d025a9 | ||
|
|
39418e5728 | ||
|
|
5622d2762d | ||
|
|
3d939fd3ee |
13
.github/FUNDING.yml
vendored
Normal file
13
.github/FUNDING.yml
vendored
Normal 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
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
blank_issues_enabled: false
|
||||
30
.github/ISSUE_TEMPLATE/issue-report.md
vendored
Normal file
30
.github/ISSUE_TEMPLATE/issue-report.md
vendored
Normal 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.
|
||||
6
.github/workflows/c-cpp.yml
vendored
6
.github/workflows/c-cpp.yml
vendored
@@ -47,7 +47,8 @@ jobs:
|
||||
sudo apt-get install -y mingw-w64
|
||||
x86_64-w64-mingw32-g++ -std=c++11 -o loader_example loader_example.cc
|
||||
|
||||
# Windows(x64) + Visual Studio 2019 build
|
||||
# Windows(x64) + Visual Studio 2022 build
|
||||
# Assume windows-latest have VS2022 installed
|
||||
build-windows-msvc:
|
||||
|
||||
runs-on: windows-latest
|
||||
@@ -62,7 +63,8 @@ jobs:
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G "Visual Studio 16 2019" -DTINYGLTF_BUILD_LOADER_EXAMPLE=On -DTINYGLTF_BUILD_GL_EXAMPLES=Off -DTINYGLTF_BUILD_VALIDATOR_EXAMPLE=On ..
|
||||
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
|
||||
|
||||
72
.github/workflows/codeql-analysis.yml
vendored
Normal file
72
.github/workflows/codeql-analysis.yml
vendored
Normal 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
.gitignore
vendored
7
.gitignore
vendored
@@ -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
|
||||
|
||||
@@ -2,11 +2,17 @@ cmake_minimum_required(VERSION 3.6)
|
||||
|
||||
PROJECT (tinygltf)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
SET(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
option(TINYGLTF_BUILD_LOADER_EXAMPLE "Build loader_example" ON)
|
||||
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
|
||||
@@ -22,20 +28,49 @@ 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)
|
||||
|
||||
#
|
||||
# TinuGLTF is a header-only library, so no library build. just install header files.
|
||||
# for add_subdirectory and standalone build
|
||||
#
|
||||
INSTALL ( FILES
|
||||
json.hpp
|
||||
stb_image.h
|
||||
stb_image_write.h
|
||||
tiny_gltf.h
|
||||
DESTINATION
|
||||
include
|
||||
if (TINYGLTF_HEADER_ONLY)
|
||||
add_library(tinygltf INTERFACE)
|
||||
|
||||
target_include_directories(tinygltf
|
||||
INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
|
||||
INSTALL ( FILES
|
||||
cmake/TinyGLTFConfig.cmake
|
||||
DESTINATION
|
||||
cmake
|
||||
)
|
||||
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)
|
||||
|
||||
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
|
||||
json.hpp
|
||||
stb_image.h
|
||||
stb_image_write.h
|
||||
tiny_gltf.h
|
||||
${TINYGLTF_EXTRA_SOUECES}
|
||||
DESTINATION
|
||||
include
|
||||
)
|
||||
|
||||
endif(TINYGLTF_INSTALL)
|
||||
|
||||
58
README.md
58
README.md
@@ -2,17 +2,28 @@
|
||||
|
||||
`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
|
||||
|
||||
[](https://travis-ci.org/syoyo/tinygltf)
|
||||
@@ -23,6 +34,8 @@ If you are looking for old, C++03 version, please use `devel-picojson` branch.
|
||||
|
||||
## 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
|
||||
@@ -73,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
|
||||
|
||||
@@ -86,11 +106,14 @@ In extension(`ExtensionMap`), JSON number value is parsed as int or float(number
|
||||
* [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 proessional 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
|
||||
@@ -101,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.
|
||||
@@ -151,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.
|
||||
@@ -160,11 +191,26 @@ 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 featrure.
|
||||
* `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.
|
||||
|
||||
## 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
|
||||
|
||||
@@ -185,7 +231,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
|
||||
|
||||
@@ -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
cmake/TinyGLTFConfig.cmake.in
Normal file
3
cmake/TinyGLTFConfig.cmake.in
Normal file
@@ -0,0 +1,3 @@
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/TinyGLTFTargets.cmake)
|
||||
1
examples/basic/.gitignore
vendored
1
examples/basic/.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
.vs
|
||||
Debug
|
||||
Release
|
||||
x64
|
||||
packages
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -39,8 +39,8 @@ bool loadModel(tinygltf::Model &model, const char *filename) {
|
||||
return res;
|
||||
}
|
||||
|
||||
std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos,
|
||||
tinygltf::Model &model, tinygltf::Mesh &mesh) {
|
||||
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
|
||||
@@ -144,12 +144,10 @@ std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vbos;
|
||||
}
|
||||
|
||||
// bind models
|
||||
void bindModelNodes(std::map<int, GLuint> vbos, tinygltf::Model &model,
|
||||
void bindModelNodes(std::map<int, GLuint>& vbos, tinygltf::Model &model,
|
||||
tinygltf::Node &node) {
|
||||
if ((node.mesh >= 0) && (node.mesh < model.meshes.size())) {
|
||||
bindMesh(vbos, model, model.meshes[node.mesh]);
|
||||
@@ -160,7 +158,8 @@ void bindModelNodes(std::map<int, GLuint> vbos, tinygltf::Model &model,
|
||||
bindModelNodes(vbos, model, model.nodes[node.children[i]]);
|
||||
}
|
||||
}
|
||||
GLuint bindModel(tinygltf::Model &model) {
|
||||
|
||||
std::pair<GLuint, std::map<int, GLuint>> bindModel(tinygltf::Model &model) {
|
||||
std::map<int, GLuint> vbos;
|
||||
GLuint vao;
|
||||
glGenVertexArrays(1, &vao);
|
||||
@@ -173,19 +172,29 @@ GLuint bindModel(tinygltf::Model &model) {
|
||||
}
|
||||
|
||||
glBindVertexArray(0);
|
||||
// cleanup vbos
|
||||
for (size_t i = 0; i < vbos.size(); ++i) {
|
||||
glDeleteBuffers(1, &vbos[i]);
|
||||
// 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;
|
||||
return {vao, vbos};
|
||||
}
|
||||
|
||||
void drawMesh(tinygltf::Model &model, tinygltf::Mesh &mesh) {
|
||||
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));
|
||||
@@ -193,20 +202,22 @@ void drawMesh(tinygltf::Model &model, tinygltf::Mesh &mesh) {
|
||||
}
|
||||
|
||||
// recursively draw node and children nodes of model
|
||||
void drawModelNodes(tinygltf::Model &model, tinygltf::Node &node) {
|
||||
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(model, model.meshes[node.mesh]);
|
||||
drawMesh(vaoAndEbos.second, model, model.meshes[node.mesh]);
|
||||
}
|
||||
for (size_t i = 0; i < node.children.size(); i++) {
|
||||
drawModelNodes(model, model.nodes[node.children[i]]);
|
||||
drawModelNodes(vaoAndEbos, model, model.nodes[node.children[i]]);
|
||||
}
|
||||
}
|
||||
void drawModel(GLuint vao, tinygltf::Model &model) {
|
||||
glBindVertexArray(vao);
|
||||
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(model, model.nodes[scene.nodes[i]]);
|
||||
drawModelNodes(vaoAndEbos, model, model.nodes[scene.nodes[i]]);
|
||||
}
|
||||
|
||||
glBindVertexArray(0);
|
||||
@@ -282,7 +293,7 @@ void displayLoop(Window &window, const std::string &filename) {
|
||||
tinygltf::Model model;
|
||||
if (!loadModel(model, filename.c_str())) return;
|
||||
|
||||
GLuint vao = bindModel(model);
|
||||
std::pair<GLuint, std::map<int, GLuint>> vaoAndEbos = bindModel(model);
|
||||
// dbgModel(model); return;
|
||||
|
||||
// Model matrix : an identity matrix (model will be at the origin)
|
||||
@@ -317,10 +328,12 @@ void displayLoop(Window &window, const std::string &filename) {
|
||||
glUniform3fv(sun_position_u, 1, &sun_position[0]);
|
||||
glUniform3fv(sun_color_u, 1, &sun_color[0]);
|
||||
|
||||
drawModel(vao, model);
|
||||
drawModel(vaoAndEbos, model);
|
||||
glfwSwapBuffers(window.window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
glDeleteVertexArrays(1, &vaoAndEbos.first);
|
||||
}
|
||||
|
||||
static void error_callback(int error, const char *description) {
|
||||
@@ -329,7 +342,7 @@ static void error_callback(int error, const char *description) {
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
std::string filename = "../../models/Cube/Cube.gltf";
|
||||
std::string filename = "../../../models/Cube/Cube.gltf";
|
||||
|
||||
if (argc > 1) {
|
||||
filename = argv[1];
|
||||
@@ -341,9 +354,12 @@ int main(int argc, char **argv) {
|
||||
|
||||
// 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
|
||||
|
||||
2
examples/build-gltf/Makefile
Normal file
2
examples/build-gltf/Makefile
Normal file
@@ -0,0 +1,2 @@
|
||||
all:
|
||||
$(CXX) -o create_triangle_gltf -I../../ create_triangle_gltf.cpp
|
||||
121
examples/build-gltf/create_triangle_gltf.cpp
Normal file
121
examples/build-gltf/create_triangle_gltf.cpp
Normal file
@@ -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
examples/dxview/CMakeLists.txt
Normal file
36
examples/dxview/CMakeLists.txt
Normal 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
examples/dxview/README.md
Normal file
37
examples/dxview/README.md
Normal 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
examples/dxview/res/gray.hlsl
Normal file
3
examples/dxview/res/gray.hlsl
Normal file
@@ -0,0 +1,3 @@
|
||||
float4 main() : SV_Target {
|
||||
return float4(0.5, 0.5, 0.5, 1.0);
|
||||
}
|
||||
52
examples/dxview/res/lighting.hlsl
Normal file
52
examples/dxview/res/lighting.hlsl
Normal 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
examples/dxview/res/primitive.hlsl
Normal file
46
examples/dxview/res/primitive.hlsl
Normal 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;
|
||||
}
|
||||
1292
examples/dxview/src/Viewer.cc
Normal file
1292
examples/dxview/src/Viewer.cc
Normal file
File diff suppressed because it is too large
Load Diff
130
examples/dxview/src/Viewer.h
Normal file
130
examples/dxview/src/Viewer.h
Normal 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
examples/dxview/src/dxview.cc
Normal file
90
examples/dxview/src/dxview.cc
Normal 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);
|
||||
}
|
||||
@@ -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}
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -524,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;
|
||||
|
||||
Binary file not shown.
267
models/regression/unassigned-skeleton.gltf
Normal file
267
models/regression/unassigned-skeleton.gltf
Normal file
File diff suppressed because one or more lines are too long
@@ -1,7 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Assume python 2.6 or 2.7
|
||||
|
||||
import glob
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
304
tests/tester.cc
304
tests/tester.cc
@@ -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"
|
||||
|
||||
@@ -389,27 +392,156 @@ TEST_CASE("pbr-khr-texture-transform", "[material]") {
|
||||
|
||||
TEST_CASE("image-uri-spaces", "[issue-236]") {
|
||||
|
||||
tinygltf::Model model;
|
||||
tinygltf::TinyGLTF ctx;
|
||||
std::string err;
|
||||
std::string warn;
|
||||
|
||||
// Test image file with single spaces.
|
||||
bool ret = ctx.LoadASCIIFromFile(&model, &err, &warn, "../models/CubeImageUriSpaces/CubeImageUriSpaces.gltf");
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
}
|
||||
{
|
||||
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(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.
|
||||
ret = ctx.LoadASCIIFromFile(&model, &err, &warn, "../models/CubeImageUriSpaces/CubeImageUriMultipleSpaces.gltf");
|
||||
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;
|
||||
ctx.WriteGltfSceneToStream(&m, os, false, false);
|
||||
|
||||
// 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;
|
||||
|
||||
ctx.WriteGltfSceneToStream(&model, os, false, false);
|
||||
|
||||
// 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
|
||||
@@ -428,3 +560,161 @@ TEST_CASE("expandpath-utf-8", "[pr-226]") {
|
||||
|
||||
}
|
||||
#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;
|
||||
ctx.WriteGltfSceneToStream(const_cast<const tinygltf::Model *>(&m), os, false,
|
||||
false);
|
||||
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);
|
||||
}
|
||||
|
||||
4
tiny_gltf.cc
Normal file
4
tiny_gltf.cc
Normal file
@@ -0,0 +1,4 @@
|
||||
#define TINYGLTF_IMPLEMENTATION
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include "tiny_gltf.h"
|
||||
1012
tiny_gltf.h
1012
tiny_gltf.h
File diff suppressed because it is too large
Load Diff
11
wasm/Makefile
Normal file
11
wasm/Makefile
Normal 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
wasm/README.md
Normal file
31
wasm/README.md
Normal file
@@ -0,0 +1,31 @@
|
||||
Experimental WASI/WASM build
|
||||
|
||||
## Build
|
||||
|
||||
Download wasi-sdk https://github.com/WebAssembly/wasi-sdk
|
||||
|
||||
Compile tinygltf with C++ exceptions and threads off. 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.
|
||||
Reference in New Issue
Block a user