From 57b27dada7e6968a6081207d9b466bf7e842039b Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 9 Mar 2026 12:17:41 +0000 Subject: Specialise glTexture::savePosition Normalises the range of position information into the range 0-255 so the resulting image is remotely useful. --- gfx/gl/glTexture.cpp | 71 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 18 deletions(-) (limited to 'gfx/gl') diff --git a/gfx/gl/glTexture.cpp b/gfx/gl/glTexture.cpp index e334d5e..0bc3d62 100644 --- a/gfx/gl/glTexture.cpp +++ b/gfx/gl/glTexture.cpp @@ -1,6 +1,8 @@ #include "glTexture.h" +#include "config/types.h" #include "filesystem.h" #include "gfx/models/tga.h" +#include "maths.h" #include #include #include @@ -95,31 +97,37 @@ Impl::glTextureDims::image(const GLenum format, const GLenum type, const v namespace { template requires(Dims >= 1 && Dims <= 3) + size_t + areaOf(glm::vec size) + { + size_t area = 1; + for (auto dim = 0; dim < Dims; ++dim) { + area *= static_cast(size[dim]); + } + return area; + } + + template + requires(Dims >= 1 && Dims <= 3) void - save(const Impl::glTextureDims & texture, const GLenum format, const GLenum type, uint8_t channels, - const char * path, uint8_t tgaFormat) + save(const Impl::glTextureDims & texture, const GLenum format, const GLenum type, const char * path, + uint8_t tgaFormat) { const auto size = texture.getSize(); - const auto area = [size]() { - size_t area = 1; - for (auto dim = 0; dim < Dims; ++dim) { - area *= static_cast(size[dim]); - } - return area; - }(); + const auto area = areaOf(size); size_t dataSize = area * channels; - const size_t fileSize = dataSize + sizeof(TGAHead); + const size_t fileSize = dataSize + sizeof(TGAHead); filesystem::fh out {path, O_RDWR | O_CREAT, 0660}; out.truncate(fileSize); auto tga = out.mmap(fileSize, 0, PROT_WRITE, MAP_SHARED); - *tga.get() = { + auto outTga = tga.get>(); + *outTga = { .format = tgaFormat, - .size = {size.x, 1 * (area / static_cast(size.x))}, - .pixelDepth = static_cast(8 * channels), + .size = {size.x, (area / static_cast(size.x))}, }; glPixelStorei(GL_PACK_ALIGNMENT, 1); - glGetTextureImage(texture, 0, format, type, static_cast(dataSize), tga.get() + 1); + glGetTextureImage(texture, 0, format, type, static_cast(dataSize), outTga->data); tga.msync(MS_ASYNC); } } @@ -129,7 +137,7 @@ template void Impl::glTextureDims::saveColour(const char * path) const { - save(*this, GL_BGR, GL_UNSIGNED_BYTE, 3, path, 2); + save(*this, GL_BGR, GL_UNSIGNED_BYTE, path, 2); } template @@ -137,7 +145,34 @@ template void Impl::glTextureDims::savePosition(const char * path) const { - save(*this, GL_BGR_INTEGER, GL_UNSIGNED_BYTE, 3, path, 2); + const auto size = getSize(); + const auto area = areaOf(size); + size_t dataSize = area * sizeof(TGAHead<3>::PixelType); + const size_t fileSize = dataSize + sizeof(TGAHead<3>); + + filesystem::fh out {path, O_RDWR | O_CREAT, 0660}; + out.truncate(fileSize); + auto tga = out.mmap(fileSize, 0, PROT_WRITE, MAP_SHARED); + auto outTga = tga.get>(); + *outTga = { + .format = 2, + .size = {size.x, (area / static_cast(size.x))}, + }; + glPixelStorei(GL_PACK_ALIGNMENT, 1); + std::vector raw {area}; + glGetTextureImage( + name, 0, GL_BGR_INTEGER, GL_INT, static_cast(sizeof(GlobalPosition3D) * area), raw.data()); + using Comp = GlobalPosition3D (*)(const GlobalPosition3D &, const GlobalPosition3D &); + auto notZero = std::views::filter([](const GlobalPosition3D & pos) { + return pos != GlobalPosition3D {}; + }); + const auto minPos = *std::ranges::fold_left_first(raw | notZero, static_cast(&glm::min)); + const auto maxPos = *std::ranges::fold_left_first(raw | notZero, static_cast(&glm::max)); + const auto rangePos = difference(maxPos, minPos); + std::ranges::transform(raw, outTga->data, [minPos, rangePos](const GlobalPosition3D & pos) { + return GlobalPosition3D(255.F * (difference(pos, minPos) / rangePos)); + }); + tga.msync(MS_ASYNC); } template @@ -145,7 +180,7 @@ template void Impl::glTextureDims::saveDepth(const char * path) const { - save(*this, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 1, path, 3); + save(*this, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, path, 3); } template @@ -153,7 +188,7 @@ template void Impl::glTextureDims::saveNormal(const char * path) const { - save(*this, GL_BGR, GL_BYTE, 3, path, 2); + save(*this, GL_BGR, GL_BYTE, path, 2); } template struct Impl::glTextureDims<1>; -- cgit v1.3