mirror of
https://github.com/syoyo/tinygltf.git
synced 2026-06-08 19:23:50 +00:00
Compare commits
92 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4de57db325 | ||
|
|
a32fa80102 | ||
|
|
5f34dab548 | ||
|
|
0d77a291f7 | ||
|
|
b926195ef8 | ||
|
|
c8ba17fcab | ||
|
|
df39e04e7b | ||
|
|
7319db7a50 | ||
|
|
7ae7110800 | ||
|
|
b864ea7349 | ||
|
|
d6b0b0b990 | ||
|
|
af3ebb2e76 | ||
|
|
105694b468 | ||
|
|
5f9cb24245 | ||
|
|
9fcd3f998e | ||
|
|
d96b45df06 | ||
|
|
dd7c9efbea | ||
|
|
80a85af661 | ||
|
|
7cf2c44ad7 | ||
|
|
f1b5bb12fd | ||
|
|
174334eaf4 | ||
|
|
1212a6ee51 | ||
|
|
8674c60781 | ||
|
|
9d89f02cf0 | ||
|
|
463408c4a0 | ||
|
|
a9d862aeee | ||
|
|
2123da775b | ||
|
|
20806b27d7 | ||
|
|
94fcfdeb9d | ||
|
|
d44b6e7bcc | ||
|
|
9df05806ad | ||
|
|
93db9e20c0 | ||
|
|
2c5597f591 | ||
|
|
2dcf79566f | ||
|
|
f20888ae8b | ||
|
|
5892d3e3ea | ||
|
|
27aab61d62 | ||
|
|
d80f0f9a6c | ||
|
|
5110820ebb | ||
|
|
c3e34c2ff7 | ||
|
|
0ddfaead8f | ||
|
|
ae2cf8e26f | ||
|
|
8b7cdde30c | ||
|
|
764bcb5a8a | ||
|
|
50ada7ff11 | ||
|
|
16fae080f9 | ||
|
|
90c0008b0e | ||
|
|
b572650d26 | ||
|
|
6af9e886cd | ||
|
|
60f97325b1 | ||
|
|
a3595488e3 | ||
|
|
cf60322e73 | ||
|
|
77decfaff8 | ||
|
|
e26117e026 | ||
|
|
33514af61a | ||
|
|
ba3c3c99ef | ||
|
|
8d96b4a14e | ||
|
|
1cef6dcf33 | ||
|
|
e46774940c | ||
|
|
dddaee695d | ||
|
|
a645cfc840 | ||
|
|
040310e0d3 | ||
|
|
d9eddbfeb9 | ||
|
|
10365a53ff | ||
|
|
d0e293fd7d | ||
|
|
3b25d9130a | ||
|
|
db7f4e4d04 | ||
|
|
30bbe0fe3c | ||
|
|
ee3d06646d | ||
|
|
924d86e362 | ||
|
|
68353f1b34 | ||
|
|
05a8d0bc52 | ||
|
|
39a263c2a8 | ||
|
|
61673a62ef | ||
|
|
fdf105645b | ||
|
|
440cb1e66b | ||
|
|
c884e5827e | ||
|
|
7cb31e4e23 | ||
|
|
2bda71c8fb | ||
|
|
13b6402388 | ||
|
|
8eb3904de2 | ||
|
|
b5a72a1ba2 | ||
|
|
0820d83a9d | ||
|
|
641b3ccf8c | ||
|
|
7518334044 | ||
|
|
efc919c022 | ||
|
|
fa0a998a8b | ||
|
|
31cb7f92d8 | ||
|
|
e59dd6a5c0 | ||
|
|
da9eac2fbe | ||
|
|
098dfee982 | ||
|
|
c0cfc1ed95 |
28
CMakeLists.txt
Normal file
28
CMakeLists.txt
Normal 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
|
||||
)
|
||||
2
Makefile
2
Makefile
@@ -6,4 +6,4 @@ all:
|
||||
clang++ $(EXTRA_CXXFLAGS) -std=c++11 -g -O0 -o loader_example loader_example.cc
|
||||
|
||||
lint:
|
||||
./cpplint.py tiny_gltf_loader.h
|
||||
deps/cpplint.py tiny_gltf.h
|
||||
|
||||
26
README.md
26
README.md
@@ -24,6 +24,7 @@ v2.0.0 release(22 Aug, 2018)!
|
||||
* [x] Windows + MinGW
|
||||
* [x] Windows + Visual Studio 2015 Update 3 or later.
|
||||
* Visual Studio 2013 is not supported since they have limited C++11 support and failed to compile `json.hpp`.
|
||||
* [x] Android NDK
|
||||
* [x] Android + CrystaX(NDK drop-in replacement) GCC
|
||||
* [x] Web using Emscripten(LLVM)
|
||||
* Moderate parsing time and memory consumption.
|
||||
@@ -32,20 +33,27 @@ v2.0.0 release(22 Aug, 2018)!
|
||||
* [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] Custom Image decoder callback(e.g. for decoding OpenEXR image)
|
||||
* Load from memory
|
||||
* Custom callback handler
|
||||
* [x] Image load
|
||||
* 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
|
||||
|
||||
@@ -57,13 +65,16 @@ v2.0.0 release(22 Aug, 2018)!
|
||||
|
||||
## 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
|
||||
* [x] Save Draco compressed mesh
|
||||
* [ ] Support `extensions` and `extras` property
|
||||
* [ ] HDR image?
|
||||
* [ ] OpenEXR extension through TinyEXR.
|
||||
* [ ] Write tests for `animation` and `skin`
|
||||
* [ ] Write example and tests for `animation` and `skin`
|
||||
* [ ] Skinning
|
||||
* [ ] Morph targets
|
||||
|
||||
## Licenses
|
||||
|
||||
@@ -120,6 +131,9 @@ 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 woulde be helpful if you do not want load image file 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.
|
||||
|
||||
### Saving gltTF 2.0 model
|
||||
* [ ] Buffers.
|
||||
|
||||
15
cmake/TinyGLTFConfig.cmake
Normal file
15
cmake/TinyGLTFConfig.cmake
Normal 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
7
examples/basic/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
.vs
|
||||
Debug
|
||||
x64
|
||||
packages
|
||||
|
||||
!*.sln
|
||||
!*.vcxproj*
|
||||
21
examples/basic/README.md
Normal file
21
examples/basic/README.md
Normal 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.
|
||||
|
||||
|
||||
31
examples/basic/basic/basic.sln
Normal file
31
examples/basic/basic/basic.sln
Normal 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
|
||||
159
examples/basic/basic/basic.vcxproj
Normal file
159
examples/basic/basic/basic.vcxproj
Normal 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>
|
||||
39
examples/basic/basic/basic.vcxproj.filters
Normal file
39
examples/basic/basic/basic.vcxproj.filters
Normal 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>
|
||||
4
examples/basic/basic/basic.vcxproj.user
Normal file
4
examples/basic/basic/basic.vcxproj.user
Normal 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>
|
||||
6
examples/basic/basic/packages.config
Normal file
6
examples/basic/basic/packages.config
Normal 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>
|
||||
334
examples/basic/main.cpp
Normal file
334
examples/basic/main.cpp
Normal file
@@ -0,0 +1,334 @@
|
||||
#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);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, &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, 2), 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();
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
std::string filename = "../../models/Cube/Cube.gltf";
|
||||
|
||||
if (argc > 1) {
|
||||
filename = argv[1];
|
||||
}
|
||||
|
||||
if (!glfwInit()) return -1;
|
||||
|
||||
// Force create 3.3 profile.
|
||||
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
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -1,34 +1,19 @@
|
||||
newoption {
|
||||
trigger = "asan",
|
||||
description = "Enable Address Sanitizer(gcc5+ ang clang only)"
|
||||
}
|
||||
|
||||
solution "skinning"
|
||||
solution "basic_viewer"
|
||||
-- location ( "build" )
|
||||
configurations { "Debug", "Release" }
|
||||
platforms {"native", "x64", "x32"}
|
||||
|
||||
project "skinning"
|
||||
|
||||
-- Use clang for better asan expericen
|
||||
if _OPTIONS["asan"] then
|
||||
toolset "clang"
|
||||
end
|
||||
project "basic_viewer"
|
||||
|
||||
kind "ConsoleApp"
|
||||
language "C++"
|
||||
cppdialect "C++11"
|
||||
files { "main.cc", "skinning.cc", "morph-targets.cc", "../common/trackball.cc", "../common/matrix.cc" }
|
||||
files { "main.cpp", "shaders.cpp", "window.cpp" }
|
||||
includedirs { "./" }
|
||||
includedirs { "../../" }
|
||||
includedirs { "../common/glm" }
|
||||
|
||||
configuration { "linux" }
|
||||
|
||||
if _OPTIONS["asan"] then
|
||||
buildoptions { "-fsanitize=address" }
|
||||
linkoptions { "-fsanitize=address" }
|
||||
end
|
||||
|
||||
linkoptions { "`pkg-config --libs glfw3`" }
|
||||
links { "GL", "GLU", "m", "GLEW", "X11", "Xrandr", "Xinerama", "Xi", "Xxf86vm", "Xcursor", "dl" }
|
||||
|
||||
BIN
examples/basic/screenshot.JPG
Normal file
BIN
examples/basic/screenshot.JPG
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
114
examples/basic/shaders.cpp
Normal file
114
examples/basic/shaders.cpp
Normal 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
13
examples/basic/shaders.h
Normal 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
27
examples/basic/window.cpp
Normal 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
15
examples/basic/window.h
Normal 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();
|
||||
};
|
||||
|
||||
@@ -99,28 +99,6 @@ void Matrix::LookAt(float m[4][4], float eye[3], float lookat[3],
|
||||
#endif
|
||||
}
|
||||
|
||||
void Matrix::Identity(float m[4][4]) {
|
||||
m[0][0] = 1.0f;
|
||||
m[0][1] = 0.0f;
|
||||
m[0][2] = 0.0f;
|
||||
m[0][3] = 0.0f;
|
||||
|
||||
m[1][0] = 0.0f;
|
||||
m[1][1] = 1.0f;
|
||||
m[1][2] = 0.0f;
|
||||
m[1][3] = 0.0f;
|
||||
|
||||
m[2][0] = 0.0f;
|
||||
m[2][1] = 0.0f;
|
||||
m[2][2] = 1.0f;
|
||||
m[2][3] = 0.0f;
|
||||
|
||||
m[3][0] = 0.0f;
|
||||
m[3][1] = 0.0f;
|
||||
m[3][2] = 0.0f;
|
||||
m[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
void Matrix::Inverse(float m[4][4]) {
|
||||
/*
|
||||
* codes from intel web
|
||||
@@ -217,16 +195,7 @@ void Matrix::Inverse(float m[4][4]) {
|
||||
}
|
||||
}
|
||||
|
||||
void Matrix::Add(float dst[4][4], const float m0[4][4], const float m1[4][4]) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
dst[i][j] += m0[i][j] + m1[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Matrix::Mult(float dst[4][4], const float m0[4][4], const float m1[4][4]) {
|
||||
void Matrix::Mult(float dst[4][4], float m0[4][4], float m1[4][4]) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
dst[i][j] = 0;
|
||||
@@ -237,7 +206,7 @@ void Matrix::Mult(float dst[4][4], const float m0[4][4], const float m1[4][4]) {
|
||||
}
|
||||
}
|
||||
|
||||
void Matrix::MultV(float dst[3], const float m[4][4], const float v[3]) {
|
||||
void Matrix::MultV(float dst[3], float m[4][4], float v[3]) {
|
||||
// printf("v = %f, %f, %f\n", v[0], v[1], v[2]);
|
||||
dst[0] = m[0][0] * v[0] + m[1][0] * v[1] + m[2][0] * v[2] + m[3][0];
|
||||
dst[1] = m[0][1] * v[0] + m[1][1] * v[1] + m[2][1] * v[2] + m[3][1];
|
||||
@@ -245,10 +214,3 @@ void Matrix::MultV(float dst[3], const float m[4][4], const float v[3]) {
|
||||
// printf("m = %f, %f, %f\n", m[3][0], m[3][1], m[3][2]);
|
||||
// printf("dst = %f, %f, %f\n", dst[0], dst[1], dst[2]);
|
||||
}
|
||||
|
||||
void Matrix::MultV4(float dst[4], const float m[4][4], const float v[4]) {
|
||||
dst[0] = m[0][0] * v[0] + m[1][0] * v[1] + m[2][0] * v[2] + m[3][0] * v[3];
|
||||
dst[1] = m[0][1] * v[0] + m[1][1] * v[1] + m[2][1] * v[2] + m[3][1] * v[3];
|
||||
dst[2] = m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2] + m[3][2] * v[3];
|
||||
dst[3] = m[0][3] * v[0] + m[1][3] * v[1] + m[2][3] * v[2] + m[3][3] * v[3];
|
||||
}
|
||||
|
||||
@@ -10,11 +10,8 @@ public:
|
||||
static void LookAt(float m[4][4], float eye[3], float lookat[3],
|
||||
float up[3]);
|
||||
static void Inverse(float m[4][4]);
|
||||
static void Identity(float m[4][4]);
|
||||
static void Add(float dst[4][4], const float m0[4][4], const float m1[4][4]);
|
||||
static void Mult(float dst[4][4], const float m0[4][4], const float m1[4][4]);
|
||||
static void MultV(float dst[3], const float m[4][4], const float v[3]);
|
||||
static void MultV4(float dst[4], const float m[4][4], const float v[4]);
|
||||
static void Mult(float dst[4][4], float m0[4][4], float m1[4][4]);
|
||||
static void MultV(float dst[3], float m[4][4], float v[3]);
|
||||
};
|
||||
|
||||
#endif //
|
||||
|
||||
@@ -52,6 +52,11 @@
|
||||
#include <math.h>
|
||||
#include "trackball.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4244)
|
||||
#pragma warning(disable : 4305)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This size should really be based on the distance from the center of
|
||||
* rotation to the point on the object underneath the mouse. That
|
||||
@@ -168,11 +173,11 @@ void trackball(float q[4], float p1x, float p1y, float p2x, float p2y) {
|
||||
/*
|
||||
* 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);
|
||||
if (t > 1.0f)
|
||||
t = 1.0f;
|
||||
if (t < -1.0f)
|
||||
t = -1.0f;
|
||||
phi = 2.0f * asinf(t);
|
||||
|
||||
axis_to_quat(a, phi, q);
|
||||
}
|
||||
|
||||
@@ -7,3 +7,9 @@ include_directories(../../)
|
||||
|
||||
file(GLOB gltfutil_sources *.cc *.h)
|
||||
add_executable(gltfutil ${gltfutil_sources})
|
||||
|
||||
install ( TARGETS
|
||||
gltfutil
|
||||
DESTINATION
|
||||
bin
|
||||
)
|
||||
|
||||
7
examples/glview/.gitignore
vendored
Normal file
7
examples/glview/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
.vs
|
||||
Debug
|
||||
x64
|
||||
packages
|
||||
|
||||
!*.sln
|
||||
!*.vcxproj*
|
||||
67
examples/glview/CMakeLists.txt
Normal file
67
examples/glview/CMakeLists.txt
Normal file
@@ -0,0 +1,67 @@
|
||||
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 (${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 ()
|
||||
|
||||
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
|
||||
)
|
||||
@@ -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
|
||||
|
||||
71
examples/glview/cmake/GLFW3Config.cmake
Normal file
71
examples/glview/cmake/GLFW3Config.cmake
Normal 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 ()
|
||||
@@ -12,15 +12,24 @@
|
||||
#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
|
||||
#include "tiny_gltf.h"
|
||||
|
||||
//#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
||||
#define BUFFER_OFFSET(i) (reinterpret_cast<void *>(i))
|
||||
#ifdef _WIN32
|
||||
#include "../../tiny_gltf.h"
|
||||
#else
|
||||
#include "tiny_gltf.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
||||
|
||||
#define CheckGLErrors(desc) \
|
||||
{ \
|
||||
@@ -252,7 +261,7 @@ static void SetupMeshState(tinygltf::Model &model, GLuint progId) {
|
||||
const tinygltf::BufferView &bufferView = model.bufferViews[i];
|
||||
if (bufferView.target == 0) {
|
||||
std::cout << "WARN: bufferView.target is zero" << std::endl;
|
||||
continue; // Unsupported or not directly used bufferView.
|
||||
continue; // Unsupported bufferView.
|
||||
}
|
||||
|
||||
const tinygltf::Buffer &buffer = model.buffers[bufferView.buffer];
|
||||
@@ -529,13 +538,6 @@ static void DrawMesh(tinygltf::Model &model, const tinygltf::Mesh &mesh) {
|
||||
for (; it != itEnd; it++) {
|
||||
assert(it->second >= 0);
|
||||
const tinygltf::Accessor &accessor = model.accessors[it->second];
|
||||
const tinygltf::BufferView &bufferView = model.bufferViews[accessor.bufferView];
|
||||
|
||||
if (bufferView.target == 0) {
|
||||
// Unsupported or not directly used buffer
|
||||
continue;
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, gBufferState[accessor.bufferView].vb);
|
||||
CheckErrors("bind buffer");
|
||||
int size = 1;
|
||||
@@ -675,20 +677,21 @@ static void DrawNode(tinygltf::Model &model, const tinygltf::Node &node) {
|
||||
// std::cout << it->first << std::endl;
|
||||
// FIXME(syoyo): Refactor.
|
||||
// DrawCurves(scene, it->second);
|
||||
|
||||
if ((node.mesh >= 0) && (node.mesh < int(model.meshes.size()))) {
|
||||
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]]);
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
static void DrawModel(tinygltf::Model &model, size_t scene_idx) {
|
||||
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());
|
||||
@@ -699,8 +702,9 @@ static void DrawModel(tinygltf::Model &model, size_t scene_idx) {
|
||||
}
|
||||
#else
|
||||
|
||||
assert(scene_idx < model.scenes.size());
|
||||
const tinygltf::Scene &scene = model.scenes[scene_idx];
|
||||
// TODO(syoyo): Support non-default scenes.
|
||||
assert(model.defaultScene >= 0);
|
||||
const tinygltf::Scene &scene = model.scenes[model.defaultScene];
|
||||
for (size_t i = 0; i < scene.nodes.size(); i++) {
|
||||
DrawNode(model, model.nodes[scene.nodes[i]]);
|
||||
}
|
||||
@@ -731,8 +735,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;
|
||||
@@ -744,7 +748,15 @@ int main(int argc, char **argv) {
|
||||
tinygltf::TinyGLTF loader;
|
||||
std::string err;
|
||||
std::string warn;
|
||||
std::string input_filename(argv[1]);
|
||||
|
||||
#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;
|
||||
@@ -770,28 +782,20 @@ int main(int argc, char **argv) {
|
||||
|
||||
Init();
|
||||
|
||||
if (model.scenes.empty()) {
|
||||
std::cerr << "glTF model does not have scenes" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// DBG
|
||||
size_t scene_idx = size_t(model.defaultScene);
|
||||
if (model.defaultScene == -1) {
|
||||
scene_idx = 0;
|
||||
}
|
||||
|
||||
PrintNodes(model.scenes[scene_idx]);
|
||||
PrintNodes(model.scenes[model.defaultScene]);
|
||||
|
||||
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();
|
||||
@@ -817,12 +821,24 @@ 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");
|
||||
@@ -873,7 +889,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
glScalef(scale, scale, scale);
|
||||
|
||||
DrawModel(model, scene_idx);
|
||||
DrawModel(model);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
|
||||
31
examples/glview/glview.sln
Normal file
31
examples/glview/glview.sln
Normal 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
|
||||
152
examples/glview/glview/glview.vcxproj
Normal file
152
examples/glview/glview/glview.vcxproj
Normal 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>
|
||||
28
examples/glview/glview/glview.vcxproj.filters
Normal file
28
examples/glview/glview/glview.vcxproj.filters
Normal 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>
|
||||
4
examples/glview/glview/glview.vcxproj.user
Normal file
4
examples/glview/glview/glview.vcxproj.user
Normal 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>
|
||||
5
examples/glview/glview/packages.config
Normal file
5
examples/glview/glview/packages.config
Normal 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>
|
||||
@@ -1,34 +1,19 @@
|
||||
newoption {
|
||||
trigger = "asan",
|
||||
description = "Enable Address Sanitizer(gcc5+ ang clang only)"
|
||||
}
|
||||
|
||||
solution "glview"
|
||||
-- location ( "build" )
|
||||
configurations { "Debug", "Release" }
|
||||
platforms {"native", "x64", "x32"}
|
||||
|
||||
|
||||
project "glview"
|
||||
|
||||
-- Use clang for better asan expericen
|
||||
if _OPTIONS["asan"] then
|
||||
toolset "clang"
|
||||
end
|
||||
|
||||
kind "ConsoleApp"
|
||||
language "C++"
|
||||
cppdialect "C++11"
|
||||
files { "glview.cc", "trackball.cc" }
|
||||
files { "glview.cc", "../common/trackball.cc" }
|
||||
includedirs { "./" }
|
||||
includedirs { "../../" }
|
||||
includedirs { "../common/" }
|
||||
|
||||
configuration { "linux" }
|
||||
|
||||
if _OPTIONS["asan"] then
|
||||
buildoptions { "-fsanitize=address,undefined" }
|
||||
linkoptions { "-fsanitize=address,undefined" }
|
||||
end
|
||||
|
||||
linkoptions { "`pkg-config --libs glfw3`" }
|
||||
links { "GL", "GLU", "m", "GLEW", "X11", "Xrandr", "Xinerama", "Xi", "Xxf86vm", "Xcursor", "dl" }
|
||||
|
||||
|
||||
@@ -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) {
|
||||
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;
|
||||
}
|
||||
@@ -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]);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,19 +0,0 @@
|
||||
# Simple glTF skinning sample with CPU skinning implementation.
|
||||
|
||||
Example use CPU implementation of skinning for the explanation of how to process skin property in glTF format.
|
||||
|
||||
Animation and skinning code is based on SacchaWillems' Vulkan-glTF-PBR: https://github.com/SaschaWillems/Vulkan-glTF-PBR
|
||||
|
||||
OpenGL is still used to display renderings.
|
||||
|
||||
## Build on Linux and macOS
|
||||
|
||||
```
|
||||
$ premake5 gmake
|
||||
$ make
|
||||
$ ./bin/native/Debug/skinning simple-skin.gltf
|
||||
```
|
||||
|
||||
## Note on asset
|
||||
|
||||
`simple-skin.gltf` is grabbed from gltfTutorial https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_019_SimpleSkin.md
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,22 +0,0 @@
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
|
||||
void MorthTargets(std::vector<float> &weights,
|
||||
std::vector<std::vector<float>> &targets,
|
||||
std::vector<float> *output)
|
||||
{
|
||||
assert(weights.size() > 0);
|
||||
assert(targets.size() > 0);
|
||||
assert(weights.size() == targets.size());
|
||||
|
||||
// Assume all position has same number of vertices;
|
||||
|
||||
// TODO(parallelize)
|
||||
for (size_t v = 0; v < targets[0].size(); v++) { // for each vertex
|
||||
(*output)[v] = 0.0f;
|
||||
for (size_t i = 0; i < weights.size(); i++) {
|
||||
(*output)[v] += weights[i] * targets[i][v];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
uniform sampler2D diffuseTex;
|
||||
uniform int uIsCurve;
|
||||
|
||||
varying vec3 normal;
|
||||
varying vec2 texcoord;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
//gl_FragColor = vec4(0.5 * normalize(normal) + 0.5, 1.0);
|
||||
//gl_FragColor = vec4(texcoord, 0.0, 1.0);
|
||||
if (uIsCurve > 0) {
|
||||
gl_FragColor = texture2D(diffuseTex, texcoord);
|
||||
} else {
|
||||
gl_FragColor = vec4(0.5 * normalize(normal) + 0.5, 1.0);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
attribute vec3 in_vertex;
|
||||
attribute vec3 in_normal;
|
||||
attribute vec2 in_texcoord;
|
||||
|
||||
varying vec3 normal;
|
||||
varying vec2 texcoord;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 p = gl_ModelViewProjectionMatrix * vec4(in_vertex, 1);
|
||||
gl_Position = p;
|
||||
vec4 nn = gl_ModelViewMatrixInverseTranspose * vec4(normalize(in_normal), 0);
|
||||
normal = nn.xyz;
|
||||
|
||||
texcoord = in_texcoord;
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
{
|
||||
"scenes" : [ {
|
||||
"nodes" : [ 0 ]
|
||||
} ],
|
||||
|
||||
"nodes" : [ {
|
||||
"skin" : 0,
|
||||
"mesh" : 0,
|
||||
"children" : [ 1 ]
|
||||
}, {
|
||||
"children" : [ 2 ],
|
||||
"translation" : [ 0.0, 1.0, 0.0 ]
|
||||
}, {
|
||||
"rotation" : [ 0.0, 0.0, 0.0, 1.0 ]
|
||||
} ],
|
||||
|
||||
"meshes" : [ {
|
||||
"primitives" : [ {
|
||||
"attributes" : {
|
||||
"POSITION" : 1,
|
||||
"JOINTS_0" : 2,
|
||||
"WEIGHTS_0" : 3
|
||||
},
|
||||
"indices" : 0
|
||||
} ]
|
||||
} ],
|
||||
|
||||
"skins" : [ {
|
||||
"inverseBindMatrices" : 4,
|
||||
"joints" : [ 1, 2 ]
|
||||
} ],
|
||||
|
||||
"animations" : [ {
|
||||
"channels" : [ {
|
||||
"sampler" : 0,
|
||||
"target" : {
|
||||
"node" : 2,
|
||||
"path" : "rotation"
|
||||
}
|
||||
} ],
|
||||
"samplers" : [ {
|
||||
"input" : 5,
|
||||
"interpolation" : "LINEAR",
|
||||
"output" : 6
|
||||
} ]
|
||||
} ],
|
||||
|
||||
"buffers" : [ {
|
||||
"uri" : "data:application/gltf-buffer;base64,AAABAAMAAAADAAIAAgADAAUAAgAFAAQABAAFAAcABAAHAAYABgAHAAkABgAJAAgAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAD8AAAAAAACAPwAAAD8AAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAwD8AAAAAAACAPwAAwD8AAAAAAAAAAAAAAEAAAAAAAACAPwAAAEAAAAAA",
|
||||
"byteLength" : 168
|
||||
}, {
|
||||
"uri" : "data:application/gltf-buffer;base64,AAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAABAPwAAgD4AAAAAAAAAAAAAQD8AAIA+AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAgD4AAEA/AAAAAAAAAAAAAIA+AABAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAA=",
|
||||
"byteLength" : 320
|
||||
}, {
|
||||
"uri" : "data:application/gltf-buffer;base64,AACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAvwAAgL8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAL8AAIC/AAAAAAAAgD8=",
|
||||
"byteLength" : 128
|
||||
}, {
|
||||
"uri" : "data:application/gltf-buffer;base64,AAAAAAAAAD8AAIA/AADAPwAAAEAAACBAAABAQAAAYEAAAIBAAACQQAAAoEAAALBAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAkxjEPkSLbD8AAAAAAAAAAPT9ND/0/TQ/AAAAAAAAAAD0/TQ/9P00PwAAAAAAAAAAkxjEPkSLbD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAkxjEvkSLbD8AAAAAAAAAAPT9NL/0/TQ/AAAAAAAAAAD0/TS/9P00PwAAAAAAAAAAkxjEvkSLbD8AAAAAAAAAAAAAAAAAAIA/",
|
||||
"byteLength" : 240
|
||||
} ],
|
||||
|
||||
"bufferViews" : [ {
|
||||
"buffer" : 0,
|
||||
"byteOffset" : 0,
|
||||
"byteLength" : 48,
|
||||
"target" : 34963
|
||||
}, {
|
||||
"buffer" : 0,
|
||||
"byteOffset" : 48,
|
||||
"byteLength" : 120,
|
||||
"target" : 34962
|
||||
}, {
|
||||
"buffer" : 1,
|
||||
"byteOffset" : 0,
|
||||
"byteLength" : 320,
|
||||
"byteStride" : 16
|
||||
}, {
|
||||
"buffer" : 2,
|
||||
"byteOffset" : 0,
|
||||
"byteLength" : 128
|
||||
}, {
|
||||
"buffer" : 3,
|
||||
"byteOffset" : 0,
|
||||
"byteLength" : 240
|
||||
} ],
|
||||
|
||||
"accessors" : [ {
|
||||
"bufferView" : 0,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5123,
|
||||
"count" : 24,
|
||||
"type" : "SCALAR",
|
||||
"max" : [ 9 ],
|
||||
"min" : [ 0 ]
|
||||
}, {
|
||||
"bufferView" : 1,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5126,
|
||||
"count" : 10,
|
||||
"type" : "VEC3",
|
||||
"max" : [ 1.0, 2.0, 0.0 ],
|
||||
"min" : [ 0.0, 0.0, 0.0 ]
|
||||
}, {
|
||||
"bufferView" : 2,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5123,
|
||||
"count" : 10,
|
||||
"type" : "VEC4",
|
||||
"max" : [ 0, 1, 0, 0 ],
|
||||
"min" : [ 0, 1, 0, 0 ]
|
||||
}, {
|
||||
"bufferView" : 2,
|
||||
"byteOffset" : 160,
|
||||
"componentType" : 5126,
|
||||
"count" : 10,
|
||||
"type" : "VEC4",
|
||||
"max" : [ 1.0, 1.0, 0.0, 0.0 ],
|
||||
"min" : [ 0.0, 0.0, 0.0, 0.0 ]
|
||||
}, {
|
||||
"bufferView" : 3,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5126,
|
||||
"count" : 2,
|
||||
"type" : "MAT4",
|
||||
"max" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -0.5, -1.0, 0.0, 1.0 ],
|
||||
"min" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -0.5, -1.0, 0.0, 1.0 ]
|
||||
}, {
|
||||
"bufferView" : 4,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5126,
|
||||
"count" : 12,
|
||||
"type" : "SCALAR",
|
||||
"max" : [ 5.5 ],
|
||||
"min" : [ 0.0 ]
|
||||
}, {
|
||||
"bufferView" : 4,
|
||||
"byteOffset" : 48,
|
||||
"componentType" : 5126,
|
||||
"count" : 12,
|
||||
"type" : "VEC4",
|
||||
"max" : [ 0.0, 0.0, 0.707, 1.0 ],
|
||||
"min" : [ 0.0, 0.0, -0.707, 0.707 ]
|
||||
} ],
|
||||
|
||||
"asset" : {
|
||||
"version" : "2.0"
|
||||
}
|
||||
}
|
||||
@@ -1,252 +0,0 @@
|
||||
#include "skinning.h"
|
||||
|
||||
#include "../common/matrix.h"
|
||||
#include "../common/trackball.h" // for quaternion
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Weverything"
|
||||
#endif
|
||||
|
||||
#define HANDMADE_MATH_IMPLEMENTATION
|
||||
#include "HandmadeMath.h"
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
namespace example {
|
||||
|
||||
struct Node {
|
||||
|
||||
float translation[3] = {0.0f, 0.0f, 0.0f};
|
||||
float scale[4] = {1.0f, 1.0f, 1.0f};
|
||||
float rotation[4] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
|
||||
|
||||
void update() {
|
||||
}
|
||||
};
|
||||
|
||||
static inline vec4 mix(vec4 x, vec4 y, float a) {
|
||||
vec4 v;
|
||||
v.f[0] = (1.0f - a) * x.f[0] + a * y.f[0];
|
||||
v.f[1] = (1.0f - a) * x.f[1] + a * y.f[1];
|
||||
v.f[2] = (1.0f - a) * x.f[2] + a * y.f[2];
|
||||
v.f[3] = (1.0f - a) * x.f[3] + a * y.f[3];
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void BuildTransofrmMatrix(const float translate[3],
|
||||
const float rotation[4], // as quaternion in glTF
|
||||
const float scale[3], mat4 *transform_matrix) {
|
||||
float T[4][4];
|
||||
T[0][0] = 1.0f;
|
||||
T[0][1] = 0.0f;
|
||||
T[0][2] = 0.0f;
|
||||
T[0][3] = 0.0f;
|
||||
|
||||
T[1][0] = 0.0f;
|
||||
T[1][1] = 1.0f;
|
||||
T[1][2] = 0.0f;
|
||||
T[1][3] = 0.0f;
|
||||
|
||||
T[2][0] = 0.0f;
|
||||
T[2][1] = 0.0f;
|
||||
T[2][2] = 1.0f;
|
||||
T[2][3] = 0.0f;
|
||||
|
||||
T[3][0] = translate[0];
|
||||
T[3][1] = translate[1];
|
||||
T[3][2] = translate[2];
|
||||
T[3][3] = 1.0f;
|
||||
|
||||
float R[4][4];
|
||||
|
||||
build_rotmatrix(R, rotation);
|
||||
|
||||
float S[4][4];
|
||||
S[0][0] = scale[0];
|
||||
S[0][1] = 0.0f;
|
||||
S[0][2] = 0.0f;
|
||||
S[0][3] = 0.0f;
|
||||
|
||||
S[1][0] = 0.0f;
|
||||
S[1][1] = scale[1];
|
||||
S[1][2] = 0.0f;
|
||||
S[1][3] = 0.0f;
|
||||
|
||||
S[2][0] = 0.0f;
|
||||
S[2][1] = 0.0f;
|
||||
S[2][2] = scale[2];
|
||||
S[2][3] = 0.0f;
|
||||
|
||||
S[3][0] = 0.0f;
|
||||
S[3][1] = 0.0f;
|
||||
S[3][2] = 0.0f;
|
||||
S[3][3] = 1.0f;
|
||||
|
||||
float RS[4][4];
|
||||
|
||||
Matrix::Mult(RS, R, S);
|
||||
|
||||
Matrix::Mult(transform_matrix->m, T, RS);
|
||||
}
|
||||
|
||||
void ComputeJointMatrices(
|
||||
const std::vector<mat4> global_transform_of_nodes,
|
||||
const std::vector<mat4> global_transform_of_joint_nodes,
|
||||
const std::vector<mat4> inverse_bind_matrix_for_joints,
|
||||
std::vector<mat4> *output_joint_matrices) {
|
||||
const size_t n = global_transform_of_nodes.size();
|
||||
|
||||
output_joint_matrices->resize(n);
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
mat4 g_inv = global_transform_of_nodes[i];
|
||||
Matrix::Inverse(g_inv.m);
|
||||
|
||||
mat4 g_joint = global_transform_of_joint_nodes[i];
|
||||
mat4 inverse_bind_matrix = inverse_bind_matrix_for_joints[i];
|
||||
|
||||
float a[4][4]; // temp matrix
|
||||
Matrix::Mult(a, g_joint.m, inverse_bind_matrix.m);
|
||||
|
||||
Matrix::Mult((*output_joint_matrices)[i].m, g_inv.m, a);
|
||||
}
|
||||
}
|
||||
|
||||
void Skining(const std::vector<float> vertices,
|
||||
const std::vector<float> weights, const std::vector<size_t> joints,
|
||||
const size_t num_skinning_weights,
|
||||
const std::vector<mat4> joint_matrices, const float t,
|
||||
std::vector<float> *skinned_vertices) {
|
||||
assert((vertices.size() % 4) == 0);
|
||||
const size_t num_vertices = vertices.size() / 4;
|
||||
|
||||
skinned_vertices->resize(vertices.size());
|
||||
|
||||
// TODO(syoyo): Ensure sum(weights) = 1.0;
|
||||
|
||||
for (size_t v = 0; v < num_vertices; v++) {
|
||||
const float *w_p = weights.data() + v * num_skinning_weights;
|
||||
const size_t *j_p = joints.data() + v * num_skinning_weights;
|
||||
|
||||
mat4 skin_mat;
|
||||
memset(skin_mat.m, 0, sizeof(float) * 4 * 4);
|
||||
|
||||
for (size_t k = 0; k < num_skinning_weights; k++) {
|
||||
const float w = w_p[k];
|
||||
const mat4 &m = joint_matrices[j_p[k]];
|
||||
|
||||
for (size_t j = 0; j < 4; j++) {
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
skin_mat.m[j][i] += w * m.m[j][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// M = lerp I and skin_mat
|
||||
mat4 M;
|
||||
|
||||
mat4 I;
|
||||
Matrix::Identity(I.m);
|
||||
|
||||
for (size_t j = 0; j < 4; j++) {
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
M.m[j][i] = I.m[j][i] * t + (1.0f - t) * skin_mat.m[j][i];
|
||||
}
|
||||
}
|
||||
|
||||
float vtx[4];
|
||||
vtx[0] = vertices[4 * v + 0];
|
||||
vtx[1] = vertices[4 * v + 1];
|
||||
vtx[2] = vertices[4 * v + 2];
|
||||
vtx[3] = vertices[4 * v + 3];
|
||||
|
||||
float ret[4];
|
||||
Matrix::MultV4(ret, M.m, vtx);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAnimation(std::vector<Animation> &animations, uint32_t index,
|
||||
float time, std::vector<Node*> &nodes) {
|
||||
if (index > uint32_t(animations.size() - 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Animation &animation = animations[index];
|
||||
|
||||
bool updated = false;
|
||||
for (auto &channel : animation.channels) {
|
||||
const AnimationSampler &sampler = animation.samplers[channel.samplerIndex];
|
||||
if (sampler.inputs.size() > sampler.outputsVec4.size()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO(LTE): support interpolation other than LINEAR
|
||||
for (size_t i = 0; i < sampler.inputs.size() - 1; i++) {
|
||||
if ((time >= sampler.inputs[i]) && (time <= sampler.inputs[i + 1])) {
|
||||
float u = std::max(0.0f, time - sampler.inputs[i]) /
|
||||
(sampler.inputs[i + 1] - sampler.inputs[i]);
|
||||
if (u <= 1.0f) {
|
||||
switch (channel.path) {
|
||||
case AnimationChannel::PathType::TRANSLATION: {
|
||||
example::vec4 trans =
|
||||
mix(sampler.outputsVec4[i], sampler.outputsVec4[i + 1], u);
|
||||
channel.node->translation[0] = trans.f[0];
|
||||
channel.node->translation[1] = trans.f[1];
|
||||
channel.node->translation[2] = trans.f[2];
|
||||
// drop w
|
||||
break;
|
||||
}
|
||||
case AnimationChannel::PathType::SCALE: {
|
||||
example::vec4 scale =
|
||||
mix(sampler.outputsVec4[i], sampler.outputsVec4[i + 1], u);
|
||||
channel.node->scale[0] = scale.f[0];
|
||||
channel.node->scale[1] = scale.f[1];
|
||||
channel.node->scale[2] = scale.f[2];
|
||||
break;
|
||||
}
|
||||
case AnimationChannel::PathType::ROTATION: {
|
||||
|
||||
hmm_quaternion q1 = HMM_Quaternion(
|
||||
sampler.outputsVec4[i].f[0],
|
||||
sampler.outputsVec4[i].f[1],
|
||||
sampler.outputsVec4[i].f[2],
|
||||
sampler.outputsVec4[i].f[3]);
|
||||
|
||||
hmm_quaternion q2 = HMM_Quaternion(
|
||||
sampler.outputsVec4[i + 1].f[0],
|
||||
sampler.outputsVec4[i + 1].f[1],
|
||||
sampler.outputsVec4[i + 1].f[2],
|
||||
sampler.outputsVec4[i + 1].f[3]);
|
||||
|
||||
hmm_quaternion q = HMM_NormalizeQuaternion(HMM_Slerp(q1, u, q2));
|
||||
|
||||
channel.node->rotation[0] = q.Elements[0];
|
||||
channel.node->rotation[1] = q.Elements[1];
|
||||
channel.node->rotation[2] = q.Elements[2];
|
||||
channel.node->rotation[3] = q.Elements[3];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (updated) {
|
||||
for (auto &node : nodes) {
|
||||
node->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace example
|
||||
@@ -1,95 +0,0 @@
|
||||
#ifndef EXAMPLE_SKINNING_H_
|
||||
#define EXAMPLE_SKINNING_H_
|
||||
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <limits>
|
||||
|
||||
namespace example {
|
||||
|
||||
struct mat4 {
|
||||
float m[4][4];
|
||||
};
|
||||
|
||||
struct vec4 {
|
||||
float f[4];
|
||||
};
|
||||
|
||||
// glTF node
|
||||
struct Node;
|
||||
|
||||
|
||||
struct AnimationChannel {
|
||||
enum PathType { TRANSLATION, ROTATION, SCALE };
|
||||
PathType path;
|
||||
Node *node;
|
||||
uint32_t samplerIndex;
|
||||
};
|
||||
|
||||
struct AnimationSampler {
|
||||
enum InterpolationType { LINEAR, STEP, CUBICSPLINE };
|
||||
InterpolationType interpolation;
|
||||
std::vector<float> inputs;
|
||||
std::vector<example::vec4> outputsVec4;
|
||||
};
|
||||
|
||||
struct Animation {
|
||||
std::string name;
|
||||
std::vector<AnimationSampler> samplers;
|
||||
std::vector<AnimationChannel> channels;
|
||||
float start = std::numeric_limits<float>::max();
|
||||
float end = std::numeric_limits<float>::min();
|
||||
};
|
||||
|
||||
///
|
||||
/// Utility function to build transformation matrix from translate/rotation/scale
|
||||
///
|
||||
/// https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_004_ScenesNodes.md
|
||||
///
|
||||
/// M = T * R * S
|
||||
///
|
||||
void BuildTransofrmMatrix(
|
||||
const float translate[3],
|
||||
const float rotation[4], // as quaternion in glTF
|
||||
const float scale[3],
|
||||
mat4 *transform_matrix);
|
||||
|
||||
|
||||
///
|
||||
/// Compute joint matrices.
|
||||
///
|
||||
/// jointMatrix(j) =
|
||||
/// globalTransformOfNodeThatTheMeshIsAttachedTo^-1 *
|
||||
/// globalTransformOfJointNode(j) *
|
||||
/// inverseBindMatrixForJoint(j);
|
||||
///
|
||||
|
||||
void ComputeJointMatrices(
|
||||
const std::vector<mat4> global_transform_of_nodes,
|
||||
const std::vector<mat4> global_transform_of_joint_nodes,
|
||||
const std::vector<mat4> inverse_bind_matrix_for_joints,
|
||||
std::vector<mat4> output_joint_matrices);
|
||||
|
||||
|
||||
///
|
||||
///
|
||||
/// @param[in] vertices Input vertices(# of elements = num_vertices * 4(xyzw))
|
||||
/// @param[in] weights Linearized weights(# of elements = num_vertices * num_skinning_weights)
|
||||
/// @param[in] weights Linearized weights(# of elements = num_vertices * num_skinning_weights)
|
||||
/// @param[in] num_weights Linearized weights(# of elements = num_vertices *
|
||||
/// @param[in] joint_matrices Array of joint matricies.
|
||||
/// @param[in] t Interpolator. [0.0, 1.0]
|
||||
/// @param[in] skinned_vertices Resulting skinned vertices
|
||||
///
|
||||
void Skining(const std::vector<float> vertices,
|
||||
const std::vector<float> weights, const std::vector<size_t> joints,
|
||||
const size_t num_skinning_weights,
|
||||
const std::vector<mat4> joint_matrices,
|
||||
const float t,
|
||||
std::vector<float> *skinned_vertices);
|
||||
|
||||
} // namespace example
|
||||
|
||||
#endif // EXAMPLE_SKINNING_H_
|
||||
@@ -45,3 +45,9 @@ endif()
|
||||
|
||||
# test-zone
|
||||
# enable_testing()
|
||||
|
||||
install ( TARGETS
|
||||
tinygltf-validator
|
||||
DESTINATION
|
||||
bin
|
||||
)
|
||||
|
||||
@@ -30,8 +30,7 @@ static std::string PrintMode(int mode) {
|
||||
} else if (mode == TINYGLTF_MODE_TRIANGLE_STRIP) {
|
||||
return "TRIANGLE_STRIP";
|
||||
}
|
||||
|
||||
return "**UNKNOWN**(" + std::to_string(mode) + ")";
|
||||
return "**UNKNOWN**";
|
||||
}
|
||||
|
||||
static std::string PrintTarget(int target) {
|
||||
@@ -40,7 +39,7 @@ static std::string PrintTarget(int target) {
|
||||
} else if (target == 34963) {
|
||||
return "GL_ELEMENT_ARRAY_BUFFER";
|
||||
} else {
|
||||
return "**UNKNOWN**(" + std::to_string(target) + ")";
|
||||
return "**UNKNOWN**";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +63,7 @@ static std::string PrintType(int ty) {
|
||||
} else if (ty == TINYGLTF_TYPE_MAT4) {
|
||||
return "MAT4";
|
||||
}
|
||||
return "**UNKNOWN**(" + std::to_string(ty) + ")";
|
||||
return "**UNKNOWN**";
|
||||
}
|
||||
|
||||
static std::string PrintComponentType(int ty) {
|
||||
@@ -86,7 +85,7 @@ static std::string PrintComponentType(int ty) {
|
||||
return "DOUBLE";
|
||||
}
|
||||
|
||||
return "**UNKNOWN**(" + std::to_string(ty) + ")";
|
||||
return "**UNKNOWN**";
|
||||
}
|
||||
|
||||
#if 0
|
||||
@@ -148,7 +147,7 @@ static std::string PrintWrapMode(int mode) {
|
||||
return "MIRRORED_REPEAT";
|
||||
}
|
||||
|
||||
return "**UNKNOWN**(" + std::to_string(mode) + ")";
|
||||
return "**UNKNOWN**";
|
||||
}
|
||||
|
||||
static std::string PrintFilterMode(int mode) {
|
||||
@@ -165,7 +164,7 @@ static std::string PrintFilterMode(int mode) {
|
||||
} else if (mode == TINYGLTF_TEXTURE_FILTER_LINEAR_MIPMAP_LINEAR) {
|
||||
return "LINEAR_MIPMAP_LINEAR";
|
||||
}
|
||||
return "**UNKNOWN**(" + std::to_string(mode) + ")";
|
||||
return "**UNKNOWN**";
|
||||
}
|
||||
|
||||
static std::string PrintIntArray(const std::vector<int> &arr) {
|
||||
|
||||
66
models/Extensions-issue97/test.gltf
Normal file
66
models/Extensions-issue97/test.gltf
Normal 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"
|
||||
]
|
||||
}
|
||||
@@ -41,4 +41,48 @@ TEST_CASE("datauri-in-glb", "[issue-79]") {
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
871
tiny_gltf.h
871
tiny_gltf.h
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user