From 2ee6151a40f99a8a31349f0743eef50a9007da9f Mon Sep 17 00:00:00 2001 From: Carsten Neumann Date: Mon, 18 May 2015 12:20:55 -0500 Subject: [PATCH] Use unions for type punning Fixes #334 --- glm/detail/func_packing.inl | 162 +++++++++++++++++++++++++++++------- 1 file changed, 132 insertions(+), 30 deletions(-) diff --git a/glm/detail/func_packing.inl b/glm/detail/func_packing.inl index 3132a279..fff9e703 100644 --- a/glm/detail/func_packing.inl +++ b/glm/detail/func_packing.inl @@ -38,82 +38,184 @@ namespace glm { GLM_FUNC_QUALIFIER uint packUnorm2x16(vec2 const & v) { - u16vec2 const Topack(round(clamp(v, 0.0f, 1.0f) * 65535.0f)); - return reinterpret_cast(Topack); + union + { + u16 in[2]; + uint out; + } u; + + u.in[0] = round(clamp(v[0], 0.0f, 1.0f) * 65535.0f); + u.in[1] = round(clamp(v[1], 0.0f, 1.0f) * 65535.0f); + + return u.out; } GLM_FUNC_QUALIFIER vec2 unpackUnorm2x16(uint p) { - vec2 Unpack(reinterpret_cast(p)); - return Unpack * float(1.5259021896696421759365224689097e-5); // 1.0 / 65535.0 + union + { + uint in; + u16 out[2]; + } u; + + u.in = p; + + return vec2( + u.out[0] * 1.5259021896696421759365224689097e-5f, + u.out[1] * 1.5259021896696421759365224689097e-5f); } GLM_FUNC_QUALIFIER uint packSnorm2x16(vec2 const & v) { - i16vec2 const Topack(round(clamp(v ,-1.0f, 1.0f) * 32767.0f)); - return reinterpret_cast(Topack); + union + { + i16 in[2]; + uint out; + } u; + + u.in[0] = round(clamp(v[0], -1.0f, 1.0f) * 32767.0f); + u.in[1] = round(clamp(v[1], -1.0f, 1.0f) * 32767.0f); + + return u.out; } GLM_FUNC_QUALIFIER vec2 unpackSnorm2x16(uint p) { - vec2 const Unpack(reinterpret_cast(p)); - return clamp( - Unpack * 3.0518509475997192297128208258309e-5f, //1.0f / 32767.0f, - -1.0f, 1.0f); + union + { + uint in; + i16 out[2]; + } u; + + u.in = p; + + return vec2( + clamp(u.out[0] * 3.0518509475997192297128208258309e-5f, + -1.0f, 1.0f), + clamp(u.out[1] * 3.0518509475997192297128208258309e-5f, + -1.0f, 1.0f)); } GLM_FUNC_QUALIFIER uint packUnorm4x8(vec4 const & v) { - u8vec4 const Topack(round(clamp(v, 0.0f, 1.0f) * 255.0f)); - return reinterpret_cast(Topack); + union + { + u8 in[4]; + uint out; + } u; + + u.in[0] = round(clamp(v[0], 0.0f, 1.0f) * 255.0f); + u.in[1] = round(clamp(v[1], 0.0f, 1.0f) * 255.0f); + u.in[2] = round(clamp(v[2], 0.0f, 1.0f) * 255.0f); + u.in[3] = round(clamp(v[3], 0.0f, 1.0f) * 255.0f); + + return u.out; } GLM_FUNC_QUALIFIER vec4 unpackUnorm4x8(uint p) { - vec4 const Unpack(reinterpret_cast(p)); - return Unpack * float(0.0039215686274509803921568627451); // 1 / 255 + union + { + uint in; + u8 out[4]; + } u; + + u.in = p; + + return vec4( + u.out[0] * 0.0039215686274509803921568627451f, + u.out[1] * 0.0039215686274509803921568627451f, + u.out[2] * 0.0039215686274509803921568627451f, + u.out[3] * 0.0039215686274509803921568627451f); } GLM_FUNC_QUALIFIER uint packSnorm4x8(vec4 const & v) { - i8vec4 const Topack(round(clamp(v ,-1.0f, 1.0f) * 127.0f)); - return reinterpret_cast(Topack); + union + { + i8 in[4]; + uint out; + } u; + + u.in[0] = round(clamp(v[0], -1.0f, 1.0f) * 127.0f); + u.in[1] = round(clamp(v[1], -1.0f, 1.0f) * 127.0f); + u.in[2] = round(clamp(v[2], -1.0f, 1.0f) * 127.0f); + u.in[3] = round(clamp(v[3], -1.0f, 1.0f) * 127.0f); + + return u.out; } GLM_FUNC_QUALIFIER glm::vec4 unpackSnorm4x8(uint p) { - vec4 const Unpack(reinterpret_cast(p)); - return clamp( - Unpack * 0.0078740157480315f, // 1.0f / 127.0f - -1.0f, 1.0f); + union + { + uint in; + i8 out[4]; + } u; + + u.in = p; + + return vec4( + clamp(u.out[0] * 0.0078740157480315f, -1.0f, 1.0f), + clamp(u.out[1] * 0.0078740157480315f, -1.0f, 1.0f), + clamp(u.out[2] * 0.0078740157480315f, -1.0f, 1.0f), + clamp(u.out[3] * 0.0078740157480315f, -1.0f, 1.0f)); } GLM_FUNC_QUALIFIER double packDouble2x32(uvec2 const & v) { - return reinterpret_cast(v); + union + { + uint in[2]; + double out; + } u; + + u.in[0] = v[0]; + u.in[1] = v[1]; + + return u.out; } GLM_FUNC_QUALIFIER uvec2 unpackDouble2x32(double v) { - return reinterpret_cast(v); + union + { + double in; + uint out[2]; + } u; + + u.in = v; + + return uvec2(u.out[0], u.out[1]); } GLM_FUNC_QUALIFIER uint packHalf2x16(vec2 const & v) { - i16vec2 const Unpack( - detail::toFloat16(v.x), - detail::toFloat16(v.y)); + union + { + i16 in[2]; + uint out; + } u; - return reinterpret_cast(Unpack); + u.in[0] = detail::toFloat16(v.x); + u.in[1] = detail::toFloat16(v.y); + + return u.out; } GLM_FUNC_QUALIFIER vec2 unpackHalf2x16(uint v) { - i16vec2 const Unpack(reinterpret_cast(v)); - + union + { + uint in; + i16 out[2]; + } u; + + u.in = v; + return vec2( - detail::toFloat32(Unpack.x), - detail::toFloat32(Unpack.y)); + detail::toFloat32(u.out[0]), + detail::toFloat32(u.out[1])); } }//namespace glm