From e4c559b29b9856d312a2103b0a8917e4d80d15d6 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Sun, 16 Oct 2016 16:40:49 +0200 Subject: [PATCH] Added RGBM encoding in GTC_packing #420 --- glm/gtc/packing.hpp | 27 ++++++++++++++++++++++++++- glm/gtc/packing.inl | 16 ++++++++++++++++ readme.md | 1 + test/gtc/gtc_packing.cpp | 19 ++++++++++++++++++- 4 files changed, 61 insertions(+), 2 deletions(-) diff --git a/glm/gtc/packing.hpp b/glm/gtc/packing.hpp index 1389d959..7cae3222 100644 --- a/glm/gtc/packing.hpp +++ b/glm/gtc/packing.hpp @@ -451,6 +451,8 @@ namespace glm /// The first vector component specifies the 11 least-significant bits of the result; /// the last component specifies the 10 most-significant bits. /// + /// packF3x9_E1x5 allows encoding into RGBE / RGB9E5 format + /// /// @see gtc_packing /// @see vec3 unpackF3x9_E1x5(uint32 const & p) GLM_FUNC_DECL uint32 packF3x9_E1x5(vec3 const & v); @@ -460,11 +462,34 @@ namespace glm /// /// The first component of the returned vector will be extracted from the least significant bits of the input; /// the last component will be extracted from the most significant bits. - /// + /// + /// unpackF3x9_E1x5 allows decoding RGBE / RGB9E5 data + /// /// @see gtc_packing /// @see uint32 packF3x9_E1x5(vec3 const & v) GLM_FUNC_DECL vec3 unpackF3x9_E1x5(uint32 p); + /// Returns an unsigned integer vector obtained by converting the components of a floating-point vector + /// to the 16-bit floating-point representation found in the OpenGL Specification. + /// The first vector component specifies the 16 least-significant bits of the result; + /// the forth component specifies the 16 most-significant bits. + /// + /// @see gtc_packing + /// @see tvec3 unpackRGBM(tvec4 const & p) + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + template + GLM_FUNC_DECL tvec4 packRGBM(tvec3 const & rgb); + + /// Returns a floating-point vector with components obtained by reinterpreting an integer vector as 16-bit floating-point numbers and converting them to 32-bit floating-point values. + /// The first component of the vector is obtained from the 16 least-significant bits of v; + /// the forth component is obtained from the 16 most-significant bits of v. + /// + /// @see gtc_packing + /// @see tvec4 packRGBM(tvec3 const & v) + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + template + GLM_FUNC_DECL tvec3 unpackRGBM(tvec4 const & rgbm); + /// Returns an unsigned integer vector obtained by converting the components of a floating-point vector /// to the 16-bit floating-point representation found in the OpenGL Specification. /// The first vector component specifies the 16 least-significant bits of the result; diff --git a/glm/gtc/packing.inl b/glm/gtc/packing.inl index 618fb9ef..c77673c1 100644 --- a/glm/gtc/packing.inl +++ b/glm/gtc/packing.inl @@ -639,6 +639,22 @@ namespace detail return vec3(Unpack.data.x, Unpack.data.y, Unpack.data.z) * pow(2.0f, Unpack.data.w - 15.f - 9.f); } + // From http://graphicrants.blogspot.fr/2009/04/rgbm-color-encoding.html + template + GLM_FUNC_QUALIFIER tvec4 packRGBM(tvec3 const & rgb) + { + tvec3 const Color(rgb * static_cast(1.0 / 6.0)); + T Alpha = clamp(max(max(Color.x, Color.y), max(Color.z, static_cast(1e-6))), static_cast(0), static_cast(1)); + Alpha = ceil(Alpha * static_cast(255.0)) / static_cast(255.0); + return tvec4(Color / Alpha, Alpha); + } + + template + GLM_FUNC_QUALIFIER tvec3 unpackRGBM(tvec4 const & rgbm) + { + return tvec3(rgbm.x, rgbm.y, rgbm.z) * rgbm.w * static_cast(6); + } + template class vecType> GLM_FUNC_QUALIFIER vecType packHalf(vecType const & v) { diff --git a/readme.md b/readme.md index 88648587..74a2ba1a 100644 --- a/readme.md +++ b/readme.md @@ -53,6 +53,7 @@ glm::mat4 camera(float Translate, glm::vec2 const & Rotate) #### [GLM 0.9.9.0](https://github.com/g-truc/glm/releases/latest) - 2017-XX-XX ##### Features: +- Added RGBM encoding in GTC_packing #420 - Added GTC_color_encoding extension ##### Improvements: diff --git a/test/gtc/gtc_packing.cpp b/test/gtc/gtc_packing.cpp index d1f40e5a..94179e8f 100644 --- a/test/gtc/gtc_packing.cpp +++ b/test/gtc/gtc_packing.cpp @@ -239,7 +239,7 @@ int test_F3x9_E1x5() Tests.push_back(glm::vec3(0.5f)); Tests.push_back(glm::vec3(0.9f)); - for (std::size_t i = 0; i < Tests.size(); ++i) + for(std::size_t i = 0; i < Tests.size(); ++i) { glm::uint32 p0 = glm::packF3x9_E1x5(Tests[i]); glm::vec3 v0 = glm::unpackF3x9_E1x5(p0); @@ -251,6 +251,22 @@ int test_F3x9_E1x5() return Error; } +int test_RGBM() +{ + int Error = 0; + + for(std::size_t i = 0; i < 1024; ++i) + { + glm::vec3 const Color(i); + glm::vec4 const RGBM = glm::packRGBM(Color); + glm::vec3 const Result= glm::unpackRGBM(RGBM); + + Error += glm::all(glm::epsilonEqual(Color, Result, 0.01f)) ? 0 : 1; + } + + return Error; +} + int test_packUnorm1x16() { int Error = 0; @@ -671,6 +687,7 @@ int main() Error += test_F2x11_1x10(); Error += test_F3x9_E1x5(); + Error += test_RGBM(); Error += test_Snorm3x10_1x2(); Error += test_Unorm3x10_1x2(); Error += test_I3x10_1x2();