asset compression

This commit is contained in:
Jorijn van der Graaf 2026-05-11 18:37:30 +02:00
commit 30a283c1b3
57 changed files with 13237 additions and 8 deletions

View file

@ -21,6 +21,7 @@ module;
#define STB_IMAGE_IMPLEMENTATION
#include "../lib/stb_image.h"
export module Crafter.Asset:Texture;
import :Compression;
import std;
import Crafter.Math;
namespace fs = std::filesystem;
@ -38,6 +39,42 @@ export namespace Crafter {
OpaqueType opaque;
};
// GDeflate-compressed counterpart of TextureAsset<T>::Save output.
// Single-region blob: the pixel array as one stream.
struct CompressedTextureAsset {
std::uint16_t sizeX = 0;
std::uint16_t sizeY = 0;
OpaqueType opaque = OpaqueType::FullyOpaque;
std::uint32_t pixelStride = 0;
Compression::CompressedBlob blob;
};
namespace TextureAssetFormat {
inline constexpr char magic[4] = {'C', 'G', 'D', 'T'};
inline constexpr std::uint32_t version = 1;
}
inline CompressedTextureAsset LoadCompressedTexture(fs::path path) {
std::ifstream file(path, std::ios::binary);
char magic[4];
file.read(magic, 4);
if (std::memcmp(magic, TextureAssetFormat::magic, 4) != 0) {
throw std::runtime_error("LoadCompressedTexture: bad magic on " + path.string());
}
std::uint32_t version = 0;
file.read(reinterpret_cast<char*>(&version), sizeof(version));
if (version != TextureAssetFormat::version) {
throw std::runtime_error("LoadCompressedTexture: unsupported version on " + path.string());
}
CompressedTextureAsset out;
file.read(reinterpret_cast<char*>(&out.sizeX), sizeof(out.sizeX));
file.read(reinterpret_cast<char*>(&out.sizeY), sizeof(out.sizeY));
file.read(reinterpret_cast<char*>(&out.opaque), sizeof(out.opaque));
file.read(reinterpret_cast<char*>(&out.pixelStride), sizeof(out.pixelStride));
out.blob = Compression::ReadBlob(file);
return out;
}
template <typename T>
struct TextureAsset {
std::uint16_t sizeX;
@ -54,6 +91,24 @@ export namespace Crafter {
file.write(reinterpret_cast<char*>(pixels.data()), pixels.size() * sizeof(T));
}
void SaveCompressed(fs::path path) const {
std::array<std::span<const std::byte>, 1> streams = {
std::as_bytes(std::span(pixels)),
};
Compression::CompressedBlob blob = Compression::CompressStreams(streams);
std::ofstream file(path, std::ios::binary);
file.write(TextureAssetFormat::magic, 4);
std::uint32_t version = TextureAssetFormat::version;
std::uint32_t stride = static_cast<std::uint32_t>(sizeof(T));
file.write(reinterpret_cast<const char*>(&version), sizeof(version));
file.write(reinterpret_cast<const char*>(&sizeX), sizeof(sizeX));
file.write(reinterpret_cast<const char*>(&sizeY), sizeof(sizeY));
file.write(reinterpret_cast<const char*>(&opaque), sizeof(opaque));
file.write(reinterpret_cast<const char*>(&stride), sizeof(stride));
Compression::WriteBlob(file, blob);
}
static TextureAsset<T> Load(fs::path path) {
TextureAsset<T> tex;