Browse Source

Added packF11F11F10 implementation

Christophe Riccio 12 years ago
parent
commit
cf14790806
4 changed files with 261 additions and 2 deletions
  1. 2 2
      glm/gtc/packing.hpp
  2. 116 0
      glm/gtc/packing.inl
  3. 1 0
      test/gtc/CMakeLists.txt
  4. 142 0
      test/gtc/gtc_packing.cpp

+ 2 - 2
glm/gtc/packing.hpp

@@ -100,8 +100,8 @@ namespace glm
 	GLM_FUNC_DECL uint32 packI3x10I1x2(ivec4 const & v);
 	GLM_FUNC_DECL uint32 packI3x10I1x2(ivec4 const & v);
 	GLM_FUNC_DECL ivec4 unpackI3x10I1x2(uint32 const & v);
 	GLM_FUNC_DECL ivec4 unpackI3x10I1x2(uint32 const & v);
 
 
-	GLM_FUNC_DECL uint32 packU3x10U1x2(uvec4 const & v);
-	GLM_FUNC_DECL uvec4 unpackU3x10U1x2(uint32 const & v);
+	GLM_FUNC_DECL uint32 packU10U10U10U2(uvec4 const & v);
+	GLM_FUNC_DECL uvec4 unpackU10U10U10U2(uint32 const & v);
 
 
 	GLM_FUNC_DECL uint32 packF11F11F10(vec3 const & v);
 	GLM_FUNC_DECL uint32 packF11F11F10(vec3 const & v);
 	GLM_FUNC_DECL vec3 unpackF11F11F10(uint32 const & v);
 	GLM_FUNC_DECL vec3 unpackF11F11F10(uint32 const & v);

+ 116 - 0
glm/gtc/packing.inl

@@ -28,5 +28,121 @@
 
 
 namespace glm
 namespace glm
 {
 {
+namespace detail
+{
+	glm::uint16 float2half(glm::uint32 const & f)
+	{
+		// 10 bits    =>                         EE EEEFFFFF
+		// 11 bits    =>                        EEE EEFFFFFF
+		// Half bits  =>                   SEEEEEFF FFFFFFFF
+		// Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF
+        
+		// 0x00007c00 => 00000000 00000000 01111100 00000000
+		// 0x000003ff => 00000000 00000000 00000011 11111111
+		// 0x38000000 => 00111000 00000000 00000000 00000000
+		// 0x7f800000 => 01111111 10000000 00000000 00000000
+		// 0x00008000 => 00000000 00000000 10000000 00000000
+		return
+        ((f >> 16) & 0x8000) | // sign
+        ((((f & 0x7f800000) - 0x38000000) >> 13) & 0x7c00) | // exponential
+        ((f >> 13) & 0x03ff); // Mantissa
+	}
+    
+	glm::uint16 float2packed11(glm::uint32 const & f)
+	{
+		// 10 bits    =>                         EE EEEFFFFF
+		// 11 bits    =>                        EEE EEFFFFFF
+		// Half bits  =>                   SEEEEEFF FFFFFFFF
+		// Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF
+        
+		// 0x000007c0 => 00000000 00000000 00000111 11000000
+		// 0x00007c00 => 00000000 00000000 01111100 00000000
+		// 0x000003ff => 00000000 00000000 00000011 11111111
+		// 0x38000000 => 00111000 00000000 00000000 00000000
+		// 0x7f800000 => 01111111 10000000 00000000 00000000
+		// 0x00008000 => 00000000 00000000 10000000 00000000
+		return
+        ((((f & 0x7f800000) - 0x38000000) >> 17) & 0x07c0) | // exponential
+        ((f >> 17) & 0x003f); // Mantissa
+	}
+    
+	glm::uint float2packed10(glm::uint const & f)
+	{
+		// 10 bits    =>                         EE EEEFFFFF
+		// 11 bits    =>                        EEE EEFFFFFF
+		// Half bits  =>                   SEEEEEFF FFFFFFFF
+		// Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF
+        
+		// 0x0000001F => 00000000 00000000 00000000 00011111
+		// 0x0000003F => 00000000 00000000 00000000 00111111
+		// 0x000003E0 => 00000000 00000000 00000011 11100000
+		// 0x000007C0 => 00000000 00000000 00000111 11000000
+		// 0x00007C00 => 00000000 00000000 01111100 00000000
+		// 0x000003FF => 00000000 00000000 00000011 11111111
+		// 0x38000000 => 00111000 00000000 00000000 00000000
+		// 0x7f800000 => 01111111 10000000 00000000 00000000
+		// 0x00008000 => 00000000 00000000 10000000 00000000
+		return
+        ((((f & 0x7f800000) - 0x38000000) >> 18) & 0x03E0) | // exponential
+        ((f >> 18) & 0x001f); // Mantissa
+	}
+    
+	glm::uint half2float(glm::uint const & h)
+	{
+		return ((h & 0x8000) << 16) | ((( h & 0x7c00) + 0x1C000) << 13) | ((h & 0x03FF) << 13);
+	}
+    
+    union uif
+    {
+        glm::uint i;
+        float f;
+    };
+    
+	glm::uint floatTo11bit(float x)
+	{
+		if(x == 0.0f)
+			return 0;
+		else if(glm::isnan(x))
+			return ~0;
+		else if(glm::isinf(x))
+			return 0x1f << 6;
+        
+		uif Union;
+		Union.f = x;
+		return float2packed11(Union.i);
+	}
+    
+	glm::uint floatTo10bit(float x)
+	{
+		if(x == 0.0f)
+			return 0;
+		else if(glm::isnan(x))
+			return ~0;
+		else if(glm::isinf(x))
+			return 0x1f << 5;
+        
+		uif Union;
+		Union.f = x;
+		return float2packed10(Union.i);
+	}
+    
+	glm::uint f11_f11_f10(float x, float y, float z)
+	{
+		return ((floatTo11bit(x) & ((1 << 11) - 1)) << 0) |  ((floatTo11bit(y) & ((1 << 11) - 1)) << 11) | ((floatTo10bit(z) & ((1 << 10) - 1)) << 22);
+	}
+}//namespace detail
+
+	GLM_FUNC_QUALIFIER uint32 packF11F11F10(vec3 const & v)
+    {
+        return 
+            ((detail::floatTo11bit(v.x) & ((1 << 11) - 1)) << 0) |
+            ((detail::floatTo11bit(v.y) & ((1 << 11) - 1)) << 11) |
+            ((detail::floatTo10bit(v.z) & ((1 << 10) - 1)) << 22);
+    }
+    
+	GLM_FUNC_QUALIFIER vec3 unpackF11F11F10(uint32 const & v)
+    {
+    
+    }
 
 
 }//namespace glm
 }//namespace glm

+ 1 - 0
test/gtc/CMakeLists.txt

@@ -6,6 +6,7 @@ glmCreateTestGTC(gtc_matrix_integer)
 glmCreateTestGTC(gtc_matrix_inverse)
 glmCreateTestGTC(gtc_matrix_inverse)
 glmCreateTestGTC(gtc_matrix_transform)
 glmCreateTestGTC(gtc_matrix_transform)
 glmCreateTestGTC(gtc_noise)
 glmCreateTestGTC(gtc_noise)
+glmCreateTestGTC(gtc_packing)
 glmCreateTestGTC(gtc_quaternion)
 glmCreateTestGTC(gtc_quaternion)
 glmCreateTestGTC(gtc_random)
 glmCreateTestGTC(gtc_random)
 glmCreateTestGTC(gtc_reciprocal)
 glmCreateTestGTC(gtc_reciprocal)

+ 142 - 0
test/gtc/gtc_packing.cpp

@@ -0,0 +1,142 @@
+///////////////////////////////////////////////////////////////////////////////////
+/// OpenGL Mathematics (glm.g-truc.net)
+///
+/// Copyright (c) 2005 - 2013 G-Truc Creation (www.g-truc.net)
+/// Permission is hereby granted, free of charge, to any person obtaining a copy
+/// of this software and associated documentation files (the "Software"), to deal
+/// in the Software without restriction, including without limitation the rights
+/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+/// copies of the Software, and to permit persons to whom the Software is
+/// furnished to do so, subject to the following conditions:
+/// 
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+/// 
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+/// THE SOFTWARE.
+///
+/// @ref test
+/// @file test/gtc/packing.cpp
+/// @date 2013-08-09 / 2013-08-09
+/// @author Christophe Riccio
+///////////////////////////////////////////////////////////////////////////////////
+
+
+#include <glm/glm.hpp>
+#include <glm/gtc/packing.hpp>
+
+void print_bits(glm::half const & s)
+{
+    union
+    {
+        glm::detail::hdata h;
+        unsigned short i;
+    } uif;
+    
+    uif.h = s._data();
+    
+    printf("f16: ");
+    for(std::size_t j = sizeof(s) * 8; j > 0; --j)
+    {
+        if(j == 10 || j == 15)
+            printf(" ");
+        printf("%d", (uif.i & (1 << (j - 1))) ? 1 : 0);
+    }
+}
+
+void print_bits(float const & s)
+{
+    union
+    {
+        float f;
+        unsigned int i;
+    } uif;
+    
+    uif.f = s;
+    
+    printf("f32: ");
+    for(std::size_t j = sizeof(s) * 8; j > 0; --j)
+    {
+        if(j == 23 || j == 31)
+            printf(" ");
+        printf("%d", (uif.i & (1 << (j - 1))) ? 1 : 0);
+    }
+}
+
+void print_10bits(glm::uint const & s)
+{
+    printf("10b: ");
+    for(std::size_t j = 10; j > 0; --j)
+    {
+        if(j == 5)
+            printf(" ");
+        printf("%d", (s & (1 << (j - 1))) ? 1 : 0);
+    }
+}
+
+void print_11bits(glm::uint const & s)
+{
+    printf("11b: ");
+    for(std::size_t j = 11; j > 0; --j)
+    {
+        if(j == 6)
+            printf(" ");
+        printf("%d", (s & (1 << (j - 1))) ? 1 : 0);
+    }
+}
+
+void print_value(float const & s)
+{
+    printf("%2.5f, ", s);
+    print_bits(s);
+    printf(", ");
+    print_bits(glm::half(s));
+    printf(", ");
+    print_11bits(detail::floatTo11bit(s));
+    printf(", ");
+    print_10bits(detail::floatTo10bit(s));
+    printf("\n");
+}
+
+int test_half()
+{
+    int Error = 0;
+
+    print_value(0.0);
+    print_value(0.1);
+    print_value(0.2);
+    print_value(0.3);
+    print_value(0.4);
+    print_value(0.5);
+    print_value(0.6);
+    print_value(1.0);
+    print_value(1.1);
+    print_value(1.2);
+    print_value(1.3);
+    print_value(1.4);
+    print_value(1.5);
+    print_value(1.6);
+    print_value(2.0);
+    print_value(2.1);
+    print_value(2.2);
+    print_value(2.3);
+    print_value(2.4);
+    print_value(2.5);
+    print_value(2.6);
+    
+    return Error;
+}
+
+int main()
+{
+	int Error(0);
+
+    Error += test_half();
+
+	return Error;
+}