75 lines
2.4 KiB
C++
75 lines
2.4 KiB
C++
#pragma once
|
|
|
|
#include "CompressedTexture.h"
|
|
#include "../../core/Util/BinaryTree.h"
|
|
#include "../../core/Serializer.h"
|
|
|
|
template<typename T>
|
|
class DagBasedTexture : public CompressedTexture<T>
|
|
{
|
|
private:
|
|
BinaryTree<T> mData;
|
|
unsigned64 mOriginalSize;
|
|
public:
|
|
DagBasedTexture() :
|
|
mData(BinaryTree<T>()),
|
|
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<T> GetTexture(size_t fromIndex = 0) override {
|
|
std::vector<T> 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<T>& 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<T, T>& 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<unsigned64>::Deserialize(mOriginalSize, file);
|
|
mData.Deserialize(file);
|
|
}
|
|
virtual void WriteToFile(std::ostream& file) const override
|
|
{
|
|
Serializer<unsigned64>::Serialize(mOriginalSize, file);
|
|
mData.Serialize(file);
|
|
}
|
|
|
|
// Use this method to output the compressed texture as a vector of one byte characters
|
|
std::vector<unsigned char> GetTexturePool() const override { return mData.Serialize(true); }
|
|
size_t GetTexturePoolSize() const override { return mData.GetSerializedByteCount(true); }
|
|
|
|
virtual std::map<std::string, std::string> GetAdditionalProperties() const override { return std::map<std::string, std::string>(); }
|
|
}; |