Files
CDAG/Research/scene/TextureCompressor/DagBasedTexture.h

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>(); }
};