Browse Source

Fixed and tested pack/unpackSnorm2x16 functions

Christophe Riccio 14 years ago
parent
commit
b21b389d2c
2 changed files with 85 additions and 24 deletions
  1. 39 23
      glm/core/func_packing.inl
  2. 46 1
      test/core/core_func_packing.cpp

+ 39 - 23
glm/core/func_packing.inl

@@ -30,16 +30,50 @@ namespace glm{
 
 GLM_FUNC_QUALIFIER detail::uint32 packUnorm2x16(detail::tvec2<detail::float32> const & v)
 {
-	detail::uint16 A((detail::uint16)round(clamp(v.x, 0.0f, 1.0f) * 65535.0f));
-	detail::uint16 B((detail::uint16)round(clamp(v.y, 0.0f, 1.0f) * 65535.0f));
+	detail::uint16 A(detail::uint16(round(clamp(v.x, 0.0f, 1.0f) * 65535.0f)));
+	detail::uint16 B(detail::uint16(round(clamp(v.y, 0.0f, 1.0f) * 65535.0f)));
 	return detail::uint32((B << 16) | A);
 }
 
+GLM_FUNC_QUALIFIER detail::tvec2<detail::float32> unpackUnorm2x16(detail::uint32 const & p)
+{
+	detail::uint32 Mask16((1 << 16) - 1);
+	detail::uint32 A((p >>  0) & Mask16);
+	detail::uint32 B((p >> 16) & Mask16);
+	return detail::tvec2<detail::float32>(
+		A * 1.0f / 65535.0f, 
+		B * 1.0f / 65535.0f);
+}
+	
 GLM_FUNC_QUALIFIER detail::uint32 packSnorm2x16(detail::tvec2<detail::float32> const & v)
 {
-	detail::uint16 A((detail::uint16)round(clamp(v.x,-1.0f, 1.0f) * 32767.0f));
-	detail::uint16 B((detail::uint16)round(clamp(v.y,-1.0f, 1.0f) * 32767.0f));
-	return detail::uint32((B << 16) | A);
+	union iu
+	{
+		detail::int16 i;
+		detail::uint16 u;
+	} A, B;
+		
+	detail::tvec2<detail::float32> Unpack = clamp(v ,-1.0f, 1.0f) * 32767.0f;
+	A.i = detail::int16(round(Unpack.x));
+	B.i = detail::int16(round(Unpack.y));
+	detail::uint32 Pack = (detail::uint32(B.u) << 16) | (detail::uint32(A.u) << 0);
+	return Pack;
+}
+
+GLM_FUNC_QUALIFIER detail::tvec2<detail::float32> unpackSnorm2x16(detail::uint32 const & p)
+{
+	union iu
+	{
+		detail::int16 i;
+		detail::uint16 u;
+	} A, B;
+		
+	detail::uint32 Mask16((1 << 16) - 1);
+	A.u = detail::uint16((p >>  0) & Mask16);
+	B.u = detail::uint16((p >> 16) & Mask16);
+	vec2 Pack(A.i, B.i);
+		
+	return clamp(Pack * 1.0f / 32767.0f, -1.0f, 1.0f);
 }
 
 GLM_FUNC_QUALIFIER detail::uint32 packUnorm4x8(detail::tvec4<detail::float32> const & v)
@@ -60,24 +94,6 @@ GLM_FUNC_QUALIFIER detail::uint32 packSnorm4x8(detail::tvec4<detail::float32> co
 		return detail::uint32((D << 24) | (C << 16) | (B << 8) | A);
 }
 
-GLM_FUNC_QUALIFIER detail::tvec2<detail::float32> unpackUnorm2x16(detail::uint32 const & p)
-{
-	detail::uint16 A(detail::uint16(p >> 0));
-	detail::uint16 B(detail::uint16(p >> 16));
-	return detail::tvec2<detail::float32>(
-		A * 1.0f / 65535.0f, 
-		B * 1.0f / 65535.0f);
-}
-
-GLM_FUNC_QUALIFIER detail::tvec2<detail::float32> unpackSnorm2x16(detail::uint32 const & p)
-{
-	detail::uint16 A(detail::uint16(p >> 0));
-	detail::uint16 B(detail::uint16(p >> 16));
-	return clamp(detail::tvec2<detail::float32>(
-		A * 1.0f / 32767.0f, 
-		B * 1.0f / 32767.0f), -1.0f, 1.0f);
-}
-
 GLM_FUNC_QUALIFIER detail::tvec4<detail::float32> unpackUnorm4x8(detail::uint32 const & p)
 {
 	detail::uint8 A(detail::uint8(p >> 0));

+ 46 - 1
test/core/core_func_packing.cpp

@@ -10,8 +10,51 @@
 #include <glm/glm.hpp>
 #include <glm/gtc/half_float.hpp>
 #include <glm/gtc/type_precision.hpp>
+#include <glm/gtx/epsilon.hpp>
 #include <vector>
 
+int test_packUnorm2x16()
+{
+	int Error = 0;
+	
+	std::vector<glm::hvec2> A;
+	A.push_back(glm::hvec2(glm::half( 1.0f), glm::half( 0.0f)));
+	A.push_back(glm::hvec2(glm::half( 0.5f), glm::half( 0.7f)));
+	A.push_back(glm::hvec2(glm::half( 0.1f), glm::half( 0.2f)));
+	
+	for(std::size_t i = 0; i < A.size(); ++i)
+	{
+		glm::vec2 B(A[i]);
+		glm::uint32 C = glm::packUnorm2x16(B);
+		glm::vec2 D = glm::unpackUnorm2x16(C);
+		Error += glm::all(glm::equalEpsilon(B, D, 0.0001f)) ? 0 : 1;
+		assert(!Error);
+	}
+	
+	return Error;
+}
+
+int test_packSnorm2x16()
+{
+	int Error = 0;
+	
+	std::vector<glm::hvec2> A;
+	A.push_back(glm::hvec2(glm::half( 1.0f), glm::half( 0.0f)));
+	A.push_back(glm::hvec2(glm::half(-0.5f), glm::half(-0.7f)));
+	A.push_back(glm::hvec2(glm::half(-0.1f), glm::half( 0.1f)));
+	
+	for(std::size_t i = 0; i < A.size(); ++i)
+	{
+		glm::vec2 B(A[i]);
+		glm::uint32 C = glm::packSnorm2x16(B);
+		glm::vec2 D = glm::unpackSnorm2x16(C);
+		Error += glm::all(glm::equalEpsilon(B, D, 0.0001f)) ? 0 : 1;
+		//assert(!Error);
+	}
+	
+	return Error;
+}
+
 int test_packHalf2x16()
 {
 	int Error = 0;
@@ -55,7 +98,9 @@ int test_packDouble2x32()
 int main()
 {
 	int Error = 0;
-
+	
+	Error += test_packSnorm2x16();
+	Error += test_packUnorm2x16();
 	Error += test_packHalf2x16();
 	Error += test_packDouble2x32();