We got exr loading

This commit is contained in:
2026-01-22 02:04:11 +01:00
parent a5b26f3bdd
commit 41ed926409
23 changed files with 529 additions and 283 deletions
+96 -8
View File
@@ -2,30 +2,118 @@
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#include <tiny_gltf.h>
#define TINYEXR_IMPLEMENTATION
#include "tinyexr.h"
#include <cstdio> // fprintf
#include <cstdlib> // free
#include "spdlog/spdlog.h"
ImageData::~ImageData()
{
if (shouldSTBFree) {
stbi_image_free(pixels);
stbi_image_free(hdrPixels);
if (pixels) stbi_image_free(pixels);
if (hdrPixels) stbi_image_free(hdrPixels);
spdlog::debug("Freed STB image memory");
}
if (shouldEXRFree) {
if (hdrPixels) free(hdrPixels);
spdlog::debug("Freed TinyEXR image memory");
}
}
namespace util
{
ImageData loadImage(const std::filesystem::path& p)
static bool isExrExt(const std::filesystem::path& p)
{
auto ext = p.extension().string();
for (auto& c : ext) c = char(::tolower(c));
return ext == ".exr";
}
ImageData loadImage(const std::filesystem::path& p, TextureIntent intent)
{
ImageData data;
// ---------- EXR ----------
if (isExrExt(p)) {
float* out = nullptr;
int w = 0, h = 0;
const char* err = nullptr;
const int ret = LoadEXR(&out, &w, &h, p.string().c_str(), &err);
if (ret != TINYEXR_SUCCESS || !out || w <= 0 || h <= 0) {
if (err) {
spdlog::error("TinyEXR error: {}", err);
FreeEXRErrorMessage(err);
}
return {};
}
data.hdr = true;
data.hdrPixels = out;
data.width = w;
data.height = h;
data.channels = 4;
data.shouldEXRFree = true;
data.vkFormat = VK_FORMAT_R32G32B32A32_SFLOAT;
data.byteSize = std::size_t(w) * std::size_t(h) * 4 * sizeof(float);
return data;
}
// ---------- STB HDR (.hdr etc) ----------
data.shouldSTBFree = true;
if (stbi_is_hdr(p.string().c_str())) {
data.hdr = true;
data.hdrPixels = stbi_loadf(p.string().c_str(), &data.width, &data.height, &data.comp, 4);
} else {
data.pixels = stbi_load(p.string().c_str(), &data.width, &data.height, &data.channels, 4);
data.hdrPixels = stbi_loadf(
p.string().c_str(),
&data.width,
&data.height,
&data.comp,
4
);
if (!data.hdrPixels || data.width <= 0 || data.height <= 0) {
return {};
}
data.channels = 4;
data.vkFormat = VK_FORMAT_R32G32B32A32_SFLOAT;
data.byteSize = std::size_t(data.width) * std::size_t(data.height) * 4 * sizeof(float);
return data;
}
// ---------- STB LDR (png/jpg/...) ----------
data.pixels = stbi_load(
p.string().c_str(),
&data.width,
&data.height,
&data.channels,
4
);
if (!data.pixels || data.width <= 0 || data.height <= 0) {
return {};
}
data.channels = 4;
// Choose color space for LDR based on intent
switch (intent) {
case TextureIntent::ColorSrgb:
data.vkFormat = VK_FORMAT_R8G8B8A8_SRGB;
break;
case TextureIntent::DataLinear:
data.vkFormat = VK_FORMAT_R8G8B8A8_UNORM;
break;
}
data.byteSize = std::size_t(data.width) * std::size_t(data.height) * 4 * sizeof(unsigned char);
return data;
}
} // namespace util
} // namespace util