mirror of
https://github.com/syoyo/tinygltf.git
synced 2026-06-08 11:13:50 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a159945db9 | ||
|
|
010ee9c67b | ||
|
|
a23971c603 | ||
|
|
1923067982 | ||
|
|
68adc4ba5e | ||
|
|
42a8cd50ff | ||
|
|
0543640a83 | ||
|
|
9c59a0b64c | ||
|
|
452541a231 | ||
|
|
78fe8d9b89 | ||
|
|
51e5508fa0 |
10
README.md
10
README.md
@@ -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.
|
||||
If you are looking for old, C++03 version, please use `devel-picojson` branch(but not maintained anymore).
|
||||
|
||||
## Status
|
||||
|
||||
@@ -13,6 +13,10 @@ If you are looking for old, C++03 version, please use `devel-picojson` branch.
|
||||
- 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
|
||||
|
||||
[](https://travis-ci.org/syoyo/tinygltf)
|
||||
@@ -151,6 +155,10 @@ if (!ret) {
|
||||
}
|
||||
```
|
||||
|
||||
#### Loader options
|
||||
|
||||
* `TinyGLTF::SetPreserveimageChannels(bool onoff)`. `true` to preserve image channels as stored in image file for loaded image. `false` by default for backward compatibility(image channels are widen to `RGBA` 4 channels). Effective only when using builtin image loader(STB image loader).
|
||||
|
||||
## Compile options
|
||||
|
||||
* `TINYGLTF_NOEXCEPTION` : Disable C++ exception in JSON parsing. You can use `-fno-exceptions` or by defining the symbol `JSON_NOEXCEPTION` and `TINYGLTF_NOEXCEPTION` to fully remove C++ exception codes when compiling TinyGLTF.
|
||||
|
||||
1
examples/basic/.gitignore
vendored
1
examples/basic/.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
.vs
|
||||
Debug
|
||||
Release
|
||||
x64
|
||||
packages
|
||||
|
||||
|
||||
@@ -22,32 +22,32 @@
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{0589AC44-0CF3-40D8-8D89-68393CFD40F3}</ProjectGuid>
|
||||
<RootNamespace>basic</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -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,9 +341,12 @@ int main(int argc, char **argv) {
|
||||
|
||||
// Force create OpenGL 3.3
|
||||
// NOTE(syoyo): Linux + NVIDIA driver segfaults for some reason? commenting out glfwWindowHint will work.
|
||||
// Note (PE): On laptops with intel hd graphics card you can overcome the segfault by enabling experimental, see below (tested on lenovo thinkpad)
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glewExperimental = GL_TRUE;
|
||||
|
||||
#ifdef __APPLE__
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include "tiny_gltf.h"
|
||||
|
||||
// Nlohmann json(include ../json.hpp)
|
||||
#include "json.hpp"
|
||||
|
||||
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
|
||||
#include "catch.hpp"
|
||||
|
||||
@@ -412,6 +415,28 @@ 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]") {
|
||||
|
||||
|
||||
101
tiny_gltf.h
101
tiny_gltf.h
@@ -26,6 +26,8 @@
|
||||
// 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.2 Decode percent-encoded URI.
|
||||
// - v2.4.1 Fix some glTF object class does not have `extensions` and/or
|
||||
// `extras` property.
|
||||
@@ -1189,7 +1191,7 @@ enum SectionCheck {
|
||||
///
|
||||
typedef bool (*LoadImageDataFunction)(Image *, const int, std::string *,
|
||||
std::string *, int, int,
|
||||
const unsigned char *, int, void *);
|
||||
const unsigned char *, int, void *user_pointer);
|
||||
|
||||
///
|
||||
/// WriteImageDataFunction type. Signature for custom image writing callbacks.
|
||||
@@ -1345,6 +1347,11 @@ class TinyGLTF {
|
||||
///
|
||||
void SetImageLoader(LoadImageDataFunction LoadImageData, void *user_data);
|
||||
|
||||
///
|
||||
/// Unset(remove) callback of loading image data
|
||||
///
|
||||
void RemoveImageLoader();
|
||||
|
||||
///
|
||||
/// Set callback to use for writing image data
|
||||
///
|
||||
@@ -1383,6 +1390,18 @@ 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).
|
||||
@@ -1402,6 +1421,8 @@ 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,
|
||||
@@ -1421,7 +1442,8 @@ class TinyGLTF {
|
||||
#else
|
||||
nullptr;
|
||||
#endif
|
||||
void *load_image_user_data_ = reinterpret_cast<void *>(&fs);
|
||||
void *load_image_user_data_{nullptr};
|
||||
bool user_image_loader_{false};
|
||||
|
||||
WriteImageDataFunction WriteImageData =
|
||||
#ifndef TINYGLTF_NO_STB_IMAGE_WRITE
|
||||
@@ -1429,7 +1451,7 @@ class TinyGLTF {
|
||||
#else
|
||||
nullptr;
|
||||
#endif
|
||||
void *write_image_user_data_ = reinterpret_cast<void *>(&fs);
|
||||
void *write_image_user_data_{nullptr};
|
||||
};
|
||||
|
||||
#ifdef __clang__
|
||||
@@ -1683,6 +1705,19 @@ 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;
|
||||
@@ -2297,22 +2332,40 @@ 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;
|
||||
|
||||
// force 32-bit textures for common Vulkan compatibility. It appears that
|
||||
// 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 = 4;
|
||||
req_comp = option.preserve_channels ? 0 : 4;
|
||||
int bits = 8;
|
||||
int pixel_type = TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE;
|
||||
|
||||
@@ -2384,13 +2437,18 @@ 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 = req_comp;
|
||||
image->component = comp;
|
||||
image->bits = bits;
|
||||
image->pixel_type = pixel_type;
|
||||
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());
|
||||
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());
|
||||
stbi_image_free(data);
|
||||
|
||||
return true;
|
||||
@@ -5825,6 +5883,18 @@ 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) {
|
||||
@@ -5837,7 +5907,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;
|
||||
}
|
||||
|
||||
@@ -5875,7 +5945,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;
|
||||
}
|
||||
@@ -7225,6 +7295,15 @@ 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));
|
||||
|
||||
Reference in New Issue
Block a user