From edc328c7c9861f962169e7707892592dfd6952fb Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Sat, 6 Aug 2016 19:28:16 +0200 Subject: [PATCH] Fixed GTX_wrap #534, improved GTX_wrap for SIMD friendliness --- glm/gtx/wrap.hpp | 17 +++--- glm/gtx/wrap.inl | 139 ++++++++---------------------------------- readme.md | 1 + test/gtx/gtx_wrap.cpp | 48 +++++++++++++++ 4 files changed, 82 insertions(+), 123 deletions(-) diff --git a/glm/gtx/wrap.hpp b/glm/gtx/wrap.hpp index 49316bfd..146088f5 100644 --- a/glm/gtx/wrap.hpp +++ b/glm/gtx/wrap.hpp @@ -14,6 +14,7 @@ // Dependency: #include "../glm.hpp" +#include "../gtc/vec1.hpp" #if(defined(GLM_MESSAGES) && !defined(GLM_EXT_INCLUDED)) # pragma message("GLM: GLM_GTX_wrap extension included") @@ -26,23 +27,23 @@ namespace glm /// Simulate GL_CLAMP OpenGL wrap mode /// @see gtx_wrap extension. - template - GLM_FUNC_DECL genType clamp(genType const & Texcoord); + template + GLM_FUNC_DECL genType clamp(genType const& Texcoord); /// Simulate GL_REPEAT OpenGL wrap mode /// @see gtx_wrap extension. - template - GLM_FUNC_DECL genType repeat(genType const & Texcoord); + template + GLM_FUNC_DECL genType repeat(genType const& Texcoord); /// Simulate GL_MIRRORED_REPEAT OpenGL wrap mode /// @see gtx_wrap extension. - template - GLM_FUNC_DECL genType mirrorClamp(genType const & Texcoord); + template + GLM_FUNC_DECL genType mirrorClamp(genType const& Texcoord); /// Simulate GL_MIRROR_REPEAT OpenGL wrap mode /// @see gtx_wrap extension. - template - GLM_FUNC_DECL genType mirrorRepeat(genType const & Texcoord); + template + GLM_FUNC_DECL genType mirrorRepeat(genType const& Texcoord); /// @} }// namespace glm diff --git a/glm/gtx/wrap.inl b/glm/gtx/wrap.inl index 6321b7ef..941a803e 100644 --- a/glm/gtx/wrap.inl +++ b/glm/gtx/wrap.inl @@ -3,147 +3,56 @@ namespace glm { - template - GLM_FUNC_QUALIFIER genType clamp(genType const & Texcoord) - { - return glm::clamp(Texcoord, genType(0), genType(1)); - } - - template - GLM_FUNC_QUALIFIER tvec2 clamp(tvec2 const & Texcoord) + template class vecType> + GLM_FUNC_QUALIFIER vecType clamp(vecType const& Texcoord) { - tvec2 Result; - for(typename tvec2::size_type i = 0; i < tvec2::value_size(); ++i) - Result[i] = clamp_to_edge(Texcoord[i]); - return Result; + return glm::clamp(Texcoord, vecType(0), vecType(1)); } - template - GLM_FUNC_QUALIFIER tvec3 clamp(tvec3 const & Texcoord) + template + GLM_FUNC_QUALIFIER genType clamp(genType const & Texcoord) { - tvec3 Result; - for(typename tvec3::size_type i = 0; i < tvec3::value_size(); ++i) - Result[i] = clamp_to_edge(Texcoord[i]); - return Result; + return clamp(tvec1(Texcoord)).x; } - template - GLM_FUNC_QUALIFIER tvec4 clamp(tvec4 const & Texcoord) + template class vecType> + GLM_FUNC_QUALIFIER vecType repeat(vecType const& Texcoord) { - tvec4 Result; - for(typename tvec4::size_type i = 0; i < tvec4::value_size(); ++i) - Result[i] = clamp_to_edge(Texcoord[i]); - return Result; + return glm::fract(Texcoord); } template GLM_FUNC_QUALIFIER genType repeat(genType const & Texcoord) { - return glm::fract(Texcoord); - } - - template - GLM_FUNC_QUALIFIER tvec2 repeat(tvec2 const & Texcoord) - { - tvec2 Result; - for(typename tvec2::size_type i = 0; i < tvec2::value_size(); ++i) - Result[i] = repeat(Texcoord[i]); - return Result; - } - - template - GLM_FUNC_QUALIFIER tvec3 repeat(tvec3 const & Texcoord) - { - tvec3 Result; - for(typename tvec3::size_type i = 0; i < tvec3::value_size(); ++i) - Result[i] = repeat(Texcoord[i]); - return Result; + return repeat(tvec1(Texcoord)).x; } - template - GLM_FUNC_QUALIFIER tvec4 repeat(tvec4 const & Texcoord) + template class vecType> + GLM_FUNC_QUALIFIER vecType mirrorClamp(vecType const& Texcoord) { - tvec4 Result; - for(typename tvec4::size_type i = 0; i < tvec4::value_size(); ++i) - Result[i] = repeat(Texcoord[i]); - return Result; + return glm::fract(glm::abs(Texcoord)); } template GLM_FUNC_QUALIFIER genType mirrorClamp(genType const & Texcoord) { - return glm::fract(glm::abs(Texcoord)); - //return glm::mod(glm::abs(Texcoord), 1.0f); - } - - template - GLM_FUNC_QUALIFIER tvec2 mirrorClamp(tvec2 const & Texcoord) - { - tvec2 Result; - for(typename tvec2::size_type i = 0; i < tvec2::value_size(); ++i) - Result[i] = mirrorClamp(Texcoord[i]); - return Result; - } - - template - GLM_FUNC_QUALIFIER tvec3 mirrorClamp(tvec3 const & Texcoord) - { - tvec3 Result; - for(typename tvec3::size_type i = 0; i < tvec3::value_size(); ++i) - Result[i] = mirrorClamp(Texcoord[i]); - return Result; + return mirrorClamp(tvec1(Texcoord)).x; } - template - GLM_FUNC_QUALIFIER tvec4 mirrorClamp(tvec4 const & Texcoord) + template class vecType> + GLM_FUNC_QUALIFIER vecType mirrorRepeat(vecType const& Texcoord) { - tvec4 Result; - for(typename tvec4::size_type i = 0; i < tvec4::value_size(); ++i) - Result[i] = mirrorClamp(Texcoord[i]); - return Result; + vecType const Abs = glm::abs(Texcoord); + vecType const Clamp = glm::mod(glm::floor(Abs), vecType(2)); + vecType const Floor = glm::floor(Abs); + vecType const Rest = Abs - Floor; + vecType const Mirror = Clamp + Rest; + return mix(Rest, vecType(1) - Rest, glm::greaterThanEqual(Mirror, vecType(1))); } template - GLM_FUNC_QUALIFIER genType mirrorRepeat(genType const & Texcoord) - { - genType const Abs = glm::abs(Texcoord); - genType const Clamp = genType(int(glm::floor(Abs)) % 2); - genType const Floor = glm::floor(Abs); - genType const Rest = Abs - Floor; - genType const Mirror = Clamp + Rest; - - genType Out; - if(Mirror >= genType(1)) - Out = genType(1) - Rest; - else - Out = Rest; - return Out; - } - - template - GLM_FUNC_QUALIFIER tvec2 mirrorRepeat(tvec2 const & Texcoord) - { - tvec2 Result; - for(typename tvec2::size_type i = 0; i < tvec2::value_size(); ++i) - Result[i] = mirrorRepeat(Texcoord[i]); - return Result; - } - - template - GLM_FUNC_QUALIFIER tvec3 mirrorRepeat(tvec3 const & Texcoord) - { - tvec3 Result; - for(typename tvec3::size_type i = 0; i < tvec3::value_size(); ++i) - Result[i] = mirrorRepeat(Texcoord[i]); - return Result; - } - - template - GLM_FUNC_QUALIFIER tvec4 mirrorRepeat(tvec4 const & Texcoord) + GLM_FUNC_QUALIFIER genType mirrorRepeat(genType const& Texcoord) { - tvec4 Result; - for(typename tvec4::size_type i = 0; i < tvec4::value_size(); ++i) - Result[i] = mirrorRepeat(Texcoord[i]); - return Result; + return mirrorRepeat(tvec1(Texcoord)).x; } }//namespace glm diff --git a/readme.md b/readme.md index 234519de..3a568186 100644 --- a/readme.md +++ b/readme.md @@ -74,6 +74,7 @@ glm::mat4 camera(float Translate, glm::vec2 const & Rotate) - Improved GTC_reciprocal documentation - Improved GLM_FORCE_EXPLICIT_CTOR coverage #481 - Improved OpenMP support detection for Clang, GCC, ICC and VC +- Improved GTX_wrap for SIMD friendliness - Added constexpr for *vec*, *mat*, *quat* and *dual_quat* types #493 - Added NEON instruction set detection - Added MIPS CPUs detection diff --git a/test/gtx/gtx_wrap.cpp b/test/gtx/gtx_wrap.cpp index 1bd478fd..cd7d7c4f 100644 --- a/test/gtx/gtx_wrap.cpp +++ b/test/gtx/gtx_wrap.cpp @@ -22,6 +22,18 @@ namespace clamp float E = glm::clamp(1.5f); Error += glm::epsilonEqual(E, 1.0f, 0.00001f) ? 0 : 1; + glm::vec2 K = glm::clamp(glm::vec2(0.5f)); + Error += glm::all(glm::epsilonEqual(K, glm::vec2(0.5f), glm::vec2(0.00001f))) ? 0 : 1; + + glm::vec3 L = glm::clamp(glm::vec3(0.5f)); + Error += glm::all(glm::epsilonEqual(L, glm::vec3(0.5f), glm::vec3(0.00001f))) ? 0 : 1; + + glm::vec4 M = glm::clamp(glm::vec4(0.5f)); + Error += glm::all(glm::epsilonEqual(M, glm::vec4(0.5f), glm::vec4(0.00001f))) ? 0 : 1; + + glm::vec1 N = glm::clamp(glm::vec1(0.5f)); + Error += glm::all(glm::epsilonEqual(N, glm::vec1(0.5f), glm::vec1(0.00001f))) ? 0 : 1; + return Error; } }//namespace clamp @@ -50,6 +62,18 @@ namespace repeat float F = glm::repeat(0.9f); Error += glm::epsilonEqual(F, 0.9f, 0.00001f) ? 0 : 1; + glm::vec2 K = glm::repeat(glm::vec2(0.5f)); + Error += glm::all(glm::epsilonEqual(K, glm::vec2(0.5f), glm::vec2(0.00001f))) ? 0 : 1; + + glm::vec3 L = glm::repeat(glm::vec3(0.5f)); + Error += glm::all(glm::epsilonEqual(L, glm::vec3(0.5f), glm::vec3(0.00001f))) ? 0 : 1; + + glm::vec4 M = glm::repeat(glm::vec4(0.5f)); + Error += glm::all(glm::epsilonEqual(M, glm::vec4(0.5f), glm::vec4(0.00001f))) ? 0 : 1; + + glm::vec1 N = glm::repeat(glm::vec1(0.5f)); + Error += glm::all(glm::epsilonEqual(N, glm::vec1(0.5f), glm::vec1(0.00001f))) ? 0 : 1; + return Error; } }//namespace repeat @@ -87,6 +111,18 @@ namespace mirrorClamp float I = glm::mirrorClamp(-0.9f); Error += glm::epsilonEqual(I, 0.9f, 0.00001f) ? 0 : 1; + glm::vec2 K = glm::mirrorClamp(glm::vec2(0.5f)); + Error += glm::all(glm::epsilonEqual(K, glm::vec2(0.5f), glm::vec2(0.00001f))) ? 0 : 1; + + glm::vec3 L = glm::mirrorClamp(glm::vec3(0.5f)); + Error += glm::all(glm::epsilonEqual(L, glm::vec3(0.5f), glm::vec3(0.00001f))) ? 0 : 1; + + glm::vec4 M = glm::mirrorClamp(glm::vec4(0.5f)); + Error += glm::all(glm::epsilonEqual(M, glm::vec4(0.5f), glm::vec4(0.00001f))) ? 0 : 1; + + glm::vec1 N = glm::mirrorClamp(glm::vec1(0.5f)); + Error += glm::all(glm::epsilonEqual(N, glm::vec1(0.5f), glm::vec1(0.00001f))) ? 0 : 1; + return Error; } }//namespace mirrorClamp @@ -124,6 +160,18 @@ namespace mirrorRepeat float I = glm::mirrorRepeat(-1.0f); Error += glm::epsilonEqual(I, 1.0f, 0.00001f) ? 0 : 1; + glm::vec2 K = glm::mirrorRepeat(glm::vec2(0.5f)); + Error += glm::all(glm::epsilonEqual(K, glm::vec2(0.5f), glm::vec2(0.00001f))) ? 0 : 1; + + glm::vec3 L = glm::mirrorRepeat(glm::vec3(0.5f)); + Error += glm::all(glm::epsilonEqual(L, glm::vec3(0.5f), glm::vec3(0.00001f))) ? 0 : 1; + + glm::vec4 M = glm::mirrorRepeat(glm::vec4(0.5f)); + Error += glm::all(glm::epsilonEqual(M, glm::vec4(0.5f), glm::vec4(0.00001f))) ? 0 : 1; + + glm::vec1 N = glm::mirrorRepeat(glm::vec1(0.5f)); + Error += glm::all(glm::epsilonEqual(N, glm::vec1(0.5f), glm::vec1(0.00001f))) ? 0 : 1; + return Error; } }//namespace mirrorRepeat