#pragma once #include "CompressedTexture.h" #include "../../core/Util/BinaryTree.h" #include "../../core/Serializer.h" template class DagBasedTexture : public CompressedTexture { private: BinaryTree mData; unsigned64 mOriginalSize; public: DagBasedTexture() : mData(BinaryTree()), mOriginalSize(0) {} ~DagBasedTexture() {} // Uncompress and retrieve the texture (possibly from a certain index) T operator[](size_t i) const override { return mData.GetValueAtLeaf(i); } unsigned64 size() const override { return mOriginalSize; } std::vector GetTexture(size_t fromIndex = 0) override { std::vector data(mOriginalSize); for (size_t i = 0; i < mOriginalSize; i++) { data[i] = operator[](i); } return data; } // Compresses the texture, replacing everything after fromIndex by whatever is in texture void SetTexture(const std::vector& texture, size_t fromIndex = 0) override { // Calculate the required tree depth unsigned8 requiredDepth = BitHelper::Log2Ceil(fromIndex + texture.size()); mData.SetDepth(requiredDepth, true); // Set all leaf nodes correctly: for (size_t i = 0; i < texture.size(); i++) mData.SetValueAtLeaf(fromIndex + i, texture[i]); mData.ToDAG(); mOriginalSize = fromIndex + texture.size(); } // Replace all materials by other colors. This could be useful as some methods don't need to fully decompress and compress the whole texture to do this. void ReplaceMaterials(const std::unordered_map& replacers) override { bool replacersEqual = true; for (auto replacer : replacers) if (replacer.first != replacer.second) { replacersEqual = false; break; } if (replacersEqual) return; mData.ReplaceValues(replacers); } void Recompress() override { return; } void ReadFromFile(std::istream& file) override { Serializer::Deserialize(mOriginalSize, file); mData.Deserialize(file); } virtual void WriteToFile(std::ostream& file) const override { Serializer::Serialize(mOriginalSize, file); mData.Serialize(file); } // Use this method to output the compressed texture as a vector of one byte characters std::vector GetTexturePool() const override { return mData.Serialize(true); } size_t GetTexturePoolSize() const override { return mData.GetSerializedByteCount(true); } virtual std::map GetAdditionalProperties() const override { return std::map(); } };