Compare commits

..

1 Commits

Author SHA1 Message Date
Syoyo Fujita
bafde6a53e Use TINYGLTF_ENABLE_SERIALIZER ifdef to enable/disable serialization code. 2020-06-08 16:46:33 +09:00
20 changed files with 61 additions and 2047 deletions

View File

@@ -1 +0,0 @@
blank_issues_enabled: false

View File

@@ -1,30 +0,0 @@
---
name: Issue report
about: Create a report
title: ''
labels: ''
assignees: ''
---
**Describe the issue**
A clear and concise description of what the issue is.
**To Reproduce**
- OS
- Compiler, compiler version, compile options
- Please attach minimal and reproducible .glTF file if you got an issue related to .glTF data
**Expected behaviour**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.

View File

@@ -6,8 +6,7 @@ SET(CMAKE_CXX_STANDARD 11)
option(TINYGLTF_BUILD_LOADER_EXAMPLE "Build loader_example" ON)
option(TINYGLTF_BUILD_GL_EXAMPLES "Build GL exampels(requires glfw, OpenGL, etc)" OFF)
option(TINYGLTF_BUILD_VALIDATOR_EXAMPLE "Build validator example" OFF)
option(TINYGLTF_BUILD_BUILDER_EXAMPLE "Build glTF builder example" OFF)
option(TINYGLTF_BUILD_VALIDATOR_EXAMPLE "Build validator exampe" OFF)
if (TINYGLTF_BUILD_LOADER_EXAMPLE)
ADD_EXECUTABLE ( loader_example
@@ -23,11 +22,6 @@ endif (TINYGLTF_BUILD_GL_EXAMPLES)
if (TINYGLTF_BUILD_VALIDATOR_EXAMPLE)
ADD_SUBDIRECTORY ( examples/validator )
endif (TINYGLTF_BUILD_VALIDATOR_EXAMPLE)
if (TINYGLTF_BUILD_BUILDER_EXAMPLE)
ADD_SUBDIRECTORY ( examples/build-gltf )
endif (TINYGLTF_BUILD_BUILDER_EXAMPLE)
#
# TinuGLTF is a header-only library, so no library build. just install header files.
#

View File

@@ -3,7 +3,7 @@
`TinyGLTF` is a header only C++11 glTF 2.0 https://github.com/KhronosGroup/glTF library.
`TinyGLTF` uses Niels Lohmann's json library(https://github.com/nlohmann/json), so now it requires C++11 compiler.
If you are looking for old, C++03 version, please use `devel-picojson` branch(but not maintained anymore).
If you are looking for old, C++03 version, please use `devel-picojson` branch.
## Status
@@ -13,10 +13,6 @@ If you are looking for old, C++03 version, please use `devel-picojson` branch(bu
- v2.1.0 release(Draco support)
- v2.0.0 release(22 Aug, 2018)!
### Branches
* `sajson` : Use sajson to parse JSON. Parsing only but faster compile time(2x reduction compared to json.hpp and RapidJson)
## Builds
[![Build Status](https://travis-ci.org/syoyo/tinygltf.svg?branch=devel)](https://travis-ci.org/syoyo/tinygltf)
@@ -77,7 +73,6 @@ In extension(`ExtensionMap`), JSON number value is parsed as int or float(number
* [glview](examples/glview) : Simple glTF geometry viewer.
* [validator](examples/validator) : Simple glTF validator with JSON schema.
* [basic](examples/basic) : Basic glTF viewer with texturing support.
* [build-gltf](examples/build-gltf) : Build simple glTF scene from a scratch.
## Projects using TinyGLTF
@@ -91,7 +86,6 @@ In extension(`ExtensionMap`), JSON number value is parsed as int or float(number
* [GlslViewer](https://github.com/patriciogonzalezvivo/glslViewer) - live GLSL coding for MacOS and Linux
* [Vulkan-Samples](https://github.com/KhronosGroup/Vulkan-Samples) - The Vulkan Samples is collection of resources to help you develop optimized Vulkan applications.
* [TDME2](https://github.com/andreasdr/tdme2) - TDME2 - ThreeDeeMiniEngine2 is a lightweight 3D engine including tools suited for 3D game development using C++11
* [SanityEngine](https://github.com/DethRaid/SanityEngine) - A C++/D3D12 renderer focused on the personal and proessional development of its developer
* Your projects here! (Please send PR)
## TODOs
@@ -157,12 +151,9 @@ if (!ret) {
}
```
#### Loader options
* `TinyGLTF::SetPreserveimageChannels(bool onoff)`. `true` to preserve image channels as stored in image file for loaded image. `false` by default for backward compatibility(image channels are widen to `RGBA` 4 channels). Effective only when using builtin image loader(STB image loader).
## Compile options
* `TINYGLTF_ENABLE_SERIALIZER` : Enable glTF serialization feature.
* `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.

View File

@@ -1,6 +1,5 @@
.vs
Debug
Release
x64
packages

View File

@@ -22,32 +22,32 @@
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{0589AC44-0CF3-40D8-8D89-68393CFD40F3}</ProjectGuid>
<RootNamespace>basic</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<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>v142</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<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>v142</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>

View File

@@ -329,7 +329,7 @@ static void error_callback(int error, const char *description) {
}
int main(int argc, char **argv) {
std::string filename = "../../../models/Cube/Cube.gltf";
std::string filename = "../../models/Cube/Cube.gltf";
if (argc > 1) {
filename = argv[1];
@@ -341,12 +341,9 @@ int main(int argc, char **argv) {
// Force create OpenGL 3.3
// NOTE(syoyo): Linux + NVIDIA driver segfaults for some reason? commenting out glfwWindowHint will work.
// Note (PE): On laptops with intel hd graphics card you can overcome the segfault by enabling experimental, see below (tested on lenovo thinkpad)
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glewExperimental = GL_TRUE;
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif

View File

@@ -1,2 +0,0 @@
all:
$(CXX) -o create_triangle_gltf -I../../ create_triangle_gltf.cpp

View File

@@ -1,121 +0,0 @@
// An example of how to generate a gltf file from scratch. This example
// was translated from the pygltlib documentation in the pypi project page,
// which in turn is based on the Khronos Sample Models at:
//
// https://github.com/KhronosGroup/glTF-Sample-Models
//
// This example is released under the MIT license.
//
// 2021-02-25 Thu
// Dov Grobgeld <dov.grobgeld@gmail.com>
// Define these only in *one* .cc file.
#define TINYGLTF_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
// #define TINYGLTF_NOEXCEPTION // optional. disable exception handling.
#include "tiny_gltf.h"
int main(int argc, char **argv)
{
// Create a model with a single mesh and save it as a gltf file
tinygltf::Model m;
tinygltf::Scene scene;
tinygltf::Mesh mesh;
tinygltf::Primitive primitive;
tinygltf::Node node;
tinygltf::Buffer buffer;
tinygltf::BufferView bufferView1;
tinygltf::BufferView bufferView2;
tinygltf::Accessor accessor1;
tinygltf::Accessor accessor2;
tinygltf::Asset asset;
// This is the raw data buffer.
buffer.data = {
// 6 bytes of indices and two bytes of padding
0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x00,
// 36 bytes of floating point numbers
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3f,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3f,
0x00,0x00,0x00,0x00};
// "The indices of the vertices (ELEMENT_ARRAY_BUFFER) take up 6 bytes in the
// start of the buffer.
bufferView1.buffer = 0;
bufferView1.byteOffset=0;
bufferView1.byteLength=6;
bufferView1.target = TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER;
// The vertices take up 36 bytes (3 vertices * 3 floating points * 4 bytes)
// at position 8 in the buffer and are of type ARRAY_BUFFER
bufferView2.buffer = 0;
bufferView2.byteOffset=8;
bufferView2.byteLength=36;
bufferView2.target = TINYGLTF_TARGET_ARRAY_BUFFER;
// Describe the layout of bufferView1, the indices of the vertices
accessor1.bufferView = 0;
accessor1.byteOffset = 0;
accessor1.componentType = TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT;
accessor1.count = 3;
accessor1.type = TINYGLTF_TYPE_SCALAR;
accessor1.maxValues.push_back(2);
accessor1.minValues.push_back(0);
// Describe the layout of bufferView2, the vertices themself
accessor2.bufferView = 1;
accessor2.byteOffset = 0;
accessor2.componentType = TINYGLTF_COMPONENT_TYPE_FLOAT;
accessor2.count = 3;
accessor2.type = TINYGLTF_TYPE_VEC3;
accessor2.maxValues = {1.0, 1.0, 0.0};
accessor2.minValues = {0.0, 0.0, 0.0};
// Build the mesh primitive and add it to the mesh
primitive.indices = 0; // The index of the accessor for the vertex indices
primitive.attributes["POSITION"] = 1; // The index of the accessor for positions
primitive.material = 0;
primitive.mode = TINYGLTF_MODE_TRIANGLES;
mesh.primitives.push_back(primitive);
// Other tie ups
node.mesh = 0;
scene.nodes.push_back(0); // Default scene
// Define the asset. The version is required
asset.version = "2.0";
asset.generator = "tinygltf";
// Now all that remains is to tie back all the loose objects into the
// our single model.
m.scenes.push_back(scene);
m.meshes.push_back(mesh);
m.nodes.push_back(node);
m.buffers.push_back(buffer);
m.bufferViews.push_back(bufferView1);
m.bufferViews.push_back(bufferView2);
m.accessors.push_back(accessor1);
m.accessors.push_back(accessor2);
m.asset = asset;
// Create a simple material
tinygltf::Material mat;
mat.pbrMetallicRoughness.baseColorFactor = {1.0f, 0.9f, 0.9f, 1.0f};
mat.doubleSided = true;
m.materials.push_back(mat);
// Save it to a file
tinygltf::TinyGLTF gltf;
gltf.WriteGltfSceneToFile(&m, "triangle.gltf",
true, // embedImages
true, // embedBuffers
true, // pretty print
false); // write binary
exit(0);
}

View File

@@ -1,36 +0,0 @@
cmake_minimum_required(VERSION 3.5)
project(dxview)
find_package(glfw3 CONFIG REQUIRED)
find_package(spdlog CONFIG REQUIRED)
add_executable(dxview
src/Viewer.h
src/Viewer.cc
src/dxview.cc
)
target_include_directories(dxview
PRIVATE
../../
)
target_compile_definitions(dxview
PRIVATE
DXVIEW_SWAP_CHAIN_BUFFER_COUNT=3
DXVIEW_RES_DIR=L"${PROJECT_SOURCE_DIR}/res"
)
target_link_libraries(dxview
PRIVATE
dxgi
d3dcompiler
d3d12
glfw
spdlog::spdlog
)
set_target_properties(dxview
PROPERTIES
CXX_STANDARD 17
)

View File

@@ -1,37 +0,0 @@
# DirectX glTF Viewer
## Overview
This project was motivated by a lack of sample code demonstrating the graphics API agnostic nature of the glTF specification. The sample code is written using modern C++ and DirectX 12 for the client application.
## Features
* [x] DirectX 12
* [ ] Loader
* [ ] Animation
* [ ] Morph Target
* [ ] Physical Base Rendering
* [ ] Environment Map
## Dependencies
* [CMake](https://github.com/Kitware/CMake)
* [Vcpkg](https://github.com/Microsoft/vcpkg)
* [GLFW](https://github.com/glfw/glfw)
* [spdlog](https://github.com/gabime/spdlog)
## Building
### Install dependencies
```
vcpkg install glfw3:x64-windows
vcpkg install spdlog:x64-windows
```
### Generate Project Files
```
mkdir build
cmake . -B build -DCMAKE_TOOLCHAIN_FILE=${VCPKG_DIR}/script/buildsystem/vcpkg.cmake
```

View File

@@ -1,3 +0,0 @@
float4 main() : SV_Target {
return float4(0.5, 0.5, 0.5, 1.0);
}

View File

@@ -1,52 +0,0 @@
struct RS2PS {
float4 position : SV_POSITION;
#ifdef HAS_TEXCOORD_0
float2 texcoord_0: TEXCOORD_0;
#endif
};
struct TextureInfo {
uint textureIndex;
uint samplerIndex;
};
struct PBRMetallicRoughness {
float4 baseColorFactor;
TextureInfo baseColorTexture;
float metallicFactor;
float roughnessFactor;
TextureInfo metallicRoughnessTexture;
};
cbuffer Material : register(b2) {
PBRMetallicRoughness pbrMetallicRoughness;
};
Texture2D textures[5] : register(t0);
SamplerState samplerState[5] : register(s0);
float4 getBaseColor(float2 uv) {
float4 baseColor = pbrMetallicRoughness.baseColorFactor;
#ifdef HAS_TEXCOORD_0
TextureInfo baseColorTexture = pbrMetallicRoughness.baseColorTexture;
if (baseColorTexture.textureIndex >= 0) {
baseColor *= textures[baseColorTexture.textureIndex].Sample(samplerState[baseColorTexture.samplerIndex], uv);
}
#endif
return baseColor;
}
float4 main(RS2PS input) : SV_Target {
float2 uv = float2(0.0, 0.0);
#ifdef HAS_TEXCOORD_0
uv = input.texcoord_0;
#endif
float4 color = getBaseColor(uv);
return color;
}

View File

@@ -1,46 +0,0 @@
struct IA2VS {
float3 position : POSITION;
#ifdef HAS_NORMAL
float3 normal : NORMAL;
#endif
#ifdef HAS_TANGENT
float4 tangent : TANGENT;
#endif
#ifdef HAS_TEXCOORD_0
float2 texcoord_0: TEXCOORD_0;
#endif
};
struct VS2RS {
float4 position : SV_POSITION;
#ifdef HAS_TEXCOORD_0
float2 texcoord_0: TEXCOORD_0;
#endif
};
cbuffer Camera : register(b0) {
float4x4 V;
float4x4 P;
float4x4 VP;
};
cbuffer Node : register(b1) {
float4x4 M;
};
VS2RS main(IA2VS input) {
VS2RS output;
output.position = mul(float4(input.position, 1.0), M);
output.position = mul(output.position, V);
output.position = mul(output.position, P);
#ifdef HAS_TEXCOORD_0
output.texcoord_0 = input.texcoord_0;
#endif
return output;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,130 +0,0 @@
#ifndef DXVIEW_VIEWER_GUARD
#define DXVIEW_VIEWER_GUARD
#include <DirectXMath.h>
#include <d3d12.h>
#include <dxgi1_6.h>
#include <tiny_gltf.h>
#include <wrl.h>
#include <filesystem>
#include <map>
#include <string>
#include <vector>
using Microsoft::WRL::ComPtr;
enum RenderPassType { RENDER_PASS_TYPE_PRESENT = 0, RENDER_PASS_TYPE_COUNT };
struct RenderTarget {
ComPtr<ID3D12Resource> pTexture;
D3D12_CPU_DESCRIPTOR_HANDLE viewDescriptor;
};
struct TextureInfo {
int32_t textureIndex;
int32_t samplerIndex;
};
struct PBRMetallicRoughness {
DirectX::XMFLOAT4 baseColorFactor;
TextureInfo baseColorTexture;
float metallicFactor;
float roughnessFactor;
TextureInfo metallicRoughnessTexture;
};
struct Material {
std::string name;
D3D12_BLEND_DESC blendDesc;
D3D12_RASTERIZER_DESC rasterizerDesc;
ComPtr<ID3D12Resource> pBuffer;
void* pBufferData;
ComPtr<ID3D12DescriptorHeap> pSRVDescriptorHeap;
ComPtr<ID3D12DescriptorHeap> pSamplerDescriptorHeap;
};
struct Attribute {
std::string name;
DXGI_FORMAT format;
D3D12_VERTEX_BUFFER_VIEW vertexBufferView;
};
struct Primitive {
std::vector<Attribute> attributes;
uint32_t vertexCount;
D3D12_PRIMITIVE_TOPOLOGY primitiveTopology;
D3D12_INDEX_BUFFER_VIEW indexBufferView;
uint32_t indexCount;
Material* pMaterial;
ComPtr<ID3D12RootSignature> pRootSignature;
ComPtr<ID3D12PipelineState> pPipelineState;
};
struct Mesh {
std::string name;
std::vector<Primitive> primitives;
};
struct Node {
DirectX::XMFLOAT4X4 M;
};
struct Camera {
DirectX::XMFLOAT4X4 V;
DirectX::XMFLOAT4X4 P;
DirectX::XMFLOAT4X4 VP;
};
class Viewer {
public:
Viewer(HWND window, tinygltf::Model* pModel);
void update(double deltaTime);
void render(double deltaTime);
private:
void initDirectX(HWND window);
void buildRenderTargets();
void buildResources();
void buildBuffers(std::vector<ComPtr<ID3D12Resource> >* pStagingResources);
void buildImages(std::vector<ComPtr<ID3D12Resource> >* pStagingResources);
void buildSamplerDescs();
void buildMaterials();
void buildMeshes();
void buildNodes();
void drawNode(uint64_t nodeIndex);
private:
tinygltf::Model* pModel_;
ComPtr<IDXGIFactory1> pFactory_;
ComPtr<IDXGIAdapter1> pAdapter_;
ComPtr<ID3D12Device> pDevice_;
ComPtr<ID3D12CommandQueue> pDirectCommandQueue_;
UINT64 directFenceValue_;
ComPtr<ID3D12Fence> pDirectFence_;
ComPtr<ID3D12CommandQueue> pCopyCommandQueue_;
UINT64 copyFenceValue_;
ComPtr<ID3D12Fence> pCopyFence_;
ComPtr<IDXGISwapChain3> pSwapChain_;
ComPtr<ID3D12Resource> pSwapChainBuffers_[DXVIEW_SWAP_CHAIN_BUFFER_COUNT];
ComPtr<ID3D12CommandAllocator>
pDirectCommandAllocators_[DXVIEW_SWAP_CHAIN_BUFFER_COUNT];
ComPtr<ID3D12GraphicsCommandList> pDirectCommandList_;
ComPtr<ID3D12CommandAllocator> pCopyCommandAllocator_;
ComPtr<ID3D12GraphicsCommandList> pCopyCommandList_;
UINT descriptorIncrementSize_[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES];
ComPtr<ID3D12DescriptorHeap>
pRTVDescriptorHeaps_[DXVIEW_SWAP_CHAIN_BUFFER_COUNT];
std::vector<RenderTarget> renderTargets_[DXVIEW_SWAP_CHAIN_BUFFER_COUNT];
std::vector<ComPtr<ID3D12Resource> > pBuffers_;
std::vector<ComPtr<ID3D12Resource> > pTextures_;
std::vector<D3D12_SAMPLER_DESC> samplerDescs_;
std::vector<Material> materials_;
std::vector<Mesh> meshes_;
std::vector<ComPtr<ID3D12Resource> > pNodeBuffers_;
ComPtr<ID3D12Resource> pCameraBuffer_;
};
#endif

View File

@@ -1,90 +0,0 @@
#define GLFW_EXPOSE_NATIVE_WIN32
#define TINYGLTF_IMPLEMENTATION
#define STBI_MSC_SECURE_CRT
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include <GLFW/glfw3.h>
#include <GLFW/glfw3native.h>
#include <spdlog/spdlog.h>
#include <tiny_gltf.h>
#undef GLFW_EXPOSE_NATIVE_WIN32
#undef TINYGLTF_IMPLEMENTATION
#undef STBI_MSC_SECURE_CRT
#undef STB_IMAGE_IMPLEMENTATION
#undef STB_IMAGE_WRITE_IMPLEMENTATION
#include <iostream>
#include <string>
#include "Viewer.h"
static void onError(int error, const char* message) {
spdlog::error("[{}] {}", error, message);
}
static void onRender(Viewer* pViewer, double deltaTime) {
pViewer->update(deltaTime);
pViewer->render(deltaTime);
}
int main(int argc, char* argv[]) {
tinygltf::TinyGLTF context;
tinygltf::Model model;
std::string error;
std::string warning;
if (!context.LoadASCIIFromFile(&model, &error, &warning, argv[1])) {
if (!error.empty()) {
spdlog::error("{}", error);
}
if (!warning.empty()) {
spdlog::warn("{}", warning);
}
exit(EXIT_FAILURE);
}
GLFWwindow* pWindow;
glfwSetErrorCallback(onError);
if (!glfwInit()) {
spdlog::error("Fail to initialize GLFW!!!");
exit(EXIT_FAILURE);
}
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
pWindow = glfwCreateWindow(512, 512, "dxview", nullptr, nullptr);
if (!pWindow) {
spdlog::error("Fail to create GLFWwindow!!!");
glfwTerminate();
exit(EXIT_FAILURE);
}
auto pViewer = std::make_unique<Viewer>(glfwGetWin32Window(pWindow), &model);
if (!pViewer) {
spdlog::error("Fail to create Viewer");
glfwDestroyWindow(pWindow);
glfwTerminate();
exit(EXIT_FAILURE);
}
auto prevTimeStamp = glfwGetTime();
while (!glfwWindowShouldClose(pWindow)) {
auto currTimeStamp = glfwGetTime();
onRender(pViewer.get(), currTimeStamp - prevTimeStamp);
prevTimeStamp = currTimeStamp;
glfwPollEvents();
}
glfwDestroyWindow(pWindow);
glfwTerminate();
exit(EXIT_SUCCESS);
}

View File

@@ -3,9 +3,6 @@
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "tiny_gltf.h"
// Nlohmann json(include ../json.hpp)
#include "json.hpp"
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
#include "catch.hpp"
@@ -415,28 +412,6 @@ TEST_CASE("image-uri-spaces", "[issue-236]") {
REQUIRE(true == ret);
}
TEST_CASE("serialize-empty-material", "[issue-294]") {
tinygltf::Model m;
tinygltf::Material mat;
mat.pbrMetallicRoughness.baseColorFactor = {1.0f, 1.0f, 1.0f, 1.0f}; // default baseColorFactor
m.materials.push_back(mat);
std::stringstream os;
tinygltf::TinyGLTF ctx;
ctx.WriteGltfSceneToStream(&m, os, false, false);
// use nlohmann json
nlohmann::json j = nlohmann::json::parse(os.str());
REQUIRE(1 == j["materials"].size());
REQUIRE(j["asset"].is_null());
REQUIRE(j["materials"][0].is_object());
}
#ifndef TINYGLTF_NO_FS
TEST_CASE("expandpath-utf-8", "[pr-226]") {

View File

@@ -26,9 +26,7 @@
// THE SOFTWARE.
// Version:
// - v2.5.0 Add SetPreserveImageChannels() option to load image data as is.
// - v2.4.3 Fix null object output when when material has all default
// parameters.
// - v2.4.3 Introduce TINYGLTF_ENABLE_SERIALIZER.
// - v2.4.2 Decode percent-encoded URI.
// - v2.4.1 Fix some glTF object class does not have `extensions` and/or
// `extras` property.
@@ -298,7 +296,7 @@ class Value {
DEFAULT_METHODS(Value)
char Type() const { return static_cast<char>(type_); }
char Type() const { return static_cast<const char>(type_); }
bool IsBool() const { return (type_ == BOOL_TYPE); }
@@ -614,7 +612,7 @@ struct Sampler {
int wrapT =
TINYGLTF_TEXTURE_WRAP_REPEAT; // ["CLAMP_TO_EDGE", "MIRRORED_REPEAT",
// "REPEAT"], default "REPEAT"
//int wrapR = TINYGLTF_TEXTURE_WRAP_REPEAT; // TinyGLTF extension. currently not used.
int wrapR = TINYGLTF_TEXTURE_WRAP_REPEAT; // TinyGLTF extension
Value extras;
ExtensionMap extensions;
@@ -627,7 +625,8 @@ struct Sampler {
: minFilter(-1),
magFilter(-1),
wrapS(TINYGLTF_TEXTURE_WRAP_REPEAT),
wrapT(TINYGLTF_TEXTURE_WRAP_REPEAT) {}
wrapT(TINYGLTF_TEXTURE_WRAP_REPEAT),
wrapR(TINYGLTF_TEXTURE_WRAP_REPEAT) {}
DEFAULT_METHODS(Sampler)
bool operator==(const Sampler &) const;
};
@@ -666,8 +665,6 @@ struct Image {
width = -1;
height = -1;
component = -1;
bits = -1;
pixel_type = -1;
}
DEFAULT_METHODS(Image)
@@ -850,10 +847,8 @@ struct Accessor {
std::string extras_json_string;
std::string extensions_json_string;
std::vector<double>
minValues; // optional. integer value is promoted to double
std::vector<double>
maxValues; // optional. integer value is promoted to double
std::vector<double> minValues; // optional
std::vector<double> maxValues; // optional
struct {
int count;
@@ -1002,7 +997,6 @@ struct Primitive {
Primitive() {
material = -1;
indices = -1;
mode = -1;
}
DEFAULT_METHODS(Primitive)
bool operator==(const Primitive &) const;
@@ -1193,8 +1187,7 @@ enum SectionCheck {
///
typedef bool (*LoadImageDataFunction)(Image *, const int, std::string *,
std::string *, int, int,
const unsigned char *, int,
void *user_pointer);
const unsigned char *, int, void *);
///
/// WriteImageDataFunction type. Signature for custom image writing callbacks.
@@ -1258,8 +1251,7 @@ struct FsCallbacks {
bool FileExists(const std::string &abs_filename, void *);
///
/// Expand file path(e.g. `~` to home directory on posix, `%APPDATA%` to
/// `C:\\Users\\tinygltf\\AppData`)
/// Expand file path(e.g. `~` to home directory on posix, `%APPDATA%` to `C:\Users\tinygltf\AppData`)
///
/// @param[in] filepath File path string. Assume UTF-8
/// @param[in] userdata User data. Set to `nullptr` if you don't need it.
@@ -1332,6 +1324,8 @@ class TinyGLTF {
const std::string &base_dir = "",
unsigned int check_sections = REQUIRE_VERSION);
#if defined(TINYGLTF_ENABLE_SERIALIZER)
///
/// Write glTF to stream, buffers and images will be embeded
///
@@ -1345,21 +1339,22 @@ class TinyGLTF {
bool embedImages, bool embedBuffers,
bool prettyPrint, bool writeBinary);
#endif
///
/// Set callback to use for loading image data
///
void SetImageLoader(LoadImageDataFunction LoadImageData, void *user_data);
///
/// Unset(remove) callback of loading image data
///
void RemoveImageLoader();
#if defined(TINYGLTF_ENABLE_SERIALIZER)
///
/// Set callback to use for writing image data
///
void SetImageWriter(WriteImageDataFunction WriteImageData, void *user_data);
#endif
///
/// Set callbacks to use for filesystem (fs) access and their user data
///
@@ -1393,16 +1388,6 @@ class TinyGLTF {
return store_original_json_for_extras_and_extensions_;
}
///
/// Specify whether preserve image channales when loading images or not.
/// (Not effective when the user suppy their own LoadImageData callbacks)
///
void SetPreserveImageChannels(bool onoff) {
preserve_image_channels_ = onoff;
}
bool GetPreserveImageChannels() const { return preserve_image_channels_; }
private:
///
/// Loads glTF asset from string(memory).
@@ -1422,9 +1407,6 @@ class TinyGLTF {
bool store_original_json_for_extras_and_extensions_ = false;
bool preserve_image_channels_ = false; /// Default false(expand channels to
/// RGBA) for backward compatibility.
FsCallbacks fs = {
#ifndef TINYGLTF_NO_FS
&tinygltf::FileExists, &tinygltf::ExpandFilePath,
@@ -1444,8 +1426,7 @@ class TinyGLTF {
#else
nullptr;
#endif
void *load_image_user_data_{nullptr};
bool user_image_loader_{false};
void *load_image_user_data_ = reinterpret_cast<void *>(&fs);
WriteImageDataFunction WriteImageData =
#ifndef TINYGLTF_NO_STB_IMAGE_WRITE
@@ -1453,7 +1434,7 @@ class TinyGLTF {
#else
nullptr;
#endif
void *write_image_user_data_{nullptr};
void *write_image_user_data_ = reinterpret_cast<void *>(&fs);
};
#ifdef __clang__
@@ -1707,19 +1688,6 @@ void JsonParse(JsonDocument &doc, const char *str, size_t length,
namespace tinygltf {
///
/// Internal LoadImageDataOption struct.
/// This struct is passed through `user_pointer` in LoadImageData.
/// The struct is not passed when the user supply their own LoadImageData
/// callbacks.
///
struct LoadImageDataOption {
// true: preserve image channels(e.g. load as RGB image if the image has RGB
// channels) default `false`(channels are expanded to RGBA for backward
// compatiblity).
bool preserve_channels{false};
};
// Equals function for Value, for recursivity
static bool Equals(const tinygltf::Value &one, const tinygltf::Value &other) {
if (one.Type() != other.Type()) return false;
@@ -1932,9 +1900,8 @@ bool Sampler::operator==(const Sampler &other) const {
return this->extensions == other.extensions && this->extras == other.extras &&
this->magFilter == other.magFilter &&
this->minFilter == other.minFilter && this->name == other.name &&
this->wrapR == other.wrapR && this->wrapS == other.wrapS &&
this->wrapT == other.wrapT;
//this->wrapR == other.wrapR && this->wrapS == other.wrapS &&
}
bool Scene::operator==(const Scene &other) const {
return this->extensions == other.extensions && this->extras == other.extras &&
@@ -2335,40 +2302,22 @@ static bool LoadExternalFile(std::vector<unsigned char> *out, std::string *err,
void TinyGLTF::SetImageLoader(LoadImageDataFunction func, void *user_data) {
LoadImageData = func;
load_image_user_data_ = user_data;
user_image_loader_ = true;
}
void TinyGLTF::RemoveImageLoader() {
LoadImageData =
#ifndef TINYGLTF_NO_STB_IMAGE
&tinygltf::LoadImageData;
#else
nullptr;
#endif
load_image_user_data_ = nullptr;
user_image_loader_ = false;
}
#ifndef TINYGLTF_NO_STB_IMAGE
bool LoadImageData(Image *image, const int image_idx, std::string *err,
std::string *warn, int req_width, int req_height,
const unsigned char *bytes, int size, void *user_data) {
(void)user_data;
(void)warn;
LoadImageDataOption option;
if (user_data) {
option = *reinterpret_cast<LoadImageDataOption *>(user_data);
}
int w = 0, h = 0, comp = 0, req_comp = 0;
unsigned char *data = nullptr;
// preserve_channels true: Use channels stored in the image file.
// false: force 32-bit textures for common Vulkan compatibility. It appears
// that some GPU drivers do not support 24-bit images for Vulkan
req_comp = option.preserve_channels ? 0 : 4;
// force 32-bit textures for common Vulkan compatibility. It appears that
// some GPU drivers do not support 24-bit images for Vulkan
req_comp = 4;
int bits = 8;
int pixel_type = TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE;
@@ -2440,29 +2389,28 @@ bool LoadImageData(Image *image, const int image_idx, std::string *err,
}
}
if (req_comp != 0) {
// loaded data has `req_comp` channels(components)
comp = req_comp;
}
image->width = w;
image->height = h;
image->component = comp;
image->component = req_comp;
image->bits = bits;
image->pixel_type = pixel_type;
image->image.resize(static_cast<size_t>(w * h * comp) * size_t(bits / 8));
std::copy(data, data + w * h * comp * (bits / 8), image->image.begin());
image->image.resize(static_cast<size_t>(w * h * req_comp) * size_t(bits / 8));
std::copy(data, data + w * h * req_comp * (bits / 8), image->image.begin());
stbi_image_free(data);
return true;
}
#endif
#if defined(TINYGLTF_ENABLE_SERIALIZER)
void TinyGLTF::SetImageWriter(WriteImageDataFunction func, void *user_data) {
WriteImageData = func;
write_image_user_data_ = user_data;
}
#endif
#ifndef TINYGLTF_NO_STB_IMAGE_WRITE
static void WriteToMemory_stbi(void *context, void *data, int size) {
std::vector<unsigned char> *buffer =
@@ -2557,7 +2505,7 @@ static inline std::wstring UTF8ToWchar(const std::string &str) {
static inline std::string WcharToUTF8(const std::wstring &wstr) {
int str_size = WideCharToMultiByte(CP_UTF8, 0, wstr.data(), (int)wstr.size(),
nullptr, 0, NULL, NULL);
nullptr, 0, NULL, NULL);
std::string str(str_size, 0);
WideCharToMultiByte(CP_UTF8, 0, wstr.data(), (int)wstr.size(), &str[0],
(int)str.size(), NULL, NULL);
@@ -2700,8 +2648,7 @@ bool ReadWholeFile(std::vector<unsigned char> *out, std::string *err,
__gnu_cxx::stdio_filebuf<char> wfile_buf(file_descriptor, std::ios_base::in);
std::istream f(&wfile_buf);
#elif defined(_MSC_VER) || defined(_LIBCPP_VERSION)
// For libcxx, assume _LIBCPP_HAS_OPEN_WITH_WCHAR is defined to accept
// `wchar_t *`
// For libcxx, assume _LIBCPP_HAS_OPEN_WITH_WCHAR is defined to accept `wchar_t *`
std::ifstream f(UTF8ToWchar(filepath).c_str(), std::ifstream::binary);
#else
// Unknown compiler/runtime
@@ -3063,9 +3010,7 @@ json_const_iterator ObjectEnd(const json &o) {
#endif
}
// Making this a const char* results in a pointer to a temporary when
// TINYGLTF_USE_RAPIDJSON is off.
std::string GetKey(json_const_iterator &it) {
const char *GetKey(json_const_iterator &it) {
#ifdef TINYGLTF_USE_RAPIDJSON
return it->name.GetString();
#else
@@ -5089,12 +5034,12 @@ static bool ParseSampler(Sampler *sampler, std::string *err, const json &o,
int magFilter = -1;
int wrapS = TINYGLTF_TEXTURE_WRAP_REPEAT;
int wrapT = TINYGLTF_TEXTURE_WRAP_REPEAT;
//int wrapR = TINYGLTF_TEXTURE_WRAP_REPEAT;
int wrapR = TINYGLTF_TEXTURE_WRAP_REPEAT;
ParseIntegerProperty(&minFilter, err, o, "minFilter", false);
ParseIntegerProperty(&magFilter, err, o, "magFilter", false);
ParseIntegerProperty(&wrapS, err, o, "wrapS", false);
ParseIntegerProperty(&wrapT, err, o, "wrapT", false);
//ParseIntegerProperty(&wrapR, err, o, "wrapR", false); // tinygltf extension
ParseIntegerProperty(&wrapR, err, o, "wrapR", false); // tinygltf extension
// TODO(syoyo): Check the value is alloed one.
// (e.g. we allow 9728(NEAREST), but don't allow 9727)
@@ -5103,7 +5048,7 @@ static bool ParseSampler(Sampler *sampler, std::string *err, const json &o,
sampler->magFilter = magFilter;
sampler->wrapS = wrapS;
sampler->wrapT = wrapT;
//sampler->wrapR = wrapR;
sampler->wrapR = wrapR;
ParseExtensionsProperty(&(sampler->extensions), err, o);
ParseExtrasProperty(&(sampler->extras), o);
@@ -5770,13 +5715,10 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
for (auto &target : primitive.targets) {
for (auto &attribute : target) {
auto bufferView =
model->accessors[size_t(attribute.second)].bufferView;
// bufferView could be null(-1) for sparse morph target
if (bufferView >= 0) {
model->bufferViews[size_t(bufferView)].target =
TINYGLTF_TARGET_ARRAY_BUFFER;
}
model
->bufferViews[size_t(
model->accessors[size_t(attribute.second)].bufferView)]
.target = TINYGLTF_TARGET_ARRAY_BUFFER;
}
}
}
@@ -5886,18 +5828,6 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
}
// 11. Parse Image
void *load_image_user_data{nullptr};
LoadImageDataOption load_image_option;
if (user_image_loader_) {
// Use user supplied pointer
load_image_user_data = load_image_user_data_;
} else {
load_image_option.preserve_channels = preserve_image_channels_;
load_image_user_data = reinterpret_cast<void *>(&load_image_option);
}
{
int idx = 0;
bool success = ForEachInArray(v, "images", [&](const json &o) {
@@ -5910,7 +5840,7 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
Image image;
if (!ParseImage(&image, idx, err, warn, o,
store_original_json_for_extras_and_extensions_, base_dir,
&fs, &this->LoadImageData, load_image_user_data)) {
&fs, &this->LoadImageData, load_image_user_data_)) {
return false;
}
@@ -5948,7 +5878,7 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
bool ret = LoadImageData(
&image, idx, err, warn, image.width, image.height,
&buffer.data[bufferView.byteOffset],
static_cast<int>(bufferView.byteLength), load_image_user_data);
static_cast<int>(bufferView.byteLength), load_image_user_data_);
if (!ret) {
return false;
}
@@ -6297,6 +6227,8 @@ bool TinyGLTF::LoadBinaryFromFile(Model *model, std::string *err,
return ret;
}
#if defined(TINYGLTF_ENABLE_SERIALIZER)
///////////////////////
// GLTF Serialization
///////////////////////
@@ -6624,33 +6556,8 @@ static void SerializeGltfAccessor(Accessor &accessor, json &o) {
SerializeNumberProperty<int>("componentType", accessor.componentType, o);
SerializeNumberProperty<size_t>("count", accessor.count, o);
if ((accessor.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT) ||
(accessor.componentType == TINYGLTF_COMPONENT_TYPE_DOUBLE)) {
SerializeNumberArrayProperty<double>("min", accessor.minValues, o);
SerializeNumberArrayProperty<double>("max", accessor.maxValues, o);
} else {
// Issue #301. Serialize as integer.
// Assume int value is within [-2**31-1, 2**31-1]
{
std::vector<int> values;
std::transform(accessor.minValues.begin(), accessor.minValues.end(),
std::back_inserter(values),
[](double v) { return static_cast<int>(v); });
SerializeNumberArrayProperty<int>("min", values, o);
}
{
std::vector<int> values;
std::transform(accessor.maxValues.begin(), accessor.maxValues.end(),
std::back_inserter(values),
[](double v) { return static_cast<int>(v); });
SerializeNumberArrayProperty<int>("max", values, o);
}
}
SerializeNumberArrayProperty<double>("min", accessor.minValues, o);
SerializeNumberArrayProperty<double>("max", accessor.maxValues, o);
if (accessor.normalized)
SerializeValue("normalized", Value(accessor.normalized), o);
std::string type;
@@ -7161,7 +7068,7 @@ static void SerializeGltfSampler(Sampler &sampler, json &o) {
if (sampler.minFilter != -1) {
SerializeNumberProperty("minFilter", sampler.minFilter, o);
}
//SerializeNumberProperty("wrapR", sampler.wrapR, o);
SerializeNumberProperty("wrapR", sampler.wrapR, o);
SerializeNumberProperty("wrapS", sampler.wrapS, o);
SerializeNumberProperty("wrapT", sampler.wrapT, o);
@@ -7323,16 +7230,6 @@ static void SerializeGltfModel(Model *model, json &o) {
for (unsigned int i = 0; i < model->materials.size(); ++i) {
json material;
SerializeGltfMaterial(model->materials[i], material);
if (JsonIsNull(material)) {
// Issue 294.
// `material` does not have any required parameters
// so the result may be null(unmodified) when all material parameters
// have default value.
//
// null is not allowed thus we create an empty JSON object.
JsonSetObject(material);
}
JsonPushBack(materials, std::move(material));
}
JsonAddMember(o, "materials", std::move(materials));
@@ -7458,9 +7355,8 @@ static void SerializeGltfModel(Model *model, json &o) {
// Also add "KHR_lights_punctual" to `extensionsUsed`
{
auto has_khr_lights_punctual =
std::find_if(extensionsUsed.begin(), extensionsUsed.end(),
[](const std::string &s) {
auto has_khr_lights_punctual = std::find_if(
extensionsUsed.begin(), extensionsUsed.end(), [](const std::string &s) {
return (s.compare("KHR_lights_punctual") == 0);
});
@@ -7471,7 +7367,7 @@ static void SerializeGltfModel(Model *model, json &o) {
}
// Extensions used
if (extensionsUsed.size()) {
if (model->extensionsUsed.size()) {
SerializeStringArrayProperty("extensionsUsed", extensionsUsed, o);
}
@@ -7738,6 +7634,8 @@ bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename,
return true;
}
#endif // TINYGLTF_ENABLE_SERIALIZER
} // namespace tinygltf
#ifdef __clang__