Compare commits

..

183 Commits

Author SHA1 Message Date
Syoyo Fujita
29c431b2f2 Add build option with draco in Makefile. 2019-03-08 14:01:06 +09:00
Syoyo Fujita
d06b2c2022 Merge pull request #154 from Ybalrid/patch-3
Fix the display of the version history
2019-03-08 13:32:31 +09:00
Arthur Brainville
339c9d578a Fix the display of the version history
Markdown is like HTML: simple line-breaks don't work.

Besides, making a list with dots here looks nicer :)
2019-03-07 19:40:57 +01:00
Syoyo Fujita
7c315fa8a8 Merge pull request #153 from Ybalrid/patch-2
fix a few typos in README.md
2019-03-07 21:30:20 +09:00
Arthur Brainville
0f04ed018a fix a few typos in README.md 2019-03-07 13:23:59 +01:00
Syoyo Fujita
ca56f726d6 Merge branch '16bit-lodepng' 2019-03-07 21:04:25 +09:00
Syoyo Fujita
e8a46c4e1d Update README.
Check bit depth when saving image as PNG.
2019-03-07 20:50:58 +09:00
Syoyo Fujita
9cd14a461b Update README. 2019-03-07 01:05:02 +09:00
Syoyo Fujita
1ef603ea2a Merge pull request #150 from Ybalrid/sparse_accessor
Sparse accessor
2019-03-07 00:49:29 +09:00
Arthur Brainville (Ybalrid)
14d259f361 glview can now load static geometry modified by sparse accessor 2019-03-06 14:48:44 +00:00
Arthur Brainville (Ybalrid)
9223d3133a Ran clang-format on tiny_gltf.h 2019-03-06 14:00:56 +00:00
Arthur Brainville (Ybalrid)
9b321a8515 clang-format + added sparse accessor in loader_example 2019-03-06 12:39:39 +00:00
Arthur Brainville (Ybalrid)
7e9f734d73 Parse sparse accessors 2019-03-06 12:27:23 +00:00
Arthur Brainville (Ybalrid)
9d86405d3d Fix accessor ctor 2019-03-06 11:33:30 +00:00
Arthur Brainville (Ybalrid)
1ccb4ff580 added sparse structure to accessors 2019-03-06 11:30:00 +01:00
Syoyo Fujita
8fd91aea04 Update TinyEXR. 2019-03-04 02:15:03 +09:00
Syoyo Fujita
8f76d790b8 Merge pull request #148 from Ybalrid/16bit-lodepng-good-byteswap
When writing out a 16bit image with lodepng, simplify the byteswap to big-endian
2019-03-04 01:15:20 +09:00
Arthur Brainville (Ybalrid)
853f6df7b5 Simplify byteswap code to convert to big endian 16bit 2019-03-03 16:26:20 +01:00
Syoyo Fujita
758a1240c9 Reorder 16 bit pixel data to big endian when saving it as 16 png, since lodepng::encode expects image data is in big endian manner.
Add OpenEXR saver for 16bit image as a bonus.
2019-03-03 21:21:18 +09:00
Syoyo Fujita
7bdfed3bec Add lodepng to save 16bit PNG.
Suppress clang/gcc warnings.
2019-03-03 17:04:49 +09:00
Syoyo Fujita
bf9c2f4abd Merge pull request #146 from WARP-LAB/master
Fix for when json and stb is aready used in project
2019-03-03 15:31:09 +09:00
kroko
fc0116b323 rename TINYGLTF_BYPASS_INCLUDE_x to TINYGLTF_NO_INCLUDE_x 2019-03-03 08:28:49 +02:00
Syoyo Fujita
962552c5c8 Merge pull request #145 from Ybalrid/upgrade_stb_libs
Upgrade the STB libraries, and fix #132
2019-03-03 13:39:10 +09:00
kroko
606e5dde31 be more precise in readme about include bypassing flags 2019-03-03 01:56:34 +02:00
kroko
6a0d4c57b1 Fix for when json and stb is aready used in project v2 2019-03-03 01:28:45 +02:00
kroko
f4b6d11abc Fix for when json and stb is aready used in project 2019-03-03 01:11:31 +02:00
Arthur Brainville (Ybalrid)
5a4c898912 Fixed wrong metadata in case 16bit image wasn't actually loaded
The fallback to 8 bit would have been broken.
2019-03-02 22:03:34 +01:00
Arthur Brainville (Ybalrid)
f2addc0e44 16bit images are 16bit images: added Image::bits and Image::pixel_type 2019-03-02 22:00:48 +01:00
Arthur Brainville (Ybalrid)
70d16a7b92 Upgrade the STB libraries, and fix #132 2019-03-02 16:10:54 +01:00
Syoyo Fujita
326d7ea310 Merge pull request #144 from SaschaWillems/master
Add direct access to texture coordinate set on texture parameter
2019-02-24 14:42:51 +09:00
Sascha Willems
eb011068c0 Added function to easily access texture coordinate set index on a texture parameter 2019-02-23 21:15:45 +01:00
Syoyo Fujita
87be0ce34b Define WIN32_LEAN_AND_MEAN to save the number of including files. 2019-02-19 21:36:32 +09:00
Syoyo Fujita
7d9a0bda3a Define NOMINMAX to avoid defining MIN/MAX macros on Windows. Without defining NOMINMAX, MIN/MAX macro would affect other header/c++ files. Fixes #143 2019-02-19 16:03:23 +09:00
Syoyo Fujita
7ece5c8275 Merge pull request #142 from ebirenbaum/animation-sampler-interpolation
Change AnimationSampler::interpolation to a non-required field.
2019-02-15 14:04:06 +09:00
Evan Birenbaum
6bdffedcbe Change AnimationSampler::interpolation to a non-required field. The spec states to default to LINEAR when not present. 2019-02-14 13:30:57 -08:00
Syoyo Fujita
d2fb7dc2af Merge pull request #140 from timmmeh/master
Adding default values for min and mag filter.
2019-02-10 00:01:11 +09:00
Syoyo Fujita
c0d0251e2c Update json.hpp to fix compilation with clang with C++17(-std=c++1z) support. 2019-02-04 16:19:13 +09:00
timmmeh
62a72c4845 fix compile 2019-01-31 11:46:19 -08:00
timmmeh
73584ba7b7 Adding default values for min and mag filter. 2019-01-30 18:38:46 -08:00
Syoyo Fujita
ead876fce9 Merge pull request #138 from dolphineye/dolphineye/add_mode_line_strip
Add line strip primitive mode define
2019-01-30 23:19:30 +09:00
Thomas Tissot
6c4a006496 Add line strip primitive mode define
This small commit adds the `TINYGLTF_MODE_LINE_STRIP` primitive mode
define whose value is set to `3` as per the GLTF 2.0 specification.
2019-01-30 13:10:51 +01:00
Syoyo Fujita
281af41b6c Merge pull request #137 from Ybalrid/pr_fix_glview_no_scene_no_nodes
Fix glView in case there is no default scene
2019-01-28 13:00:26 +09:00
Arthur Brainville (Ybalrid)
215e1fae61 handle not having default scene 2019-01-27 20:52:04 +00:00
Arthur Brainville (Ybalrid)
cba75b9927 fix glview in case gltf asset doesn't have a default scene 2019-01-27 20:52:04 +00:00
Syoyo Fujita
4de57db325 Add TINYGLTF_ENABLE_DRACO flag to README. 2019-01-27 00:43:02 +09:00
Syoyo Fujita
a32fa80102 Add support for building glview with draco.
Fix out-of-bounds access when calling DrawMesh().
Fix potential out-of-bounds access when filling window title string.
2019-01-27 00:38:34 +09:00
Syoyo Fujita
5f34dab548 Merge pull request #136 from abwood/draco
Fixed decoding bugs in draco
2019-01-26 23:22:55 +09:00
Alexander Wood
0d77a291f7 Updates to draco decoding:
- When injecting draco decoded meshes into accessor data, update count to match the optimized and decoded draco mesh
 - accessor.componentType is now used for extraction of decoded draco meshes.

Fixes #135
2019-01-26 08:58:45 -05:00
Syoyo Fujita
b926195ef8 Merge pull request #134 from abwood/draco
Initial support for draco mesh compression
2019-01-25 16:45:33 +09:00
Alex Wood
c8ba17fcab Looks like I'm colliding with work by syoyo. Only difference so far appears to be our macro name. 2019-01-24 15:45:16 -05:00
Alex Wood
df39e04e7b Merge branch 'draco' of https://github.com/abwood/tinygltf into draco 2019-01-24 15:40:28 -05:00
Alex Wood
7319db7a50 Initial support for draco mesh compression. In this PR, we establish that draco is a dependency built external to tinygltf, which breaks from the current tradition of header only dependencies. For that reason, this feature is hidden behind a #define TINYGLTF_ENABLE_DRACO and requires developers to explicitly opt-in for draco support.
In this change, tinygltf any primitive using draco compression will:
If indices are specified
1) Decode the index buffer using draco, creating a new buffer and bufferview, adding to Model::bufferViews and Model::buffer collections
2) Update the primitive's accessor id to reference this new decoded bufferview.
For each attribute semantic specified by the draco extension
1) Decode the vertex buffer using draco, creating a new buffer and bufferview, adding to Model::bufferViews and Model::buffer collections
2) Update the primitive's accessor id to reference this new decoded bufferview.
2019-01-24 15:38:16 -05:00
Syoyo Fujita
7ae7110800 Begin supporting draco. 2019-01-19 03:03:22 +09:00
Syoyo Fujita
b864ea7349 Support macOS + OpenGL 3.3+ GPU 2019-01-14 22:11:11 +09:00
Syoyo Fujita
d6b0b0b990 Convert UTF16 file to UTF8.
Add premake project to build on Linux.
2019-01-14 21:30:53 +09:00
Syoyo Fujita
af3ebb2e76 Show more expressive messages when parsing image. 2019-01-06 18:55:57 +09:00
Syoyo Fujita
105694b468 Merge pull request #129 from SaschaWillems/master
Added new compiler option for loading all gltf related files from android app asset package
2018-12-29 12:33:34 +09:00
Sascha Willems
5f9cb24245 Added new feature for loading all gltf related files (including textures, binaries, etc.) from assets packaged with an Android app 2018-12-28 20:53:41 +01:00
Syoyo Fujita
9fcd3f998e Merge pull request #127 from nyue/master
Renamed glTFConfig to TinyGLTFConfig
2018-12-28 14:31:33 +09:00
Tan Meng Yue
d96b45df06 Renamed glTFConfig to TinyGLTFConfig
This renaming is done so that the config file matches
the project name which is TinyGLTF. This is done to prevent
future name collision should the Khronos glTF project decides
to provide their own CMake configuration file.
2018-12-27 10:24:13 +11:00
Syoyo Fujita
dd7c9efbea Merge pull request #125 from nyue/master
Fix bug in handling OS X build via CMake
2018-12-25 15:06:37 +09:00
Tan Meng Yue
80a85af661 Fix bug in handling OS X build via CMake
The OS macros needs to be upper case for the
if statement to work as expected
2018-12-25 17:03:58 +11:00
Syoyo Fujita
7cf2c44ad7 Merge pull request #124 from nyue/master
Fix GLFW3 handling on CentOS
2018-12-25 11:27:33 +09:00
Nicholas Yue
f1b5bb12fd Add support for static GLFW3 library linking 2018-12-25 09:48:26 +11:00
Nicholas Yue
174334eaf4 Fix GLFW3 handling on CentOS 2018-12-25 09:15:13 +11:00
Syoyo Fujita
1212a6ee51 Update README. 2018-12-24 01:50:17 +09:00
Syoyo Fujita
8674c60781 Add document on TINYGLTF_NO_EXTERNAL_IMAGE. Fixes #123 2018-12-18 21:59:23 +09:00
Syoyo Fujita
9d89f02cf0 Merge pull request #122 from lebek/master
Fix incorrect index into bufferViews array
2018-12-09 12:23:39 +09:00
Peter Le Bek
463408c4a0 Fix incorrect index into bufferViews array 2018-12-08 16:04:42 -08:00
Syoyo Fujita
a9d862aeee Merge pull request #119 from nyue/master
Add CMake package for developer
2018-12-07 18:48:14 +09:00
Tan Meng Yue
2123da775b Add CMake package for developer
Added the glTFConfig.cmake file so that once
installed, it is easy for developers to find
all the path location for include purposes.
2018-12-07 20:45:13 +11:00
Syoyo Fujita
20806b27d7 Merge pull request #118 from nyue/master
Added more CMake support
2018-12-07 16:07:16 +09:00
Tan Meng Yue
94fcfdeb9d Added installation of headers and target binaries 2018-12-07 18:01:08 +11:00
Syoyo Fujita
d44b6e7bcc Merge pull request #117 from viperscape/master
Fill in missing bufferView targets
2018-12-06 11:20:18 +09:00
viperscape
9df05806ad find missing bufferView target types and fill them in 2018-12-05 14:11:01 -05:00
Chris Gill
93db9e20c0 Merge pull request #1 from syoyo/master
update to latest
2018-12-05 13:03:44 -05:00
Syoyo Fujita
2c5597f591 Merge pull request #115 from Selmar/serialization_fixes
some serialization fixes
2018-12-06 02:05:26 +09:00
Tan Meng Yue
2dcf79566f Add CMake configuration for glview
So that we can build more of the examples consistently
with CMake
2018-12-05 23:56:23 +11:00
Tan Meng Yue
f20888ae8b Added top level CMake configuration file 2018-12-05 23:55:53 +11:00
Selmar Kok
5892d3e3ea Set a default for sampler.wrapR, because it was serializing an uninitialized value 2018-12-04 19:55:56 +01:00
Selmar Kok
27aab61d62 Fix prettyprint to really not print pretty 2018-11-30 18:01:31 +01:00
Syoyo Fujita
d80f0f9a6c Merge pull request #111 from viperscape/master
This is a basic example I added after figuring out how to use the tinygltf library
2018-11-16 14:01:13 +09:00
Syoyo Fujita
5110820ebb Merge pull request #110 from AlvaroBarua/warnings_cleanup
Removed unreachable code and fixed ambiguity warning.
2018-11-16 14:00:33 +09:00
viperscape
c3e34c2ff7 add screenshot 2018-11-15 17:03:38 -05:00
viperscape
0ddfaead8f add basic example 2018-11-15 17:02:20 -05:00
Unknown
ae2cf8e26f Removed unreachable code and fixed ambiguity warning. 2018-11-15 18:36:59 +00:00
Syoyo Fujita
8b7cdde30c Merge pull request #109 from viperscape/master
Windows build with provided VS solution
2018-11-15 00:28:06 +09:00
viperscape
764bcb5a8a add win32 includes 2018-11-14 10:19:39 -05:00
viperscape
50ada7ff11 rework to include VS 2017 project, fully configured and tested 2018-11-14 10:15:58 -05:00
Syoyo Fujita
16fae080f9 Merge branch 'master' of github.com:syoyo/tinygltf 2018-11-10 20:08:02 +09:00
Syoyo Fujita
90c0008b0e Merge branch 'loomai-master' 2018-11-10 20:07:47 +09:00
Syoyo Fujita
b572650d26 Merge branch 'master' of https://github.com/loomai/tinygltf into loomai-master 2018-11-10 20:07:15 +09:00
Syoyo Fujita
6af9e886cd Merge pull request #107 from Selmar/serialization_fixes
Add missing serialization of `sampler.wrapR`
2018-11-10 02:32:56 +09:00
Selmar Kok
60f97325b1 Merge remote-tracking branch 'origin/master' into serialization_fixes 2018-11-09 10:34:55 +01:00
Selmar Kok
a3595488e3 Fix missing serialization: sampler.wrapR 2018-11-09 10:34:39 +01:00
Syoyo Fujita
cf60322e73 Merge pull request #105 from rapidimages/bugfix/write_image_to_disk
Fixed a reference error which cause an error when writing images to disk
2018-11-07 00:56:34 +09:00
Johan Bowald
77decfaff8 fixed a reference error which cause an error when writing images to disk 2018-11-06 14:28:20 +01:00
Syoyo Fujita
e26117e026 Merge branch 'master' of github.com:syoyo/tinygltf 2018-11-05 13:33:27 +09:00
Syoyo Fujita
33514af61a Fix logic error. Fixes #104 2018-11-05 13:32:43 +09:00
Syoyo Fujita
ba3c3c99ef Merge pull request #102 from 1div0/master
Building glview failed
2018-10-28 15:30:21 +09:00
Syoyo Fujita
8d96b4a14e Merge pull request #103 from Selmar/serialization_fixes
[serialization] handle failing buffer file writes
2018-10-26 02:12:24 +09:00
Selmar Kok
1cef6dcf33 Merge remote-tracking branch 'origin/master' into serialization_fixes 2018-10-25 16:48:14 +02:00
Selmar Kok
e46774940c fail serialization if a buffer file fails to be written (e.g. due to access rights) 2018-10-25 16:45:49 +02:00
Peter Kovář
dddaee695d Merge branch 'master' of https://github.com/1div0/tinygltf 2018-10-17 15:30:33 +02:00
Peter Kovář
a645cfc840 Added include directory ../common/ for trackball.h 2018-10-17 15:29:56 +02:00
Peter Kovář
040310e0d3 Added include direectory ../common/ for trackball.h 2018-10-17 15:24:59 +02:00
Syoyo Fujita
d9eddbfeb9 Merge pull request #101 from 1div0/master
make lint
2018-10-16 19:11:17 +09:00
Peter Kovář
10365a53ff Fixed make lint 2018-10-16 12:03:45 +02:00
Peter Kovář
d0e293fd7d Fixed typos 2018-10-16 12:00:24 +02:00
Syoyo Fujita
3b25d9130a Merge pull request #100 from Selmar/serialization_fixes
yet another serialization fix
2018-10-11 01:25:12 +09:00
Selmar Kok
db7f4e4d04 fix an issue when serializing an empty extension object would serialize as type null (and thus deserialize as type null, causing it to be ignored) 2018-10-10 18:10:58 +02:00
Syoyo Fujita
30bbe0fe3c Merge pull request #99 from Selmar/serialization_fixes
Pretty print & some (de)serialization fixes
2018-10-09 02:12:38 +09:00
Selmar Kok
ee3d06646d // pretty print as optional parameter, default true
// serialize name instead of type for camera.name
// create empy Value::Object if extension value parsing failed
2018-10-08 16:20:43 +02:00
Syoyo Fujita
924d86e362 Serialize extension with empty object. Fixes #97
Use pretty printing JSON when serializing for the readability.
2018-10-08 21:18:33 +09:00
Syoyo Fujita
68353f1b34 Merge branch 'master' of github.com:syoyo/tinygltf 2018-10-07 20:35:14 +09:00
Syoyo Fujita
05a8d0bc52 Fix premake script. 2018-10-07 20:34:45 +09:00
Syoyo Fujita
39a263c2a8 Merge branch 'master' of github.com:syoyo/tinygltf 2018-10-06 03:20:31 +09:00
Syoyo Fujita
61673a62ef Update README. 2018-10-06 03:20:11 +09:00
Syoyo Fujita
fdf105645b Merge pull request #96 from Selmar/serialization_fixes
Serialization & comparison fixes
2018-10-06 01:36:27 +09:00
Selmar Kok
440cb1e66b tabs to spaces 2018-10-05 16:30:50 +02:00
Selmar Kok
c884e5827e better implementation for bin file name checking 2018-10-05 16:25:54 +02:00
Selmar Kok
7cb31e4e23 - support writing multiple bin files
- use existing buffer.uri as filename if not empty and not a data uri
2018-10-05 16:02:29 +02:00
Selmar Kok
2bda71c8fb - always check Parameter::number_value to catch user errors, e.g. setting number_value without setting has_number_value, which will cause it to serialize as a bool but read back in as a float anyway 2018-10-05 14:36:05 +02:00
Selmar Kok
13b6402388 Merge branch 'master' of github.com:syoyo/tinygltf into serialization_fixes 2018-10-05 14:30:16 +02:00
Selmar Kok
8eb3904de2 - Parse image extras property
- Optionally serialize texture.source (it is not required in the current spec)
2018-10-05 14:29:35 +02:00
Syoyo Fujita
b5a72a1ba2 Remove duplicated files. 2018-10-04 15:48:17 +09:00
Syoyo Fujita
0820d83a9d Update to v2.0.1 2018-10-04 15:45:13 +09:00
Syoyo Fujita
641b3ccf8c Suppress clang warnings.
Apply clang-format.
2018-10-04 15:43:33 +09:00
Syoyo Fujita
7518334044 Merge pull request #95 from Selmar/equality_operator_and_some_additions
Equality operator and some additions
2018-10-04 13:56:35 +09:00
Syoyo Fujita
efc919c022 Merge branch 'master' into devel 2018-10-04 13:55:21 +09:00
Selmar Kok
fa0a998a8b Merge branch 'master' of github.com:syoyo/tinygltf into equality_operator_and_some_additions
# Conflicts:
#	tiny_gltf.h
2018-10-03 15:46:23 +02:00
Selmar Kok
31cb7f92d8 // equality operator for tinygltf::Model and types contained by it
// double comparison (although perhaps not necessary, as json reads/writes bytes directly? unsure..)
// initialize some variables for operator==() reliabiltiy
// change some floats to doubles
// intellisense define
// serialize accessor.name
// dont serialize some names if they're empty
// return false if writing gltf file fails
2018-10-03 15:39:05 +02:00
Syoyo Fujita
e59dd6a5c0 Update TODOs. 2018-09-25 03:03:49 +09:00
Syoyo Fujita
e66d8c992f Add as-is flag to Image. Tentative solution for issue #82 2018-09-02 16:58:43 +09:00
Syoyo Fujita
3e53feb046 Parse extensions property of Image. 2018-09-02 15:36:17 +09:00
Syoyo Fujita
9ec7109089 Bump clang version from 3.7 to 3.9 since clang-3.7 apt source is untrusted. 2018-08-30 21:27:11 +09:00
David Harmon
da9eac2fbe Enable support for writing binary glTF. 2018-08-30 08:06:05 -04:00
Syoyo Fujita
5cf22e3abc Merge branch 'master' of github.com:syoyo/tinygltf 2018-08-28 21:34:06 +09:00
Syoyo Fujita
a8f0b1c383 Suppress unknown pragma warning on clang 3.7 2018-08-28 21:33:40 +09:00
Syoyo Fujita
098dfee982 Merge pull request #92 from walf443/respect_stb_image_write_error
handling stbi_write_xxx_to_func return code
2018-08-28 21:33:07 +09:00
Keiji Yoshimi
c0cfc1ed95 handling stbi_write_xxx_to_func return code 2018-08-28 21:13:03 +09:00
Syoyo Fujita
be718436c1 Merge pull request #90 from victorbush/force_32bit_tex
Force default image loader to use 32-bit images
2018-08-23 12:51:43 +09:00
Victor Bushong
18ef338ff5 Force default image loader to use 32-bit images for Vulkan compatibility. 2018-08-22 22:03:30 -05:00
Syoyo Fujita
1d0bd6c64f Merge pull request #89 from Selmar/missing_bin_to_error_message
missing bin files are reported as warning instead of error
2018-08-23 02:16:10 +09:00
Selmar Kok
e3b3fa9eb6 add required parameter to LoadExternalFile 2018-08-22 19:04:21 +02:00
Selmar Kok
cda38e03ed change from warning to error for missing bin files 2018-08-22 18:26:10 +02:00
Syoyo Fujita
fcdfc71ba6 Merge pull request #88 from Selmar/forward_declare_dataUri_utils
forward declare DataURI helpers
2018-08-22 21:36:16 +09:00
Selmar Kok
0d0e97e8cd forward declare DataURI helper functions to allow usage outside of implementation file (in case of custom image handling) 2018-08-22 14:01:57 +02:00
Syoyo Fujita
dfc3545d79 Fix unit test.
Update README.
2018-08-22 20:35:04 +09:00
Syoyo Fujita
1898f10836 Merge branch 'devel' 2018-08-22 20:30:52 +09:00
Syoyo Fujita
96d2f314cd Merge pull request #86 from mosra/fail-when-bin-missing-from-glb
Properly fail also when external *.bin are missing from *.glb.
2018-08-17 19:52:09 +09:00
Vladimír Vondruš
fd84ceb791 Properly fail also when external *.bin are missing from *.glb.
Consistency with behavior for external *.bin files referenced from
*.gltf.
2018-08-16 21:07:56 +02:00
Syoyo Fujita
6d38ca3894 Merge branch 'devel' of github.com:syoyo/tinygltf into devel 2018-08-16 15:57:28 +09:00
Syoyo Fujita
a6802d10fb Fix typo(n2.z -> n1.z) 2018-08-16 15:56:13 +09:00
Syoyo Fujita
28dc902368 Add link to px_render. 2018-08-09 01:58:40 +09:00
Syoyo Fujita
7c8d4ed748 Added 'warning' message parameter to glTF loader API.
Asset loading failure messages(e.g. image file is missing) are now stored in `warning` message, not `error` message.
2018-07-27 16:49:10 +09:00
Syoyo Fujita
a71be9cc98 Merge pull request #80 from mosra/texture-name
Import texture names as well
2018-07-25 13:51:41 +09:00
Syoyo Fujita
8c29e35b42 Merge pull request #81 from mosra/emscripten-file-paths
Don't try to expand file paths on Emscripten.
2018-07-25 13:51:00 +09:00
Vladimír Vondruš
9f04583280 Don't try to expand file paths on Emscripten.
Since the same is done on all mobile platforms already, I think it
should not do any harm. Without this I was getting compilation/linker
errors.
2018-07-24 23:32:17 +02:00
Vladimír Vondruš
239be2c09f Import texture names as well.
Every other structure has it already.
2018-07-24 23:23:56 +02:00
Syoyo Fujita
39abfb5f91 Consider Data URI buffers in binary. Fixes #79. 2018-07-11 02:46:52 +09:00
Syoyo Fujita
81bbf86e2a Merge pull request #78 from UberLambda/devel
Added filesystem callback support (#77)
2018-07-08 15:17:13 +09:00
Paolo Jovon
b2a587af96 Fixed C++11 compliance of previous commit 2018-07-07 21:50:01 +02:00
Paolo Jovon
e6601bfb4b Added filesystem callback support
Now a library like PhysFS can be used to load files by defining custom
callbacks and disabling the builtin ones by #define TINYGLTF_NO_FS
2018-07-07 20:43:33 +02:00
Syoyo Fujita
90e2c9cc74 Merge pull request #76 from mynz/devel
parse extras on the root object
2018-06-28 20:25:23 +02:00
mynz
c0d4d1c50c parse extras on the root object 2018-06-28 23:06:00 +09:00
Syoyo Fujita
0f282f7e26 Merge pull request #75 from holzon/fix/allextras
Adding missing extras field serializaton
2018-06-04 19:07:49 +09:00
Jens Olsson
b3af2f1cf6 adding missing extras field serializaton 2018-06-04 11:56:00 +02:00
Syoyo Fujita
4769b1ca37 Apply clang-format. 2018-06-04 18:40:16 +09:00
Syoyo Fujita
0067a9e43a Support gltf-buffer mime.
Make `min` and `max` parameters in `Accessor` optional.
2018-06-04 18:26:05 +09:00
Syoyo Fujita
57f8e7ca3b Correctly handle filename containing spaces for external resources. Fixes #74. 2018-06-04 17:52:08 +09:00
Syoyo Fujita
a48f12d2fc Merge pull request #73 from holzon/fix/extras
Added missing extras serialization for nodes
2018-05-24 23:59:56 +09:00
Jens Olsson
a9718668b4 fixing typo 2018-05-24 15:48:49 +02:00
Jens Olsson
b96f6966ab added missing extras serialization for nodes 2018-05-24 15:29:54 +02:00
Syoyo Fujita
7c56f8eb9e Merge pull request #69 from benbuzbee/serialization-fixes
Serialization fixes for single-number values and integers
2018-04-26 14:06:18 +09:00
Ben Buzbee
f6af224135 Remove use of optional 2018-04-25 15:13:05 -07:00
Ben Buzbee
3b735bb878 Serialization fixes 2018-04-24 11:39:30 -07:00
Syoyo Fujita
2d17a31d3b typedef struct -> struct for enabling forward declarations of struct. 2018-04-17 15:45:42 +09:00
Syoyo Fujita
48f6db0994 Suppress clang warnings. 2018-04-15 18:40:55 +09:00
Syoyo Fujita
c89fc5f06b Describe supported VS 2015 update revision. 2018-04-12 11:52:14 +09:00
Syoyo Fujita
1e629c8efe Fix printing accessor.min and accessor.max in loader_example.
Initial support for printing extensions(no pretty printing at the moment).
Merge branch 'generic_extension_support' of https://github.com/Selmar/tinygltf into Selmar-generic_extension_support
2018-04-05 15:37:57 +09:00
Selmar Kok
341fc31aee Merge remote-tracking branch 'origin/devel' into generic_extension_support
# Conflicts:
#	tiny_gltf.h
2018-04-04 18:34:30 +02:00
Syoyo Fujita
5307850555 Update README. 2017-06-21 19:27:18 +09:00
55 changed files with 25268 additions and 7373 deletions

View File

@@ -7,15 +7,15 @@ matrix:
sources:
- george-edison55-precise-backports
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
- llvm-toolchain-trusty-3.9
packages:
- g++-4.9
- clang-3.7
- clang-3.9
compiler: clang
env: COMPILER_VERSION=3.7 BUILD_TYPE=Debug
env: COMPILER_VERSION=3.9 BUILD_TYPE=Debug
- addons: *1
compiler: clang
env: COMPILER_VERSION=3.7 BUILD_TYPE=Release
env: COMPILER_VERSION=3.9 BUILD_TYPE=Release
- addons: &2
apt:
sources:
@@ -30,7 +30,7 @@ matrix:
env: COMPILER_VERSION=4.9 BUILD_TYPE=Release EXTRA_CXXFLAGS="-fsanitize=address"
- addons: *1
compiler: clang
env: COMPILER_VERSION=3.7 BUILD_TYPE=Debug CFLAGS="-O0" CXXFLAGS="-O0"
env: COMPILER_VERSION=3.9 BUILD_TYPE=Debug CFLAGS="-O0" CXXFLAGS="-O0"
before_install:
- ./.travis-before-install.sh

28
CMakeLists.txt Normal file
View File

@@ -0,0 +1,28 @@
cmake_minimum_required(VERSION 3.6)
PROJECT (tinygltf)
SET(CMAKE_CXX_STANDARD 11)
ADD_EXECUTABLE ( loader_example
loader_example.cc
)
ADD_SUBDIRECTORY ( examples/gltfutil )
ADD_SUBDIRECTORY ( examples/glview )
ADD_SUBDIRECTORY ( examples/validator )
INSTALL ( FILES
json.hpp
stb_image.h
stb_image_write.h
tiny_gltf.h
DESTINATION
include
)
INSTALL ( FILES
cmake/TinyGLTFConfig.cmake
DESTINATION
cmake
)

View File

@@ -1,9 +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
#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
clang++ $(EXTRA_CXXFLAGS) -std=c++11 -g -O0 -o loader_example loader_example.cc $(EXTRA_LINKFLAGS)
lint:
./cpplint.py tiny_gltf_loader.h
deps/cpplint.py tiny_gltf.h

View File

@@ -2,12 +2,14 @@
`TinyGLTF` is a header only C++11 glTF 2.0 https://github.com/KhronosGroup/glTF library.
`TinyGLTF` uses Niels Lohmann's json library(https://github.com/nlohmann/json), so now it requires C++11 compiler.
If you are looking for old, C++03 version, please use `devel-picojson` branch.
## Status
Work in process(`devel` branch). Very near to release, but need more tests and examples.
`TinyGLTF` uses Niels Lohmann's json library(https://github.com/nlohmann/json), so now it requires C++11 compiler.
If you are looking for old, C++03 version, please use `devel-picojson` branch.
- v2.2.0 release(Support loading 16bit PNG. Sparse accessor support)
- v2.1.0 release(Draco support)
- v2.0.0 release(22 Aug, 2018)!
## Builds
@@ -22,8 +24,9 @@ If you are looking for old, C++03 version, please use `devel-picojson` branch.
* [x] iOS + clang
* [x] Linux + gcc/clang
* [x] Windows + MinGW
* [x] Windows + Visual Studio 2015 or later.
* [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.
@@ -32,23 +35,34 @@ If you are looking for old, C++03 version, please use `devel-picojson` branch.
* [x] Binary glTF(GLB)
* [x] PBR material description
* Buffers
* [x] Parse BASE64 encoded embedded buffer fata(DataURI).
* [x] Parse BASE64 encoded embedded buffer data(DataURI).
* [x] Load `.bin` file.
* Image(Using stb_image)
* [x] Parse BASE64 encoded embedded image fata(DataURI).
* [x] Parse BASE64 encoded embedded image data(DataURI).
* [x] Load external image file.
* [x] PNG(8bit only)
* [x] JPEG(8bit only)
* [x] BMP
* [x] GIF
* [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
## 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.
## 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.
@@ -56,13 +70,16 @@ If you are looking for old, C++03 version, please use `devel-picojson` branch.
## TODOs
* [ ] Write C++ code generator from jSON schema for robust parsing.
* [x] Serialization
* [ ] Compression/decompression(Open3DGC, etc)
* [ ] Write C++ code generator which emits C++ code from JSON schema for robust parsing.
* [ ] Mesh Compression/decompression(Open3DGC, etc)
* [x] Load Draco compressed mesh
* [ ] Save Draco compressed mesh
* [ ] Open3DGC?
* [ ] Support `extensions` and `extras` property
* [ ] HDR image?
* [ ] OpenEXR extension through TinyEXR.
* [ ] Write tests for `animation` and `skin`
* [ ] 16bit PNG support in Serialization
* [ ] Write example and tests for `animation` and `skin`
## Licenses
@@ -92,12 +109,18 @@ Copy `stb_image.h`, `stb_image_write.h`, `json.hpp` and `tiny_gltf.h` to your pr
using namespace tinygltf;
Model model;
Model model;
TinyGLTF loader;
std::string err;
bool ret = loader.LoadASCIIFromFile(&model, &err, argv[1]);
//bool ret = loader.LoadBinaryFromFile(&model, &err, argv[1]); // for binary glTF(.glb)
std::string warn;
bool ret = loader.LoadASCIIFromFile(&model, &err, &warn, argv[1]);
//bool ret = loader.LoadBinaryFromFile(&model, &err, &warn, argv[1]); // for binary glTF(.glb)
if (!warn.empty()) {
printf("Warn: %s\n", warn.c_str());
}
if (!err.empty()) {
printf("Err: %s\n", err.c_str());
}
@@ -113,6 +136,13 @@ if (!ret) {
* `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_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`.
### Saving gltTF 2.0 model
* [ ] Buffers.

View File

@@ -0,0 +1,15 @@
# -*- cmake -*-
# - Find TinyGLTF
# TinyGLTF_INCLUDE_DIR TinyGLTF's include directory
FIND_PACKAGE ( PackageHandleStandardArgs )
SET ( TinyGLTF_INCLUDE_DIR "${TinyGLTF_DIR}/../include" CACHE STRING "TinyGLTF include directory")
FIND_FILE ( TinyGLTF_HEADER tiny_gltf.h PATHS ${TinyGLTF_INCLUDE_DIR} )
IF (NOT TinyGLTF_HEADER)
MESSAGE ( FATAL_ERROR "Unable to find tiny_gltf.h, TinyGLTF_INCLUDE_DIR = ${TinyGLTF_INCLUDE_DIR}")
ENDIF ()

7
examples/basic/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
.vs
Debug
x64
packages
!*.sln
!*.vcxproj*

21
examples/basic/README.md Normal file
View File

@@ -0,0 +1,21 @@
# Basic glTF viewer
## Requirements
* glew
* glfw3
* premake5(linux)
* OpenGL 3.3+ GPU
## Build on Linux and macOS
```
$ premake5 gmake
$ make
```
## Build on Visual Studio
Plese use solution file located at `basic` folder.

View File

@@ -0,0 +1,31 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28010.2050
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic", "basic.vcxproj", "{0589AC44-0CF3-40D8-8D89-68393CFD40F3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0589AC44-0CF3-40D8-8D89-68393CFD40F3}.Debug|x64.ActiveCfg = Debug|x64
{0589AC44-0CF3-40D8-8D89-68393CFD40F3}.Debug|x64.Build.0 = Debug|x64
{0589AC44-0CF3-40D8-8D89-68393CFD40F3}.Debug|x86.ActiveCfg = Debug|Win32
{0589AC44-0CF3-40D8-8D89-68393CFD40F3}.Debug|x86.Build.0 = Debug|Win32
{0589AC44-0CF3-40D8-8D89-68393CFD40F3}.Release|x64.ActiveCfg = Release|x64
{0589AC44-0CF3-40D8-8D89-68393CFD40F3}.Release|x64.Build.0 = Release|x64
{0589AC44-0CF3-40D8-8D89-68393CFD40F3}.Release|x86.ActiveCfg = Release|Win32
{0589AC44-0CF3-40D8-8D89-68393CFD40F3}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {055E97C4-43DC-41B4-8D61-4FDDBC7B1EF7}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,159 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{0589AC44-0CF3-40D8-8D89-68393CFD40F3}</ProjectGuid>
<RootNamespace>basic</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies);opengl32.lib</AdditionalDependencies>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies);opengl32.lib</AdditionalDependencies>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies);opengl32.lib</AdditionalDependencies>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies);opengl32.lib</AdditionalDependencies>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\main.cpp" />
<ClCompile Include="..\shaders.cpp" />
<ClCompile Include="..\window.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\shaders.h" />
<ClInclude Include="..\window.h" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="packages\nupengl.core.redist.0.1.0.1\build\native\nupengl.core.redist.targets" Condition="Exists('packages\nupengl.core.redist.0.1.0.1\build\native\nupengl.core.redist.targets')" />
<Import Project="packages\nupengl.core.0.1.0.1\build\native\nupengl.core.targets" Condition="Exists('packages\nupengl.core.0.1.0.1\build\native\nupengl.core.targets')" />
<Import Project="packages\glm.0.9.9.200\build\native\glm.targets" Condition="Exists('packages\glm.0.9.9.200\build\native\glm.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('packages\nupengl.core.redist.0.1.0.1\build\native\nupengl.core.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\nupengl.core.redist.0.1.0.1\build\native\nupengl.core.redist.targets'))" />
<Error Condition="!Exists('packages\nupengl.core.0.1.0.1\build\native\nupengl.core.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\nupengl.core.0.1.0.1\build\native\nupengl.core.targets'))" />
<Error Condition="!Exists('packages\glm.0.9.9.200\build\native\glm.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\glm.0.9.9.200\build\native\glm.targets'))" />
</Target>
</Project>

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\window.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\shaders.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\window.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\shaders.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="glm" version="0.9.9.200" targetFramework="native" />
<package id="nupengl.core" version="0.1.0.1" targetFramework="native" />
<package id="nupengl.core.redist" version="0.1.0.1" targetFramework="native" />
</packages>

365
examples/basic/main.cpp Normal file
View File

@@ -0,0 +1,365 @@
#include <fstream>
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/gtc/matrix_transform.hpp>
#include "shaders.h"
#include "window.h"
#define TINYGLTF_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#define TINYGLTF_NOEXCEPTION
#define JSON_NOEXCEPTION
#include "../../tiny_gltf.h"
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
bool loadModel(tinygltf::Model &model, const char *filename) {
tinygltf::TinyGLTF loader;
std::string err;
std::string warn;
bool res = loader.LoadASCIIFromFile(&model, &err, &warn, filename);
if (!warn.empty()) {
std::cout << "WARN: " << warn << std::endl;
}
if (!err.empty()) {
std::cout << "ERR: " << err << std::endl;
}
if (!res)
std::cout << "Failed to load glTF: " << filename << std::endl;
else
std::cout << "Loaded glTF: " << filename << std::endl;
return res;
}
std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos,
tinygltf::Model &model, tinygltf::Mesh &mesh) {
for (size_t i = 0; i < model.bufferViews.size(); ++i) {
const tinygltf::BufferView &bufferView = model.bufferViews[i];
if (bufferView.target == 0) { // TODO impl drawarrays
std::cout << "WARN: bufferView.target is zero" << std::endl;
continue; // Unsupported bufferView.
/*
From spec2.0 readme:
https://github.com/KhronosGroup/glTF/tree/master/specification/2.0
... drawArrays function should be used with a count equal to
the count property of any of the accessors referenced by the
attributes property (they are all equal for a given
primitive).
*/
}
tinygltf::Buffer buffer = model.buffers[bufferView.buffer];
std::cout << "bufferview.target " << bufferView.target << std::endl;
GLuint vbo;
glGenBuffers(1, &vbo);
vbos[i] = vbo;
glBindBuffer(bufferView.target, vbo);
std::cout << "buffer.data.size = " << buffer.data.size()
<< ", bufferview.byteOffset = " << bufferView.byteOffset
<< std::endl;
glBufferData(bufferView.target, bufferView.byteLength,
&buffer.data.at(0) + bufferView.byteOffset, GL_STATIC_DRAW);
}
for (size_t i = 0; i < mesh.primitives.size(); ++i) {
tinygltf::Primitive primitive = mesh.primitives[i];
tinygltf::Accessor indexAccessor = model.accessors[primitive.indices];
for (auto &attrib : primitive.attributes) {
tinygltf::Accessor accessor = model.accessors[attrib.second];
int byteStride =
accessor.ByteStride(model.bufferViews[accessor.bufferView]);
glBindBuffer(GL_ARRAY_BUFFER, vbos[accessor.bufferView]);
int size = 1;
if (accessor.type != TINYGLTF_TYPE_SCALAR) {
size = accessor.type;
}
int vaa = -1;
if (attrib.first.compare("POSITION") == 0) vaa = 0;
if (attrib.first.compare("NORMAL") == 0) vaa = 1;
if (attrib.first.compare("TEXCOORD_0") == 0) vaa = 2;
if (vaa > -1) {
glEnableVertexAttribArray(vaa);
glVertexAttribPointer(vaa, size, accessor.componentType,
accessor.normalized ? GL_TRUE : GL_FALSE,
byteStride, BUFFER_OFFSET(accessor.byteOffset));
} else
std::cout << "vaa missing: " << attrib.first << std::endl;
}
GLuint texid;
glGenTextures(1, &texid);
tinygltf::Texture &tex = model.textures[0];
tinygltf::Image &image = model.images[tex.source];
glBindTexture(GL_TEXTURE_2D, texid);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
GLenum format = GL_RGBA;
if (image.component == 1) {
format = GL_RED;
} else if (image.component == 2) {
format = GL_RG;
} else if (image.component == 3) {
format = GL_RGB;
} else {
// ???
}
GLenum type = GL_UNSIGNED_BYTE;
if (image.bits == 8) {
// ok
} else if (image.bits == 16) {
type = GL_UNSIGNED_SHORT;
} else {
// ???
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0,
format, type, &image.image.at(0));
}
return vbos;
}
// bind models
void bindModelNodes(std::map<int, GLuint> vbos, tinygltf::Model &model,
tinygltf::Node &node) {
bindMesh(vbos, model, model.meshes[node.mesh]);
for (size_t i = 0; i < node.children.size(); i++) {
bindModelNodes(vbos, model, model.nodes[node.children[i]]);
}
}
GLuint bindModel(tinygltf::Model &model) {
std::map<int, GLuint> vbos;
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
const tinygltf::Scene &scene = model.scenes[model.defaultScene];
for (size_t i = 0; i < scene.nodes.size(); ++i) {
bindModelNodes(vbos, model, model.nodes[scene.nodes[i]]);
}
glBindVertexArray(0);
// cleanup vbos
for (size_t i = 0; i < vbos.size(); ++i) {
glDeleteBuffers(1, &vbos[i]);
}
return vao;
}
void drawMesh(tinygltf::Model &model, tinygltf::Mesh &mesh) {
for (size_t i = 0; i < mesh.primitives.size(); ++i) {
tinygltf::Primitive primitive = mesh.primitives[i];
tinygltf::Accessor indexAccessor = model.accessors[primitive.indices];
glDrawElements(primitive.mode, indexAccessor.count,
indexAccessor.componentType,
BUFFER_OFFSET(indexAccessor.byteOffset));
}
}
// recursively draw node and children nodes of model
void drawModelNodes(tinygltf::Model &model, tinygltf::Node &node) {
drawMesh(model, model.meshes[node.mesh]);
for (size_t i = 0; i < node.children.size(); i++) {
drawModelNodes(model, model.nodes[node.children[i]]);
}
}
void drawModel(GLuint vao, tinygltf::Model &model) {
glBindVertexArray(vao);
const tinygltf::Scene &scene = model.scenes[model.defaultScene];
for (size_t i = 0; i < scene.nodes.size(); ++i) {
drawModelNodes(model, model.nodes[scene.nodes[i]]);
}
glBindVertexArray(0);
}
void dbgModel(tinygltf::Model &model) {
for (auto &mesh : model.meshes) {
std::cout << "mesh : " << mesh.name << std::endl;
for (auto &primitive : mesh.primitives) {
const tinygltf::Accessor &indexAccessor =
model.accessors[primitive.indices];
std::cout << "indexaccessor: count " << indexAccessor.count << ", type "
<< indexAccessor.componentType << std::endl;
tinygltf::Material &mat = model.materials[primitive.material];
for (auto &mats : mat.values) {
std::cout << "mat : " << mats.first.c_str() << std::endl;
}
for (auto &image : model.images) {
std::cout << "image name : " << image.uri << std::endl;
std::cout << " size : " << image.image.size() << std::endl;
std::cout << " w/h : " << image.width << "/" << image.height
<< std::endl;
}
std::cout << "indices : " << primitive.indices << std::endl;
std::cout << "mode : "
<< "(" << primitive.mode << ")" << std::endl;
for (auto &attrib : primitive.attributes) {
std::cout << "attribute : " << attrib.first.c_str() << std::endl;
}
}
}
}
glm::mat4 genView(glm::vec3 pos, glm::vec3 lookat) {
// Camera matrix
glm::mat4 view = glm::lookAt(
pos, // Camera in World Space
lookat, // and looks at the origin
glm::vec3(0, 1, 0) // Head is up (set to 0,-1,0 to look upside-down)
);
return view;
}
glm::mat4 genMVP(glm::mat4 view_mat, glm::mat4 model_mat, float fov, int w,
int h) {
glm::mat4 Projection =
glm::perspective(glm::radians(fov), (float)w / (float)h, 0.01f, 1000.0f);
// Or, for an ortho camera :
// glm::mat4 Projection = glm::ortho(-10.0f,10.0f,-10.0f,10.0f,0.0f,100.0f);
// // In world coordinates
glm::mat4 mvp = Projection * view_mat * model_mat;
return mvp;
}
void displayLoop(Window &window, const std::string &filename) {
Shaders shader = Shaders();
glUseProgram(shader.pid);
// grab uniforms to modify
GLuint MVP_u = glGetUniformLocation(shader.pid, "MVP");
GLuint sun_position_u = glGetUniformLocation(shader.pid, "sun_position");
GLuint sun_color_u = glGetUniformLocation(shader.pid, "sun_color");
tinygltf::Model model;
if (!loadModel(model, filename.c_str())) return;
GLuint vao = bindModel(model);
// dbgModel(model); return;
// Model matrix : an identity matrix (model will be at the origin)
glm::mat4 model_mat = glm::mat4(1.0f);
glm::mat4 model_rot = glm::mat4(1.0f);
glm::vec3 model_pos = glm::vec3(-3, 0, -3);
// generate a camera view, based on eye-position and lookAt world-position
glm::mat4 view_mat = genView(glm::vec3(2, 2, 20), model_pos);
glm::vec3 sun_position = glm::vec3(3.0, 10.0, -5.0);
glm::vec3 sun_color = glm::vec3(1.0);
while (!window.Close()) {
window.Resize();
glClearColor(0.2, 0.2, 0.2, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 trans =
glm::translate(glm::mat4(1.0f), model_pos); // reposition model
model_rot = glm::rotate(model_rot, glm::radians(0.8f),
glm::vec3(0, 1, 0)); // rotate model on y axis
model_mat = trans * model_rot;
// build a model-view-projection
GLint w, h;
glfwGetWindowSize(window.window, &w, &h);
glm::mat4 mvp = genMVP(view_mat, model_mat, 45.0f, w, h);
glUniformMatrix4fv(MVP_u, 1, GL_FALSE, &mvp[0][0]);
glUniform3fv(sun_position_u, 1, &sun_position[0]);
glUniform3fv(sun_color_u, 1, &sun_color[0]);
drawModel(vao, model);
glfwSwapBuffers(window.window);
glfwPollEvents();
}
}
static void error_callback(int error, const char *description) {
(void)error;
fprintf(stderr, "Error: %s\n", description);
}
int main(int argc, char **argv) {
std::string filename = "../../models/Cube/Cube.gltf";
if (argc > 1) {
filename = argv[1];
}
glfwSetErrorCallback(error_callback);
if (!glfwInit()) return -1;
// Force create OpenGL 3.3
// NOTE(syoyo): Linux + NVIDIA driver segfaults for some reason? commenting out glfwWindowHint will work.
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
#endif
Window window = Window(800, 600, "TinyGLTF basic example");
glfwMakeContextCurrent(window.window);
#ifdef __APPLE__
// https://stackoverflow.com/questions/50192625/openggl-segmentation-fault
glewExperimental = GL_TRUE;
#endif
glewInit();
std::cout << glGetString(GL_RENDERER) << ", " << glGetString(GL_VERSION)
<< std::endl;
if (!GLEW_VERSION_3_3) {
std::cerr << "OpenGL 3.3 is required to execute this app." << std::endl;
return EXIT_FAILURE;
}
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
displayLoop(window, filename);
glfwTerminate();
return 0;
}

View File

@@ -0,0 +1,44 @@
solution "basic_viewer"
-- location ( "build" )
configurations { "Debug", "Release" }
platforms {"native", "x64", "x32"}
project "basic_viewer"
kind "ConsoleApp"
language "C++"
cppdialect "C++11"
files { "main.cpp", "shaders.cpp", "window.cpp" }
includedirs { "./" }
includedirs { "../../" }
includedirs { "../common/glm" }
configuration { "linux" }
linkoptions { "`pkg-config --libs glfw3`" }
links { "GL", "GLU", "m", "GLEW", "X11", "Xrandr", "Xinerama", "Xi", "Xxf86vm", "Xcursor", "dl" }
configuration { "windows" }
-- Edit path to glew and GLFW3 fit to your environment.
includedirs { "../../../../local/glew-1.13.0/include/" }
includedirs { "../../../../local/glfw-3.2.bin.WIN32/include/" }
libdirs { "../../../../local/glew-1.13.0/lib/Release/Win32/" }
libdirs { "../../../../local/glfw-3.2.bin.WIN32/lib-vc2013/" }
links { "glfw3", "gdi32", "winmm", "user32", "glew32", "glu32","opengl32", "kernel32" }
defines { "_CRT_SECURE_NO_WARNINGS" }
configuration { "macosx" }
includedirs { "/usr/local/include" }
buildoptions { "-Wno-deprecated-declarations" }
libdirs { "/usr/local/lib" }
links { "glfw", "GLEW" }
linkoptions { "-framework OpenGL", "-framework Cocoa", "-framework IOKit", "-framework CoreVideo" }
configuration "Debug"
defines { "DEBUG" }
symbols "On"
warnings "Extra"
configuration "Release"
defines { "NDEBUG" }
optimize "On"
warnings "Extra"

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

114
examples/basic/shaders.cpp Normal file
View File

@@ -0,0 +1,114 @@
#include "shaders.h"
#include <iostream>
#include <vector>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
std::string FragmentShaderCode =
"#version 330 core\n\
in vec3 normal;\n\
in vec3 position;\n\
in vec2 texcoord;\n\
\n\
uniform sampler2D tex;\n\
uniform vec3 sun_position; \n\
uniform vec3 sun_color; \n\
\n\
out vec4 color;\n\
void main() {\n\
float lum = max(dot(normal, normalize(sun_position)), 0.0);\n\
color = texture(tex, texcoord) * vec4((0.3 + 0.7 * lum) * sun_color, 1.0);\n\
}\n\
";
std::string VertexShaderCode =
"#version 330 core\n\
layout(location = 0) in vec3 in_vertex;\n\
layout(location = 1) in vec3 in_normal;\n\
layout(location = 2) in vec2 in_texcoord;\n\
\n\
uniform mat4 MVP;\n\
\n\
out vec3 normal;\n\
out vec3 position;\n\
out vec2 texcoord;\n\
\n\
void main(){\n\
gl_Position = MVP * vec4(in_vertex, 1);\n\
position = gl_Position.xyz;\n\
normal = normalize(mat3(MVP) * in_normal);\n\
position = in_vertex;\n\
texcoord = in_texcoord;\n\
}";
Shaders::Shaders()
{
// Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
GLint Result = GL_FALSE;
int InfoLogLength;
// Compile Vertex Shader
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL);
glCompileShader(VertexShaderID);
// Check Vertex Shader
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
std::vector<char> VertexShaderErrorMessage(InfoLogLength + 1);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
printf("%s\n", &VertexShaderErrorMessage[0]);
}
// Compile Fragment Shader
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL);
glCompileShader(FragmentShaderID);
// Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
std::vector<char> FragmentShaderErrorMessage(InfoLogLength + 1);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
printf("%s\n", &FragmentShaderErrorMessage[0]);
}
// Link the program
printf("Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
std::vector<char> ProgramErrorMessage(InfoLogLength + 1);
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
printf("%s\n", &ProgramErrorMessage[0]);
}
glDetachShader(ProgramID, VertexShaderID);
glDetachShader(ProgramID, FragmentShaderID);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
this->pid = ProgramID;
}
Shaders::~Shaders()
{
}

13
examples/basic/shaders.h Normal file
View File

@@ -0,0 +1,13 @@
#pragma once
#include <GL/glew.h>
#include <GLFW/glfw3.h>
class Shaders
{
public:
GLuint pid;
Shaders();
~Shaders();
};

27
examples/basic/window.cpp Normal file
View File

@@ -0,0 +1,27 @@
#include "window.h"
Window::Window(int x, int y, const char* title)
{
GLFWwindow* window = glfwCreateWindow(x, y, title, NULL, NULL);
this->window = window;
}
Window::~Window()
{
glfwDestroyWindow(this->window);
}
void Window::Resize()
{
GLint w, h;
glfwGetWindowSize(this->window, &w, &h);
glViewport(0, 0, w, h);
}
int Window::Close()
{
return glfwWindowShouldClose(this->window);
}

15
examples/basic/window.h Normal file
View File

@@ -0,0 +1,15 @@
#pragma once
#include <GLFW/glfw3.h>
class Window
{
public:
GLFWwindow* window;
Window(int x, int y, const char* title);
~Window();
void Resize();
int Close();
};

View File

@@ -0,0 +1,21 @@
Copyright (c) 2005-2018 Lode Vandevenne
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.

5992
examples/common/lodepng.cpp Normal file

File diff suppressed because it is too large Load Diff

1919
examples/common/lodepng.h Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,13 @@ project(gltfutil)
set(CMAKE_CXX_STANDARD 11)
include_directories(../../)
include_directories(../common/)
file(GLOB gltfutil_sources *.cc *.h)
add_executable(gltfutil ${gltfutil_sources})
add_executable(gltfutil ${gltfutil_sources} ../common/lodepng.cpp)
install ( TARGETS
gltfutil
DESTINATION
bin
)

View File

@@ -49,6 +49,7 @@ struct configuration {
cli_action action = cli_action::not_set;
texture_dumper::texture_output_format requested_format =
texture_dumper::texture_output_format::not_specified;
bool use_exr = false;
bool has_output_dir;
bool is_valid() {

View File

@@ -11,6 +11,9 @@
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
#define TINYEXR_IMPLEMENTATION
#include "tinyexr.h"
namespace gltfutil {
int usage(int ret = 0) {
using std::cout;
@@ -20,8 +23,9 @@ int usage(int ret = 0) {
"[path to output directory])\n\n"
//<< "\t\t -i: start in interactive mode\n"
<< "\t\t -d: dump enclosed content (image assets)\n"
<< "\t\t -f: file format for image output"
<< "\t\t -o: ouptput directory path"
<< "\t\t -f: file format for image output\n"
<< "\t\t -o: ouptput directory path\n"
<< "\t\t -e: Use OpenEXR format for 16bit image\n"
<< "\t\t -h: print this help\n";
return ret;
}
@@ -44,6 +48,9 @@ int parse_args(int argc, char** argv) {
config.mode = ui_mode::cli;
config.action = cli_action::dump;
break;
case 'e':
config.use_exr = true;
break;
case 'i':
config.mode = ui_mode::interactive;
break;
@@ -69,13 +76,14 @@ int parse_args(int argc, char** argv) {
tinygltf::TinyGLTF loader;
tinygltf::Model model;
std::string error;
std::string warning;
bool state;
switch (detectType(config.input_path)) {
case FileType::Ascii:
state = loader.LoadASCIIFromFile(&model, &error, config.input_path);
state = loader.LoadASCIIFromFile(&model, &error, &warning, config.input_path);
break;
case FileType::Binary:
state = loader.LoadBinaryFromFile(&model, &error, config.input_path);
state = loader.LoadBinaryFromFile(&model, &error, &warning, config.input_path);
break;
case FileType::Unknown:
default:
@@ -96,6 +104,11 @@ int parse_args(int argc, char** argv) {
case cli_action::dump: {
texture_dumper dumper(model);
if (config.use_exr) {
dumper.set_use_exr(true);
}
if (config.requested_format !=
texture_dumper::texture_output_format::not_specified)
dumper.set_output_format(config.requested_format);

View File

@@ -1,14 +1,84 @@
#include <algorithm>
#include <iostream>
#include "stb_image_write.h"
#include "texture_dumper.h"
#include "lodepng.h" // ../common
#include "tinyexr.h"
#include <tiny_gltf.h>
using namespace gltfutil;
using namespace tinygltf;
using std::cout;
static LodePNGColorType GetLodePNGColorType(int channels) {
if (channels == 1) {
return LodePNGColorType::LCT_GREY;
} else if (channels == 2) {
return LodePNGColorType::LCT_GREY_ALPHA;
} else if (channels == 3) {
return LodePNGColorType::LCT_RGB;
} else if (channels == 4) {
return LodePNGColorType::LCT_RGBA;
} else {
std::cerr << "??? unsupported channels " << channels << "\n";
return LodePNGColorType::LCT_RGB; // FIXME(syoyo): Raise error
}
}
static void ToBigEndian(std::vector<uint8_t>* image) {
assert(image->size() % 2 == 0);
union {
unsigned int i;
char c[4];
} bint = {0x01020304};
bool is_big_endian = (bint.c[0] == 1);
if (is_big_endian) {
return;
}
uint16_t *ptr = reinterpret_cast<uint16_t *>(image->data());
size_t n = image->size() / 2;
for (size_t i = 0; i < n; i++) {
ptr[i] = ((0xFF00 & ptr[i]) >> 8) | ((0x00FF & ptr[i]) << 8);
}
}
static bool Save16bitImageAsEXR(const std::string& filename,
const tinygltf::Image& image) {
assert(image.bits == 16);
std::vector<float> buf(image.width * image.height * image.component);
// widen to float image.
// Store as is(i.e, pixel value range is [0.0, 65535.0])
const unsigned short* ptr =
reinterpret_cast<const unsigned short*>(image.image.data());
for (size_t i = 0; i < image.width * image.height * image.component; i++) {
buf[i] = float(ptr[i]);
}
const char* err = nullptr;
int ret = SaveEXR(buf.data(), image.width, image.height, image.component,
/* save_as_fp16 */ 0, filename.c_str(), &err);
if (err) {
std::cerr << "EXR err: " << err << std::endl;
FreeEXRErrorMessage(err);
return false;
}
return (ret == TINYEXR_SUCCESS);
}
texture_dumper::texture_dumper(const Model& input)
: model(input), configured_format(texture_output_format::png) {
cout << "Texture dumper\n";
@@ -25,26 +95,58 @@ void texture_dumper::dump_to_folder(const std::string& path) {
cout << "image name is: \"" << image.name << "\"\n";
cout << "image size is: " << image.width << 'x' << image.height << '\n';
cout << "pixel channel count :" << image.component << '\n';
std::string name = image.name.empty() ? std::to_string(index) : image.name;
cout << "pixel bit depth :" << image.bits << '\n';
std::string basename =
image.name.empty() ? std::to_string(index) : image.name;
unsigned char* bytes_to_write =
const_cast<unsigned char*>(image.image.data());
std::string filename;
switch (configured_format) {
case texture_output_format::png:
name = path + "/" + name + ".png";
std::cout << "Image will be written to " << name << '\n';
stbi_write_png(name.c_str(), image.width, image.height, image.component,
image.image.data(), 0);
filename = path + "/" + basename + ".png";
if (this->use_exr) {
if (image.pixel_type == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT) {
filename = path + "/" + basename + ".exr";
}
}
std::cout << "Image will be written to " << filename << '\n';
if (image.pixel_type == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT) {
if (this->use_exr) {
bool ret = Save16bitImageAsEXR(filename, image);
assert(ret);
} else {
// Use lodepng to save 16bit PNG.
// NOTE(syoyo): `loadpng::encode` requires image data must be stored in big endian.
std::vector<uint8_t> tmp = image.image; // copy
ToBigEndian(&tmp);
unsigned ret = lodepng::encode(
filename, tmp.data(), image.width, image.height,
GetLodePNGColorType(image.component), /* bits */ 16);
assert(ret == 0); // 0 = no err.
}
} else {
// TODO(syoyo): check status
stbi_write_png(filename.c_str(), image.width, image.height,
image.component, bytes_to_write, 0);
}
break;
case texture_output_format::bmp:
std::cout << "Image will be written to " << name << '\n';
name = path + "/" + name + ".bmp";
stbi_write_bmp(name.c_str(), image.width, image.height, image.component,
image.image.data());
filename = path + "/" + basename + ".bmp";
std::cout << "Image will be written to " << filename << '\n';
stbi_write_bmp(filename.c_str(), image.width, image.height,
image.component, bytes_to_write);
break;
case texture_output_format::tga:
std::cout << "Image will be written to " << name << '\n';
name = path + "/" + name + ".tga";
stbi_write_tga(name.c_str(), image.width, image.height, image.component,
image.image.data());
filename = path + "/" + basename + ".tga";
std::cout << "Image will be written to " << filename << '\n';
stbi_write_tga(filename.c_str(), image.width, image.height,
image.component, bytes_to_write);
break;
}
}

View File

@@ -12,11 +12,15 @@ class texture_dumper {
private:
const tinygltf::Model& model;
texture_output_format configured_format;
bool use_exr = false; // Use EXR for 16bit image?
public:
texture_dumper(const tinygltf::Model& inputModel);
void dump_to_folder(const std::string& path = "./");
void set_output_format(texture_output_format format);
void set_use_exr(const bool value) {
use_exr = value;
}
static texture_output_format get_fromat_from_string(const std::string& str);
};

7
examples/glview/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
.vs
Debug
x64
packages
!*.sln
!*.vcxproj*

View File

@@ -0,0 +1,69 @@
cmake_minimum_required(VERSION 3.5)
project(glview)
set ( CMAKE_PREFIX_PATH cmake )
set ( DRACO_DIR "" CACHE STRING "Path to draco" )
find_package ( GLEW REQUIRED )
find_package ( GLFW3 REQUIRED )
find_package ( OpenGL REQUIRED )
if (APPLE)
find_library(COCOA_LIBRARY Cocoa)
find_library(COREVIDEO_LIBRARY CoreVideo)
find_library(IOKIT_LIBRARY IOKit)
else ()
if (NOT WIN32)
# This means it is Unices
set ( GLFW3_UNIX_LINK_LIBRARIES X11 Xxf86vm Xrandr Xi Xinerama Xcursor )
find_package (Threads)
endif()
endif (APPLE)
set(CMAKE_CXX_STANDARD 11)
if (DEFINED DRACO_DIR)
if (DRACO_DIR STREQUAL "")
else ()
# TODO(syoyo): better CMake script for draco
add_definitions(-DTINYGLTF_ENABLE_DRACO)
include_directories(${DRACO_DIR}/include)
link_directories(${DRACO_DIR}/lib)
set(DRACO_LIBRARY draco)
endif ()
endif()
include_directories(
../../
../common
# ${OPENGL_INCLUDE_DIR}
${GLEW_INCLUDE_DIR}
${GLFW3_INCLUDE_DIR}
)
add_executable(glview
glview.cc
../common/trackball.cc
)
target_link_libraries ( glview
${DRACO_LIBRARY}
${GLFW3_UNIX_LINK_LIBRARIES}
${GLEW_LIBRARY}
${GLFW3_glfw_LIBRARY}
${OPENGL_gl_LIBRARY}
${OPENGL_glu_LIBRARY}
${COCOA_LIBRARY}
${COREVIDEO_LIBRARY}
${IOKIT_LIBRARY}
${CMAKE_DL_LIBS}
${CMAKE_THREAD_LIBS_INIT}
)
install ( TARGETS
glview
DESTINATION
bin
)

View File

@@ -27,6 +27,17 @@ Open .sln in Visual Studio 2013
When running .exe, glew and glfw dll must exist in the working directory.
#### Build with Draco(optional)
Assume CMake build.
```
$ mkdir build
$ cd build
$ cmake -DDRACO_DIR=/path/to/draco ../
$ make
```
## TODO
* [ ] PBR Material

View File

@@ -0,0 +1,71 @@
#-*-cmake-*-
#
# yue.nicholas@gmail.com
#
# This auxiliary CMake file helps in find the glfw3 headers and libraries
#
# GLFW3_FOUND set if glfw3 is found.
# GLFW3_INCLUDE_DIR glfw3's include directory
# GLFW3_LIBRARY_DIR glfw3's library directory
# GLFW3_LIBRARIES all glfw3 libraries
FIND_PACKAGE (Threads)
FIND_PACKAGE ( PackageHandleStandardArgs )
FIND_PATH( GLFW3_LOCATION include/GLFW/glfw3.h
"$ENV{GLFW3_HOME}"
)
FIND_PACKAGE_HANDLE_STANDARD_ARGS ( GLFW3
REQUIRED_VARS GLFW3_LOCATION
)
IF (GLFW3_FOUND)
SET( GLFW3_INCLUDE_DIR "${GLFW3_LOCATION}/include" CACHE STRING "GLFW3 include path")
IF (GLFW3_USE_STATIC_LIBS)
FIND_LIBRARY ( GLFW3_glfw_LIBRARY libglfw3.a ${GLFW3_LOCATION}/lib
)
ELSE (GLFW3_USE_STATIC_LIBS)
# On windows build, we need to look for glfw3
IF (WIN32)
SET ( GLFW3_LIBRARY_NAME glfw3 )
ELSE ()
SET ( GLFW3_LIBRARY_NAME glfw )
ENDIF()
FIND_LIBRARY ( GLFW3_glfw_LIBRARY ${GLFW3_LIBRARY_NAME} ${GLFW3_LOCATION}/lib
)
ENDIF (GLFW3_USE_STATIC_LIBS)
IF (APPLE)
FIND_LIBRARY ( COCOA_LIBRARY Cocoa )
FIND_LIBRARY ( IOKIT_LIBRARY IOKit )
FIND_LIBRARY ( COREVIDEO_LIBRARY CoreVideo )
ELSEIF (UNIX AND NOT APPLE)
SET ( GLFW3_REQUIRED_X11_LIBRARIES
X11
Xi
Xrandr
Xinerama
Xcursor
Xxf86vm
m
${CMAKE_DL_LIBS}
${CMAKE_THREAD_LIBS_INIT}
)
ENDIF ()
SET ( GLFW3_LIBRARIES
${OPENGL_gl_LIBRARY}
${OPENGL_glu_LIBRARY}
${GLFW3_glfw_LIBRARY}
# UNIX
${GLFW3_REQUIRED_X11_LIBRARIES}
# APPLE
${COCOA_LIBRARY}
${IOKIT_LIBRARY}
${COREVIDEO_LIBRARY}
CACHE STRING "GLFW3 required libraries"
)
ENDIF ()

View File

@@ -12,11 +12,21 @@
#define GLFW_INCLUDE_GLU
#include <GLFW/glfw3.h>
#ifdef _WIN32
#include "../common/trackball.h"
#else
#include "trackball.h"
#endif
#define TINYGLTF_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#ifdef _WIN32
#include "../../tiny_gltf.h"
#else
#include "tiny_gltf.h"
#endif
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
@@ -44,7 +54,9 @@ float eye[3], lookat[3], up[3];
GLFWwindow *window;
typedef struct { GLuint vb; } GLBufferState;
typedef struct {
GLuint vb;
} GLBufferState;
typedef struct {
std::vector<GLuint> diffuseTex; // for each primitive in mesh
@@ -243,6 +255,26 @@ void motionFunc(GLFWwindow *window, double mouse_x, double mouse_y) {
prevMouseY = mouse_y;
}
static size_t ComponentTypeByteSize(int type) {
switch (type) {
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE:
case TINYGLTF_COMPONENT_TYPE_BYTE:
return sizeof(char);
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
case TINYGLTF_COMPONENT_TYPE_SHORT:
return sizeof(short);
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT:
case TINYGLTF_COMPONENT_TYPE_INT:
return sizeof(int);
case TINYGLTF_COMPONENT_TYPE_FLOAT:
return sizeof(float);
case TINYGLTF_COMPONENT_TYPE_DOUBLE:
return sizeof(double);
default:
return 0;
}
}
static void SetupMeshState(tinygltf::Model &model, GLuint progId) {
// Buffer
{
@@ -253,14 +285,117 @@ static void SetupMeshState(tinygltf::Model &model, GLuint progId) {
continue; // Unsupported bufferView.
}
int sparse_accessor = -1;
for (size_t a_i = 0; a_i < model.accessors.size(); ++a_i) {
const auto &accessor = model.accessors[a_i];
if (accessor.bufferView == i) {
std::cout << i << " is used by accessor " << a_i << std::endl;
if (accessor.sparse.isSparse) {
std::cout
<< "WARN: this bufferView has at least one sparse accessor to "
"it. We are going to load the data as patched by this "
"sparse accessor, not the original data"
<< std::endl;
sparse_accessor = a_i;
break;
}
}
}
const tinygltf::Buffer &buffer = model.buffers[bufferView.buffer];
GLBufferState state;
glGenBuffers(1, &state.vb);
glBindBuffer(bufferView.target, state.vb);
std::cout << "buffer.size= " << buffer.data.size()
<< ", byteOffset = " << bufferView.byteOffset << std::endl;
glBufferData(bufferView.target, bufferView.byteLength,
&buffer.data.at(0) + bufferView.byteOffset, GL_STATIC_DRAW);
if (sparse_accessor < 0)
glBufferData(bufferView.target, bufferView.byteLength,
&buffer.data.at(0) + bufferView.byteOffset,
GL_STATIC_DRAW);
else {
const auto accessor = model.accessors[sparse_accessor];
// copy the buffer to a temporary one for sparse patching
unsigned char *tmp_buffer = new unsigned char[bufferView.byteLength];
memcpy(tmp_buffer, buffer.data.data() + bufferView.byteOffset,
bufferView.byteLength);
const size_t size_of_object_in_buffer =
ComponentTypeByteSize(accessor.componentType);
const size_t size_of_sparse_indices =
ComponentTypeByteSize(accessor.sparse.indices.componentType);
const auto &indices_buffer_view =
model.bufferViews[accessor.sparse.indices.bufferView];
const auto &indices_buffer = model.buffers[indices_buffer_view.buffer];
const auto &values_buffer_view =
model.bufferViews[accessor.sparse.values.bufferView];
const auto &values_buffer = model.buffers[values_buffer_view.buffer];
for (size_t sparse_index = 0; sparse_index < accessor.sparse.count;
++sparse_index) {
int index = 0;
// std::cout << "accessor.sparse.indices.componentType = " <<
// accessor.sparse.indices.componentType << std::endl;
switch (accessor.sparse.indices.componentType) {
case TINYGLTF_COMPONENT_TYPE_BYTE:
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE:
index = (int)*(
unsigned char *)(indices_buffer.data.data() +
indices_buffer_view.byteOffset +
accessor.sparse.indices.byteOffset +
(sparse_index * size_of_sparse_indices));
break;
case TINYGLTF_COMPONENT_TYPE_SHORT:
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
index = (int)*(
unsigned short *)(indices_buffer.data.data() +
indices_buffer_view.byteOffset +
accessor.sparse.indices.byteOffset +
(sparse_index * size_of_sparse_indices));
break;
case TINYGLTF_COMPONENT_TYPE_INT:
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT:
index = (int)*(
unsigned int *)(indices_buffer.data.data() +
indices_buffer_view.byteOffset +
accessor.sparse.indices.byteOffset +
(sparse_index * size_of_sparse_indices));
break;
}
std::cout << "updating sparse data at index : " << index
<< std::endl;
// index is now the target of the sparse index to patch in
const unsigned char *read_from =
values_buffer.data.data() +
(values_buffer_view.byteOffset +
accessor.sparse.values.byteOffset) +
(sparse_index * (size_of_object_in_buffer * accessor.type));
/*
std::cout << ((float*)read_from)[0] << "\n";
std::cout << ((float*)read_from)[1] << "\n";
std::cout << ((float*)read_from)[2] << "\n";
*/
unsigned char *write_to =
tmp_buffer + index * (size_of_object_in_buffer * accessor.type);
memcpy(write_to, read_from, size_of_object_in_buffer * accessor.type);
}
// debug:
/*for(size_t p = 0; p < bufferView.byteLength/sizeof(float); p++)
{
float* b = (float*)tmp_buffer;
std::cout << "modified_buffer [" << p << "] = " << b[p] << '\n';
}*/
glBufferData(bufferView.target, bufferView.byteLength, tmp_buffer,
GL_STATIC_DRAW);
delete[] tmp_buffer;
}
glBindBuffer(bufferView.target, 0);
gBufferState[i] = state;
@@ -268,55 +403,55 @@ static void SetupMeshState(tinygltf::Model &model, GLuint progId) {
}
#if 0 // TODO(syoyo): Implement
// Texture
{
for (size_t i = 0; i < model.meshes.size(); i++) {
const tinygltf::Mesh &mesh = model.meshes[i];
// Texture
{
for (size_t i = 0; i < model.meshes.size(); i++) {
const tinygltf::Mesh &mesh = model.meshes[i];
gMeshState[mesh.name].diffuseTex.resize(mesh.primitives.size());
for (size_t primId = 0; primId < mesh.primitives.size(); primId++) {
const tinygltf::Primitive &primitive = mesh.primitives[primId];
gMeshState[mesh.name].diffuseTex.resize(mesh.primitives.size());
for (size_t primId = 0; primId < mesh.primitives.size(); primId++) {
const tinygltf::Primitive &primitive = mesh.primitives[primId];
gMeshState[mesh.name].diffuseTex[primId] = 0;
gMeshState[mesh.name].diffuseTex[primId] = 0;
if (primitive.material < 0) {
continue;
}
tinygltf::Material &mat = model.materials[primitive.material];
// printf("material.name = %s\n", mat.name.c_str());
if (mat.values.find("diffuse") != mat.values.end()) {
std::string diffuseTexName = mat.values["diffuse"].string_value;
if (model.textures.find(diffuseTexName) != model.textures.end()) {
tinygltf::Texture &tex = model.textures[diffuseTexName];
if (scene.images.find(tex.source) != model.images.end()) {
tinygltf::Image &image = model.images[tex.source];
GLuint texId;
glGenTextures(1, &texId);
glBindTexture(tex.target, texId);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameterf(tex.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(tex.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (primitive.material < 0) {
continue;
}
tinygltf::Material &mat = model.materials[primitive.material];
// printf("material.name = %s\n", mat.name.c_str());
if (mat.values.find("diffuse") != mat.values.end()) {
std::string diffuseTexName = mat.values["diffuse"].string_value;
if (model.textures.find(diffuseTexName) != model.textures.end()) {
tinygltf::Texture &tex = model.textures[diffuseTexName];
if (scene.images.find(tex.source) != model.images.end()) {
tinygltf::Image &image = model.images[tex.source];
GLuint texId;
glGenTextures(1, &texId);
glBindTexture(tex.target, texId);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameterf(tex.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(tex.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Ignore Texture.fomat.
GLenum format = GL_RGBA;
if (image.component == 3) {
format = GL_RGB;
}
glTexImage2D(tex.target, 0, tex.internalFormat, image.width,
image.height, 0, format, tex.type,
&image.image.at(0));
// Ignore Texture.fomat.
GLenum format = GL_RGBA;
if (image.component == 3) {
format = GL_RGB;
}
glTexImage2D(tex.target, 0, tex.internalFormat, image.width,
image.height, 0, format, tex.type,
&image.image.at(0));
CheckErrors("texImage2D");
glBindTexture(tex.target, 0);
CheckErrors("texImage2D");
glBindTexture(tex.target, 0);
printf("TexId = %d\n", texId);
gMeshState[mesh.name].diffuseTex[primId] = texId;
}
}
}
}
}
}
printf("TexId = %d\n", texId);
gMeshState[mesh.name].diffuseTex[primId] = texId;
}
}
}
}
}
}
#endif
glUseProgram(progId);
@@ -337,164 +472,164 @@ static void SetupMeshState(tinygltf::Model &model, GLuint progId) {
#if 0 // TODO(syoyo): Implement
// Setup curves geometry extension
static void SetupCurvesState(tinygltf::Scene &scene, GLuint progId) {
// Find curves primitive.
{
std::map<std::string, tinygltf::Mesh>::const_iterator it(
scene.meshes.begin());
std::map<std::string, tinygltf::Mesh>::const_iterator itEnd(
scene.meshes.end());
// Find curves primitive.
{
std::map<std::string, tinygltf::Mesh>::const_iterator it(
scene.meshes.begin());
std::map<std::string, tinygltf::Mesh>::const_iterator itEnd(
scene.meshes.end());
for (; it != itEnd; it++) {
const tinygltf::Mesh &mesh = it->second;
for (; it != itEnd; it++) {
const tinygltf::Mesh &mesh = it->second;
// Currently we only support one primitive per mesh.
if (mesh.primitives.size() > 1) {
continue;
}
// Currently we only support one primitive per mesh.
if (mesh.primitives.size() > 1) {
continue;
}
for (size_t primId = 0; primId < mesh.primitives.size(); primId++) {
const tinygltf::Primitive &primitive = mesh.primitives[primId];
for (size_t primId = 0; primId < mesh.primitives.size(); primId++) {
const tinygltf::Primitive &primitive = mesh.primitives[primId];
gMeshState[mesh.name].diffuseTex[primId] = 0;
gMeshState[mesh.name].diffuseTex[primId] = 0;
if (primitive.material.empty()) {
continue;
}
if (primitive.material.empty()) {
continue;
}
bool has_curves = false;
if (primitive.extras.IsObject()) {
if (primitive.extras.Has("ext_mode")) {
const tinygltf::Value::Object &o =
primitive.extras.Get<tinygltf::Value::Object>();
const tinygltf::Value &ext_mode = o.find("ext_mode")->second;
bool has_curves = false;
if (primitive.extras.IsObject()) {
if (primitive.extras.Has("ext_mode")) {
const tinygltf::Value::Object &o =
primitive.extras.Get<tinygltf::Value::Object>();
const tinygltf::Value &ext_mode = o.find("ext_mode")->second;
if (ext_mode.IsString()) {
const std::string &str = ext_mode.Get<std::string>();
if (str.compare("curves") == 0) {
has_curves = true;
}
}
}
}
if (ext_mode.IsString()) {
const std::string &str = ext_mode.Get<std::string>();
if (str.compare("curves") == 0) {
has_curves = true;
}
}
}
}
if (!has_curves) {
continue;
}
if (!has_curves) {
continue;
}
// Construct curves buffer
const tinygltf::Accessor &vtx_accessor =
scene.accessors[primitive.attributes.find("POSITION")->second];
const tinygltf::Accessor &nverts_accessor =
scene.accessors[primitive.attributes.find("NVERTS")->second];
const tinygltf::BufferView &vtx_bufferView =
scene.bufferViews[vtx_accessor.bufferView];
const tinygltf::BufferView &nverts_bufferView =
scene.bufferViews[nverts_accessor.bufferView];
const tinygltf::Buffer &vtx_buffer =
scene.buffers[vtx_bufferView.buffer];
const tinygltf::Buffer &nverts_buffer =
scene.buffers[nverts_bufferView.buffer];
// Construct curves buffer
const tinygltf::Accessor &vtx_accessor =
scene.accessors[primitive.attributes.find("POSITION")->second];
const tinygltf::Accessor &nverts_accessor =
scene.accessors[primitive.attributes.find("NVERTS")->second];
const tinygltf::BufferView &vtx_bufferView =
scene.bufferViews[vtx_accessor.bufferView];
const tinygltf::BufferView &nverts_bufferView =
scene.bufferViews[nverts_accessor.bufferView];
const tinygltf::Buffer &vtx_buffer =
scene.buffers[vtx_bufferView.buffer];
const tinygltf::Buffer &nverts_buffer =
scene.buffers[nverts_bufferView.buffer];
// std::cout << "vtx_bufferView = " << vtx_accessor.bufferView <<
// std::endl;
// std::cout << "nverts_bufferView = " << nverts_accessor.bufferView <<
// std::endl;
// std::cout << "vtx_buffer.size = " << vtx_buffer.data.size() <<
// std::endl;
// std::cout << "nverts_buffer.size = " << nverts_buffer.data.size() <<
// std::endl;
// std::cout << "vtx_bufferView = " << vtx_accessor.bufferView <<
// std::endl;
// std::cout << "nverts_bufferView = " << nverts_accessor.bufferView <<
// std::endl;
// std::cout << "vtx_buffer.size = " << vtx_buffer.data.size() <<
// std::endl;
// std::cout << "nverts_buffer.size = " << nverts_buffer.data.size() <<
// std::endl;
const int *nverts =
reinterpret_cast<const int *>(nverts_buffer.data.data());
const float *vtx =
reinterpret_cast<const float *>(vtx_buffer.data.data());
const int *nverts =
reinterpret_cast<const int *>(nverts_buffer.data.data());
const float *vtx =
reinterpret_cast<const float *>(vtx_buffer.data.data());
// Convert to GL_LINES data.
std::vector<float> line_pts;
size_t vtx_offset = 0;
for (int k = 0; k < static_cast<int>(nverts_accessor.count); k++) {
for (int n = 0; n < nverts[k] - 1; n++) {
// Convert to GL_LINES data.
std::vector<float> line_pts;
size_t vtx_offset = 0;
for (int k = 0; k < static_cast<int>(nverts_accessor.count); k++) {
for (int n = 0; n < nverts[k] - 1; n++) {
line_pts.push_back(vtx[3 * (vtx_offset + n) + 0]);
line_pts.push_back(vtx[3 * (vtx_offset + n) + 1]);
line_pts.push_back(vtx[3 * (vtx_offset + n) + 2]);
line_pts.push_back(vtx[3 * (vtx_offset + n) + 0]);
line_pts.push_back(vtx[3 * (vtx_offset + n) + 1]);
line_pts.push_back(vtx[3 * (vtx_offset + n) + 2]);
line_pts.push_back(vtx[3 * (vtx_offset + n + 1) + 0]);
line_pts.push_back(vtx[3 * (vtx_offset + n + 1) + 1]);
line_pts.push_back(vtx[3 * (vtx_offset + n + 1) + 2]);
line_pts.push_back(vtx[3 * (vtx_offset + n + 1) + 0]);
line_pts.push_back(vtx[3 * (vtx_offset + n + 1) + 1]);
line_pts.push_back(vtx[3 * (vtx_offset + n + 1) + 2]);
// std::cout << "p0 " << vtx[3 * (vtx_offset + n) + 0] << ", "
// << vtx[3 * (vtx_offset + n) + 1] << ", "
// << vtx[3 * (vtx_offset + n) + 2] << std::endl;
// std::cout << "p0 " << vtx[3 * (vtx_offset + n) + 0] << ", "
// << vtx[3 * (vtx_offset + n) + 1] << ", "
// << vtx[3 * (vtx_offset + n) + 2] << std::endl;
// std::cout << "p1 " << vtx[3 * (vtx_offset + n+1) + 0] << ", "
// << vtx[3 * (vtx_offset + n+1) + 1] << ", "
// << vtx[3 * (vtx_offset + n+1) + 2] << std::endl;
}
// std::cout << "p1 " << vtx[3 * (vtx_offset + n+1) + 0] << ", "
// << vtx[3 * (vtx_offset + n+1) + 1] << ", "
// << vtx[3 * (vtx_offset + n+1) + 2] << std::endl;
}
vtx_offset += nverts[k];
}
vtx_offset += nverts[k];
}
GLCurvesState state;
glGenBuffers(1, &state.vb);
glBindBuffer(GL_ARRAY_BUFFER, state.vb);
glBufferData(GL_ARRAY_BUFFER, line_pts.size() * sizeof(float),
line_pts.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
GLCurvesState state;
glGenBuffers(1, &state.vb);
glBindBuffer(GL_ARRAY_BUFFER, state.vb);
glBufferData(GL_ARRAY_BUFFER, line_pts.size() * sizeof(float),
line_pts.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
state.count = line_pts.size() / 3;
gCurvesMesh[mesh.name] = state;
state.count = line_pts.size() / 3;
gCurvesMesh[mesh.name] = state;
// Material
tinygltf::Material &mat = scene.materials[primitive.material];
// printf("material.name = %s\n", mat.name.c_str());
if (mat.values.find("diffuse") != mat.values.end()) {
std::string diffuseTexName = mat.values["diffuse"].string_value;
if (scene.textures.find(diffuseTexName) != scene.textures.end()) {
tinygltf::Texture &tex = scene.textures[diffuseTexName];
if (scene.images.find(tex.source) != scene.images.end()) {
tinygltf::Image &image = scene.images[tex.source];
GLuint texId;
glGenTextures(1, &texId);
glBindTexture(tex.target, texId);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameterf(tex.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(tex.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Material
tinygltf::Material &mat = scene.materials[primitive.material];
// printf("material.name = %s\n", mat.name.c_str());
if (mat.values.find("diffuse") != mat.values.end()) {
std::string diffuseTexName = mat.values["diffuse"].string_value;
if (scene.textures.find(diffuseTexName) != scene.textures.end()) {
tinygltf::Texture &tex = scene.textures[diffuseTexName];
if (scene.images.find(tex.source) != scene.images.end()) {
tinygltf::Image &image = scene.images[tex.source];
GLuint texId;
glGenTextures(1, &texId);
glBindTexture(tex.target, texId);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameterf(tex.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(tex.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Ignore Texture.fomat.
GLenum format = GL_RGBA;
if (image.component == 3) {
format = GL_RGB;
}
glTexImage2D(tex.target, 0, tex.internalFormat, image.width,
image.height, 0, format, tex.type,
&image.image.at(0));
// Ignore Texture.fomat.
GLenum format = GL_RGBA;
if (image.component == 3) {
format = GL_RGB;
}
glTexImage2D(tex.target, 0, tex.internalFormat, image.width,
image.height, 0, format, tex.type,
&image.image.at(0));
CheckErrors("texImage2D");
glBindTexture(tex.target, 0);
CheckErrors("texImage2D");
glBindTexture(tex.target, 0);
printf("TexId = %d\n", texId);
gMeshState[mesh.name].diffuseTex[primId] = texId;
}
}
}
}
}
}
printf("TexId = %d\n", texId);
gMeshState[mesh.name].diffuseTex[primId] = texId;
}
}
}
}
}
}
glUseProgram(progId);
GLint vtloc = glGetAttribLocation(progId, "in_vertex");
GLint nrmloc = glGetAttribLocation(progId, "in_normal");
GLint uvloc = glGetAttribLocation(progId, "in_texcoord");
glUseProgram(progId);
GLint vtloc = glGetAttribLocation(progId, "in_vertex");
GLint nrmloc = glGetAttribLocation(progId, "in_normal");
GLint uvloc = glGetAttribLocation(progId, "in_texcoord");
GLint diffuseTexLoc = glGetUniformLocation(progId, "diffuseTex");
GLint isCurvesLoc = glGetUniformLocation(progId, "uIsCurves");
GLint diffuseTexLoc = glGetUniformLocation(progId, "diffuseTex");
GLint isCurvesLoc = glGetUniformLocation(progId, "uIsCurves");
gGLProgramState.attribs["POSITION"] = vtloc;
gGLProgramState.attribs["NORMAL"] = nrmloc;
gGLProgramState.attribs["TEXCOORD_0"] = uvloc;
gGLProgramState.uniforms["diffuseTex"] = diffuseTexLoc;
gGLProgramState.uniforms["uIsCurves"] = isCurvesLoc;
gGLProgramState.attribs["POSITION"] = vtloc;
gGLProgramState.attribs["NORMAL"] = nrmloc;
gGLProgramState.attribs["TEXCOORD_0"] = uvloc;
gGLProgramState.uniforms["diffuseTex"] = diffuseTexLoc;
gGLProgramState.uniforms["uIsCurves"] = isCurvesLoc;
};
#endif
@@ -547,12 +682,13 @@ static void DrawMesh(tinygltf::Model &model, const tinygltf::Mesh &mesh) {
(it->first.compare("TEXCOORD_0") == 0)) {
if (gGLProgramState.attribs[it->first] >= 0) {
// Compute byteStride from Accessor + BufferView combination.
int byteStride = accessor.ByteStride(model.bufferViews[accessor.bufferView]);
int byteStride =
accessor.ByteStride(model.bufferViews[accessor.bufferView]);
assert(byteStride != -1);
glVertexAttribPointer(gGLProgramState.attribs[it->first], size,
accessor.componentType, accessor.normalized ? GL_TRUE : GL_FALSE,
byteStride,
BUFFER_OFFSET(accessor.byteOffset));
accessor.componentType,
accessor.normalized ? GL_TRUE : GL_FALSE,
byteStride, BUFFER_OFFSET(accessor.byteOffset));
CheckErrors("vertex attrib pointer");
glEnableVertexAttribArray(gGLProgramState.attribs[it->first]);
CheckErrors("enable vertex attrib array");
@@ -606,32 +742,32 @@ static void DrawMesh(tinygltf::Model &model, const tinygltf::Mesh &mesh) {
#if 0 // TODO(syoyo): Implement
static void DrawCurves(tinygltf::Scene &scene, const tinygltf::Mesh &mesh) {
(void)scene;
(void)scene;
if (gCurvesMesh.find(mesh.name) == gCurvesMesh.end()) {
return;
}
if (gCurvesMesh.find(mesh.name) == gCurvesMesh.end()) {
return;
}
if (gGLProgramState.uniforms["isCurvesLoc"] >= 0) {
glUniform1i(gGLProgramState.uniforms["isCurvesLoc"], 1);
}
if (gGLProgramState.uniforms["isCurvesLoc"] >= 0) {
glUniform1i(gGLProgramState.uniforms["isCurvesLoc"], 1);
}
GLCurvesState &state = gCurvesMesh[mesh.name];
GLCurvesState &state = gCurvesMesh[mesh.name];
if (gGLProgramState.attribs["POSITION"] >= 0) {
glBindBuffer(GL_ARRAY_BUFFER, state.vb);
glVertexAttribPointer(gGLProgramState.attribs["POSITION"], 3, GL_FLOAT,
GL_FALSE, /* stride */ 0, BUFFER_OFFSET(0));
CheckErrors("curve: vertex attrib pointer");
glEnableVertexAttribArray(gGLProgramState.attribs["POSITION"]);
CheckErrors("curve: enable vertex attrib array");
}
if (gGLProgramState.attribs["POSITION"] >= 0) {
glBindBuffer(GL_ARRAY_BUFFER, state.vb);
glVertexAttribPointer(gGLProgramState.attribs["POSITION"], 3, GL_FLOAT,
GL_FALSE, /* stride */ 0, BUFFER_OFFSET(0));
CheckErrors("curve: vertex attrib pointer");
glEnableVertexAttribArray(gGLProgramState.attribs["POSITION"]);
CheckErrors("curve: enable vertex attrib array");
}
glDrawArrays(GL_LINES, 0, state.count);
glDrawArrays(GL_LINES, 0, state.count);
if (gGLProgramState.attribs["POSITION"] >= 0) {
glDisableVertexAttribArray(gGLProgramState.attribs["POSITION"]);
}
if (gGLProgramState.attribs["POSITION"] >= 0) {
glDisableVertexAttribArray(gGLProgramState.attribs["POSITION"]);
}
}
#endif
@@ -666,10 +802,14 @@ static void DrawNode(tinygltf::Model &model, const tinygltf::Node &node) {
// std::cout << it->first << std::endl;
// FIXME(syoyo): Refactor.
// DrawCurves(scene, it->second);
DrawMesh(model, model.meshes[node.mesh]);
if (node.mesh > -1) {
assert(node.mesh < model.meshes.size());
DrawMesh(model, model.meshes[node.mesh]);
}
// Draw child nodes.
for (size_t i = 0; i < node.children.size(); i++) {
assert(node.children[i] < model.nodes.size());
DrawNode(model, model.nodes[node.children[i]]);
}
@@ -678,18 +818,19 @@ static void DrawNode(tinygltf::Model &model, const tinygltf::Node &node) {
static void DrawModel(tinygltf::Model &model) {
#if 0
std::map<std::string, tinygltf::Mesh>::const_iterator it(scene.meshes.begin());
std::map<std::string, tinygltf::Mesh>::const_iterator itEnd(scene.meshes.end());
std::map<std::string, tinygltf::Mesh>::const_iterator it(scene.meshes.begin());
std::map<std::string, tinygltf::Mesh>::const_iterator itEnd(scene.meshes.end());
for (; it != itEnd; it++) {
DrawMesh(scene, it->second);
DrawCurves(scene, it->second);
}
for (; it != itEnd; it++) {
DrawMesh(scene, it->second);
DrawCurves(scene, it->second);
}
#else
// TODO(syoyo): Support non-default scenes.
assert(model.defaultScene >= 0);
const tinygltf::Scene &scene = model.scenes[model.defaultScene];
// If the glTF asset has at least one scene, and doesn't define a default one
// just show the first one we can find
assert(model.scenes.size() > 0);
int scene_to_display = model.defaultScene > -1 ? model.defaultScene : 0;
const tinygltf::Scene &scene = model.scenes[scene_to_display];
for (size_t i = 0; i < scene.nodes.size(); i++) {
DrawNode(model, model.nodes[scene.nodes[i]]);
}
@@ -720,8 +861,8 @@ static void PrintNodes(const tinygltf::Scene &scene) {
int main(int argc, char **argv) {
if (argc < 2) {
std::cout << "glview input.gltf <scale>\n" << std::endl;
return 0;
std::cout << "glview input.gltf <scale>" << std::endl;
std::cout << "defaulting to example cube model" << std::endl;
}
float scale = 1.0f;
@@ -732,16 +873,31 @@ int main(int argc, char **argv) {
tinygltf::Model model;
tinygltf::TinyGLTF loader;
std::string err;
std::string input_filename(argv[1]);
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, input_filename.c_str());
ret =
loader.LoadBinaryFromFile(&model, &err, &warn, input_filename.c_str());
} else {
// assume ascii glTF.
ret = loader.LoadASCIIFromFile(&model, &err, input_filename.c_str());
ret = loader.LoadASCIIFromFile(&model, &err, &warn, input_filename.c_str());
}
if (!warn.empty()) {
printf("Warn: %s\n", warn.c_str());
}
if (!err.empty()) {
@@ -755,17 +911,19 @@ int main(int argc, char **argv) {
Init();
// DBG
PrintNodes(model.scenes[model.defaultScene]);
PrintNodes(model.scenes[model.defaultScene > -1 ? model.defaultScene : 0]);
if (!glfwInit()) {
std::cerr << "Failed to initialize GLFW." << std::endl;
return -1;
}
char title[1024];
sprintf(title, "Simple glTF viewer: %s", input_filename.c_str());
std::stringstream ss;
ss << "Simple glTF viewer: " << input_filename;
window = glfwCreateWindow(width, height, title, NULL, NULL);
std::string title = ss.str();
window = glfwCreateWindow(width, height, title.c_str(), NULL, NULL);
if (window == NULL) {
std::cerr << "Failed to open GLFW window. " << std::endl;
glfwTerminate();
@@ -791,12 +949,23 @@ int main(int argc, char **argv) {
reshapeFunc(window, width, height);
GLuint vertId = 0, fragId = 0, progId = 0;
if (false == LoadShader(GL_VERTEX_SHADER, vertId, "shader.vert")) {
#ifdef _WIN32
#ifdef _DEBUG
const char *shader_frag_filename = "../shader.frag";
const char *shader_vert_filename = "../shader.vert";
#endif
#else
const char *shader_frag_filename = "shader.frag";
const char *shader_vert_filename = "shader.vert";
#endif
if (false == LoadShader(GL_VERTEX_SHADER, vertId, shader_vert_filename)) {
return -1;
}
CheckErrors("load vert shader");
if (false == LoadShader(GL_FRAGMENT_SHADER, fragId, "shader.frag")) {
if (false == LoadShader(GL_FRAGMENT_SHADER, fragId, shader_frag_filename)) {
return -1;
}
CheckErrors("load frag shader");

View File

@@ -0,0 +1,31 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28010.2050
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glview", "glview\glview.vcxproj", "{D078BB24-377E-497B-8045-03AF2A0547ED}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D078BB24-377E-497B-8045-03AF2A0547ED}.Debug|x64.ActiveCfg = Debug|x64
{D078BB24-377E-497B-8045-03AF2A0547ED}.Debug|x64.Build.0 = Debug|x64
{D078BB24-377E-497B-8045-03AF2A0547ED}.Debug|x86.ActiveCfg = Debug|Win32
{D078BB24-377E-497B-8045-03AF2A0547ED}.Debug|x86.Build.0 = Debug|Win32
{D078BB24-377E-497B-8045-03AF2A0547ED}.Release|x64.ActiveCfg = Release|x64
{D078BB24-377E-497B-8045-03AF2A0547ED}.Release|x64.Build.0 = Release|x64
{D078BB24-377E-497B-8045-03AF2A0547ED}.Release|x86.ActiveCfg = Release|Win32
{D078BB24-377E-497B-8045-03AF2A0547ED}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DB7C2F91-06C9-4BD8-95BF-04814E0C62DA}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,152 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{D078BB24-377E-497B-8045-03AF2A0547ED}</ProjectGuid>
<RootNamespace>glview</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies);opengl32.lib;glu32.lib</AdditionalDependencies>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies);opengl32.lib;glu32.lib</AdditionalDependencies>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies);opengl32.lib;glu32.lib</AdditionalDependencies>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies);opengl32.lib;glu32.lib</AdditionalDependencies>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\common\trackball.cc" />
<ClCompile Include="..\glview.cc" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\nupengl.core.redist.0.1.0.1\build\native\nupengl.core.redist.targets" Condition="Exists('..\packages\nupengl.core.redist.0.1.0.1\build\native\nupengl.core.redist.targets')" />
<Import Project="..\packages\nupengl.core.0.1.0.1\build\native\nupengl.core.targets" Condition="Exists('..\packages\nupengl.core.0.1.0.1\build\native\nupengl.core.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\nupengl.core.redist.0.1.0.1\build\native\nupengl.core.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\nupengl.core.redist.0.1.0.1\build\native\nupengl.core.redist.targets'))" />
<Error Condition="!Exists('..\packages\nupengl.core.0.1.0.1\build\native\nupengl.core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\nupengl.core.0.1.0.1\build\native\nupengl.core.targets'))" />
</Target>
</Project>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\glview.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\common\trackball.cc">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="nupengl.core" version="0.1.0.1" targetFramework="native" />
<package id="nupengl.core.redist" version="0.1.0.1" targetFramework="native" />
</packages>

View File

@@ -8,9 +8,10 @@ solution "glview"
kind "ConsoleApp"
language "C++"
cppdialect "C++11"
files { "glview.cc", "trackball.cc" }
files { "glview.cc", "../common/trackball.cc" }
includedirs { "./" }
includedirs { "../../" }
includedirs { "../common/" }
configuration { "linux" }
linkoptions { "`pkg-config --libs glfw3`" }

View File

@@ -1,292 +0,0 @@
/*
* (c) Copyright 1993, 1994, Silicon Graphics, Inc.
* ALL RIGHTS RESERVED
* Permission to use, copy, modify, and distribute this software for
* any purpose and without fee is hereby granted, provided that the above
* copyright notice appear in all copies and that both the copyright notice
* and this permission notice appear in supporting documentation, and that
* the name of Silicon Graphics, Inc. not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission.
*
* THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
* AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
* GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
* SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
* KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
* LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
* THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
* POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
*
* US Government Users Restricted Rights
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
* (c)(1)(ii) of the Rights in Technical Data and Computer Software
* clause at DFARS 252.227-7013 and/or in similar or successor
* clauses in the FAR or the DOD or NASA FAR Supplement.
* Unpublished-- rights reserved under the copyright laws of the
* United States. Contractor/manufacturer is Silicon Graphics,
* Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
*
* OpenGL(TM) is a trademark of Silicon Graphics, Inc.
*/
/*
* Trackball code:
*
* Implementation of a virtual trackball.
* Implemented by Gavin Bell, lots of ideas from Thant Tessman and
* the August '88 issue of Siggraph's "Computer Graphics," pp. 121-129.
*
* Vector manip code:
*
* Original code from:
* David M. Ciemiewicz, Mark Grossman, Henry Moreton, and Paul Haeberli
*
* Much mucking with by:
* Gavin Bell
*/
#include <math.h>
#include "trackball.h"
/*
* This size should really be based on the distance from the center of
* rotation to the point on the object underneath the mouse. That
* point would then track the mouse as closely as possible. This is a
* simple example, though, so that is left as an Exercise for the
* Programmer.
*/
#define TRACKBALLSIZE (0.8)
/*
* Local function prototypes (not defined in trackball.h)
*/
static float tb_project_to_sphere(float, float, float);
static void normalize_quat(float[4]);
static void vzero(float *v) {
v[0] = 0.0;
v[1] = 0.0;
v[2] = 0.0;
}
static void vset(float *v, float x, float y, float z) {
v[0] = x;
v[1] = y;
v[2] = z;
}
static void vsub(const float *src1, const float *src2, float *dst) {
dst[0] = src1[0] - src2[0];
dst[1] = src1[1] - src2[1];
dst[2] = src1[2] - src2[2];
}
static void vcopy(const float *v1, float *v2) {
register int i;
for (i = 0; i < 3; i++)
v2[i] = v1[i];
}
static void vcross(const float *v1, const float *v2, float *cross) {
float temp[3];
temp[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]);
temp[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]);
temp[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]);
vcopy(temp, cross);
}
static float vlength(const float *v) {
return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
}
static void vscale(float *v, float div) {
v[0] *= div;
v[1] *= div;
v[2] *= div;
}
static void vnormal(float *v) { vscale(v, 1.0 / vlength(v)); }
static float vdot(const float *v1, const float *v2) {
return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
}
static void vadd(const float *src1, const float *src2, float *dst) {
dst[0] = src1[0] + src2[0];
dst[1] = src1[1] + src2[1];
dst[2] = src1[2] + src2[2];
}
/*
* Ok, simulate a track-ball. Project the points onto the virtual
* trackball, then figure out the axis of rotation, which is the cross
* product of P1 P2 and O P1 (O is the center of the ball, 0,0,0)
* Note: This is a deformed trackball-- is a trackball in the center,
* but is deformed into a hyperbolic sheet of rotation away from the
* center. This particular function was chosen after trying out
* several variations.
*
* It is assumed that the arguments to this routine are in the range
* (-1.0 ... 1.0)
*/
void trackball(float q[4], float p1x, float p1y, float p2x, float p2y) {
float a[3]; /* Axis of rotation */
float phi; /* how much to rotate about axis */
float p1[3], p2[3], d[3];
float t;
if (p1x == p2x && p1y == p2y) {
/* Zero rotation */
vzero(q);
q[3] = 1.0;
return;
}
/*
* First, figure out z-coordinates for projection of P1 and P2 to
* deformed sphere
*/
vset(p1, p1x, p1y, tb_project_to_sphere(TRACKBALLSIZE, p1x, p1y));
vset(p2, p2x, p2y, tb_project_to_sphere(TRACKBALLSIZE, p2x, p2y));
/*
* Now, we want the cross product of P1 and P2
*/
vcross(p2, p1, a);
/*
* Figure out how much to rotate around that axis.
*/
vsub(p1, p2, d);
t = vlength(d) / (2.0 * TRACKBALLSIZE);
/*
* Avoid problems with out-of-control values...
*/
if (t > 1.0)
t = 1.0;
if (t < -1.0)
t = -1.0;
phi = 2.0 * asin(t);
axis_to_quat(a, phi, q);
}
/*
* Given an axis and angle, compute quaternion.
*/
void axis_to_quat(float a[3], float phi, float q[4]) {
vnormal(a);
vcopy(a, q);
vscale(q, sin(phi / 2.0));
q[3] = cos(phi / 2.0);
}
/*
* Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet
* if we are away from the center of the sphere.
*/
static float tb_project_to_sphere(float r, float x, float y) {
float d, t, z;
d = sqrt(x * x + y * y);
if (d < r * 0.70710678118654752440) { /* Inside sphere */
z = sqrt(r * r - d * d);
} else { /* On hyperbola */
t = r / 1.41421356237309504880;
z = t * t / d;
}
return z;
}
/*
* Given two rotations, e1 and e2, expressed as quaternion rotations,
* figure out the equivalent single rotation and stuff it into dest.
*
* This routine also normalizes the result every RENORMCOUNT times it is
* called, to keep error from creeping in.
*
* NOTE: This routine is written so that q1 or q2 may be the same
* as dest (or each other).
*/
#define RENORMCOUNT 97
void add_quats(float q1[4], float q2[4], float dest[4]) {
static int count = 0;
float t1[4], t2[4], t3[4];
float tf[4];
vcopy(q1, t1);
vscale(t1, q2[3]);
vcopy(q2, t2);
vscale(t2, q1[3]);
vcross(q2, q1, t3);
vadd(t1, t2, tf);
vadd(t3, tf, tf);
tf[3] = q1[3] * q2[3] - vdot(q1, q2);
dest[0] = tf[0];
dest[1] = tf[1];
dest[2] = tf[2];
dest[3] = tf[3];
if (++count > RENORMCOUNT) {
count = 0;
normalize_quat(dest);
}
}
/*
* Quaternions always obey: a^2 + b^2 + c^2 + d^2 = 1.0
* If they don't add up to 1.0, dividing by their magnitued will
* renormalize them.
*
* Note: See the following for more information on quaternions:
*
* - Shoemake, K., Animating rotation with quaternion curves, Computer
* Graphics 19, No 3 (Proc. SIGGRAPH'85), 245-254, 1985.
* - Pletinckx, D., Quaternion calculus as a basic tool in computer
* graphics, The Visual Computer 5, 2-13, 1989.
*/
static void normalize_quat(float q[4]) {
int i;
float mag;
mag = (q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]);
for (i = 0; i < 4; i++)
q[i] /= mag;
}
/*
* Build a rotation matrix, given a quaternion rotation.
*
*/
void build_rotmatrix(float m[4][4], const float q[4]) {
m[0][0] = 1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]);
m[0][1] = 2.0 * (q[0] * q[1] - q[2] * q[3]);
m[0][2] = 2.0 * (q[2] * q[0] + q[1] * q[3]);
m[0][3] = 0.0;
m[1][0] = 2.0 * (q[0] * q[1] + q[2] * q[3]);
m[1][1] = 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0]);
m[1][2] = 2.0 * (q[1] * q[2] - q[0] * q[3]);
m[1][3] = 0.0;
m[2][0] = 2.0 * (q[2] * q[0] - q[1] * q[3]);
m[2][1] = 2.0 * (q[1] * q[2] + q[0] * q[3]);
m[2][2] = 1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0]);
m[2][3] = 0.0;
m[3][0] = 0.0;
m[3][1] = 0.0;
m[3][2] = 0.0;
m[3][3] = 1.0;
}

View File

@@ -1,75 +0,0 @@
/*
* (c) Copyright 1993, 1994, Silicon Graphics, Inc.
* ALL RIGHTS RESERVED
* Permission to use, copy, modify, and distribute this software for
* any purpose and without fee is hereby granted, provided that the above
* copyright notice appear in all copies and that both the copyright notice
* and this permission notice appear in supporting documentation, and that
* the name of Silicon Graphics, Inc. not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission.
*
* THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
* AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
* GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
* SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
* KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
* LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
* THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
* POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
*
* US Government Users Restricted Rights
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
* (c)(1)(ii) of the Rights in Technical Data and Computer Software
* clause at DFARS 252.227-7013 and/or in similar or successor
* clauses in the FAR or the DOD or NASA FAR Supplement.
* Unpublished-- rights reserved under the copyright laws of the
* United States. Contractor/manufacturer is Silicon Graphics,
* Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
*
* OpenGL(TM) is a trademark of Silicon Graphics, Inc.
*/
/*
* trackball.h
* A virtual trackball implementation
* Written by Gavin Bell for Silicon Graphics, November 1988.
*/
/*
* Pass the x and y coordinates of the last and current positions of
* the mouse, scaled so they are from (-1.0 ... 1.0).
*
* The resulting rotation is returned as a quaternion rotation in the
* first paramater.
*/
void trackball(float q[4], float p1x, float p1y, float p2x, float p2y);
void negate_quat(float *q, float *qn);
/*
* Given two quaternions, add them together to get a third quaternion.
* Adding quaternions to get a compound rotation is analagous to adding
* translations to get a compound translation. When incrementally
* adding rotations, the first argument here should be the new
* rotation, the second and third the total rotation (which will be
* over-written with the resulting new total rotation).
*/
void add_quats(float *q1, float *q2, float *dest);
/*
* A useful function, builds a rotation matrix in Matrix based on
* given quaternion.
*/
void build_rotmatrix(float m[4][4], const float q[4]);
/*
* This function computes a quaternion based on an axis (defined by
* the given vector) and an angle about which to rotate. The angle is
* expressed in radians. The result is put into the third argument.
*/
void axis_to_quat(float a[3], float phi, float q[4]);

View File

@@ -26,15 +26,20 @@ bool LoadGLTF(const std::string &filename, float scale,
tinygltf::Model model;
tinygltf::TinyGLTF loader;
std::string err;
std::string warn;
const std::string ext = GetFilePathExtension(filename);
bool ret = false;
if (ext.compare("glb") == 0) {
// assume binary glTF.
ret = loader.LoadBinaryFromFile(&model, &err, filename.c_str());
ret = loader.LoadBinaryFromFile(&model, &err, &warn, filename.c_str());
} else {
// assume ascii glTF.
ret = loader.LoadASCIIFromFile(&model, &err, filename.c_str());
ret = loader.LoadASCIIFromFile(&model, &err, &warn, filename.c_str());
}
if (!warn.empty()) {
std::cout << "glTF parse warning: " << warn << std::endl;
}
if (!err.empty()) {
@@ -293,7 +298,7 @@ bool LoadGLTF(const std::string &filename, float scale,
loadedMesh.facevarying_normals.push_back(n1.x);
loadedMesh.facevarying_normals.push_back(n1.y);
loadedMesh.facevarying_normals.push_back(n2.z);
loadedMesh.facevarying_normals.push_back(n1.z);
loadedMesh.facevarying_normals.push_back(n2.x);
loadedMesh.facevarying_normals.push_back(n2.y);
@@ -328,7 +333,7 @@ bool LoadGLTF(const std::string &filename, float scale,
loadedMesh.facevarying_normals.push_back(n1.x);
loadedMesh.facevarying_normals.push_back(n1.y);
loadedMesh.facevarying_normals.push_back(n2.z);
loadedMesh.facevarying_normals.push_back(n1.z);
loadedMesh.facevarying_normals.push_back(n2.x);
loadedMesh.facevarying_normals.push_back(n2.y);

View File

@@ -25,13 +25,17 @@ int main(int argc, char *argv[]) {
tinygltf::Model model;
tinygltf::TinyGLTF loader;
std::string err;
std::string warn;
std::string input_filename(argv[1]);
std::string output_filename(argv[2]);
std::string embedded_filename =
output_filename.substr(0, output_filename.size() - 5) + "-Embedded.gltf";
// assume ascii glTF.
bool ret = loader.LoadASCIIFromFile(&model, &err, input_filename.c_str());
bool ret = loader.LoadASCIIFromFile(&model, &err, &warn, input_filename.c_str());
if (!warn.empty()) {
std::cout << "warn : " << warn << std::endl;
}
if (!ret) {
if (!err.empty()) {
std::cerr << err << std::endl;

View File

@@ -45,3 +45,9 @@ endif()
# test-zone
# enable_testing()
install ( TARGETS
tinygltf-validator
DESTINATION
bin
)

15
experimental/README.md Normal file
View File

@@ -0,0 +1,15 @@
# Python script which generates C++11 code from JSON schema.
## Requirements
* python3
* jsonref
## Generate
Run `gen.py` by specifing the path to glTF schema directory(from https://github.com/KhronosGroup/glTF.git)
```
$ python gen.py /path/to/glTF/specification/2.0/schema
```

34
experimental/gen.py Normal file
View File

@@ -0,0 +1,34 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys, os
import subprocess
import json
from pprint import pprint
import jsonref
# glTF 2.0
schema_files = [
"glTF.schema.json"
]
def main():
if len(sys.argv) < 2:
print("Requires path to glTF scheme directory.")
sys.exit(-1)
gltf_schema_dir = sys.argv[1]
gltf_schema_filepath = os.path.join(gltf_schema_dir, schema_files[0])
if not os.path.exists(gltf_schema_filepath):
print("File not found: {}".format(gltf_schema_filepath))
sys.exit(-1)
gltf_schema_uri = 'file://{}/'.format(gltf_schema_dir)
with open(gltf_schema_filepath) as schema_file:
j = jsonref.loads(schema_file.read(), base_uri=gltf_schema_uri, jsonschema=True)
pprint(j)
main()

12480
json.hpp

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,6 @@
//
// TODO(syoyo): Print extensions and extras for each glTF object.
//
#define TINYGLTF_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
@@ -225,7 +228,8 @@ static std::string PrintParameterMap(const tinygltf::ParameterMap &pmap) {
#endif
static std::string PrintValue(const std::string &name,
const tinygltf::Value &value, const int indent) {
const tinygltf::Value &value, const int indent,
const bool tag = true) {
std::stringstream ss;
if (value.IsObject()) {
@@ -233,19 +237,44 @@ static std::string PrintValue(const std::string &name,
tinygltf::Value::Object::const_iterator it(o.begin());
tinygltf::Value::Object::const_iterator itEnd(o.end());
for (; it != itEnd; it++) {
ss << PrintValue(name, it->second, indent + 1);
ss << PrintValue(it->first, it->second, indent + 1) << std::endl;
}
} else if (value.IsString()) {
ss << Indent(indent) << name << " : " << value.Get<std::string>()
<< std::endl;
if (tag) {
ss << Indent(indent) << name << " : " << value.Get<std::string>();
} else {
ss << " " << value.Get<std::string>() << " ";
}
} else if (value.IsBool()) {
ss << Indent(indent) << name << " : " << value.Get<bool>() << std::endl;
if (tag) {
ss << Indent(indent) << name << " : " << value.Get<bool>();
} else {
ss << " " << value.Get<bool>() << " ";
}
} else if (value.IsNumber()) {
ss << Indent(indent) << name << " : " << value.Get<double>() << std::endl;
if (tag) {
ss << Indent(indent) << name << " : " << value.Get<double>();
} else {
ss << " " << value.Get<double>() << " ";
}
} else if (value.IsInt()) {
ss << Indent(indent) << name << " : " << value.Get<int>() << std::endl;
if (tag) {
ss << Indent(indent) << name << " : " << value.Get<int>();
} else {
ss << " " << value.Get<int>() << " ";
}
} else if (value.IsArray()) {
ss << Indent(indent) << name << " [ ";
for (size_t i = 0; i < value.Size(); i++) {
ss << PrintValue("", value.Get(int(i)), indent + 1, /* tag */ false);
if (i != (value.ArrayLen() - 1)) {
ss << ", ";
}
}
ss << Indent(indent) << "] ";
}
// @todo { binary, array }
// @todo { binary }
return ss.str();
}
@@ -301,13 +330,13 @@ static void DumpPrimitive(const tinygltf::Primitive &primitive, int indent) {
<< PrintValue("extras", primitive.extras, indent + 1) << std::endl;
}
static void DumpExtensions(const tinygltf::ExtensionMap &extension, const int indent)
{
// TODO(syoyo): Print extensions
static void DumpExtensions(const tinygltf::ExtensionMap &extension,
const int indent) {
// TODO(syoyo): pritty print Value
for (auto &e : extension) {
std::cout << Indent(indent) << e.first << std::endl;
//std::cout << Indent(indent+1) << PrintParameterMap(e.second);
}
std::cout << PrintValue("extensions", e.second, indent + 1) << std::endl;
}
}
static void Dump(const tinygltf::Model &model) {
@@ -368,7 +397,7 @@ static void Dump(const tinygltf::Model &model) {
std::cout << Indent(2) << "min : [";
for (size_t k = 0; k < accessor.minValues.size(); k++) {
std::cout << accessor.minValues[k]
<< ((i != accessor.minValues.size() - 1) ? ", " : "");
<< ((k != accessor.minValues.size() - 1) ? ", " : "");
}
std::cout << "]" << std::endl;
}
@@ -376,10 +405,34 @@ static void Dump(const tinygltf::Model &model) {
std::cout << Indent(2) << "max : [";
for (size_t k = 0; k < accessor.maxValues.size(); k++) {
std::cout << accessor.maxValues[k]
<< ((i != accessor.maxValues.size() - 1) ? ", " : "");
<< ((k != accessor.maxValues.size() - 1) ? ", " : "");
}
std::cout << "]" << std::endl;
}
if (accessor.sparse.isSparse) {
std::cout << Indent(2) << "sparse:" << std::endl;
std::cout << Indent(3) << "count : " << accessor.sparse.count
<< std::endl;
std::cout << Indent(3) << "indices: " << std::endl;
std::cout << Indent(4)
<< "bufferView : " << accessor.sparse.indices.bufferView
<< std::endl;
std::cout << Indent(4)
<< "byteOffset : " << accessor.sparse.indices.byteOffset
<< std::endl;
std::cout << Indent(4) << "componentType: "
<< PrintComponentType(accessor.sparse.indices.componentType)
<< "(" << accessor.sparse.indices.componentType << ")"
<< std::endl;
std::cout << Indent(3) << "values : " << std::endl;
std::cout << Indent(4)
<< "bufferView : " << accessor.sparse.values.bufferView
<< std::endl;
std::cout << Indent(4)
<< "byteOffset : " << accessor.sparse.values.byteOffset
<< std::endl;
}
}
}
@@ -488,6 +541,7 @@ static void Dump(const tinygltf::Model &model) {
std::cout << Indent(2) << "width : " << image.width << std::endl;
std::cout << Indent(2) << "height : " << image.height << std::endl;
std::cout << Indent(2) << "component : " << image.component << std::endl;
DumpExtensions(image.extensions, 1);
}
}
@@ -499,6 +553,7 @@ static void Dump(const tinygltf::Model &model) {
<< std::endl;
std::cout << Indent(1) << "source : " << texture.source
<< std::endl;
DumpExtensions(texture.extensions, 1);
}
}
@@ -554,10 +609,11 @@ static void Dump(const tinygltf::Model &model) {
}
}
}
// toplevel extensions
{
std::cout << "extensions(items=" << model.extensions.size() << ")" << std::endl;
std::cout << "extensions(items=" << model.extensions.size() << ")"
<< std::endl;
DumpExtensions(model.extensions, 1);
}
}
@@ -571,6 +627,7 @@ int main(int argc, char **argv) {
tinygltf::Model model;
tinygltf::TinyGLTF gltf_ctx;
std::string err;
std::string warn;
std::string input_filename(argv[1]);
std::string ext = GetFilePathExtension(input_filename);
@@ -578,11 +635,17 @@ int main(int argc, char **argv) {
if (ext.compare("glb") == 0) {
std::cout << "Reading binary glTF" << std::endl;
// assume binary glTF.
ret = gltf_ctx.LoadBinaryFromFile(&model, &err, input_filename.c_str());
ret = gltf_ctx.LoadBinaryFromFile(&model, &err, &warn,
input_filename.c_str());
} else {
std::cout << "Reading ASCII glTF" << std::endl;
// assume ascii glTF.
ret = gltf_ctx.LoadASCIIFromFile(&model, &err, input_filename.c_str());
ret =
gltf_ctx.LoadASCIIFromFile(&model, &err, &warn, input_filename.c_str());
}
if (!warn.empty()) {
printf("Warn: %s\n", warn.c_str());
}
if (!err.empty()) {

View File

@@ -0,0 +1,66 @@
{
"scenes" : [
{
"nodes" : [ 0 ]
}
],
"nodes" : [
{
"mesh" : 0
}
],
"meshes" : [
{
"primitives" : [ {
"attributes" : {
"POSITION" : 0
}
} ]
}
],
"buffers" : [
{
"uri" : "data:application/octet-stream;base64,AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAA",
"byteLength" : 36
}
],
"bufferViews" : [
{
"buffer" : 0,
"byteOffset" : 0,
"byteLength" : 36,
"target" : 34962
}
],
"accessors" : [
{
"bufferView" : 0,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 3,
"type" : "VEC3",
"max" : [ 1.0, 1.0, 0.0 ],
"min" : [ 0.0, 0.0, 0.0 ]
}
],
"asset" : {
"version" : "2.0"
},
"materials" : [
{ "name" : "WHITE",
"extensions": {
"VENDOR_material_some_ext" : { }
}
}
],
"extensionsUsed" : [
"VENDOR_material_some_ext"
]
}

BIN
models/box01.glb Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -14,6 +14,7 @@ import subprocess
sample_model_dir = "/home/syoyo/work/glTF-Sample-Models"
base_model_dir = os.path.join(sample_model_dir, "2.0")
# Include `glTF-Draco` when you build `loader_example` with draco support.
kinds = [ "glTF", "glTF-Binary", "glTF-Embedded", "glTF-MaterialsCommon"]
# ---------------------------------
@@ -28,7 +29,7 @@ def run(filename):
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = p.communicate()
except:
print "Failed to execute: ", cmd
print("Failed to execute: ", cmd)
raise
if p.returncode != 0:

View File

@@ -1,5 +1,6 @@
#define TINYGLTF_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "tiny_gltf.h"
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
@@ -17,10 +18,71 @@ TEST_CASE("parse-error", "[parse]") {
tinygltf::Model model;
tinygltf::TinyGLTF ctx;
std::string err;
std::string warn;
bool ret = ctx.LoadASCIIFromString(&model, &err, "bora", strlen("bora"), /* basedir*/ "");
bool ret = ctx.LoadASCIIFromString(&model, &err, &warn, "bora", strlen("bora"), /* basedir*/ "");
REQUIRE(false == ret);
}
TEST_CASE("datauri-in-glb", "[issue-79]") {
tinygltf::Model model;
tinygltf::TinyGLTF ctx;
std::string err;
std::string warn;
bool ret = ctx.LoadBinaryFromFile(&model, &err, &warn, "../models/box01.glb");
if (!err.empty()) {
std::cerr << err << std::endl;
}
REQUIRE(true == ret);
}
TEST_CASE("extension-with-empty-object", "[issue-97]") {
tinygltf::Model model;
tinygltf::TinyGLTF ctx;
std::string err;
std::string warn;
bool ret = ctx.LoadASCIIFromFile(&model, &err, &warn, "../models/Extensions-issue97/test.gltf");
if (!err.empty()) {
std::cerr << err << std::endl;
}
REQUIRE(true == ret);
REQUIRE(model.extensionsUsed.size() == 1);
REQUIRE(model.extensionsUsed[0].compare("VENDOR_material_some_ext") == 0);
REQUIRE(model.materials.size() == 1);
REQUIRE(model.materials[0].extensions.size() == 1);
REQUIRE(model.materials[0].extensions.count("VENDOR_material_some_ext") == 1);
// TODO(syoyo): create temp directory.
{
ret = ctx.WriteGltfSceneToFile(&model, "issue-97.gltf", true, true);
REQUIRE(true == ret);
tinygltf::Model m;
// read back serialized glTF
bool ret = ctx.LoadASCIIFromFile(&m, &err, &warn, "issue-97.gltf");
if (!err.empty()) {
std::cerr << err << std::endl;
}
REQUIRE(true == ret);
REQUIRE(m.extensionsUsed.size() == 1);
REQUIRE(m.extensionsUsed[0].compare("VENDOR_material_some_ext") == 0);
REQUIRE(m.materials.size() == 1);
REQUIRE(m.materials[0].extensions.size() == 1);
REQUIRE(m.materials[0].extensions.count("VENDOR_material_some_ext") == 1);
}
}

File diff suppressed because it is too large Load Diff