We got exr loading
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user