diff --git a/README.md b/README.md index 07c42d3..8854fec 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ * [ ] Write C++ code generator from json schema for robust parsing. * [ ] Support multiple scenes in `.gltf` -* [ ] Parse `sampler`, `skin` +* [ ] Parse `skin` * [ ] Compression/decompression(Open3DGC, etc) * [ ] Support `extensions` and `extras` property * [ ] HDR image? diff --git a/loader_example.cc b/loader_example.cc index 09e523b..aec14d5 100644 --- a/loader_example.cc +++ b/loader_example.cc @@ -140,6 +140,36 @@ static std::string PrintParameterType(int ty) { return "**UNKNOWN**"; } + +static std::string PrintWrapMode(int mode) { + if (mode == TINYGLTF_TEXTURE_WRAP_RPEAT) { + return "REPEAT"; + } else if (mode == TINYGLTF_TEXTURE_WRAP_CLAMP_TO_EDGE) { + return "CLAMP_TO_EDGE"; + } else if (mode == TINYGLTF_TEXTURE_WRAP_MIRRORED_REPEAT) { + return "MIRRORED_REPEAT"; + } + + return "**UNKNOWN**"; +} + +static std::string PrintFilterMode(int mode) { + if (mode == TINYGLTF_TEXTURE_FILTER_NEAREST) { + return "NEAREST"; + } else if (mode == TINYGLTF_TEXTURE_FILTER_LINEAR) { + return "LINEAR"; + } else if (mode == TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_NEAREST) { + return "NEAREST_MIPMAP_NEAREST"; + } else if (mode == TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_LINEAR) { + return "NEAREST_MIPMAP_LINEAR"; + } else if (mode == TINYGLTF_TEXTURE_FILTER_LINEAR_MIPMAP_NEAREST) { + return "LINEAR_MIPMAP_NEAREST"; + } else if (mode == TINYGLTF_TEXTURE_FILTER_LINEAR_MIPMAP_LINEAR) { + return "LINEAR_MIPMAP_LINEAR"; + } + return "**UNKNOWN**"; +} + static std::string PrintFloatArray(const std::vector &arr) { if (arr.size() == 0) { return ""; @@ -608,6 +638,31 @@ static void Dump(const tinygltf::Scene &scene) { DumpStringMap(it->second.uniforms, 3); } } + + { + std::map::const_iterator it( + scene.samplers.begin()); + std::map::const_iterator itEnd( + scene.samplers.end()); + + std::cout << "samplers(items=" << scene.samplers.size() << ")" << std::endl; + + for (; it != itEnd; it++) { + std::cout << Indent(1) << "name (id) : " << it->first << std::endl; + std::cout << Indent(2) + << "minFilter : " << PrintFilterMode(it->second.minFilter) + << std::endl; + std::cout << Indent(2) + << "magFilter : " << PrintFilterMode(it->second.magFilter) + << std::endl; + std::cout << Indent(2) + << "wrapS : " << PrintWrapMode(it->second.wrapS) + << std::endl; + std::cout << Indent(2) + << "wrapT : " << PrintWrapMode(it->second.wrapT) + << std::endl; + } + } } int main(int argc, char **argv) { diff --git a/tiny_gltf_loader.h b/tiny_gltf_loader.h index a38c5f8..cf2c950 100644 --- a/tiny_gltf_loader.h +++ b/tiny_gltf_loader.h @@ -69,6 +69,17 @@ namespace tinygltf { #define TINYGLTF_COMPONENT_TYPE_FLOAT (5126) #define TINYGLTF_COMPONENT_TYPE_DOUBLE (5127) +#define TINYGLTF_TEXTURE_FILTER_NEAREST (9728) +#define TINYGLTF_TEXTURE_FILTER_LINEAR (9729) +#define TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_NEAREST (9984) +#define TINYGLTF_TEXTURE_FILTER_LINEAR_MIPMAP_NEAREST (9985) +#define TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_LINEAR (9986) +#define TINYGLTF_TEXTURE_FILTER_LINEAR_MIPMAP_LINEAR (9987) + +#define TINYGLTF_TEXTURE_WRAP_RPEAT (10497) +#define TINYGLTF_TEXTURE_WRAP_CLAMP_TO_EDGE (33071) +#define TINYGLTF_TEXTURE_WRAP_MIRRORED_REPEAT (33071) + // Redeclarations of the above for technique.parameters. #define TINYGLTF_PARAMETER_TYPE_BYTE (5120) #define TINYGLTF_PARAMETER_TYPE_UNSIGNED_BYTE (5121) @@ -150,6 +161,15 @@ typedef struct { ParameterMap parameters; } Animation; +typedef struct { + std::string name; + int minFilter; + int magFilter; + int wrapS; + int wrapT; + int wrapR; // TinyGLTF extension +} Sampler; + typedef struct { std::string name; int width; @@ -309,6 +329,7 @@ class Scene { std::map shaders; std::map programs; std::map techniques; + std::map samplers; std::map > scenes; // list of nodes std::string defaultScene; @@ -1856,6 +1877,28 @@ static bool ParseAnimation(Animation *animation, std::string *err, return true; } +static bool ParseSampler(Sampler *sampler, std::string *err, + const picojson::object &o) { + ParseStringProperty(&sampler->name, err, o, "name", false); + + double minFilter = + static_cast(TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_LINEAR); + double magFilter = static_cast(TINYGLTF_TEXTURE_FILTER_LINEAR); + double wrapS = static_cast(TINYGLTF_TEXTURE_WRAP_RPEAT); + double wrapT = static_cast(TINYGLTF_TEXTURE_WRAP_RPEAT); + ParseNumberProperty(&minFilter, err, o, "minFilter", false); + ParseNumberProperty(&magFilter, err, o, "magFilter", false); + ParseNumberProperty(&wrapS, err, o, "wrapS", false); + ParseNumberProperty(&wrapT, err, o, "wrapT", false); + + sampler->minFilter = static_cast(minFilter); + sampler->magFilter = static_cast(magFilter); + sampler->wrapS = static_cast(wrapS); + sampler->wrapT = static_cast(wrapT); + + return true; +} + bool TinyGLTFLoader::LoadFromString(Scene *scene, std::string *err, const char *str, unsigned int length, const std::string &base_dir) { @@ -2194,6 +2237,21 @@ bool TinyGLTFLoader::LoadFromString(Scene *scene, std::string *err, } } + // 15. Parse Sampler + if (v.contains("samplers") && v.get("samplers").is()) { + const picojson::object &root = v.get("samplers").get(); + + picojson::object::const_iterator it(root.begin()); + picojson::object::const_iterator itEnd(root.end()); + for (; it != itEnd; ++it) { + Sampler sampler; + if (!ParseSampler(&sampler, err, (it->second).get())) { + return false; + } + + scene->samplers[it->first] = sampler; + } + } return true; }