This commit is contained in:
Jorijn van der Graaf 2026-05-18 22:31:28 +02:00
commit 765cf33069
6 changed files with 10895 additions and 11 deletions

View file

@ -20,6 +20,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
module;
#define STB_IMAGE_IMPLEMENTATION
#include "../lib/stb_image.h"
#define STB_IMAGE_RESIZE_IMPLEMENTATION
#include "../lib/stb_image_resize2.h"
export module Crafter.Asset:Texture;
import :Compression;
import std;
@ -59,12 +61,12 @@ export namespace Crafter {
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());
Compression::Fatal("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());
Compression::Fatal("LoadCompressedTexture: unsupported version on " + path.string());
}
CompressedTextureAsset out;
file.read(reinterpret_cast<char*>(&out.sizeX), sizeof(out.sizeX));
@ -123,6 +125,22 @@ export namespace Crafter {
return tex;
}
// Bilinear-resize the pixel buffer in-place to `newW × newH`.
// Used to normalize albedos to a uniform size before stacking them
// into a WebGPU texture_2d_array (which requires identical layer
// dimensions). stb_image_resize2 handles RGBA8 directly.
void Resize(std::uint16_t newW, std::uint16_t newH) requires (sizeof(T) == 4) {
if (sizeX == newW && sizeY == newH) return;
std::vector<T> out(static_cast<std::size_t>(newW) * newH);
stbir_resize_uint8_linear(
reinterpret_cast<const std::uint8_t*>(pixels.data()), sizeX, sizeY, 0,
reinterpret_cast<std::uint8_t*>(out.data()), newW, newH, 0,
STBIR_RGBA);
pixels = std::move(out);
sizeX = newW;
sizeY = newH;
}
static TextureAssetInfo LoadInfo(fs::path path) {
TextureAssetInfo info;
@ -159,7 +177,11 @@ export namespace Crafter {
tex.opaque = OpaqueType::FullyOpaque;
if constexpr(std::same_as<TT, _Float16> || std::same_as<TT, float> || std::same_as<TT, double>) {
if constexpr(
#ifndef __wasm__
std::same_as<TT, _Float16> ||
#endif
std::same_as<TT, float> || std::same_as<TT, double>) {
for(std::uint32_t i = 0; i < sizeX*sizeY; i++) {
tex.pixels[i].r = TT(data[i*4])/255;
tex.pixels[i].g = TT(data[i*4+1])/255;