Compare commits

...

111 Commits

Author SHA1 Message Date
Syoyo Fujita
0d9ce1a956 Fix Windows path split in tester_v3_c parse_file_arg too
parse_file_arg() duplicated the '/' only base-dir split from
parse_path_for_test(); a Windows-style arg (models\Cube\Cube.gltf)
yielded an empty base dir and external buffers failed to load.
2026-07-31 22:17:13 +09:00
Syoyo Fujita
b30be77ad7 Fix tester_v3_c base-dir split on Windows paths
parse_path_for_test() split the file path on '/' only, so a Windows
style arg like models\Cube\Cube.gltf produced an empty base dir and
external buffers (Cube.bin) failed to resolve. Split on '\' too.
2026-07-31 22:13:14 +09:00
Syoyo Fujita
9b56d2f600 Fix Windows CI: use msvc-dev-cmd + Ninja instead of hardcoded VS2022
windows-latest now resolves to the windows-2025-vs2026 image, which no
longer ships Visual Studio 2022: the 'Visual Studio 17 2022' CMake
generator and the hardcoded vcvars64.bat path both fail. Use
ilammy/msvc-dev-cmd (vswhere-based, version agnostic) to set up cl.exe
and the Ninja generator for the CMake jobs.
2026-07-31 22:09:06 +09:00
Syoyo Fujita
6257f5024d Add pre-push audit checklist (AGENTS.md) 2026-07-31 21:43:33 +09:00
Syoyo Fujita
a040827363 Add Emscripten WASM build and three.js web demo
web/ compiles the v3 C runtime with emcc (Emscripten SDK from
~/work/emsdk by default) and ships a simple browser demo that loads
glTF/GLB files via drag & drop and renders them with three.js:

- loader.c: C bridge exporting flattened primitives, materials,
  textures (bufferView + data-URI paths) and the scene graph to JS
- main.js/index.html/style.css: three.js viewer (OrbitControls,
  PBR materials, textures, node hierarchy, primitive modes)
- gen_sample.py: generates a small self-contained textured Cube.glb
  sample from tracked assets (no large binaries committed)
- Makefile: emcc build (MODULARIZE + ES6, no filesystem), sample
  generation and local http server targets

Verified end-to-end: native bridge tests, Node harness exercising the
WASM exports (parse, geometry, images, clear) and HTTP serving.
2026-07-31 21:42:31 +09:00
Syoyo Fujita
76a3b70751 Update build, tests, CI and docs to tinygltf v3 C only
- CMakeLists.txt: build v3 C testers, install v3 C files only
- tests/Makefile and Makefile: build/run v3 C testers
- test_runner.py: verify v3 C tester output, drop v1 ground truth
- CI: build and test v3 C only (GCC/Clang/MSVC/Meson/sanitizers)
- README: v3 C mainline, legacy moved to attic/
2026-07-31 21:42:31 +09:00
Syoyo Fujita
5aa461e477 Deprecate legacy v1/v2/v3 C++ API; make v3 C the mainline
Move tiny_gltf.h/.cc, tinygltf_json.h, json.hpp, stb_image*, loader_example.cc,
examples/, wasm/, experimental/, legacy tests and fuzzers under attic/.

TinyGLTF v3 C (tiny_gltf_v3.h/.c + tinygltf_json_c.h) is now the mainline:
- CMakeLists.txt: v3 C tests only, installs only v3 files
- tests/Makefile and Makefile: build/run the v3 C testers
- test_runner.py: verifies v3 C tester output only (no v1 ground truth)
- CI workflows: build and test v3 C only (GCC/Clang/MSVC/Meson/sanitizers)
- README: v3 C quick start, testing, licenses; legacy moved to attic/
2026-07-31 21:42:31 +09:00
Syoyo Fujita
96cd2fe5fc Ignore compiled test binaries
The v3 tester executables were accidentally committed. Ignore all
test binaries built by tests/Makefile, CMakeLists.txt and meson.build
so they can't be re-added by mistake.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 21:03:45 +09:00
copilot-swe-agent[bot]
153838db36 Tighten README security wording 2026-06-03 20:58:55 +09:00
copilot-swe-agent[bot]
af5f023495 Remove security docs 2026-06-03 20:58:55 +09:00
Syoyo Fujita
75081ef5f0 Fix MSVC /W4 unreachable-code error in v3 C dtoa
When TG3JSON_USE_STDLIB_FPCONV is enabled (auto-selected on MSVC), the
stdlib float-formatting block in tg3json__dtoa_c() always returns, making
the manual long-double formatting fallback dead code. MSVC /W4 /WX turned
the resulting C4702 (unreachable code) into a build error.

Make the manual fallback an #else branch of the stdlib path so neither
configuration contains unreachable code, and guard the fallback-only
locals and helpers (tg3json__utoa, tg3json__write_exp,
tg3json__format_decimal_digits) under !TG3JSON_USE_STDLIB_FPCONV to avoid
unused-function/variable warnings on the stdlib path.

Verified with gcc -Wall -Wextra -Werror across all v3 C test sources in
both fpconv configurations, plus runtime runs of tester_v3_json_c.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 21:15:33 +09:00
Syoyo Fujita
544290f60d fix build and remove unused workflows. 2026-06-02 19:16:37 +09:00
Syoyo Fujita
b88fadb61a Fix MSVC v3 C JSON float conversion 2026-06-01 20:08:32 +09:00
Syoyo Fujita
9d09d4c76f Run v3 C tests with CMake and Meson 2026-06-01 18:31:49 +09:00
Syoyo Fujita
234f19b774 Complete freestanding v3 C JSON conversion tests 2026-06-01 16:11:22 +09:00
Syoyo Fujita
a441a310fd Harden and optimize v3 C parser 2026-05-31 22:20:46 +09:00
Syoyo Fujita
bade0670eb CI: fix clang -Werror on unknown flag and MSVC fopen warning
run 25611531122 surfaced two failures:

- Stock Ubuntu clang errored on `-Wno-pre-c11-compat` (added in newer
  clang). Add `-Wno-unknown-warning-option` so older clang silently
  ignores warning flags it doesn't know.

- MSVC /W4 /WX failed on C4996 (fopen deprecation). Define
  `_CRT_SECURE_NO_WARNINGS` for the v3 C MSVC build; the parser uses
  fopen by design and v1 already takes the same approach.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 06:00:09 +09:00
Syoyo Fujita
d5a63adb47 CI: bump GitHub Actions to Node.js 24 versions
Silence the deprecation warnings reported on
https://github.com/syoyo/tinygltf/actions/runs/25610558215 by upgrading
all `actions/checkout` usages from v1/v2/v3/v4 to v5 (Node 24 runtime)
and the CodeQL actions from v2 to v3.

msys2/setup-msys2 stays at v2 — it's the latest tag.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 05:34:39 +09:00
Syoyo Fujita
fc04226d57 Build v3 C under clang -Weverything and MSVC /W4
Escalate v3 C warning levels in CI to catch latent issues:
gcc/clang now run with -Werror, clang adds -Weverything (with a
small irreducible suppression list for -Wpadded, -Wunsafe-buffer-usage,
-Wcast-align, etc.), and a new MSVC job builds tester_v3_c with /W4 /WX.

Source fixes to clear the elevated warnings:
- tg3__arena_new_block: cast through void* to silence -Wcast-align.
- tg3__value_to_json: handle TG3_VALUE_BINARY explicitly and drop the
  default label so -Wswitch-enum and -Wcovered-switch-default agree.
- Drop unused tg3__json_set_value_copy.
- tinygltf_json_c.h: enumerate all tg3json_value_type cases in
  tg3json_value_free / tg3json_value_copy / tg3json__stringify_value_ex.
- tester_v3_c_v1port FAIL macro: split the format/newline prints so it
  no longer relies on the GNU `, ##__VA_ARGS__` extension.

Verified: clang -Werror -Weverything builds clean, 13/13 internal
tests, 18/18 v1-port tests, and 134/134 cross-version regression all
pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 04:33:21 +09:00
Syoyo Fujita
a3e10174c5 Build v3 C tests under clang too; drop GNU VA_ARGS extension
ci.yml now runs the v3 C suites under three Linux toolchains:
- v3-c-tests        (default cc / GCC, -Wall -Wextra)
- v3-c-tests-clang  (stock Ubuntu clang)
- v3-c-tests-clang21 (clang 21 from apt.llvm.org, matching local dev)

The validator helper macros TG3__IDX_BAD / TG3__CHECK_REQ /
TG3__CHECK_OPT used the GNU `, ##__VA_ARGS__` extension, which clang
flags under -Wpedantic. Every call site already passes at least one
variadic argument, so plain __VA_ARGS__ (C11) suffices.

Local verification: clang-21 -Wall -Wextra builds tester_v3_c and
tester_v3_c_v1port with zero warnings introduced by the v3 changes
(only the pre-existing tg3__json_set_value_copy unused-function
notice remains, unrelated to this work). All suites pass under gcc
13.3 and clang 21.1 alike, plus the 134-model cross-version
verifier.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 04:04:15 +09:00
Syoyo Fujita
e32724d4cd Run v3 C tests in GitHub CI
ci.yml: two new jobs.
  - v3-c-tests builds tester_v3_c (security regressions) and
    tester_v3_c_v1port (18 ported v1 unit tests) with the default
    system cc (gcc on ubuntu-latest) and runs both.
  - v3-c-tests-sanitizers rebuilds the same suites under clang with
    -fsanitize=address,undefined and ASAN_OPTIONS=halt_on_error=1 plus
    leak detection so memory-safety regressions break CI.

c-cpp.yml: add a v3_c_tests step to build-linux so the legacy gcc
workflow also exercises the v3 C parser end-to-end.

Both invoke the parser via parse_auto with TINYGLTF3_ENABLE_FS so the
external-file paths (and the new path-traversal/file-size guards)
are exercised end-to-end.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 03:56:13 +09:00
Syoyo Fujita
51a675b30d Port v1 unit tests to v3 C; enforce max_external_file_size
tests/tester_v3_c_v1port.c mirrors 18 parse/load test cases from
tester.cc against the pure-C v3 runtime: parse-error, datauri-in-glb,
extension-with-empty-object, extension-overwrite, four bounds-checking
cases, glb-invalid-length, integer-out-of-bounds,
pbr-khr-texture-transform (verifies KHR_texture_transform scale via
tg3_value introspection), image-uri-spaces (single + multiple),
empty-skeleton-id, filesize-check, load-issue-416-model,
zero-sized-bin-chunk-glb, images-as-is, inverse-bind-matrices-optional,
default-material. Header comment lists tester.cc cases skipped because
they exercise the v3 writer or v1-internal helpers (out of scope).

Wiring max_external_file_size in the parser exposed by the
filesize-check port: the option was declared in tg3_parse_options but
never enforced. tg3__load_external_file now rejects loaded files larger
than the cap with TG3_ERR_FILE_TOO_LARGE and frees the buffer the fs
callback returned to avoid a leak. The 134-model verifier and the
existing tester_v3_c security regressions still pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 01:31:03 +09:00
Syoyo Fujita
57f4256812 Document v3 C security model and verification layers in README
Adds a Security model subsection covering URI sanitization, index-bounds
validation, strict numeric ranges, the 1 GB memory budget, image-decoder
opt-out, and error message lifetime — pointing to the authoritative
Security Considerations block in tiny_gltf_v3.h.

Adds a Testing & verification subsection describing the three coverage
layers shipped with the v3 C runtime: internal regression tests in
tester_v3_c, the cross-version DIGEST verifier in test_runner.py, and
the libFuzzer harness with ASan+UBSan in tests/v3/fuzzer/.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 14:16:30 +09:00
Syoyo Fujita
1b4b1bedda Harden v3 C parser against untrusted glTF input
Threat model: parser is intended for server-side processing of attacker-
supplied glTF/GLB. Two adversarial review rounds plus a 1-hour libFuzzer
run (4 workers, ASan+UBSan, ~420M execs total, zero new artifacts) drove
this set of fixes. Concrete PoCs in tests/v3/security/ confirmed each
issue was exploitable on the prior code.

Path traversal (CRITICAL): tg3__load_external_file concatenated base_dir
with the JSON-supplied URI verbatim. A glTF with
"uri":"../../../tmp/secret" successfully loaded the file from outside
base_dir (verified by FNV64 match). New tg3__uri_is_safe rejects empty,
NUL, leading / or \\, Windows drive prefixes, and any '..' segment.
Path-buffer length checks switched to saturating subtraction so 32-bit
size_t cannot wrap.

Sign-coercion in byteStride: int32_t -1 was cast directly to uint32_t,
producing 0xFFFFFFFF and propagating into downstream count*stride math.
Restrict to glTF spec range: 0 (tightly packed) or [4, 252].

Index validation: parsed int32 index fields (accessor.bufferView,
primitive.indices/material/attributes, node.mesh/skin/camera/light,
scene.nodes[], skin.joints[], animation channel/sampler refs, MSFT_lod
ids, KHR_audio emitter/source refs, etc.) were stored unchecked. New
tg3__validate_indices walks every index field and returns
TG3_ERR_INVALID_INDEX on out-of-range. Gated by
tg3_parse_options.validate_indices, defaulting to 1.

Use-after-free on parse failure (PRE-EXISTING, surfaced by ASan during
fix verification): tg3_parse and tg3_parse_glb destroyed model->arena_
on error paths, but error messages on the user-facing tg3_error_stack
were arena-allocated. Any caller reading errors.entries[i].message
after parse failure read freed memory. tg3_model_free is now sole arena
owner; arena lives across error paths so messages stay valid until the
caller frees the model.

Other fixes:
- tg3_parse_glb: hoist tg3__model_init before header parse so callers
  can safely tg3_model_free on header failure.
- tg3__parse_primitive morph targets: when arena alloc returns NULL,
  pair with target_counts[ti]=0 so validators do not deref.
- Defensive 'if (!tarr) continue' in the morph-target validator loop.
- New Security Considerations block in tiny_gltf_v3.h documents the
  threat model, default-on validation, fs-callback contract, and error
  message lifetime.

Verification: 13 internal tests in tester_v3_c (incl. 7 new security
regressions covering path traversal absolute and relative, fs-callback
no-call assertion, byteStride wrap, OOB index, opt-in raw mode, ext
fields, and arena-message lifetime), 134/134 Khronos sample models
match v1 ground truth digest, 1-hour ASan+UBSan fuzz on the final code
clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 14:02:34 +09:00
Syoyo Fujita
99e2af8a86 Cross-version verifier comparing v3 C parser against v1 ground truth
Adds a structured DIGEST block (asset, buffers w/ FNV-1a hash, bufferViews,
accessors w/ min/max, mesh primitives w/ sorted attribute maps, nodes w/
normalized TRS+matrix, materials, textures/samplers/images, skins,
animations, cameras, scenes) emitted by both loader_example (v1) and
tester_v3_c (v3 C, now accepting a file arg). test_runner.py runs both,
diffs the digests, and reports counts/digest mismatches with v1 as truth.

Also rolls in /simplify follow-ups on top of d2837e3: a shared
tg3__json_number_to_double helper to dedupe inline number coercions, a
collapsed fuzz_gltf_v3_c harness using a single tg3_fuzz_run dispatcher,
a rewritten max_safe_uint64_real comment explaining the 53-bit mantissa
constraint, and a tests/Makefile fix so tester_v3_c is a real prerequisite
of `all` (built once via the dedicated rule, not duplicated).

Verifier passes 134/134 on the Khronos glTF-Sample-Models/2.0 suite.
bufferView.target and image.mime_type/uri are intentionally excluded from
the digest: v1 infers target from accessor usage and rewrites image
URIs/mime via stb_image, neither of which is a parse-fidelity concern.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 11:50:28 +09:00
Syoyo Fujita
d2837e31fe Harden v3 numeric parsing and add C fuzz harness
Reject non-finite/out-of-range JSON numbers in int32/uint64 fields and
array/attribute elements instead of silently truncating, initialize the
model on parse-file failure, and free the partial JSON document when the
root is not an object. Adds a pure-C libFuzzer harness (fuzz_gltf_v3_c)
alongside the existing C++ one and tests covering the new failure modes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 04:10:32 +09:00
Syoyo Fujita
463bc4c292 Mark v3 C runtime experimental
Update README.md to describe the pure-C v3 runtime accurately, fix the JSON backend reference, and mark the new C implementation as experimental.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-06 09:16:14 +09:00
Syoyo Fujita
7c3d89ed5c Add pure-C TinyGLTF v3 runtime
Introduce a C-first TinyGLTF v3 runtime in tiny_gltf_v3.c with a pure-C JSON backend, hook the public header to the new implementation, and add CMake/test coverage for parse and write round-trips.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-06 04:28:41 +09:00
Syoyo Fujita
fcfce6fc63 Remove projects section from README
Removed the list of projects using TinyGLTF from the README.
2026-05-04 05:37:00 +09:00
Syoyo Fujita
f215e1ed51 add pr template. 2026-04-06 04:43:12 +09:00
Syoyo Fujita
310201d843 Create SECURITY.md 2026-04-06 04:30:19 +09:00
Syoyo Fujita
28e201e001 Modify copyright notice in tiny_gltf_v3.h
Updated copyright year and authorship information.
2026-03-25 02:35:54 +09:00
Syoyo Fujita
cfcadfa8d1 Clarify C++ version requirement in README
Updated README to reflect C++11 requirement and removed outdated information.
2026-03-24 04:52:36 +09:00
Syoyo Fujita
563fdd8ef8 Merge pull request #537 from syoyo/v3
V3
2026-03-24 04:50:29 +09:00
Syoyo Fujita
b665415cb3 Merge pull request #544 from syoyo/copilot/sub-pr-537-8bf00c20-87df-4d41-b746-2db2da281b7c
docs: Add v3 API section to README with deprecation notice for v2
2026-03-24 01:49:04 +09:00
copilot-swe-agent[bot]
68ef5901e2 Add v3 documentation to README.md with summary, quick start, and v2 deprecation notice
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/syoyo/tinygltf/sessions/ffbaa2c3-7ad0-4210-b802-3253f1443ec2
2026-03-23 16:38:16 +00:00
copilot-swe-agent[bot]
f6404c1943 Initial plan 2026-03-23 16:36:22 +00:00
Syoyo Fujita
14f42b0467 Merge pull request #543 from syoyo/copilot/sub-pr-537-please-work
Fix misleading comment on cj_dbl_to_i64 clamping behavior
2026-03-24 01:32:48 +09:00
copilot-swe-agent[bot]
f9c969f859 Remove accidentally committed tmp.glb
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/syoyo/tinygltf/sessions/74f01d98-ca42-4950-984e-458d4e3eeccd
2026-03-21 20:39:39 +00:00
copilot-swe-agent[bot]
5b736326c7 Fix cj_dbl_to_i64 comment to accurately describe clamping behavior
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/syoyo/tinygltf/sessions/74f01d98-ca42-4950-984e-458d4e3eeccd
2026-03-21 20:39:31 +00:00
copilot-swe-agent[bot]
4f3fbcaeb5 Initial plan 2026-03-21 20:37:03 +00:00
Syoyo Fujita
9f7a9ef098 Merge pull request #536 from syoyo/copilot/implement-gltf-parser-unit-tester
Add intensive parser unit tester and LLVM fuzzer for tinygltf_json.h backend
2026-03-22 05:33:43 +09:00
Syoyo Fujita
48fb4c8ce2 Update tests/fuzzer/fuzz_gltf_customjson.cc
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-22 02:50:24 +09:00
Syoyo Fujita
fc295b0d57 Update tests/fuzzer/README.md
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-22 02:50:11 +09:00
Syoyo Fujita
3b30a551c4 Update tests/tester_intensive_customjson.cc
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-22 02:50:02 +09:00
Syoyo Fujita
38ce868f79 Merge pull request #540 from syoyo/copilot/sub-pr-537-another-one
Fix float32_mode mis-classifying long integer tokens as floats
2026-03-21 07:04:36 +09:00
Syoyo Fujita
c20c15dcc8 Merge pull request #541 from syoyo/copilot/sub-pr-537-yet-again
Fix `tg3__arena_strdup` conflating empty strings with absent strings
2026-03-21 07:04:10 +09:00
Syoyo Fujita
358ea9a37c Merge pull request #538 from syoyo/copilot/sub-pr-537
Fix tg3_writer allocation: replace calloc/free with new/delete
2026-03-21 06:38:06 +09:00
Syoyo Fujita
e44a1aee19 Merge pull request #542 from syoyo/copilot/sub-pr-537-one-more-time
Guard TINYGLTF3_IMPLEMENTATION against C translation units
2026-03-21 06:37:42 +09:00
copilot-swe-agent[bot]
a7b51ed0ed Fix float32_mode integer parsing: preserve int64 precision for integer-only tokens
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/syoyo/tinygltf/sessions/a77fd614-00f3-49c1-bb4a-0498771cc63b
2026-03-20 21:24:37 +00:00
copilot-swe-agent[bot]
6845653b38 Fix tg3__arena_strdup to distinguish empty strings from absent strings
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/syoyo/tinygltf/sessions/445ab61b-4294-45e6-8faf-4f2fc8dfe369
2026-03-20 21:21:35 +00:00
copilot-swe-agent[bot]
bd9999c297 Add C++ compilation guard for TINYGLTF3_IMPLEMENTATION
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/syoyo/tinygltf/sessions/9d34bfe8-6b91-44f8-aedc-adb3bfeadf84
2026-03-20 21:21:26 +00:00
Syoyo Fujita
6d2f83fb7a Merge pull request #539 from syoyo/copilot/sub-pr-537-again
Use `__VA_OPT__` for variadic comma elision in C++20, `##__VA_ARGS__` fallback for C++17
2026-03-21 06:19:35 +09:00
copilot-swe-agent[bot]
308c405b09 Initial plan 2026-03-20 21:15:51 +00:00
copilot-swe-agent[bot]
94d6b7e266 Initial plan 2026-03-20 21:15:45 +00:00
copilot-swe-agent[bot]
8820c3113b Initial plan 2026-03-20 21:15:36 +00:00
copilot-swe-agent[bot]
e003bc7f9e Replace ##__VA_ARGS__ with portable TG3__COMMA_VA_ARGS helper (C++17/C++20)
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/syoyo/tinygltf/sessions/a7105342-8673-4241-b727-29026461cc67
2026-03-20 20:42:17 +00:00
copilot-swe-agent[bot]
c55665b60c Fix tg3_writer allocation: use new/delete instead of calloc/free
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/syoyo/tinygltf/sessions/c2a9ce6c-1c60-4925-b67b-e5ad2ffe1cd2
2026-03-20 20:39:43 +00:00
Syoyo Fujita
2e4d3d06ba Update tiny_gltf_v3.h
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-21 05:36:13 +09:00
Syoyo Fujita
4569d5fc5b Update tiny_gltf_v3.h
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-21 05:35:53 +09:00
Syoyo Fujita
ccc8115321 Update tinygltf_json.h
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-21 05:35:34 +09:00
copilot-swe-agent[bot]
860f96c670 Initial plan 2026-03-20 20:35:31 +00:00
copilot-swe-agent[bot]
f985381049 Initial plan 2026-03-20 20:34:21 +00:00
Syoyo Fujita
f6c101ca28 Fix fuzzer-found bugs, add libFuzzer harness for v3
Add tests/v3/fuzzer/ with libFuzzer harness covering all four parse
paths (auto-detect, JSON, GLB, float32 mode) with ASan+UBSan.

Fix two bugs found by 10+ hours of fuzzing (~23M iterations):

1. UB: (int64_t)inf in cj_parse_number when extreme exponents like
   22222222e222222 produce infinity. Add cj_dbl_to_i64() that clamps
   inf/NaN/out-of-range values before casting.

2. Null deref in tg3__parse_string when glTF array elements are not
   JSON objects (e.g. "scenes": [[3]]). Add is_object() validation
   in TG3__PARSE_ARRAY_SIMPLE and TG3__PARSE_ARRAY_IDX macros.

Verified clean: 5.8M additional runs with zero crashes after fixes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 04:10:25 +09:00
Syoyo Fujita
108a4065d0 Add fast float parser and benchmark float-heavy scene
Replace strtod() with Clinger's fast path in tinygltf_json.h for ~1.5x
faster JSON float parsing. The new parser accumulates all digits into a
uint64 mantissa and uses exact power-of-10 tables for conversion,
avoiding locale-dependent strtod for ~99% of JSON float values.

Add optional float32 parse mode (parse_float32 option) that parses JSON
floats at single precision — fewer significant digits needed, wider fast
path range. Breaks strict double-precision conformance but sufficient
for glTF data which is typically single-precision.

Benchmark additions:
- gen_synthetic: add float_heavy preset (~500MB ASCII float JSON)
- bench_v3: add --float32 flag for float32 parse mode benchmarking

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 09:00:30 +09:00
Syoyo Fujita
d8d9e67da2 Add tinygltf v3 single-header C API (tiny_gltf_v3.h)
Ground-up C-centric rewrite of tinygltf with pure C POD structs,
arena-based memory management, structured error reporting, streaming
callbacks, and no STL dependency in the public API. Uses tinygltf_json.h
as the sole JSON backend.

Includes complete parser (JSON + GLB), writer (JSON + GLB), streaming
writer, C++ RAII wrappers, and C++20 coroutine facade. Verified with
Cube.gltf and Fox.glb parse/write round-trips.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 03:31:05 +09:00
Syoyo Fujita
ac606e8f34 Merge branch 'release' of github.com:syoyo/tinygltf into release 2026-03-19 13:39:50 +09:00
Syoyo Fujita
f4c5782140 ignore build/ 2026-03-19 13:39:37 +09:00
copilot-swe-agent[bot]
c7ef1aa801 Address code review feedback: .gitignore path, fuzzer docs, trailing whitespace test
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
2026-03-19 00:44:04 +00:00
copilot-swe-agent[bot]
482ffb1008 Add intensive parser unit tester and LLVM fuzzer for tinygltf_json.h backend
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
2026-03-19 00:42:53 +00:00
copilot-swe-agent[bot]
c464487c00 Initial plan 2026-03-19 00:32:52 +00:00
Syoyo Fujita
ef0e19bd86 Merge pull request #535 from syoyo/copilot/optimize-json-parser
Add tinygltf_json.h: fast custom JSON parser with optional SIMD acceleration
2026-03-19 09:29:56 +09:00
copilot-swe-agent[bot]
61976df9bf Super final review: fix cj_unescape_string data-loss, escape-scan infinite loop, operator[] destructor
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
2026-03-18 21:44:18 +00:00
copilot-swe-agent[bot]
6a9ab4cc5e Final review: fix stray *out_len=len UB, add get<T> primary template for size_t
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
2026-03-18 20:16:01 +00:00
Syoyo Fujita
27ead283a0 Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-19 02:39:27 +09:00
Syoyo Fujita
2e96f282a0 Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-19 02:39:13 +09:00
Syoyo Fujita
0da972149a Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-19 02:38:55 +09:00
Syoyo Fujita
18dda78116 Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-19 02:38:40 +09:00
Syoyo Fujita
d910e58c3a Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-19 02:38:28 +09:00
Syoyo Fujita
7c7eadba3a Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-19 02:38:10 +09:00
Syoyo Fujita
1d34438a74 Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-19 02:37:50 +09:00
Syoyo Fujita
239e832bf7 Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-19 02:37:37 +09:00
Syoyo Fujita
673b454123 Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-19 02:37:10 +09:00
copilot-swe-agent[bot]
fe23326b70 Mitochondria-level review: fix NULL ptr + nonzero length → serializer overread (6 sites)
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
2026-03-18 04:34:13 +00:00
copilot-swe-agent[bot]
28c139869a Deepest-ever review: NaN/Inf->null, operator[] null key, copy_from_ arr_size_ tracking
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
2026-03-18 04:10:06 +00:00
copilot-swe-agent[bot]
b611d7b1f5 Ultra deep final review: 6 correctness/safety fixes in tinygltf_json.h
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
2026-03-18 03:32:36 +00:00
copilot-swe-agent[bot]
4a05b8e0f3 Fix security/correctness issues from thorough code review of tinygltf_json.h
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
2026-03-17 23:17:24 +00:00
copilot-swe-agent[bot]
36cf721b8c Make C++ exceptions optional in tinygltf_json.h (default off)
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
2026-03-17 19:33:02 +00:00
copilot-swe-agent[bot]
a1c09a7760 Replace recursive parser with iterative loop using CJ_MAX_ITER explicit frame stack
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
2026-03-17 19:24:38 +00:00
copilot-swe-agent[bot]
8c0bb9739d Security fixes: null key guard, allocation overflow protection, parser depth limit
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
2026-03-17 16:02:25 +00:00
copilot-swe-agent[bot]
e9ba157058 Remove accidental test artifact files and update .gitignore
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
2026-03-17 15:52:12 +00:00
copilot-swe-agent[bot]
8f8b5ec1e0 Add tinygltf_json.h: fast custom JSON parser with optional SIMD support
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
2026-03-17 15:49:46 +00:00
copilot-swe-agent[bot]
1616826478 Initial plan 2026-03-17 15:15:01 +00:00
Syoyo Fujita
a08acf4cee Merge pull request #533 from syoyo/copilot/remove-appveyor-ci-config
Remove AppVeyor CI config and badge from README
2026-03-05 13:29:40 +09:00
copilot-swe-agent[bot]
2df78ad4af Remove AppVeyor CI config and badge from README
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
2026-03-05 04:27:49 +00:00
copilot-swe-agent[bot]
ee3ff55b26 Initial plan 2026-03-05 04:27:04 +00:00
Syoyo Fujita
0941911736 Merge pull request #532 from AnisB/remove_std_namespace
Removing problematic using namespace in a header file
2026-03-03 02:59:00 +09:00
benyo-razer
d9f5488a84 Removing problematic using namespace in a header file 2026-03-02 12:21:07 +01:00
Syoyo Fujita
cc9a863c9a Merge pull request #531 from syoyo/copilot/update-ci-workflow-comprehensive-builds
Update Linux Clang CI job to use Clang 21
2026-02-06 01:39:55 +09:00
Syoyo Fujita
e017002baa Use CMake and ctest for Linux and macOS native builds
Convert manual g++/clang++ builds to CMake for consistency with
Windows builds:
- Linux x64 (GCC)
- Linux ARM64 (GCC)
- macOS ARM64 Apple Silicon (Clang)

All native builds now use:
- cmake -B build -DTINYGLTF_BUILD_LOADER_EXAMPLE=ON
- cmake --build build
- ctest --test-dir build --output-on-failure

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 00:52:59 +09:00
Syoyo Fujita
392e9f4df3 Update Linux Clang job to use Clang 21
- Install Clang 21 from LLVM apt repository
- Use CMake with clang-21/clang++-21 compilers
- Run tests with ctest

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 00:24:55 +09:00
Syoyo Fujita
f10abe07e5 Merge pull request #529 from syoyo/copilot/update-ci-workflow-comprehensive-builds
Add comprehensive multi-platform CI workflow with 15 build configurations
2026-02-05 05:42:31 +09:00
Syoyo Fujita
57b1c99db2 Use CMake and ctest for RapidJSON backend build
Convert RapidJSON backend job from manual g++ builds to CMake,
enabling ctest for running tests.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 05:35:46 +09:00
Syoyo Fujita
47717e469c Add ctest to CMake-based builds
Run ctest after build for:
- Windows x64 MSVC
- Windows x86 MSVC
- Windows MinGW MSYS2
- Linux Header-Only Mode

Cross-compile builds (Windows ARM64, Linux→Windows MinGW) are excluded
since tests cannot run on the host.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 05:19:22 +09:00
Syoyo Fujita
a3618c945b Remove macOS Intel job from CI
macOS Intel runners are being deprecated. Keep only the ARM64
Apple Silicon job for macOS coverage.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 05:08:09 +09:00
Syoyo Fujita
80e94aeec8 Fix CI: update macOS runner and remove Windows unit tests
- Change macos-13 to macos-15-large for Intel x64 (macos-13 is retired)
- Remove Windows MSVC unit tests (they have path-related issues and
  the existing c-cpp.yml workflow doesn't run tests on Windows either)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 04:54:40 +09:00
Syoyo Fujita
604411c80a Fix Windows MSVC unit tests build by setting up developer environment
The `cl` compiler was not in PATH because the Visual Studio developer
environment needs to be set up before calling MSVC tools directly.
Added `ilammy/msvc-dev-cmd@v1` action to configure the environment.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 04:54:40 +09:00
copilot-swe-agent[bot]
f5dcdf2e9a Add security: restrict GITHUB_TOKEN permissions to read-only
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
2026-02-05 04:54:40 +09:00
copilot-swe-agent[bot]
2746c376f8 Add comprehensive CI workflow with multi-platform builds and tests
Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
2026-02-05 04:54:40 +09:00
copilot-swe-agent[bot]
3216eb4df5 Initial plan 2026-02-05 04:54:40 +09:00
Syoyo Fujita
dda694e13f Merge pull request #530 from syoyo/add-cmake-test-target
Add CMake test target and fix Windows test failure
2026-02-05 04:52:23 +09:00
1415 changed files with 75379 additions and 714 deletions

45
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,45 @@
## Description
What does this PR do? Provide a brief summary of the changes.
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Refactoring (no functional changes)
- [ ] Documentation update
- [ ] Other (please describe):
## Checklist
### Required for All PRs
- [ ] Reproducible glTF test file(s) are included (e.g., `models/regression/`, `tests/issue-***.gltf`, etc.)
- [ ] Unit tests are written and pass locally (`cd tests && make run`)
### Required for Feature PRs
- [ ] Specification document is included (e.g., `docs/spec/<feature-name>.md`)
- The spec should cover: purpose, API design, usage examples, and edge cases
### Security Policy
This project manages CVE assignments exclusively through GitHub Security Advisories.
PRs that include or reference independently obtained CVE IDs or external vulnerability disclosures will be closed.
## Test Instructions
How can reviewers verify your changes?
```
# Example:
cd build && cmake .. && make test
```
## Related Issues
Link related issues:
## Additional Notes
Any other context, screenshots, or information relevant to the review.

View File

@@ -1,92 +0,0 @@
# Copilot Review Instructions for TinyGLTF
This document provides guidelines for reviewing code changes in the TinyGLTF repository.
## Memory Safety
- **Buffer Overflows**: Check for proper bounds checking when accessing arrays, vectors, and buffers. Verify that buffer sizes are validated before read/write operations.
- **Null Pointer Dereferences**: Ensure all pointers are checked for null before dereferencing, especially when handling optional glTF fields.
- **Memory Leaks**: Verify proper resource management, including RAII patterns for file handles, image data, and dynamically allocated memory.
- **Use-After-Free**: Check for proper lifetime management of objects, especially when dealing with callbacks and asynchronous operations.
## Error Handling
- **File I/O**: Verify that all file operations have proper error checking and meaningful error messages.
- **JSON Parsing**: Ensure JSON parsing errors are caught and reported with helpful context about the location and nature of the error.
- **Resource Loading**: Check that failures in loading images, buffers, and other resources are properly handled and don't cause crashes.
- **Error Propagation**: Verify that errors are properly propagated through the call stack with appropriate error messages.
## glTF 2.0 Specification Compliance
- **Required Fields**: Ensure all required glTF fields are validated and present.
- **Data Types**: Verify that data types match the glTF specification (e.g., component types, accessor types).
- **Constraints**: Check that glTF constraints are enforced (e.g., valid ranges for enums, buffer stride requirements).
- **Extensions**: Verify proper handling of glTF extensions and that unknown extensions are handled gracefully.
- **Validation**: Ensure new features align with the glTF 2.0 specification from the Khronos Group.
## Cross-Platform Compatibility
- **Windows**: Check for proper handling of Windows-specific issues (path separators, line endings, file operations).
- **Linux**: Verify compatibility with various Linux distributions and compilers (GCC, Clang).
- **macOS**: Ensure macOS-specific considerations are addressed (case-sensitive filesystems, Clang compatibility).
- **Mobile Platforms**: Consider Android and iOS compatibility where applicable.
- **Endianness**: Verify proper handling of byte order when reading binary data.
- **Compiler Compatibility**: Ensure code compiles with C++11 standard and supported compilers (MSVC, GCC, Clang).
## Edge Cases in glTF Parsing
- **Empty/Minimal Files**: Verify handling of minimal valid glTF files.
- **Large Files**: Check for proper handling of large glTF files and buffers without memory exhaustion.
- **Malformed Data**: Ensure graceful handling of malformed or invalid glTF data.
- **Missing Optional Fields**: Verify correct behavior when optional glTF fields are absent.
- **Edge Values**: Check handling of boundary values (e.g., maximum buffer sizes, extreme floating-point values).
- **Base64 Encoding**: Verify proper handling of base64-encoded data URIs and invalid encodings.
## Backwards Compatibility
- **API Changes**: Ensure public API changes maintain backwards compatibility or are properly deprecated.
- **Breaking Changes**: Flag any breaking changes for major version updates and document migration paths.
- **Binary Compatibility**: Consider ABI stability for header-only library changes.
- **Default Behavior**: Verify that default behavior of existing functionality remains unchanged.
## Performance Considerations
- **Parsing Performance**: Check for unnecessary copies, redundant allocations, and inefficient algorithms in parsing logic.
- **Memory Usage**: Verify efficient memory usage, especially when loading large glTF files.
- **I/O Operations**: Ensure efficient file reading and minimize unnecessary disk access.
- **String Operations**: Check for efficient string handling (use of string_view, move semantics).
- **STL Usage**: Verify appropriate use of STL containers and algorithms.
## Documentation
- **Public API**: Ensure all public functions, classes, and methods have clear documentation comments.
- **Parameters**: Verify that function parameters are documented, including expected ranges and constraints.
- **Return Values**: Document return values and possible error conditions.
- **Examples**: Check that complex features include usage examples.
- **Changelog**: Verify that significant changes are documented in release notes or changelog.
## Testing
- **Test Coverage**: Ensure new features include appropriate unit tests or integration tests.
- **Edge Cases**: Verify that tests cover edge cases and error conditions.
- **Cross-Platform Tests**: Check that tests run on all supported platforms.
- **Regression Tests**: Ensure bug fixes include regression tests to prevent recurrence.
- **Sample Files**: Verify that changes are tested with various valid and invalid glTF sample files.
## Code Style Consistency
- **Header-Only Pattern**: Maintain the header-only library structure.
- **Naming Conventions**: Follow existing naming conventions (CamelCase for types, snake_case for functions where applicable).
- **Formatting**: Adhere to the existing code formatting style (check `.clang-format` if available).
- **Include Guards**: Verify proper include guards and header organization.
- **Namespace Usage**: Ensure proper use of the `tinygltf` namespace.
- **Comments**: Maintain consistent comment style with existing code.
- **C++11 Compliance**: Verify that code uses C++11 features appropriately and doesn't require newer standards unless specified.
## Additional Considerations
- **Third-Party Dependencies**: Minimize new dependencies; prefer existing dependencies (json.hpp, stb_image).
- **Warnings**: Ensure code compiles without warnings on supported compilers.
- **const Correctness**: Verify proper use of const for parameters and methods.
- **RAII**: Prefer RAII patterns for resource management over manual cleanup.
- **noexcept**: Use noexcept appropriately for move constructors and move assignment operators.

View File

@@ -4,166 +4,65 @@ 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
name: Build v3 C tests with MinGW gcc cross
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v5
- 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
cd tests
x86_64-w64-mingw32-gcc -I../ -std=c11 -DTINYGLTF3_ENABLE_FS -o tester_v3_c.exe tester_v3_c.c ../tiny_gltf_v3.c
# Windows(x64) + Visual Studio 2022 build
# Assume windows-latest have VS2022 installed
# Windows(x64) + MSVC build (VS version agnostic: msvc-dev-cmd locates
# whatever Visual Studio the runner image ships, e.g. VS2022 or VS2026)
build-windows-msvc:
runs-on: windows-latest
name: Build for Windows(x64, MSVC)
name: Build v3 C tests on 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
uses: actions/checkout@v5
- name: Set up MSVC environment
uses: ilammy/msvc-dev-cmd@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 ..
run: cmake -B build -G Ninja -DTINYGLTF3_BUILD_TESTS=ON
- name: Build
run: cmake --build build --config Release
run: cmake --build build
- name: Run tests
run: ctest --test-dir build --output-on-failure
build-linux:
runs-on: ubuntu-latest
name: Buld with gcc
name: Build v3 C tests with gcc
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v5
- name: build
run: |
g++ -std=c++11 -o loader_example loader_example.cc
cd tests
cc -I../ -std=c11 -g -O0 -DTINYGLTF3_ENABLE_FS -o tester_v3_c tester_v3_c.c ../tiny_gltf_v3.c
- name: test
run: |
./loader_example models/Cube/Cube.gltf
./tests/tester_v3_c models/Cube/Cube.gltf
- name: tests
run: |
cd tests
g++ -I../ -std=c++11 -g -O0 -o tester tester.cc
./tester
make all
./tester_v3_c
./tester_v3_c_v1port
./tester_v3_json_c
./tester_v3_freestanding
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

389
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,389 @@
name: Comprehensive CI
on:
push:
branches:
- master
- release
- devel
pull_request:
branches:
- master
- release
- devel
workflow_dispatch:
permissions:
contents: read
jobs:
# Linux x64 - GCC
linux-gcc-x64:
runs-on: ubuntu-latest
name: Linux x64 (GCC)
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Configure
run: cmake -B build -DTINYGLTF3_BUILD_TESTS=ON
- name: Build
run: cmake --build build
- name: Run tester_v3_c on a sample model
run: ./build/tester_v3_c models/Cube/Cube.gltf
- name: Run tests
run: ctest --test-dir build --output-on-failure
# Linux x64 - Clang 21
linux-clang-x64:
runs-on: ubuntu-24.04
name: Linux x64 (Clang 21)
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Install Clang 21
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 21
- name: Configure
run: |
cmake -B build -DCMAKE_C_COMPILER=clang-21 -DTINYGLTF3_BUILD_TESTS=ON
- name: Build
run: cmake --build build
- name: Run tester_v3_c on a sample model
run: ./build/tester_v3_c models/Cube/Cube.gltf
- name: Run tests
run: ctest --test-dir build --output-on-failure
# Linux ARM64 - GCC (native)
linux-arm64:
runs-on: ubuntu-24.04-arm
name: Linux ARM64 (GCC)
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Configure
run: cmake -B build -DTINYGLTF3_BUILD_TESTS=ON
- name: Build
run: cmake --build build
- name: Run tester_v3_c on a sample model
run: ./build/tester_v3_c models/Cube/Cube.gltf
- name: Run tests
run: ctest --test-dir build --output-on-failure
# macOS ARM64 Apple Silicon
macos-arm64:
runs-on: macos-14
name: macOS ARM64 Apple Silicon (Clang)
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Configure
run: cmake -B build -DTINYGLTF3_BUILD_TESTS=ON
- name: Build
run: cmake --build build
- name: Run tester_v3_c on a sample model
run: ./build/tester_v3_c models/Cube/Cube.gltf
- name: Run tests
run: ctest --test-dir build --output-on-failure
# Windows x64 - MSVC (VS version agnostic; msvc-dev-cmd locates the
# Visual Studio shipped with the runner image, e.g. VS2022 or VS2026)
windows-msvc-x64:
runs-on: windows-latest
name: Windows x64 (MSVC)
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up MSVC environment
uses: ilammy/msvc-dev-cmd@v1
- name: Configure
run: cmake -B build -G Ninja -DTINYGLTF3_BUILD_TESTS=ON
- name: Build
run: cmake --build build
- name: Run tester_v3_c on a sample model
run: |
.\build\tester_v3_c.exe models\Cube\Cube.gltf
- name: Run tests
run: ctest --test-dir build --output-on-failure
# Windows MinGW - MSYS2
windows-mingw-msys2:
runs-on: windows-latest
name: Windows x64 (MinGW MSYS2)
defaults:
run:
shell: msys2 {0}
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Setup MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: UCRT64
install: base-devel
pacboy: >-
cc:p cmake:p ninja:p
update: true
release: false
- name: Build with CMake
run: |
cmake -G"Ninja" -S . -B build -DTINYGLTF3_BUILD_TESTS=ON
cmake --build build
- name: Run tester_v3_c on a sample model
run: |
./build/tester_v3_c models/Cube/Cube.gltf
- name: Run tests
run: ctest --test-dir build --output-on-failure
# Linux -> Windows MinGW Cross-compile
linux-mingw-cross:
runs-on: ubuntu-latest
name: Linux→Windows (MinGW Cross) - Build Only
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Install MinGW
run: |
sudo apt-get update
sudo apt-get install -y build-essential mingw-w64
- name: Build
run: |
cd tests
x86_64-w64-mingw32-gcc -I../ -std=c11 -g -O0 -DTINYGLTF3_ENABLE_FS -o tester_v3_c.exe tester_v3_c.c ../tiny_gltf_v3.c
# v3 C tests through Meson on the primary desktop platforms.
v3-c-meson:
runs-on: ${{ matrix.os }}
name: v3 C Meson (${{ matrix.os }})
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Install Meson
run: python -m pip install meson ninja
- name: Configure
run: meson setup build-meson -Dtests=true
- name: Build
run: meson compile -C build-meson
- name: Run v3 C tests
run: meson test -C build-meson --print-errorlogs
# v3 C runtime: internal security regression tests + ported v1 unit tests.
v3-c-tests:
runs-on: ubuntu-latest
name: v3 C tests (Linux x64, GCC)
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Build tester_v3_c
run: |
cd tests
cc -I../ -std=c11 -g -O0 -Wall -Wextra -Wpedantic -Werror -DTINYGLTF3_ENABLE_FS \
-o tester_v3_c tester_v3_c.c ../tiny_gltf_v3.c
- name: Build tester_v3_c_v1port
run: |
cd tests
cc -I../ -std=c11 -g -O0 -Wall -Wextra -Wpedantic -Werror -DTINYGLTF3_ENABLE_FS \
-o tester_v3_c_v1port tester_v3_c_v1port.c ../tiny_gltf_v3.c
- name: Run tester_v3_c (security regressions)
run: |
cd tests
./tester_v3_c
- name: Run tester_v3_c_v1port (ported unit tests)
run: |
cd tests
./tester_v3_c_v1port
# v3 C runtime under stock Ubuntu clang.
v3-c-tests-clang:
runs-on: ubuntu-latest
name: v3 C tests (Linux x64, Clang)
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Install clang
run: |
sudo apt-get update
sudo apt-get install -y clang
- name: Build tester_v3_c
run: |
cd tests
clang -I../ -std=c11 -g -O0 -Werror -Weverything \
-Wno-padded -Wno-unsafe-buffer-usage -Wno-switch-default \
-Wno-format-nonliteral -Wno-float-equal -Wno-cast-align \
-Wno-declaration-after-statement -Wno-unknown-warning-option \
-Wno-pre-c11-compat \
-DTINYGLTF3_ENABLE_FS \
-o tester_v3_c tester_v3_c.c ../tiny_gltf_v3.c
- name: Build tester_v3_c_v1port
run: |
cd tests
clang -I../ -std=c11 -g -O0 -Werror -Weverything \
-Wno-padded -Wno-unsafe-buffer-usage -Wno-switch-default \
-Wno-format-nonliteral -Wno-float-equal -Wno-cast-align \
-Wno-declaration-after-statement -Wno-unknown-warning-option \
-Wno-pre-c11-compat \
-DTINYGLTF3_ENABLE_FS \
-o tester_v3_c_v1port tester_v3_c_v1port.c ../tiny_gltf_v3.c
- name: Run tester_v3_c
run: |
cd tests
./tester_v3_c
- name: Run tester_v3_c_v1port
run: |
cd tests
./tester_v3_c_v1port
# v3 C runtime under bleeding-edge clang 21 (matches local dev environment).
v3-c-tests-clang21:
runs-on: ubuntu-24.04
name: v3 C tests (Linux x64, Clang 21)
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Install clang 21
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 21
- name: Build tester_v3_c
run: |
cd tests
clang-21 -I../ -std=c11 -g -O0 -Werror -Weverything \
-Wno-padded -Wno-unsafe-buffer-usage -Wno-switch-default \
-Wno-format-nonliteral -Wno-float-equal -Wno-cast-align \
-Wno-declaration-after-statement -Wno-unknown-warning-option \
-Wno-pre-c11-compat \
-DTINYGLTF3_ENABLE_FS \
-o tester_v3_c tester_v3_c.c ../tiny_gltf_v3.c
- name: Build tester_v3_c_v1port
run: |
cd tests
clang-21 -I../ -std=c11 -g -O0 -Werror -Weverything \
-Wno-padded -Wno-unsafe-buffer-usage -Wno-switch-default \
-Wno-format-nonliteral -Wno-float-equal -Wno-cast-align \
-Wno-declaration-after-statement -Wno-unknown-warning-option \
-Wno-pre-c11-compat \
-DTINYGLTF3_ENABLE_FS \
-o tester_v3_c_v1port tester_v3_c_v1port.c ../tiny_gltf_v3.c
- name: Run tester_v3_c
run: |
cd tests
./tester_v3_c
- name: Run tester_v3_c_v1port
run: |
cd tests
./tester_v3_c_v1port
# v3 C runtime built with MSVC at warning-level 4 (/W4 /WX).
v3-c-tests-msvc:
runs-on: windows-latest
name: v3 C tests (Windows x64, MSVC /W4)
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up MSVC environment
uses: ilammy/msvc-dev-cmd@v1
- name: Build and run tester_v3_c
shell: cmd
run: |
cd tests
cl /nologo /W4 /WX /std:c11 /Zi /Od /D_CRT_SECURE_NO_WARNINGS /DTINYGLTF3_ENABLE_FS /I.. tester_v3_c.c ..\tiny_gltf_v3.c /Fe:tester_v3_c.exe
tester_v3_c.exe
- name: Build and run tester_v3_c_v1port
shell: cmd
run: |
cd tests
cl /nologo /W4 /WX /std:c11 /Zi /Od /D_CRT_SECURE_NO_WARNINGS /DTINYGLTF3_ENABLE_FS /I.. tester_v3_c_v1port.c ..\tiny_gltf_v3.c /Fe:tester_v3_c_v1port.exe
tester_v3_c_v1port.exe
# v3 C runtime under ASan + UBSan for memory-safety + UB checks.
v3-c-tests-sanitizers:
runs-on: ubuntu-latest
name: v3 C tests (Clang ASan + UBSan)
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Build tester_v3_c with ASan + UBSan
run: |
cd tests
clang -I../ -std=c11 -g -O1 -DTINYGLTF3_ENABLE_FS \
-fsanitize=address,undefined -fno-omit-frame-pointer \
-o tester_v3_c tester_v3_c.c ../tiny_gltf_v3.c
- name: Build tester_v3_c_v1port with ASan + UBSan
run: |
cd tests
clang -I../ -std=c11 -g -O1 -DTINYGLTF3_ENABLE_FS \
-fsanitize=address,undefined -fno-omit-frame-pointer \
-o tester_v3_c_v1port tester_v3_c_v1port.c ../tiny_gltf_v3.c
- name: Run tester_v3_c
env:
ASAN_OPTIONS: detect_leaks=1:halt_on_error=1
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
run: |
cd tests
./tester_v3_c
- name: Run tester_v3_c_v1port
env:
ASAN_OPTIONS: detect_leaks=1:halt_on_error=1
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
run: |
cd tests
./tester_v3_c_v1port

View File

@@ -1,72 +0,0 @@
# 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

View File

@@ -7,7 +7,11 @@ on:
- devel
paths:
- 'tiny_gltf.*'
- 'tinygltf_json_c.h'
- 'CMakeLists.txt'
- 'meson.build'
- 'meson_options.txt'
- 'tests/tester_v3*.c'
- '.github/workflows/mingw-w64-msys2.yml'
pull_request:
workflow_dispatch:
@@ -20,7 +24,7 @@ jobs:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v5
- name: Install core & build dependencies
uses: msys2/setup-msys2@v2
@@ -37,9 +41,13 @@ jobs:
cmake \
-G"Ninja" \
-S . \
-B build
-B build \
-DTINYGLTF3_BUILD_TESTS=ON
- name: Build
run: |
cmake --build build
- name: Run tests
run: |
ctest --test-dir build --output-on-failure

26
.gitignore vendored
View File

@@ -1,4 +1,5 @@
# CMake
/build/
CMakeCache.txt
CMakeFiles
CMakeScripts
@@ -21,6 +22,9 @@ premake5.tar.gz
*.vcxproj*
.vs
# default cmake build dir
build/
#binary directories
bin/
obj/
@@ -66,14 +70,22 @@ imgui.ini
*.app
loader_example
tests/tester
tests/tester_noexcept
tests/issue-97.gltf
tests/issue-261.gltf
# Compiled test binaries (built by tests/Makefile, CMakeLists.txt, meson.build)
tests/tester_v3
tests/tester_v3_c
tests/tester_v3_c_cpp
tests/tester_v3_c_v1port
tests/tester_v3_c_v1port_cpp
tests/tester_v3_freestanding
tests/tester_v3_json_c
tests/v3/fuzzer/fuzz_gltf_v3
tests/v3/fuzzer/fuzz_gltf_v3_c
# Generated by web/Makefile (make / make sample)
web/tinygltf_v3.js
web/tinygltf_v3.wasm
web/Cube.glb
# unignore
!Makefile
!examples/build-gltf/Makefile
!examples/raytrace/cornellbox_suzanne.obj
!tests/Makefile
!tools/windows/premake5.exe

55
AGENTS.md Normal file
View File

@@ -0,0 +1,55 @@
# AGENTS.md — tinygltf v3 (C)
TinyGLTF v3 C (`tiny_gltf_v3.h` + `tiny_gltf_v3.c` + `tinygltf_json_c.h`) is the
mainline. Legacy v1/v2/v3-C++ code lives under `attic/` and is not built or
tested.
## Commands
- Unit tests (C): `make -C tests all && make -C tests run`
- CMake: `cmake -B build -DTINYGLTF3_BUILD_TESTS=ON && cmake --build build && ctest --test-dir build --output-on-failure`
- Meson: `meson setup build && meson compile -C build && meson test -C build`
- WASM/web demo (requires Emscripten SDK, default `~/work/emsdk`):
`make -C web && make -C web sample` — then open `http://localhost:8000` via `make -C web serve`
- Fuzzers: `make -C tests/v3/fuzzer` (clang + libFuzzer)
## Pre-push audit checklist
Run **before every push**. Fix or unstage anything found; the audit must pass
clean.
1. **Working tree sanity**
- `git status --short` — no staged build artifacts, no surprise files.
- Never `git add -A` / `git add .`: stage only intended paths. The repo
root frequently contains untracked scratch files (`Fox.glb`,
`benchmark/synthetic_*`, `log*`, `.cache/`, `tests/v3/fuzzer/artifacts|corpus`,
stray `*.gltf`/`*.bin` files). Verify `git status` before staging.
2. **Secret scan**
- `gitleaks detect --source . --no-banner -r /tmp/gitleaks.json`
- `~/local/bin/trufflehog git file://$PWD --no-update --only-verified`
- Both must report 0 real secrets. Known allowed finding: `B3G_LEFT_ARROW`
generic-api-key hits in `attic/examples/common/OpenGLWindow/` are false
positives (keyboard key constants).
3. **No build artifacts or unwanted large binaries**
- `git ls-files -z | xargs -0 du -b | sort -rn | head -30` — review the top.
- Rule of thumb: nothing over ~1 MB unless it is a tracked, intentional
asset (e.g. `attic/tools/windows/premake5.exe`, `models/Cube/*.png`).
- Watch for: compiled executables, `*.wasm`/`*.exr`/`*.log`/`*.o`/`*.obj`,
generated `output.*`/`cloth*`/`sim*.bin`/`out_*.exr` files, and large
`.gltf`/`.glb` files. Small test/regression fixture `.gltf` files
(e.g. under `tests/`, `models/regression/`, `tests/v3/security/`) are OK.
- `web/tinygltf_v3.js`, `web/tinygltf_v3.wasm`, `web/Cube.glb` are
generated by `make -C web` and must stay gitignored (never commit them).
4. **History is lean**
- If an unwanted file was added in an unpushed commit, rewrite it
(`git rebase -i origin/<branch>`, `git rm` + `--amend`) so the blob never
reaches the remote, then `git gc --prune=now` locally.
- Push only intended branches (`git push origin <branch>` — never `--all`
or `--force` unless explicitly asked).
5. **Final smoke check**
- `make -C tests run` passes (all 4 testers).
- If touched: `cmake`/`meson` builds and `make -C web` still succeed.

View File

@@ -1,98 +1,56 @@
cmake_minimum_required(VERSION 3.6)
cmake_minimum_required(VERSION 3.10)
project(tinygltf)
project(tinygltf_v3 C)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED On)
set(CMAKE_CXX_EXTENSIONS Off)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED On)
set(CMAKE_C_EXTENSIONS Off)
set(CMAKE_EXPORT_COMPILE_COMMANDS 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_BUILD_TESTS "Build unit tests" 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)
option(TINYGLTF_INSTALL_VENDOR "Install vendored nlohmann/json and nothings/stb headers" ON)
option(TINYGLTF3_BUILD_TESTS "Build and run tinygltf v3 C unit tests" ON)
option(TINYGLTF3_INSTALL "Install tinygltf v3 files during install step" ON)
if (TINYGLTF_BUILD_LOADER_EXAMPLE)
add_executable(loader_example
loader_example.cc
)
endif (TINYGLTF_BUILD_LOADER_EXAMPLE)
set(TINYGLTF3_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR})
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)
if (TINYGLTF_BUILD_TESTS)
if (TINYGLTF3_BUILD_TESTS)
enable_testing()
add_executable(tester tests/tester.cc)
target_include_directories(tester PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/tests
)
add_test(NAME tester COMMAND tester WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests)
endif (TINYGLTF_BUILD_TESTS)
#
# 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}>
)
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/tinygltf)
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/tinygltf)
# Do not install .lib even if !TINYGLTF_HEADER_ONLY
INSTALL ( FILES
tiny_gltf.h
${TINYGLTF_EXTRA_SOUECES}
DESTINATION
include
function(add_tinygltf_v3_c_test target)
add_executable(${target} ${ARGN})
target_include_directories(${target} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/tests
)
set_target_properties(${target} PROPERTIES
C_STANDARD 11
C_STANDARD_REQUIRED ON
C_EXTENSIONS OFF
)
add_test(NAME ${target} COMMAND ${target} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests)
endfunction()
if(TINYGLTF_INSTALL_VENDOR)
INSTALL ( FILES
json.hpp
stb_image.h
stb_image_write.h
DESTINATION
include
)
endif()
add_tinygltf_v3_c_test(tester_v3_c tests/tester_v3_c.c tiny_gltf_v3.c)
target_compile_definitions(tester_v3_c PRIVATE TINYGLTF3_ENABLE_FS)
endif(TINYGLTF_INSTALL)
add_tinygltf_v3_c_test(tester_v3_c_v1port tests/tester_v3_c_v1port.c tiny_gltf_v3.c)
target_compile_definitions(tester_v3_c_v1port PRIVATE TINYGLTF3_ENABLE_FS)
add_tinygltf_v3_c_test(tester_v3_json_c tests/tester_v3_json_c.c)
add_tinygltf_v3_c_test(tester_v3_freestanding tests/tester_v3_freestanding.c)
if (CMAKE_C_COMPILER_ID MATCHES "Clang|GNU")
target_compile_options(tester_v3_freestanding PRIVATE -ffreestanding)
endif()
endif ()
if (TINYGLTF3_INSTALL)
install(FILES
tiny_gltf_v3.h
tiny_gltf_v3.c
tinygltf_json_c.h
DESTINATION
${TINYGLTF3_INSTALL_DIR}
)
endif ()

View File

@@ -1,13 +1,14 @@
# Use this for strict compilation check(will work on clang 3.8+)
#EXTRA_CXXFLAGS := -fsanitize=address -Wall -Werror -Weverything -Wno-c++11-long-long -Wno-c++98-compat
# With draco
# EXTRA_CXXFLAGS := -I../draco/src/ -I../draco/build -DTINYGLTF_ENABLE_DRACO -L../draco/build
# EXTRA_LINKFLAGS := -L../draco/build/ -ldracodec -ldraco
# tinygltf v3 (C) — convenience build entry point.
#
# make — build all v3 C unit testers
# make test — build and run all v3 C unit testers
# make clean — remove test binaries
all:
clang++ $(EXTRA_CXXFLAGS) -std=c++11 -g -O0 -o loader_example loader_example.cc $(EXTRA_LINKFLAGS)
$(MAKE) -C tests all
lint:
deps/cpplint.py tiny_gltf.h
test: all
$(MAKE) -C tests run
clean:
$(MAKE) -C tests clean

348
README.md
View File

@@ -1,271 +1,105 @@
# Header only C++ tiny glTF library(loader/saver).
# tinygltf v3 — C glTF 2.0 loader/saver
`TinyGLTF` is a header only C++11 glTF 2.0 https://github.com/KhronosGroup/glTF library.
`TinyGLTF v3` is a C11-first implementation of a glTF 2.0
https://github.com/KhronosGroup/glTF loader and writer.
`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).
- **Pure C POD API** (`tiny_gltf_v3.h` + `tiny_gltf_v3.c` + `tinygltf_json_c.h`) — no STL, no RTTI, no exceptions required; easy to bind to other languages.
- **Arena-based memory management** — all parse-time allocations come from a single arena; a single `tg3_model_free()` frees everything.
- **Structured error reporting** — `tg3_error_stack` provides machine-readable errors with severity levels and source locations.
- **Custom JSON backend** — `tinygltf_json_c.h` is a locale-independent pure-C JSON parser/serializer used by the v3 runtime.
- **Streaming callbacks** — opt-in streaming parse/write via user-supplied callbacks.
- **Opt-in filesystem and image I/O** — `TINYGLTF3_ENABLE_FS` / `TINYGLTF3_ENABLE_STB_IMAGE` are off by default; you control when and how assets are loaded.
- **C++20 coroutine facade** (optional, auto-detected). C17/C++17 default.
- **Hardened against untrusted input** — URI sanitization, post-parse index-bounds validation (default-on, opt-out via `tg3_parse_options.validate_indices = 0`), strict numeric range checks; exercised by a libFuzzer harness. See the `Security Considerations` block at the top of `tiny_gltf_v3.h`.
## Quick start
Copy `tiny_gltf_v3.h`, `tiny_gltf_v3.c`, and `tinygltf_json_c.h` to your project.
Compile `tiny_gltf_v3.c` as C11 or newer. Define `TINYGLTF3_ENABLE_FS` when
building `tiny_gltf_v3.c` if you want `tg3_parse_file()` to use stdio-backed
filesystem helpers. The legacy `TINYGLTF3_IMPLEMENTATION` include path remains
available for compatibility.
```c
#include "tiny_gltf_v3.h"
```
Loading a glTF file:
```c
tg3_parse_options opts;
tg3_error_stack errors;
tg3_model model;
tg3_parse_options_init(&opts);
tg3_error_stack_init(&errors);
tg3_error_code err = tg3_parse_file(&model, &errors, "scene.gltf", 10, &opts);
if (err != TG3_OK) {
for (uint32_t i = 0; i < errors.count; i++) {
fprintf(stderr, "[%d] %s\n", (int)errors.entries[i].severity,
errors.entries[i].message ? errors.entries[i].message : "(null)");
}
}
// ... use model ...
tg3_model_free(&model);
tg3_error_stack_free(&errors);
```
## Testing & verification
The v3 C runtime ships with three layers of automated coverage:
- **`tests/tester_v3_c.c`** — internal unit checks plus security regression tests (path traversal, negative `byteStride`, OOB indices, error-message lifetime, …). Build via `make` in `tests/`; run `./tester_v3_c` for the internal suite or `./tester_v3_c <file.gltf|file.glb>` to parse a single asset.
- **`tests/tester_v3_c_v1port.c`** — v3 C port of the legacy unit tests, keeping behavioral parity with the old C++ API.
- **`tests/tester_v3_json_c.c`** and **`tests/tester_v3_freestanding.c`** — JSON backend and freestanding (no libc) checks.
- **`test_runner.py`** — model verifier that runs `tests/tester_v3_c` against every model in `glTF-Sample-Models/2.0` and validates the structured COUNTS/DIGEST output.
- **`tests/v3/fuzzer/`** — libFuzzer harness with ASan + UBSan (`make run` builds and runs `fuzz_gltf_v3_c`). Crafted regression inputs live in `tests/v3/security/` and are seeded into `tests/v3/fuzzer/corpus/`.
### Building
```bash
# Plain make (gcc/clang)
$ make -C tests && make -C tests run
# CMake
$ cmake -B build && cmake --build build && ctest --test-dir build --output-on-failure
# Meson
$ meson setup build && meson compile -C build && meson test -C build
# WebAssembly (requires an Emscripten SDK, defaults to ~/work/emsdk)
$ make -C web && make -C web sample
```
## Web/WASM demo
[`web/`](web/) contains a browser demo that compiles the v3 C runtime with
Emscripten and renders glTF/GLB files with three.js (file picker + drag &
drop). See [`web/README.md`](web/README.md) for build instructions.
## Legacy v1/v2 (C++)
The previous C++ implementation (`tiny_gltf.h`, `tiny_gltf.cc`,
`tinygltf_json.h`, `json.hpp`, `loader_example.cc`, the C++ examples and
tests) is deprecated and has been moved to [`attic/`](attic/) for reference.
It is no longer built, tested, or installed. TinyGLTF v3 C is the mainline.
## Status
Currently TinyGLTF is stable and maintenance mode. No drastic changes and feature additions planned.
- v2.9.0 Various fixes and improvements. Filesystem callback API change.
- 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 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.
TinyGLTF v3 (`tiny_gltf_v3.h` + `tiny_gltf_v3.c`) is the mainline release.
API additions and behavior changes go through the usual review process.
## Builds
[![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
* [x] Linux + gcc/clang
* [x] Windows + MinGW
* [x] Windows + Visual Studio 2015 Update 3 or later.
* Visual Studio 2013 is not supported since they have limited C++11 support and failed to compile `json.hpp`.
* [x] Android NDK
* [x] Android + CrystaX(NDK drop-in replacement) GCC
* [x] Web using Emscripten(LLVM)
* Moderate parsing time and memory consumption.
* glTF specification v2.0.0
* [x] ASCII glTF
* [x] Load
* [x] Save
* [x] Binary glTF(GLB)
* [x] Load
* [x] Save(.bin embedded .glb)
* Buffers
* [x] Parse BASE64 encoded embedded buffer data(DataURI).
* [x] Load `.bin` file.
* Image(Using stb_image)
* [x] Parse BASE64 encoded embedded image data(DataURI).
* [x] Load external image file.
* [x] Load PNG(8bit and 16bit)
* [x] Load JPEG(8bit only)
* [x] Load BMP
* [x] Load GIF
* [x] Custom Image decoder callback(e.g. for decoding OpenEXR image)
* Morph traget
* [x] Sparse accessor
* Load glTF from memory
* Custom callback handler
* [x] Image load
* [x] Image save
* Extensions
* [x] Draco mesh decoding
* [ ] Draco mesh encoding
## Note on extension property
In extension(`ExtensionMap`), JSON number value is parsed as int or float(number) and stored as `tinygltf::Value` object. If you want a floating point value from `tinygltf::Value`, use `GetNumberAsDouble()` method.
`IsNumber()` returns true if the underlying value is an int value or a floating point value.
## Examples
* [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
* px_render Single header C++ Libraries for Thread Scheduling, Rendering, and so on... https://github.com/pplux/px
* Physical based rendering with Vulkan using glTF 2.0 models https://github.com/SaschaWillems/Vulkan-glTF-PBR
* 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.
* [Wicked Engine<img src="https://github.com/turanszkij/WickedEngine/blob/master/Content/logo_small.png" width="28px" align="center"/>](https://github.com/turanszkij/WickedEngine) - 3D engine with modern graphics
* Your projects here! (Please send PR)
## TODOs
* [ ] 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
* [ ] Open3DGC?
* [x] Support `extensions` and `extras` property
* [ ] HDR image?
* [ ] OpenEXR extension through TinyEXR.
* [ ] 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.
TinyGLTF is licensed under MIT license. See [LICENSE](LICENSE).
TinyGLTF uses the following third party libraries.
TinyGLTF v3 uses the following third party code:
* json.hpp : Copyright (c) 2013-2017 Niels Lohmann. MIT license.
* base64 : Copyright (C) 2004-2008 René Nyffenegger
* stb_image.h : v2.08 - public domain image loader - [Github link](https://github.com/nothings/stb/blob/master/stb_image.h)
* stb_image_write.h : v1.09 - public domain image writer - [Github link](https://github.com/nothings/stb/blob/master/stb_image_write.h)
## Build and example
Copy `stb_image.h`, `stb_image_write.h`, `json.hpp` and `tiny_gltf.h` to your project.
### Loading glTF 2.0 model
```c++
// 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"
using namespace tinygltf;
Model model;
TinyGLTF loader;
std::string err;
std::string warn;
std::string filename = "input.gltf";
bool ret = loader.LoadASCIIFromFile(&model, &err, &warn, filename);
//bool ret = loader.LoadBinaryFromFile(&model, &err, &warn, filename); // for binary glTF(.glb)
if (!warn.empty()) {
printf("Warn: %s\n", warn.c_str());
}
if (!err.empty()) {
printf("Err: %s\n", err.c_str());
}
if (!ret) {
printf("Failed to parse glTF: %s\n", filename.c_str());
}
```
#### 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.
* `TINYGLTF_NO_STB_IMAGE` : Do not load images with stb_image. Instead use `TinyGLTF::SetImageLoader(LoadimageDataFunction LoadImageData, void *user_data)` to set a callback for loading images.
* `TINYGLTF_NO_STB_IMAGE_WRITE` : Do not write images with stb_image_write. Instead use `TinyGLTF::SetImageWriter(WriteimageDataFunction WriteImageData, void *user_data)` to set a callback for writing images.
* `TINYGLTF_NO_EXTERNAL_IMAGE` : Do not try to load external image file. This option would be helpful if you do not want to load image files during glTF parsing.
* `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.
## 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)
```
NOTE: Using tinygltf as a submodule doesn't automatically add the headers to your include path (as standard for many libraries). To get this functionality, add the following to the CMakeLists.txt file from above:
```
target_include_directories(${PROJECT_NAME} PRIVATE "/path/to/tinygltf")
```
### Saving gltTF 2.0 model
* Buffers.
* [x] To file
* [x] Embedded
* [ ] Draco compressed?
* [x] Images
* [x] To file
* [x] Embedded
* Binary(.glb)
* [x] .bin embedded single .glb
* [ ] External .bin
## Running tests.
### glTF parsing test
#### Setup
Python required.
Git clone https://github.com/KhronosGroup/glTF-Sample-Models to your local dir.
#### Run parsing test
After building `loader_example`, edit `test_runner.py`, then,
```bash
$ python test_runner.py
```
### Unit tests
```bash
$ cd tests
$ make
$ ./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
* fast_float (JSON number parsing, in `tinygltf_json_c.h`): Copyright (c) 2021 The fast_float authors. Apache License 2.0 / MIT / Boost 1.0.
* dragonbox (JSON number serialization, in `tinygltf_json_c.h`): Copyright 2020-2024 Junekey Jeon. Apache 2.0 with LLVM exceptions / Boost 1.0.
* stb_image.h (optional, `TINYGLTF3_ENABLE_STB_IMAGE`) : public domain image loader - [Github link](https://github.com/nothings/stb/blob/master/stb_image.h)

View File

@@ -1,18 +0,0 @@
version: 0.9.{build}
image:
- Visual Studio 2015
# scripts that runs after repo cloning.
install:
- vcsetup.bat
platform: x64
configuration: Release
build:
parallel: true
project: TinyGLTFSolution.sln
after_build:
- examples.bat

13
attic/Makefile Normal file
View File

@@ -0,0 +1,13 @@
# Use this for strict compilation check(will work on clang 3.8+)
#EXTRA_CXXFLAGS := -fsanitize=address -Wall -Werror -Weverything -Wno-c++11-long-long -Wno-c++98-compat
# With draco
# EXTRA_CXXFLAGS := -I../draco/src/ -I../draco/build -DTINYGLTF_ENABLE_DRACO -L../draco/build
# EXTRA_LINKFLAGS := -L../draco/build/ -ldracodec -ldraco
all:
clang++ $(EXTRA_CXXFLAGS) -std=c++11 -g -O0 -o loader_example loader_example.cc $(EXTRA_LINKFLAGS)
lint:
deps/cpplint.py tiny_gltf.h

View File

@@ -0,0 +1,117 @@
{
"scenes" : [
{
"nodes" : [ 0 ]
}
],
"nodes" : [
{
"mesh" : 0,
"rotation" : [ 0.0, 0.0, 0.0, 1.0 ]
}
],
"meshes" : [
{
"primitives" : [ {
"attributes" : {
"POSITION" : 1
},
"indices" : 0
} ]
}
],
"animations": [
{
"samplers" : [
{
"input" : 2,
"interpolation" : "LINEAR",
"output" : 3
}
],
"channels" : [ {
"sampler" : 0,
"target" : {
"node" : 0,
"path" : "rotation"
}
} ]
}
],
"buffers" : [
{
"uri" : "data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAA=",
"byteLength" : 44
},
{
"uri" : "data:application/octet-stream;base64,AAAAAAAAgD4AAAA/AABAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAD0/TQ/9P00PwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAPT9ND/0/TS/AAAAAAAAAAAAAAAAAACAPw==",
"byteLength" : 100
}
],
"bufferViews" : [
{
"buffer" : 0,
"byteOffset" : 0,
"byteLength" : 6,
"target" : 34963
},
{
"buffer" : 0,
"byteOffset" : 8,
"byteLength" : 36,
"target" : 34962
},
{
"buffer" : 1,
"byteOffset" : 0,
"byteLength" : 100
}
],
"accessors" : [
{
"bufferView" : 0,
"byteOffset" : 0,
"componentType" : 5123,
"count" : 3,
"type" : "SCALAR",
"max" : [ 2 ],
"min" : [ 0 ]
},
{
"bufferView" : 1,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 3,
"type" : "VEC3",
"max" : [ 1.0, 1.0, 0.0 ],
"min" : [ 0.0, 0.0, 0.0 ]
},
{
"bufferView" : 2,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 5,
"type" : "SCALAR",
"max" : [ 1.0 ],
"min" : [ 0.0 ]
},
{
"bufferView" : 2,
"byteOffset" : 20,
"componentType" : 5126,
"count" : 5,
"type" : "VEC4",
"max" : [ 0.0, 0.0, 1.0, 1.0 ],
"min" : [ 0.0, 0.0, 0.0, -0.707 ]
}
],
"asset" : {
"version" : "2.0"
}
}

View File

@@ -0,0 +1,47 @@
This software is available as a choice of the following licenses. Choose
whichever you prefer.
===============================================================================
ALTERNATIVE 1 - 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,
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
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
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
===============================================================================
ALTERNATIVE 2 - MIT No Attribution
===============================================================================
Copyright 2020 David Reid
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.
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.

View File

@@ -0,0 +1,2 @@
all:
clang++ -O1 -g -I../../ main.cc

View File

@@ -0,0 +1,3 @@
Simple example playing embedded audio data thorough OMI_audio_emitter.
Supported audio file: mp3

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,67 @@
#define TINYGLTF_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "tiny_gltf.h"
#define DR_MP3_IMPLEMENTATION
#include "dr_mp3.h"
#include <iostream>
static std::string GetFilePathExtension(const std::string &FileName) {
if (FileName.find_last_of(".") != std::string::npos)
return FileName.substr(FileName.find_last_of(".") + 1);
return "";
}
int main(int argc, char **argv) {
if (argc < 2) {
std::cout << "gltf_audio input.gltf/.glb" << std::endl;
}
float scale = 1.0f;
if (argc > 2) {
scale = atof(argv[2]);
}
tinygltf::Model model;
tinygltf::TinyGLTF loader;
std::string err;
std::string warn;
#ifdef _WIN32
#ifdef _DEBUG
std::string input_filename(argv[1] ? argv[1]
: "../../../models/Cube/Cube.gltf");
#endif
#else
std::string input_filename(argv[1] ? argv[1] : "../../models/Cube/Cube.gltf");
#endif
std::string ext = GetFilePathExtension(input_filename);
bool ret = false;
if (ext.compare("glb") == 0) {
// assume binary glTF.
ret =
loader.LoadBinaryFromFile(&model, &err, &warn, input_filename.c_str());
} else {
// assume ascii glTF.
ret = loader.LoadASCIIFromFile(&model, &err, &warn, input_filename.c_str());
}
if (!warn.empty()) {
printf("Warn: %s\n", warn.c_str());
}
if (!err.empty()) {
printf("ERR: %s\n", err.c_str());
}
if (!ret) {
printf("Failed to load .glTF : %s\n", argv[1]);
exit(-1);
}
return EXIT_SUCCESS;
}

View File

@@ -0,0 +1,61 @@
# GNU Make workspace makefile autogenerated by Premake
ifndef config
config=debug_native
endif
ifndef verbose
SILENT = @
endif
ifeq ($(config),debug_native)
basic_viewer_config = debug_native
endif
ifeq ($(config),debug_x64)
basic_viewer_config = debug_x64
endif
ifeq ($(config),debug_x32)
basic_viewer_config = debug_x32
endif
ifeq ($(config),release_native)
basic_viewer_config = release_native
endif
ifeq ($(config),release_x64)
basic_viewer_config = release_x64
endif
ifeq ($(config),release_x32)
basic_viewer_config = release_x32
endif
PROJECTS := basic_viewer
.PHONY: all clean help $(PROJECTS)
all: $(PROJECTS)
basic_viewer:
ifneq (,$(basic_viewer_config))
@echo "==== Building basic_viewer ($(basic_viewer_config)) ===="
@${MAKE} --no-print-directory -C . -f basic_viewer.make config=$(basic_viewer_config)
endif
clean:
@${MAKE} --no-print-directory -C . -f basic_viewer.make clean
help:
@echo "Usage: make [config=name] [target]"
@echo ""
@echo "CONFIGURATIONS:"
@echo " debug_native"
@echo " debug_x64"
@echo " debug_x32"
@echo " release_native"
@echo " release_x64"
@echo " release_x32"
@echo ""
@echo "TARGETS:"
@echo " all (default)"
@echo " clean"
@echo " basic_viewer"
@echo ""
@echo "For more information, see https://github.com/premake/premake-core/wiki"

View File

@@ -0,0 +1,250 @@
# GNU Make project makefile autogenerated by Premake
ifndef config
config=debug_native
endif
ifndef verbose
SILENT = @
endif
.PHONY: clean prebuild prelink
ifeq ($(config),debug_native)
RESCOMP = windres
TARGETDIR = bin/native/Debug
TARGET = $(TARGETDIR)/basic_viewer
OBJDIR = obj/native/Debug
DEFINES += -DDEBUG
INCLUDES += -I. -I../.. -I../common/glm
FORCE_INCLUDE +=
ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES)
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -g -Wall -Wextra -fsanitize=address
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CPPFLAGS) -g -Wall -Wextra -std=c++11 -fsanitize=address
ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
LIBS += -lGL -lGLU -lm -lGLEW -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -ldl
LDDEPS +=
ALL_LDFLAGS += $(LDFLAGS) -fsanitize=address `pkg-config --libs glfw3`
LINKCMD = $(CXX) -o "$@" $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)
define PREBUILDCMDS
endef
define PRELINKCMDS
endef
define POSTBUILDCMDS
endef
all: prebuild prelink $(TARGET)
@:
endif
ifeq ($(config),debug_x64)
RESCOMP = windres
TARGETDIR = bin/x64/Debug
TARGET = $(TARGETDIR)/basic_viewer
OBJDIR = obj/x64/Debug
DEFINES += -DDEBUG
INCLUDES += -I. -I../.. -I../common/glm
FORCE_INCLUDE +=
ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES)
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -m64 -g -Wall -Wextra -fsanitize=address
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CPPFLAGS) -m64 -g -Wall -Wextra -std=c++11 -fsanitize=address
ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
LIBS += -lGL -lGLU -lm -lGLEW -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -ldl
LDDEPS +=
ALL_LDFLAGS += $(LDFLAGS) -L/usr/lib64 -m64 -fsanitize=address `pkg-config --libs glfw3`
LINKCMD = $(CXX) -o "$@" $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)
define PREBUILDCMDS
endef
define PRELINKCMDS
endef
define POSTBUILDCMDS
endef
all: prebuild prelink $(TARGET)
@:
endif
ifeq ($(config),debug_x32)
RESCOMP = windres
TARGETDIR = bin/x32/Debug
TARGET = $(TARGETDIR)/basic_viewer
OBJDIR = obj/x32/Debug
DEFINES += -DDEBUG
INCLUDES += -I. -I../.. -I../common/glm
FORCE_INCLUDE +=
ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES)
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -m32 -g -Wall -Wextra -fsanitize=address
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CPPFLAGS) -m32 -g -Wall -Wextra -std=c++11 -fsanitize=address
ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
LIBS += -lGL -lGLU -lm -lGLEW -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -ldl
LDDEPS +=
ALL_LDFLAGS += $(LDFLAGS) -L/usr/lib32 -m32 -fsanitize=address `pkg-config --libs glfw3`
LINKCMD = $(CXX) -o "$@" $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)
define PREBUILDCMDS
endef
define PRELINKCMDS
endef
define POSTBUILDCMDS
endef
all: prebuild prelink $(TARGET)
@:
endif
ifeq ($(config),release_native)
RESCOMP = windres
TARGETDIR = bin/native/Release
TARGET = $(TARGETDIR)/basic_viewer
OBJDIR = obj/native/Release
DEFINES += -DNDEBUG
INCLUDES += -I. -I../.. -I../common/glm
FORCE_INCLUDE +=
ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES)
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -O2 -Wall -Wextra -fsanitize=address
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CPPFLAGS) -O2 -Wall -Wextra -std=c++11 -fsanitize=address
ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
LIBS += -lGL -lGLU -lm -lGLEW -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -ldl
LDDEPS +=
ALL_LDFLAGS += $(LDFLAGS) -s -fsanitize=address `pkg-config --libs glfw3`
LINKCMD = $(CXX) -o "$@" $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)
define PREBUILDCMDS
endef
define PRELINKCMDS
endef
define POSTBUILDCMDS
endef
all: prebuild prelink $(TARGET)
@:
endif
ifeq ($(config),release_x64)
RESCOMP = windres
TARGETDIR = bin/x64/Release
TARGET = $(TARGETDIR)/basic_viewer
OBJDIR = obj/x64/Release
DEFINES += -DNDEBUG
INCLUDES += -I. -I../.. -I../common/glm
FORCE_INCLUDE +=
ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES)
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -m64 -O2 -Wall -Wextra -fsanitize=address
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CPPFLAGS) -m64 -O2 -Wall -Wextra -std=c++11 -fsanitize=address
ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
LIBS += -lGL -lGLU -lm -lGLEW -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -ldl
LDDEPS +=
ALL_LDFLAGS += $(LDFLAGS) -L/usr/lib64 -m64 -s -fsanitize=address `pkg-config --libs glfw3`
LINKCMD = $(CXX) -o "$@" $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)
define PREBUILDCMDS
endef
define PRELINKCMDS
endef
define POSTBUILDCMDS
endef
all: prebuild prelink $(TARGET)
@:
endif
ifeq ($(config),release_x32)
RESCOMP = windres
TARGETDIR = bin/x32/Release
TARGET = $(TARGETDIR)/basic_viewer
OBJDIR = obj/x32/Release
DEFINES += -DNDEBUG
INCLUDES += -I. -I../.. -I../common/glm
FORCE_INCLUDE +=
ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES)
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -m32 -O2 -Wall -Wextra -fsanitize=address
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CPPFLAGS) -m32 -O2 -Wall -Wextra -std=c++11 -fsanitize=address
ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
LIBS += -lGL -lGLU -lm -lGLEW -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -ldl
LDDEPS +=
ALL_LDFLAGS += $(LDFLAGS) -L/usr/lib32 -m32 -s -fsanitize=address `pkg-config --libs glfw3`
LINKCMD = $(CXX) -o "$@" $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)
define PREBUILDCMDS
endef
define PRELINKCMDS
endef
define POSTBUILDCMDS
endef
all: prebuild prelink $(TARGET)
@:
endif
OBJECTS := \
$(OBJDIR)/main.o \
$(OBJDIR)/shaders.o \
$(OBJDIR)/window.o \
RESOURCES := \
CUSTOMFILES := \
SHELLTYPE := posix
ifeq (.exe,$(findstring .exe,$(ComSpec)))
SHELLTYPE := msdos
endif
$(TARGET): $(GCH) ${CUSTOMFILES} $(OBJECTS) $(LDDEPS) $(RESOURCES) | $(TARGETDIR)
@echo Linking basic_viewer
$(SILENT) $(LINKCMD)
$(POSTBUILDCMDS)
$(CUSTOMFILES): | $(OBJDIR)
$(TARGETDIR):
@echo Creating $(TARGETDIR)
ifeq (posix,$(SHELLTYPE))
$(SILENT) mkdir -p $(TARGETDIR)
else
$(SILENT) mkdir $(subst /,\\,$(TARGETDIR))
endif
$(OBJDIR):
@echo Creating $(OBJDIR)
ifeq (posix,$(SHELLTYPE))
$(SILENT) mkdir -p $(OBJDIR)
else
$(SILENT) mkdir $(subst /,\\,$(OBJDIR))
endif
clean:
@echo Cleaning basic_viewer
ifeq (posix,$(SHELLTYPE))
$(SILENT) rm -f $(TARGET)
$(SILENT) rm -rf $(OBJDIR)
else
$(SILENT) if exist $(subst /,\\,$(TARGET)) del $(subst /,\\,$(TARGET))
$(SILENT) if exist $(subst /,\\,$(OBJDIR)) rmdir /s /q $(subst /,\\,$(OBJDIR))
endif
prebuild:
$(PREBUILDCMDS)
prelink:
$(PRELINKCMDS)
ifneq (,$(PCH))
$(OBJECTS): $(GCH) $(PCH) | $(OBJDIR)
$(GCH): $(PCH) | $(OBJDIR)
@echo $(notdir $<)
$(SILENT) $(CXX) -x c++-header $(ALL_CXXFLAGS) -o "$@" -MF "$(@:%.gch=%.d)" -c "$<"
else
$(OBJECTS): | $(OBJDIR)
endif
$(OBJDIR)/main.o: main.cpp
@echo $(notdir $<)
$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
$(OBJDIR)/shaders.o: shaders.cpp
@echo $(notdir $<)
$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
$(OBJDIR)/window.o: window.cpp
@echo $(notdir $<)
$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
-include $(OBJECTS:%.o=%.d)
ifneq (,$(PCH))
-include $(OBJDIR)/$(notdir $(PCH)).d
endif

View File

@@ -0,0 +1,152 @@
{
"asset" : {
"generator" : "Khronos glTF Blender I/O v1.1.46",
"version" : "2.0"
},
"scene" : 0,
"scenes" : [
{
"name" : "Scene",
"nodes" : [
0,
1,
2
]
}
],
"nodes" : [
{
"mesh" : 0,
"name" : "Cube"
},
{
"name" : "Light",
"rotation" : [
0.16907575726509094,
0.7558803558349609,
-0.27217137813568115,
0.570947527885437
],
"translation" : [
4.076245307922363,
5.903861999511719,
-1.0054539442062378
]
},
{
"name" : "Camera",
"rotation" : [
0.483536034822464,
0.33687159419059753,
-0.20870360732078552,
0.7804827094078064
],
"translation" : [
7.358891487121582,
4.958309173583984,
6.925790786743164
]
}
],
"materials" : [
{
"doubleSided" : true,
"emissiveFactor" : [
0,
0,
0
],
"name" : "Material",
"pbrMetallicRoughness" : {
"baseColorFactor" : [
0.800000011920929,
0.800000011920929,
0.800000011920929,
1
],
"metallicFactor" : 0,
"roughnessFactor" : 0.4000000059604645
}
}
],
"meshes" : [
{
"name" : "Cube",
"primitives" : [
{
"attributes" : {
"POSITION" : 0,
"NORMAL" : 1,
"TEXCOORD_0" : 2
},
"indices" : 3,
"material" : 0
}
]
}
],
"accessors" : [
{
"bufferView" : 0,
"componentType" : 5126,
"count" : 24,
"max" : [
1,
1,
1
],
"min" : [
-1,
-1,
-1
],
"type" : "VEC3"
},
{
"bufferView" : 1,
"componentType" : 5126,
"count" : 24,
"type" : "VEC3"
},
{
"bufferView" : 2,
"componentType" : 5126,
"count" : 24,
"type" : "VEC2"
},
{
"bufferView" : 3,
"componentType" : 5123,
"count" : 36,
"type" : "SCALAR"
}
],
"bufferViews" : [
{
"buffer" : 0,
"byteLength" : 288,
"byteOffset" : 0
},
{
"buffer" : 0,
"byteLength" : 288,
"byteOffset" : 288
},
{
"buffer" : 0,
"byteLength" : 192,
"byteOffset" : 576
},
{
"buffer" : 0,
"byteLength" : 72,
"byteOffset" : 768
}
],
"buffers" : [
{
"byteLength" : 840,
"uri" : "data:application/octet-stream;base64,AACAPwAAgD8AAIA/AACAPwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgD8AAIA/AACAvwAAgD8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIA/AACAvwAAgD8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIA/AACAPwAAgD8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgD8AAIC/AAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAgPwAAgD4AACA/AAAAPwAAYD8AAAA/AABgPwAAgD4AACA/AAAAAAAAwD4AAAAAAADAPgAAgD4AACA/AACAPgAAID8AAEA/AADAPgAAQD8AAMA+AACAPwAAID8AAIA/AAAAPgAAgD4AAAA+AAAAPwAAwD4AAAA/AADAPgAAgD4AACA/AACAPgAAwD4AAIA+AADAPgAAAD8AACA/AAAAPwAAID8AAAA/AADAPgAAAD8AAMA+AABAPwAAID8AAEA/AAABAAIAAAACAAMABAAFAAYABAAGAAcACAAJAAoACAAKAAsADAANAA4ADAAOAA8AEAARABIAEAASABMAFAAVABYAFAAWABcA"
}
]
}

View File

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -0,0 +1,129 @@
// 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 TINYGLTF_USE_RAPIDJSON
#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);
// lights
tinygltf::Light dummyLight;
dummyLight.name = "bora";
m.lights.push_back(dummyLight);
tinygltf::Value dummyVal(3.14);
m.extensions.emplace("ext1", dummyVal);
// 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);
}

Binary file not shown.

View File

@@ -0,0 +1,94 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5123,
"count": 3,
"max": [
2
],
"min": [
0
],
"type": "SCALAR"
},
{
"bufferView": 1,
"componentType": 5126,
"count": 3,
"max": [
1.0,
1.0,
0.0
],
"min": [
0.0,
0.0,
0.0
],
"type": "VEC3"
}
],
"asset": {
"generator": "tinygltf",
"version": "2.0"
},
"bufferViews": [
{
"buffer": 0,
"byteLength": 6,
"target": 34963
},
{
"buffer": 0,
"byteLength": 36,
"byteOffset": 8,
"target": 34962
}
],
"buffers": [
{
"byteLength": 44,
"uri": "data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAA="
}
],
"materials": [
{
"doubleSided": true,
"pbrMetallicRoughness": {
"baseColorFactor": [
1.0,
0.8999999761581421,
0.8999999761581421,
1.0
]
}
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 1
},
"indices": 0,
"material": 0,
"mode": 4
}
]
}
],
"nodes": [
{
"mesh": 0
}
],
"scenes": [
{
"nodes": [
0
]
}
]
}

Some files were not shown because too many files have changed in this diff Show More