Browse Source

Added 16bit pack and unpack to GTC_packing

Christophe Riccio 10 years ago
parent
commit
bb9ce516b0
4 changed files with 254 additions and 1 deletions
  1. 48 0
      glm/gtc/packing.hpp
  2. 119 0
      glm/gtc/packing.inl
  3. 1 0
      readme.md
  4. 86 1
      test/gtc/gtc_packing.cpp

+ 48 - 0
glm/gtc/packing.hpp

@@ -543,6 +543,54 @@ namespace glm
 	template <typename intType, typename floatType, precision P, template <typename, precision> class vecType>
 	GLM_FUNC_DECL vecType<floatType, P> unpackSnorm(vecType<intType, P> const & v);
 
+	/// Convert each component of the normalized floating-point vector into unsigned integer values.
+	///
+	/// @see gtc_packing
+	/// @see vec2 unpackUnorm2x4(uint8 p)
+	GLM_FUNC_DECL uint8 packUnorm2x4(vec2 const & v);
+
+	/// Convert each unsigned integer components of a vector to normalized floating-point values.
+	/// 
+	/// @see gtc_packing
+	/// @see uint8 packUnorm2x4(vec2 const & v)
+	GLM_FUNC_DECL vec2 unpackUnorm2x4(uint8 p);
+
+	/// Convert each component of the normalized floating-point vector into unsigned integer values.
+	///
+	/// @see gtc_packing
+	/// @see vec4 unpackUnorm4x4(uint16 p)
+	GLM_FUNC_DECL uint16 packUnorm4x4(vec4 const & v);
+
+	/// Convert each unsigned integer components of a vector to normalized floating-point values.
+	/// 
+	/// @see gtc_packing
+	/// @see uint16 packUnorm4x4(vec4 const & v)
+	GLM_FUNC_DECL vec4 unpackUnorm4x4(uint16 p);
+
+	/// Convert each component of the normalized floating-point vector into unsigned integer values.
+	///
+	/// @see gtc_packing
+	/// @see vec3 unpackUnorm1x5_1x6_1x5(uint16 p)
+	GLM_FUNC_DECL uint16 packUnorm1x5_1x6_1x5(vec3 const & v);
+
+	/// Convert each unsigned integer components of a vector to normalized floating-point values.
+	/// 
+	/// @see gtc_packing
+	/// @see uint16 packUnorm1x5_1x6_1x5(vec3 const & v)
+	GLM_FUNC_DECL vec3 unpackUnorm1x5_1x6_1x5(uint16 p);
+
+	/// Convert each component of the normalized floating-point vector into unsigned integer values.
+	///
+	/// @see gtc_packing
+	/// @see vec4 unpackUnorm3x5_1x1(uint16 p)
+	GLM_FUNC_DECL uint16 packUnorm3x5_1x1(vec4 const & v);
+
+	/// Convert each unsigned integer components of a vector to normalized floating-point values.
+	/// 
+	/// @see gtc_packing
+	/// @see uint16 packUnorm3x5_1x1(vec4 const & v)
+	GLM_FUNC_DECL vec4 unpackUnorm3x5_1x1(uint16 p);
+
 	/// @}
 }// namespace glm
 

+ 119 - 0
glm/gtc/packing.inl

@@ -225,6 +225,51 @@ namespace detail
 //		return ((floatTo11bit(x) & ((1 << 11) - 1)) << 0) |  ((floatTo11bit(y) & ((1 << 11) - 1)) << 11) | ((floatTo10bit(z) & ((1 << 10) - 1)) << 22);
 //	}
 
+	union u4u4
+	{
+		struct
+		{
+			uint x : 4;
+			uint y : 4;
+		} data;
+		uint8 pack;
+	};
+
+	union u4u4u4u4
+	{
+		struct
+		{
+			uint x : 4;
+			uint y : 4;
+			uint z : 4;
+			uint w : 4;
+		} data;
+		uint16 pack;
+	};
+
+	union u5u6u5
+	{
+		struct
+		{
+			uint x : 5;
+			uint y : 6;
+			uint z : 5;
+		} data;
+		uint16 pack;
+	};
+
+	union u5u5u5u1
+	{
+		struct
+		{
+			uint x : 5;
+			uint y : 5;
+			uint z : 5;
+			uint w : 1;
+		} data;
+		uint16 pack;
+	};
+
 	union u10u10u10u2
 	{
 		struct
@@ -655,4 +700,78 @@ namespace detail
 
 		return clamp(vecType<floatType, P>(v) * (static_cast<floatType>(1) / static_cast<floatType>(std::numeric_limits<intType>::max())), static_cast<floatType>(-1), static_cast<floatType>(1));
 	}
+
+	GLM_FUNC_QUALIFIER uint8 packUnorm2x4(vec2 const & v)
+	{
+		u32vec2 const Unpack(round(clamp(v, 0.0f, 1.0f) * 15.0f));
+		detail::u4u4 Result;
+		Result.data.x = Unpack.x;
+		Result.data.y = Unpack.y;
+		return Result.pack;
+	}
+
+	GLM_FUNC_QUALIFIER vec2 unpackUnorm2x4(uint8 v)
+	{
+		float const ScaleFactor(1.f / 15.f);
+		detail::u4u4 Unpack;
+		Unpack.pack = v;
+		return vec2(Unpack.data.x, Unpack.data.y) * ScaleFactor;
+	}
+
+	GLM_FUNC_QUALIFIER uint16 packUnorm4x4(vec4 const & v)
+	{
+		u32vec4 const Unpack(round(clamp(v, 0.0f, 1.0f) * 15.0f));
+		detail::u4u4u4u4 Result;
+		Result.data.x = Unpack.x;
+		Result.data.y = Unpack.y;
+		Result.data.z = Unpack.z;
+		Result.data.w = Unpack.w;
+		return Result.pack;
+	}
+
+	GLM_FUNC_QUALIFIER vec4 unpackUnorm4x4(uint16 v)
+	{
+		float const ScaleFactor(1.f / 15.f);
+		detail::u4u4u4u4 Unpack;
+		Unpack.pack = v;
+		return vec4(Unpack.data.x, Unpack.data.y, Unpack.data.z, Unpack.data.w) * ScaleFactor;
+	}
+
+	GLM_FUNC_QUALIFIER uint16 packUnorm1x5_1x6_1x5(vec3 const & v)
+	{
+		u32vec3 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec3(15.f, 31.f, 15.f)));
+		detail::u5u6u5 Result;
+		Result.data.x = Unpack.x;
+		Result.data.y = Unpack.y;
+		Result.data.z = Unpack.z;
+		return Result.pack;
+	}
+
+	GLM_FUNC_QUALIFIER vec3 unpackUnorm1x5_1x6_1x5(uint16 v)
+	{
+		vec3 const ScaleFactor(1.f / 15.f, 1.f / 31.f, 1.f / 15.f);
+		detail::u5u6u5 Unpack;
+		Unpack.pack = v;
+		return vec3(Unpack.data.x, Unpack.data.y, Unpack.data.z) * ScaleFactor;
+	}
+
+	GLM_FUNC_QUALIFIER uint16 packUnorm3x5_1x1(vec4 const & v)
+	{
+		u32vec4 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec4(15.f, 15.f, 15.f, 1.f)));
+		detail::u5u5u5u1 Result;
+		Result.data.x = Unpack.x;
+		Result.data.y = Unpack.y;
+		Result.data.z = Unpack.z;
+		Result.data.w = Unpack.w;
+		return Result.pack;
+	}
+
+	GLM_FUNC_QUALIFIER vec4 unpackUnorm3x5_1x1(uint16 v)
+	{
+		vec4 const ScaleFactor(1.f / 15.f, 1.f / 15.f, 1.f / 15.f, 1.f);
+		detail::u5u5u5u1 Unpack;
+		Unpack.pack = v;
+		return vec4(Unpack.data.x, Unpack.data.y, Unpack.data.z, Unpack.data.w) * ScaleFactor;
+	}
 }//namespace glm
+

+ 1 - 0
readme.md

@@ -57,6 +57,7 @@ glm::mat4 camera(float Translate, glm::vec2 const & Rotate)
 - Added packF3x9_E1x5 and unpackF3x9_E1x5 to GTC_packing for RGB9E5 #416
 - Added (un)packHalf to GTC_packing
 - Added (un)packUnorm and (un)packSnorm to GTC_packing
+- Added 16bit pack and unpack to GTC_packing
 
 ##### Improvements:
 - Improved GTC_random linearRand documentation

+ 86 - 1
test/gtc/gtc_packing.cpp

@@ -570,9 +570,89 @@ int test_packSnorm()
 	return Error;
 }
 
+int test_packUnorm2x4()
+{
+	int Error = 0;
+
+	std::vector<glm::vec2> A;
+	A.push_back(glm::vec2(1.0f, 0.7f));
+	A.push_back(glm::vec2(0.5f, 0.0f));
+
+	for(std::size_t i = 0; i < A.size(); ++i)
+	{
+		glm::vec2 B(A[i]);
+		glm::uint8 C = glm::packUnorm2x4(B);
+		glm::vec2 D = glm::unpackUnorm2x4(C);
+		Error += glm::all(glm::epsilonEqual(B, D, 1.0f / 15.f)) ? 0 : 1;
+		assert(!Error);
+	}
+
+	return Error;
+}
+
+int test_packUnorm4x4()
+{
+	int Error = 0;
+
+	std::vector<glm::vec4> A;
+	A.push_back(glm::vec4(1.0f, 0.7f, 0.5f, 0.0f));
+	A.push_back(glm::vec4(0.5f, 0.1f, 0.0f, 1.0f));
+
+	for(std::size_t i = 0; i < A.size(); ++i)
+	{
+		glm::vec4 B(A[i]);
+		glm::uint16 C = glm::packUnorm4x4(B);
+		glm::vec4 D = glm::unpackUnorm4x4(C);
+		Error += glm::all(glm::epsilonEqual(B, D, 1.0f / 15.f)) ? 0 : 1;
+		assert(!Error);
+	}
+
+	return Error;
+}
+
+int test_packUnorm3x5_1x1()
+{
+	int Error = 0;
+
+	std::vector<glm::vec4> A;
+	A.push_back(glm::vec4(1.0f, 0.7f, 0.5f, 0.0f));
+	A.push_back(glm::vec4(0.5f, 0.1f, 0.0f, 1.0f));
+
+	for(std::size_t i = 0; i < A.size(); ++i)
+	{
+		glm::vec4 B(A[i]);
+		glm::uint16 C = glm::packUnorm3x5_1x1(B);
+		glm::vec4 D = glm::unpackUnorm3x5_1x1(C);
+		Error += glm::all(glm::epsilonEqual(B, D, 1.0f / 15.f)) ? 0 : 1;
+		assert(!Error);
+	}
+
+	return Error;
+}
+
+int test_packUnorm1x5_1x6_1x5()
+{
+	int Error = 0;
+
+	std::vector<glm::vec3> A;
+	A.push_back(glm::vec3(1.0f, 0.7f, 0.5f));
+	A.push_back(glm::vec3(0.5f, 0.1f, 0.0f));
+
+	for(std::size_t i = 0; i < A.size(); ++i)
+	{
+		glm::vec3 B(A[i]);
+		glm::uint16 C = glm::packUnorm1x5_1x6_1x5(B);
+		glm::vec3 D = glm::unpackUnorm1x5_1x6_1x5(C);
+		Error += glm::all(glm::epsilonEqual(B, D, 1.0f / 15.f)) ? 0 : 1;
+		assert(!Error);
+	}
+
+	return Error;
+}
+
 int main()
 {
-	int Error(0);
+	int Error = 0;
 
 	Error += test_packUnorm();
 	Error += test_packSnorm();
@@ -593,6 +673,11 @@ int main()
 	Error += test_packUnorm2x8();
 	Error += test_packUnorm4x8();
 
+	Error += test_packUnorm2x4();
+	Error += test_packUnorm4x4();
+	Error += test_packUnorm3x5_1x1();
+	Error += test_packUnorm1x5_1x6_1x5();
+
 	Error += test_F2x11_1x10();
 	Error += test_F3x9_E1x5();
 	Error += test_Snorm3x10_1x2();