Merge branch '0.9.3' into swizzle

This commit is contained in:
Christophe Riccio 2011-10-13 11:46:09 +01:00
commit c4af12634b
9 changed files with 246 additions and 81 deletions

View File

@ -42,6 +42,7 @@ namespace detail
detail::type<genFIType>::is_float || detail::type<genFIType>::is_float ||
detail::type<genFIType>::is_int, "'abs' only accept floating-point and integer inputs"); detail::type<genFIType>::is_int, "'abs' only accept floating-point and integer inputs");
return x >= genFIType(0) ? x : -x; return x >= genFIType(0) ? x : -x;
// TODO, perf comp with: *(((int *) &x) + 1) &= 0x7fffffff;
} }
}; };

View File

@ -26,6 +26,11 @@
/// @author Christophe Riccio /// @author Christophe Riccio
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
#if(GLM_COMPILER & GLM_COMPILER_VC)
#include <intrin.h>
#pragma intrinsic(_BitScanReverse)
#endif
namespace glm namespace glm
{ {
// uaddCarry // uaddCarry
@ -550,6 +555,32 @@ namespace glm
} }
// findMSB // findMSB
#if(GLM_COMPILER & GLM_COMPILER_VC)
template <typename genIUType>
GLM_FUNC_QUALIFIER int findMSB
(
genIUType const & Value
)
{
unsigned long Result(0);
_BitScanReverse(&Result, Value);
return int(Result);
}
#elif((GLM_COMPILER & GLM_COMPILER_GCC) && __has_builtin(__builtin_clz))
template <typename genIUType>
GLM_FUNC_QUALIFIER int findMSB
(
genIUType const & Value
)
{
return __builtin_clz(x);
}
#else
template <typename genIUType> template <typename genIUType>
GLM_FUNC_QUALIFIER int findMSB GLM_FUNC_QUALIFIER int findMSB
( (
@ -564,6 +595,7 @@ namespace glm
for(genIUType tmp = Value; tmp; tmp >>= 1, ++bit){} for(genIUType tmp = Value; tmp; tmp >>= 1, ++bit){}
return bit; return bit;
} }
#endif//(GLM_COMPILER)
template <typename T> template <typename T>
GLM_FUNC_QUALIFIER detail::tvec2<int> findMSB GLM_FUNC_QUALIFIER detail::tvec2<int> findMSB

View File

@ -124,7 +124,6 @@
#include "./gtx/transform.hpp" #include "./gtx/transform.hpp"
#include "./gtx/transform2.hpp" #include "./gtx/transform2.hpp"
#include "./gtx/ulp.hpp" #include "./gtx/ulp.hpp"
#include "./gtx/unsigned_int.hpp"
#include "./gtx/vec1.hpp" #include "./gtx/vec1.hpp"
#include "./gtx/vector_access.hpp" #include "./gtx/vector_access.hpp"
#include "./gtx/vector_angle.hpp" #include "./gtx/vector_angle.hpp"

View File

@ -58,6 +58,14 @@ namespace glm
//! From GLM_GTX_integer extension. //! From GLM_GTX_integer extension.
int sqrt(int x); int sqrt(int x);
//! Returns the log2 of x. Can be reliably using to compute mipmap count from the texture size.
//! From GLM_GTX_integer extension.
unsigned int log2(unsigned int x);
//! Returns the floor log2 of x.
//! From GLM_GTX_integer extension.
unsigned int floor_log2(unsigned int x);
//! Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y. //! Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y.
//! From GLM_GTX_integer extension. //! From GLM_GTX_integer extension.
int mod(int x, int y); int mod(int x, int y);
@ -67,6 +75,26 @@ namespace glm
template <typename genType> template <typename genType>
genType factorial(genType const & x); genType factorial(genType const & x);
//! 32bit signed integer.
//! From GLM_GTX_integer extension.
typedef signed int sint;
//! Returns x raised to the y power.
//! From GLM_GTX_integer extension.
uint pow(uint x, uint y);
//! Returns the positive square root of x.
//! From GLM_GTX_integer extension.
uint sqrt(uint x);
//! Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y.
//! From GLM_GTX_integer extension.
uint mod(uint x, uint y);
//! Returns the number of leading zeros.
//! From GLM_GTX_integer extension.
uint nlz(uint x);
/// @} /// @}
}//namespace glm }//namespace glm

View File

@ -37,6 +37,52 @@ GLM_FUNC_QUALIFIER int sqrt(int x)
return CurrentAnswer; return CurrentAnswer;
} }
// Henry Gordon Dietz: http://aggregate.org/MAGIC/
namespace detail
{
GLM_FUNC_QUALIFIER unsigned int ones32(unsigned int x)
{
/* 32-bit recursive reduction using SWAR...
but first step is mapping 2-bit values
into sum of 2 1-bit values in sneaky way
*/
x -= ((x >> 1) & 0x55555555);
x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
x = (((x >> 4) + x) & 0x0f0f0f0f);
x += (x >> 8);
x += (x >> 16);
return(x & 0x0000003f);
}
}//namespace detail
#if(GLM_COMPILER & (GLM_COMPILER_VC | GLM_COMPILER_GCC))
GLM_FUNC_QUALIFIER unsigned int log2(unsigned int x)
{
return x <= 1 ? 0 : unsigned(32) - nlz(x - 1u);
}
#else
GLM_FUNC_QUALIFIER unsigned int log2(unsigned int x)
{
return unsigned(32) - nlz(x - 1u);
}
#endif
// Henry Gordon Dietz: http://aggregate.org/MAGIC/
unsigned int floor_log2(unsigned int x)
{
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return(detail::ones32(x) - 1);
}
// mod // mod
GLM_FUNC_QUALIFIER int mod(int x, int y) GLM_FUNC_QUALIFIER int mod(int x, int y)
{ {
@ -84,4 +130,74 @@ GLM_FUNC_QUALIFIER detail::tvec4<valType> factorial(
factorial(x.w)); factorial(x.w));
} }
GLM_FUNC_QUALIFIER uint pow(uint x, uint y)
{
uint result = x;
for(uint i = 1; i < y; ++i)
result *= x;
return result;
}
GLM_FUNC_QUALIFIER uint sqrt(uint x)
{
if(x <= 1) return x;
uint NextTrial = x >> 1;
uint CurrentAnswer;
do
{
CurrentAnswer = NextTrial;
NextTrial = (NextTrial + x / NextTrial) >> 1;
} while(NextTrial < CurrentAnswer);
return CurrentAnswer;
}
GLM_FUNC_QUALIFIER uint mod(uint x, uint y)
{
return x - y * (x / y);
}
#if(GLM_COMPILER & (GLM_COMPILER_VC | GLM_COMPILER_GCC))
GLM_FUNC_QUALIFIER unsigned int nlz(unsigned int x)
{
return 31u - findMSB(x);
}
#else
// Hackers Delight: http://www.hackersdelight.org/HDcode/nlz.c.txt
GLM_FUNC_QUALIFIER unsigned int nlz(unsigned int x)
{
int y, m, n;
y = -int(x >> 16); // If left half of x is 0,
m = (y >> 16) & 16; // set n = 16. If left half
n = 16 - m; // is nonzero, set n = 0 and
x = x >> m; // shift x right 16.
// Now x is of the form 0000xxxx.
y = x - 0x100; // If positions 8-15 are 0,
m = (y >> 16) & 8; // add 8 to n and shift x left 8.
n = n + m;
x = x << m;
y = x - 0x1000; // If positions 12-15 are 0,
m = (y >> 16) & 4; // add 4 to n and shift x left 4.
n = n + m;
x = x << m;
y = x - 0x4000; // If positions 14-15 are 0,
m = (y >> 16) & 2; // add 2 to n and shift x left 2.
n = n + m;
x = x << m;
y = x >> 14; // Set y = 0, 1, 2, or 3.
m = y & ~(y >> 1); // Set m = 0, 1, 2, or 2 resp.
return unsigned(n + 2 - m);
}
#endif//(GLM_COMPILER)
}//namespace glm }//namespace glm

View File

@ -19,58 +19,8 @@
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE. /// THE SOFTWARE.
///
/// @ref gtx_unsigned_int
/// @file glm/gtx/unsigned_int.hpp
/// @date 2005-12-24 / 2011-06-07
/// @author Christophe Riccio
///
/// @see core (dependence)
/// @see gtx_integer (dependence)
///
/// @defgroup gtx_unsigned_int GLM_GTX_unsigned_int: Unsigned int
/// @ingroup gtx
///
/// @brief Add support for unsigned integer for core functions
///
/// <glm/gtx/unsigned_int.hpp> need to be included to use these functionalities.
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
#ifndef GLM_GTX_unsigned_int #if(defined(GLM_MESSAGES))
#define GLM_GTX_unsigned_int GLM_VERSION # pragma message("GLM: GLM_GTX_unsigned_int extension is deprecated, include GLM_GTX_integer instead")
// Dependency:
#include "../glm.hpp"
#include "../gtx/integer.hpp"
#if(defined(GLM_MESSAGES) && !defined(glm_ext))
# pragma message("GLM: GLM_GTX_unsigned_int extension included")
#endif #endif
namespace glm
{
/// @addtogroup gtx_unsigned_int
/// @{
//! 32bit signed integer.
//! From GLM_GTX_unsigned_int extension.
typedef signed int sint;
//! Returns x raised to the y power.
//! From GLM_GTX_unsigned_int extension.
uint pow(uint x, uint y);
//! Returns the positive square root of x.
//! From GLM_GTX_unsigned_int extension.
uint sqrt(uint x);
//! Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y.
//! From GLM_GTX_unsigned_int extension.
uint mod(uint x, uint y);
/// @}
}//namespace glm
#include "unsigned_int.inl"
#endif//GLM_GTX_unsigned_int

View File

@ -9,33 +9,5 @@
namespace glm{ namespace glm{
GLM_FUNC_QUALIFIER uint pow(uint x, uint y)
{
uint result = x;
for(uint i = 1; i < y; ++i)
result *= x;
return result;
}
GLM_FUNC_QUALIFIER uint sqrt(uint x)
{
if(x <= 1) return x;
uint NextTrial = x >> 1;
uint CurrentAnswer;
do
{
CurrentAnswer = NextTrial;
NextTrial = (NextTrial + x / NextTrial) >> 1;
} while(NextTrial < CurrentAnswer);
return CurrentAnswer;
}
GLM_FUNC_QUALIFIER uint mod(uint x, uint y)
{
return x - y * (x / y);
}
}//namespace glm }//namespace glm

View File

@ -1,4 +1,5 @@
glmCreateTestGTC(gtx_bit) glmCreateTestGTC(gtx_bit)
glmCreateTestGTC(gtx_integer)
glmCreateTestGTC(gtx_noise) glmCreateTestGTC(gtx_noise)
glmCreateTestGTC(gtx_quaternion) glmCreateTestGTC(gtx_quaternion)
glmCreateTestGTC(gtx_random) glmCreateTestGTC(gtx_random)

66
test/gtx/gtx_integer.cpp Normal file
View File

@ -0,0 +1,66 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Created : 2011-10-11
// Updated : 2011-10-11
// Licence : This source is under MIT licence
// File : test/gtx/gtx_integer.cpp
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <glm/glm.hpp>
#include <glm/gtx/integer.hpp>
#include <glm/gtx/epsilon.hpp>
#include <iostream>
int test_floor_log2()
{
int Error = 0;
for(std::size_t i = 1; i < 1000000; ++i)
{
glm::uint A = glm::floor_log2(glm::uint(i));
glm::uint B = glm::uint(glm::log2(double(i))); // Will fail with float, lack of accuracy
Error += A == B ? 0 : 1;
assert(!Error);
}
return Error;
}
int test_log2()
{
int Error = 0;
for(std::size_t i = 1; i < 1000000; ++i)
{
glm::uint A = glm::log2(glm::uint(i));
double B = glm::log2(double(i));
Error += glm::equalEpsilon(double(A), B, 1.0) ? 0 : 1;
//assert(!Error);
}
return Error;
}
int test_nlz()
{
int Error = 0;
for(std::size_t i = 1; i < 33; ++i)
printf("%d, %d\n", glm::nlz(i), 31u - glm::findMSB(i));
return Error;
}
int main()
{
int Error = 0;
Error += test_nlz();
Error += test_floor_log2();
Error += test_log2();
return Error;
}