diff options
| author | Dan Goodliffe <dan.goodliffe@octal.co.uk> | 2026-03-09 12:17:41 +0000 |
|---|---|---|
| committer | Dan Goodliffe <dan.goodliffe@octal.co.uk> | 2026-03-09 12:18:59 +0000 |
| commit | 57b27dada7e6968a6081207d9b466bf7e842039b (patch) | |
| tree | 0acfb043f44c789fc5ee9696ac34ea9ed7fed767 /gfx | |
| parent | Remove identifier naming lint comments, gl* is fine (diff) | |
| download | ilt-57b27dada7e6968a6081207d9b466bf7e842039b.tar.bz2 ilt-57b27dada7e6968a6081207d9b466bf7e842039b.tar.xz ilt-57b27dada7e6968a6081207d9b466bf7e842039b.zip | |
Specialise glTexture::savePosition
Normalises the range of position information into the range 0-255 so the
resulting image is remotely useful.
Diffstat (limited to 'gfx')
| -rw-r--r-- | gfx/gl/glTexture.cpp | 71 | ||||
| -rw-r--r-- | gfx/models/tga.h | 9 |
2 files changed, 58 insertions, 22 deletions
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 <fcntl.h> #include <ranges> #include <sys/mman.h> @@ -95,31 +97,37 @@ Impl::glTextureDims<Dims>::image(const GLenum format, const GLenum type, const v namespace { template<glm::length_t Dims> requires(Dims >= 1 && Dims <= 3) + size_t + areaOf(glm::vec<Dims, GLsizei> size) + { + size_t area = 1; + for (auto dim = 0; dim < Dims; ++dim) { + area *= static_cast<size_t>(size[dim]); + } + return area; + } + + template<glm::length_t Dims, glm::length_t channels> + requires(Dims >= 1 && Dims <= 3) void - save(const Impl::glTextureDims<Dims> & texture, const GLenum format, const GLenum type, uint8_t channels, - const char * path, uint8_t tgaFormat) + save(const Impl::glTextureDims<Dims> & 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_t>(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<channels>); filesystem::fh out {path, O_RDWR | O_CREAT, 0660}; out.truncate(fileSize); auto tga = out.mmap(fileSize, 0, PROT_WRITE, MAP_SHARED); - *tga.get<TGAHead>() = { + auto outTga = tga.get<TGAHead<channels>>(); + *outTga = { .format = tgaFormat, - .size = {size.x, 1 * (area / static_cast<size_t>(size.x))}, - .pixelDepth = static_cast<uint8_t>(8 * channels), + .size = {size.x, (area / static_cast<size_t>(size.x))}, }; glPixelStorei(GL_PACK_ALIGNMENT, 1); - glGetTextureImage(texture, 0, format, type, static_cast<GLsizei>(dataSize), tga.get<TGAHead>() + 1); + glGetTextureImage(texture, 0, format, type, static_cast<GLsizei>(dataSize), outTga->data); tga.msync(MS_ASYNC); } } @@ -129,7 +137,7 @@ template<glm::length_t Dims> void Impl::glTextureDims<Dims>::saveColour(const char * path) const { - save(*this, GL_BGR, GL_UNSIGNED_BYTE, 3, path, 2); + save<Dims, 3>(*this, GL_BGR, GL_UNSIGNED_BYTE, path, 2); } template<glm::length_t Dims> @@ -137,7 +145,34 @@ template<glm::length_t Dims> void Impl::glTextureDims<Dims>::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<TGAHead<3>>(); + *outTga = { + .format = 2, + .size = {size.x, (area / static_cast<size_t>(size.x))}, + }; + glPixelStorei(GL_PACK_ALIGNMENT, 1); + std::vector<GlobalPosition3D> raw {area}; + glGetTextureImage( + name, 0, GL_BGR_INTEGER, GL_INT, static_cast<GLsizei>(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<Comp>(&glm::min)); + const auto maxPos = *std::ranges::fold_left_first(raw | notZero, static_cast<Comp>(&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<glm::length_t Dims> @@ -145,7 +180,7 @@ template<glm::length_t Dims> void Impl::glTextureDims<Dims>::saveDepth(const char * path) const { - save(*this, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 1, path, 3); + save<Dims, 1>(*this, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, path, 3); } template<glm::length_t Dims> @@ -153,7 +188,7 @@ template<glm::length_t Dims> void Impl::glTextureDims<Dims>::saveNormal(const char * path) const { - save(*this, GL_BGR, GL_BYTE, 3, path, 2); + save<Dims, 3>(*this, GL_BGR, GL_BYTE, path, 2); } template struct Impl::glTextureDims<1>; diff --git a/gfx/models/tga.h b/gfx/models/tga.h index 3d072fb..955e5e1 100644 --- a/gfx/models/tga.h +++ b/gfx/models/tga.h @@ -3,14 +3,15 @@ #include <cstdint> #include <glm/vec2.hpp> -struct TGAHead { +template<glm::length_t Channels> struct TGAHead { using XY = glm::vec<2, uint16_t>; + using PixelType = glm::vec<Channels, uint8_t>; + uint8_t idLength {}, colorMapType {}, format {}; uint16_t __attribute__((packed)) colorMapFirst {}, colorMapLength {}; uint8_t colorMapEntrySize {}; XY origin {}, size {}; - uint8_t pixelDepth {}; + uint8_t pixelDepth {8 * Channels}; uint8_t descriptor {}; + PixelType data[1] {}; }; - -static_assert(sizeof(TGAHead) == 18); |
