From 0619232aef234f5c0b34a35283ba7caaba9c0150 Mon Sep 17 00:00:00 2001 From: Angelo Scandaliato Date: Fri, 30 Sep 2016 17:23:38 -0700 Subject: [PATCH] included samplers dictionary for textures --- code/glTFAsset.h | 44 +++++++++++++++++++++++++++++++----- code/glTFAsset.inl | 41 +++++++++++++++++++++++++-------- code/glTFAssetWriter.inl | 16 ++++++++++++- code/glTFExporter.cpp | 49 ++++++++++++++++++++++++++++++++++++++++ code/glTFExporter.h | 1 + 5 files changed, 135 insertions(+), 16 deletions(-) diff --git a/code/glTFAsset.h b/code/glTFAsset.h index f105d6b6c..78b456405 100644 --- a/code/glTFAsset.h +++ b/code/glTFAsset.h @@ -236,6 +236,32 @@ namespace glTF BufferViewTarget_ELEMENT_ARRAY_BUFFER = 34963 }; + //! Values for the Sampler::magFilter field + enum SamplerMagFilter + { + SamplerMagFilter_Nearest = 9728, + SamplerMagFilter_Linear = 9729 + }; + + //! Values for the Sampler::minFilter field + enum SamplerMinFilter + { + SamplerMinFilter_Nearest = 9728, + SamplerMinFilter_Linear = 9729, + SamplerMinFilter_Nearest_Mipmap_Nearest = 9984, + SamplerMinFilter_Linear_Mipmap_Nearest = 9985, + SamplerMinFilter_Nearest_Mipmap_Linear = 9986, + SamplerMinFilter_Linear_Mipmap_Linear = 9987 + }; + + //! Values for the Sampler::wrapS and Sampler::wrapT field + enum SamplerWrap + { + SamplerWrap_Clamp_To_Edge = 33071, + SamplerWrap_Mirrored_Repeat = 33648, + SamplerWrap_Repeat = 10497 + }; + //! Values for the Texture::format and Texture::internalFormat fields enum TextureFormat { @@ -812,8 +838,14 @@ namespace glTF struct Sampler : public Object { + SamplerMagFilter magFilter; //!< The texture magnification filter. (required) + SamplerMinFilter minFilter; //!< The texture minification filter. (required) + SamplerWrap wrapS; //!< The texture wrapping in the S direction. (required) + SamplerWrap wrapT; //!< The texture wrapping in the T direction. (required) + Sampler() {} void Read(Value& obj, Asset& r); + void SetDefaults(); }; struct Scene : public Object @@ -860,8 +892,8 @@ namespace glTF //! A texture and its sampler. struct Texture : public Object { - //Ref source; //!< The ID of the sampler used by this texture. (required) - Ref source; //!< The ID of the image used by this texture. (required) + Ref sampler; //!< The ID of the sampler used by this texture. (required) + Ref source; //!< The ID of the image used by this texture. (required) //TextureFormat format; //!< The texture's format. (default: TextureFormat_RGBA) //TextureFormat internalFormat; //!< The texture's internal format. (default: TextureFormat_RGBA) @@ -921,7 +953,7 @@ namespace glTF //! (Implemented in glTFAssetWriter.h) template void WriteLazyDict(LazyDict& d, AssetWriter& w); - + //! Manages lazy loading of the glTF top-level objects, and keeps a reference to them by ID //! It is the owner the loaded objects, so when it is destroyed it also deletes them @@ -983,7 +1015,7 @@ namespace glTF int version; //!< The glTF format version (should be 1) void Read(Document& doc); - + AssetMetadata() : premultipliedAlpha(false) , version(0) @@ -1049,7 +1081,7 @@ namespace glTF LazyDict meshes; LazyDict nodes; //LazyDict programs; - //LazyDict samplers; + LazyDict samplers; LazyDict scenes; //LazyDict shaders; //LazyDict skins; @@ -1074,7 +1106,7 @@ namespace glTF , meshes (*this, "meshes") , nodes (*this, "nodes") //, programs (*this, "programs") - //, samplers (*this, "samplers") + , samplers (*this, "samplers") , scenes (*this, "scenes") //, shaders (*this, "shaders") //, skins (*this, "skins") diff --git a/code/glTFAsset.inl b/code/glTFAsset.inl index b9f3fccd8..a7dbebde2 100644 --- a/code/glTFAsset.inl +++ b/code/glTFAsset.inl @@ -53,7 +53,7 @@ using namespace Assimp; namespace glTF { namespace { - + // // JSON Value reading helpers // @@ -62,7 +62,7 @@ namespace { struct ReadHelper { static bool Read(Value& val, T& out) { return val.IsInt() ? out = static_cast(val.GetInt()), true : false; }}; - + template<> struct ReadHelper { static bool Read(Value& val, bool& out) { return val.IsBool() ? out = val.GetBool(), true : false; }}; @@ -70,7 +70,7 @@ namespace { template<> struct ReadHelper { static bool Read(Value& val, float& out) { return val.IsNumber() ? out = static_cast(val.GetDouble()), true : false; }}; - + template struct ReadHelper { static bool Read(Value& val, float (&out)[N]) { if (!val.IsArray() || val.Size() != N) return false; for (unsigned int i = 0; i < N; ++i) { @@ -312,7 +312,7 @@ inline void Buffer::Read(Value& obj, Asset& r) if (file) { bool ok = LoadFromStream(*file, byteLength); delete file; - + if (!ok) throw DeadlyImportError("GLTF: error while reading referenced file \"" + std::string(uri) + "\"" ); } @@ -439,7 +439,7 @@ inline void BufferView::Read(Value& obj, Asset& r) if (bufferId) { buffer = r.buffers.Get(bufferId); } - + byteOffset = MemberOrDefault(obj, "byteOffset", 0u); byteLength = MemberOrDefault(obj, "byteLength", 0u); } @@ -599,7 +599,7 @@ inline Image::Image() inline void Image::Read(Value& obj, Asset& r) { - // Check for extensions first (to detect binary embedded data) + // Check for extensions first (to detect binary embedded data) if (Value* extensions = FindObject(obj, "extensions")) { if (r.extensionsUsed.KHR_binary_glTF) { if (Value* ext = FindObject(*extensions, "KHR_binary_glTF")) { @@ -665,12 +665,35 @@ inline void Image::SetData(uint8_t* data, size_t length, Asset& r) } } +inline void Sampler::Read(Value& obj, Asset& r) +{ + SetDefaults(); + + ReadMember(obj, "magFilter", magFilter); + ReadMember(obj, "minFilter", minFilter); + ReadMember(obj, "wrapS", wrapS); + ReadMember(obj, "wrapT", wrapT); +} + +inline void Sampler::SetDefaults() +{ + magFilter = SamplerMagFilter_Linear; + minFilter = SamplerMinFilter_Linear; + wrapS = SamplerWrap_Repeat; + wrapT = SamplerWrap_Repeat; +} + inline void Texture::Read(Value& obj, Asset& r) { const char* sourcestr; if (ReadMember(obj, "source", sourcestr)) { source = r.images.Get(sourcestr); } + + const char* samplerstr; + if (ReadMember(obj, "sampler", samplerstr)) { + sampler = r.samplers.Get(samplerstr); + } } namespace { @@ -1131,7 +1154,7 @@ inline void Node::Read(Value& obj, Asset& r) } } - + if (Value* matrix = FindArray(obj, "matrix")) { ReadValue(*matrix, this->matrix); } @@ -1407,13 +1430,13 @@ inline std::string Asset::FindUniqueID(const std::string& str, const char* suffi id = buffer; it = mUsedIds.find(id); } - + return id; } namespace Util { - inline + inline bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out) { if ( NULL == const_uri ) { return false; diff --git a/code/glTFAssetWriter.inl b/code/glTFAssetWriter.inl index 24c6c8c35..c440ca116 100644 --- a/code/glTFAssetWriter.inl +++ b/code/glTFAssetWriter.inl @@ -333,7 +333,18 @@ namespace glTF { inline void Write(Value& obj, Sampler& b, AssetWriter& w) { - + if (b.wrapS) { + obj.AddMember("wrapS", b.wrapS, w.mAl); + } + if (b.wrapT) { + obj.AddMember("wrapT", b.wrapT, w.mAl); + } + if (b.magFilter) { + obj.AddMember("magFilter", b.magFilter, w.mAl); + } + if (b.minFilter) { + obj.AddMember("minFilter", b.minFilter, w.mAl); + } } inline void Write(Value& scene, Scene& s, AssetWriter& w) @@ -361,6 +372,9 @@ namespace glTF { if (tex.source) { obj.AddMember("source", Value(tex.source->id, w.mAl).Move(), w.mAl); } + if (tex.sampler) { + obj.AddMember("sampler", Value(tex.sampler->id, w.mAl).Move(), w.mAl); + } } inline void Write(Value& obj, Light& b, AssetWriter& w) diff --git a/code/glTFExporter.cpp b/code/glTFExporter.cpp index 83a2e0eee..0981a7a33 100644 --- a/code/glTFExporter.cpp +++ b/code/glTFExporter.cpp @@ -235,6 +235,52 @@ namespace { } } +void glTFExporter::GetTexSampler(const aiMaterial* mat, glTF::TexProperty& prop) +{ + std::string samplerId = mAsset->FindUniqueID("", "sampler"); + prop.texture->sampler = mAsset->samplers.Create(samplerId); + + aiTextureMapMode mapU, mapV; + aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0),(int*)&mapU); + aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0),(int*)&mapV); + + switch (mapU) { + case aiTextureMapMode_Wrap: + prop.texture->sampler->wrapS = SamplerWrap_Repeat; + break; + case aiTextureMapMode_Clamp: + prop.texture->sampler->wrapS = SamplerWrap_Clamp_To_Edge; + break; + case aiTextureMapMode_Mirror: + prop.texture->sampler->wrapS = SamplerWrap_Mirrored_Repeat; + break; + case aiTextureMapMode_Decal: + default: + prop.texture->sampler->wrapS = SamplerWrap_Repeat; + break; + }; + + switch (mapV) { + case aiTextureMapMode_Wrap: + prop.texture->sampler->wrapT = SamplerWrap_Repeat; + break; + case aiTextureMapMode_Clamp: + prop.texture->sampler->wrapT = SamplerWrap_Clamp_To_Edge; + break; + case aiTextureMapMode_Mirror: + prop.texture->sampler->wrapT = SamplerWrap_Mirrored_Repeat; + break; + case aiTextureMapMode_Decal: + default: + prop.texture->sampler->wrapT = SamplerWrap_Repeat; + break; + }; + + // Hard coded Texture filtering options because I do not know where to find them in the aiMaterial. + prop.texture->sampler->magFilter = SamplerMagFilter_Linear; + prop.texture->sampler->minFilter = SamplerMinFilter_Linear; +} + void glTFExporter::GetMatColorOrTex(const aiMaterial* mat, glTF::TexProperty& prop, const char* propName, int type, int idx, aiTextureType tt) { aiString tex; @@ -274,6 +320,8 @@ void glTFExporter::GetMatColorOrTex(const aiMaterial* mat, glTF::TexProperty& pr else { prop.texture->source->uri = path; } + + GetTexSampler(mat, prop); } } } @@ -284,6 +332,7 @@ void glTFExporter::GetMatColorOrTex(const aiMaterial* mat, glTF::TexProperty& pr } } + void glTFExporter::ExportMaterials() { aiString aiName; diff --git a/code/glTFExporter.h b/code/glTFExporter.h index dfd0108b5..554bb17aa 100644 --- a/code/glTFExporter.h +++ b/code/glTFExporter.h @@ -94,6 +94,7 @@ namespace Assimp void WriteBinaryData(IOStream* outfile, std::size_t sceneLength); + void GetTexSampler(const aiMaterial* mat, glTF::TexProperty& prop); void GetMatColorOrTex(const aiMaterial* mat, glTF::TexProperty& prop, const char* propName, int type, int idx, aiTextureType tt); void ExportMetadata(); void ExportMaterials();