Added (un)packHalf

This commit is contained in:
Christophe Riccio 2015-10-10 01:54:54 +02:00
parent 8508e099d0
commit 65c8f8fcf0
4 changed files with 118 additions and 1 deletions

View File

@ -494,6 +494,27 @@ namespace glm
/// @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 vecType<float, P> unpackHalf(vecType<uint16, P> const & p)
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
template <precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<uint16, P> packHalf(vecType<float, P> const & v);
/// 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 vecType<uint16, P> packHalf(vecType<float, P> const & v)
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
template <precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<float, P> unpackHalf(vecType<uint16, P> const & p);
/// @}
}// namespace glm

View File

@ -260,6 +260,85 @@ namespace detail
uint32 pack;
};
template <precision P, template <typename, precision> class vecType>
struct compute_half
{};
template <precision P>
struct compute_half<P, tvec1>
{
GLM_FUNC_QUALIFIER static tvec1<uint16, P> pack(tvec1<float, P> const & v)
{
int16 const Topack(detail::toFloat16(v.x));
return tvec1<uint16, P>(reinterpret_cast<uint16 const &>(Topack));
}
GLM_FUNC_QUALIFIER static tvec1<float, P> unpack(tvec1<uint16, P> const & v)
{
return tvec1<float, P>(detail::toFloat32(reinterpret_cast<int16 const &>(v.x)));
}
};
template <precision P>
struct compute_half<P, tvec2>
{
GLM_FUNC_QUALIFIER static tvec2<uint16, P> pack(tvec2<float, P> const & v)
{
return tvec2<uint16, P>(
reinterpret_cast<uint16 const &>(detail::toFloat16(v.x)),
reinterpret_cast<uint16 const &>(detail::toFloat16(v.x)));
}
GLM_FUNC_QUALIFIER static tvec2<float, P> unpack(tvec2<uint16, P> const & v)
{
return tvec2<float, P>(
detail::toFloat32(reinterpret_cast<int16 const &>(v.x)),
detail::toFloat32(reinterpret_cast<int16 const &>(v.y)));
}
};
template <precision P>
struct compute_half<P, tvec3>
{
GLM_FUNC_QUALIFIER static tvec3<uint16, P> pack(tvec3<float, P> const & v)
{
return tvec3<uint16, P>(
reinterpret_cast<uint16 const &>(detail::toFloat16(v.x)),
reinterpret_cast<uint16 const &>(detail::toFloat16(v.y)),
reinterpret_cast<uint16 const &>(detail::toFloat16(v.z)));
}
GLM_FUNC_QUALIFIER static tvec3<float, P> unpack(tvec3<uint16, P> const & v)
{
return tvec3<float, P>(
detail::toFloat32(reinterpret_cast<int16 const &>(v.x)),
detail::toFloat32(reinterpret_cast<int16 const &>(v.y)),
detail::toFloat32(reinterpret_cast<int16 const &>(v.z)));
}
};
template <precision P>
struct compute_half<P, tvec4>
{
GLM_FUNC_QUALIFIER static tvec4<uint16, P> pack(tvec4<float, P> const & v)
{
tvec4<int16, P> unpacked(detail::toFloat16(v.x), detail::toFloat16(v.y), detail::toFloat16(v.z), detail::toFloat16(v.w));
return tvec4<uint16, P>(
reinterpret_cast<uint16 const &>(unpacked.x),
reinterpret_cast<uint16 const &>(unpacked.y),
reinterpret_cast<uint16 const &>(unpacked.z),
reinterpret_cast<uint16 const &>(unpacked.w));
}
GLM_FUNC_QUALIFIER static tvec4<float, P> unpack(tvec4<uint16, P> const & v)
{
return tvec4<float, P>(
detail::toFloat32(reinterpret_cast<int16 const &>(v.x)),
detail::toFloat32(reinterpret_cast<int16 const &>(v.y)),
detail::toFloat32(reinterpret_cast<int16 const &>(v.z)),
detail::toFloat32(reinterpret_cast<int16 const &>(v.w)));
}
};
}//namespace detail
GLM_FUNC_QUALIFIER uint8 packUnorm1x8(float v)
@ -525,4 +604,16 @@ namespace detail
return vec3(Unpack.data.x, Unpack.data.y, Unpack.data.z) * pow(2.0f, Unpack.data.w - 15.f - 9.f);
}
template <precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<uint16, P> packHalf(vecType<float, P> const & v)
{
return detail::compute_half<P, vecType>::pack(v);
}
template <precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<float, P> unpackHalf(vecType<uint16, P> const & v)
{
return detail::compute_half<P, vecType>::unpack(v);
}
}//namespace glm

View File

@ -55,6 +55,7 @@ glm::mat4 camera(float Translate, glm::vec2 const & Rotate)
##### Features:
- Added compNormalize and compScale functions to GTX_component_wise
- Added packF3x9_E1x5 and unpackF3x9_E1x5 to GTC_packing for RGB9E5 #416
- Added packHalf and unpackHalf to GTC_packing
##### Improvements:
- Improved GTC_random linearRand documentation

View File

@ -128,7 +128,11 @@ int test_Half4x16()
glm::vec4 v0 = glm::unpackHalf4x16(p0);
glm::uint64 p1 = glm::packHalf4x16(v0);
glm::vec4 v1 = glm::unpackHalf4x16(p1);
glm::u16vec4 p2 = glm::packHalf(v0);
glm::vec4 v2 = glm::unpackHalf(p2);
Error += glm::all(glm::equal(v0, v1)) ? 0 : 1;
Error += glm::all(glm::equal(v0, v2)) ? 0 : 1;
}
return Error;
@ -552,7 +556,7 @@ int main()
Error += test_I3x10_1x2();
Error += test_U3x10_1x2();
Error += test_Half1x16();
Error += test_U3x10_1x2();
Error += test_Half4x16();
return Error;
}