📄 d3dflt.h
字号:
// May produce invalid results for exceptional or denormal values.
// BUGBUG - Alpha exposes float math routines and they may be a small win.
//
#define COSF(fV) ((FLOAT)cos((double)(fV)))
#define SINF(fV) ((FLOAT)sin((double)(fV)))
#define SQRTF(fV) ((FLOAT)sqrt((double)(fV)))
#define POWF(fV, fE) ((FLOAT)pow((double)(fV), (double)(fE)))
// Approximate log and power functions using Jim Blinn's CG&A technique.
// Only work for positive values.
#ifdef POINTER_CASTING
__inline FLOAT
APPXLG2F(FLOAT f)
{
return (FLOAT)(ASINT32(f) - INT32_FLOAT_ONE) * g_fOoExpScale;
}
__inline FLOAT
APPXPOW2F(FLOAT f)
{
INT32 i = (INT32)(f * g_fExpScale) + INT32_FLOAT_ONE;
return ASFLOAT(i);
}
__inline FLOAT
APPXINVF(FLOAT f)
{
INT32 i = (INT32_FLOAT_ONE << 1) - ASINT32(f);
return ASFLOAT(i);
}
__inline FLOAT
APPXSQRTF(FLOAT f)
{
INT32 i = (ASINT32(f) >> 1) + (INT32_FLOAT_ONE >> 1);
return ASFLOAT(i);
}
__inline FLOAT
APPXISQRTF(FLOAT f)
{
INT32 i = INT32_FLOAT_ONE + (INT32_FLOAT_ONE >> 1) - (ASINT32(f) >> 1);
return ASFLOAT(i);
}
__inline FLOAT
APPXPOWF(FLOAT f, FLOAT exp)
{
INT32 i = (INT32)(exp * (ASINT32(f) - INT32_FLOAT_ONE)) + INT32_FLOAT_ONE;
return ASFLOAT(i);
}
#else
__inline FLOAT
APPXLG2F(FLOAT f)
{
FLOATINT32 fi;
fi.f = f;
return (FLOAT)(fi.i - INT32_FLOAT_ONE) * g_fOoExpScale;
}
__inline FLOAT
APPXPOW2F(FLOAT f)
{
FLOATINT32 fi;
fi.i = (INT32)(f * g_fExpScale) + INT32_FLOAT_ONE;
return fi.f;
}
__inline FLOAT
APPXINVF(FLOAT f)
{
FLOATINT32 fi;
fi.f = f;
fi.i = (INT32_FLOAT_ONE << 1) - fi.i;
return fi.f;
}
__inline FLOAT
APPXSQRTF(FLOAT f)
{
FLOATINT32 fi;
fi.f = f;
fi.i = (fi.i >> 1) + (INT32_FLOAT_ONE >> 1);
return fi.f;
}
__inline FLOAT
APPXISQRTF(FLOAT f)
{
FLOATINT32 fi;
fi.f = f;
fi.i = INT32_FLOAT_ONE + (INT32_FLOAT_ONE >> 1) - (fi.i >> 1);
return fi.f;
}
__inline FLOAT
APPXPOWF(FLOAT f, FLOAT exp)
{
FLOATINT32 fi;
fi.f = f;
fi.i = (INT32)(exp * (fi.i - INT32_FLOAT_ONE)) + INT32_FLOAT_ONE;
return fi.f;
}
#endif
#ifdef _X86_
// Uses a table
float __fastcall TableInvSqrt(float value);
// Uses Jim Blinn's floating point trick
float __fastcall JBInvSqrt(float value);
#define ISQRTF(fV) TableInvSqrt(fV);
#ifdef POINTER_CASTING
// Strip sign bit in integer.
__inline FLOAT
ABSF(FLOAT f)
{
UINT32 i = ASUINT32(f) & 0x7fffffff;
return ASFLOAT(i);
}
// Toggle sign bit in integer.
__inline FLOAT
NEGF(FLOAT f)
{
UINT32 i = ASUINT32(f) ^ 0x80000000;
return ASFLOAT(i);
}
#else
// Strip sign bit in integer.
__inline FLOAT
ABSF(FLOAT f)
{
FLOATINT32 fi;
fi.f = f;
fi.u &= 0x7fffffff;
return fi.f;
}
// Toggle sign bit in integer.
__inline FLOAT
NEGF(FLOAT f)
{
FLOATINT32 fi;
fi.f = f;
fi.u ^= 0x80000000;
return fi.f;
}
#endif // POINTER_CASTING
// Requires chop rounding.
__inline INT32
SCALED_FRACTION(FLOAT f)
{
LARGE_INTEGER i;
__asm
{
fld f
fmul g_fTwoPow31
fistp i
}
return i.LowPart;
}
// Requires chop rounding.
__inline INT
FTOI(FLOAT f)
{
LARGE_INTEGER i;
__asm
{
fld f
fistp i
}
return i.LowPart;
}
// Requires chop rounding.
#define ICEILF(f) (FLOAT_LEZ(f) ? FTOI(f) : FTOI((f) + g_fOneMinusEps))
#define CEILF(f) ((FLOAT)ICEILF(f))
#define IFLOORF(f) (FLOAT_LTZ(f) ? FTOI((f) - g_fOneMinusEps) : FTOI(f))
#define FLOORF(f) ((FLOAT)IFLOORF(f))
#else // _X86_
#define ISQRTF(fV) (1.0f / (FLOAT)sqrt((double)(fV)))
#define ABSF(f) ((FLOAT)fabs((double)(f)))
#define NEGF(f) (-(f))
#define SCALED_FRACTION(f) ((INT32)((f) * g_fTwoPow31))
#define FTOI(f) ((INT)(f))
#define CEILF(f) ((FLOAT)ceil((double)(f)))
#define ICEILF(f) ((INT)CEILF(f))
#define FLOORF(f) ((FLOAT)floor((double)(f)))
#define IFLOORF(f) ((INT)FLOORF(f))
#endif // _X86_
//
// Overlapped divide support.
//
#ifdef _X86_
// Starts a divide directly from memory. Result field is provided for
// compatibility with non-x86 code that does the divide immediately.
#define FLD_BEGIN_DIVIDE(Num, Den, Res) { __asm fld Num __asm fdiv Den }
#define FLD_BEGIN_IDIVIDE(Num, Den, Res) { __asm fld Num __asm fidiv Den }
// Store a divide result directly to memory.
#define FSTP_END_DIVIDE(Res) { __asm fstp Res }
#else // _X86_
#define FLD_BEGIN_DIVIDE(Num, Den, Res) ((Res) = (Num) / (Den))
#define FLD_BEGIN_IDIVIDE(Num, Den, Res) ((Res) = (Num) / (FLOAT)(Den))
#define FSTP_END_DIVIDE(Res)
#endif // _X86_
//
// Specialized FP comparison functions.
//
// On the x86, it's faster to do compares with an integer cast
// than it is to do the fcom.
//
// The zero operations work for all normalized FP numbers, -0 included.
//
#ifdef _X86_
#define FLOAT_CMP_POS(fa, op, fb) (ASINT32(fa) op ASINT32(fb))
#define FLOAT_CMP_PONE(flt, op) (ASINT32(flt) op INT32_FLOAT_ONE)
#ifdef POINTER_CASTING
#define FLOAT_GTZ(flt) (ASINT32(flt) > 0)
#define FLOAT_LTZ(flt) (ASUINT32(flt) > 0x80000000)
#define FLOAT_GEZ(flt) (ASUINT32(flt) <= 0x80000000)
#define FLOAT_LEZ(flt) (ASINT32(flt) <= 0)
#define FLOAT_EQZ(flt) ((ASUINT32(flt) & 0x7fffffff) == 0)
#define FLOAT_NEZ(flt) ((ASUINT32(flt) & 0x7fffffff) != 0)
#else
__inline int FLOAT_GTZ(FLOAT f)
{
FLOATINT32 fi;
fi.f = f;
return fi.i > 0;
}
__inline int FLOAT_LTZ(FLOAT f)
{
FLOATINT32 fi;
fi.f = f;
return fi.u > 0x80000000;
}
__inline int FLOAT_GEZ(FLOAT f)
{
FLOATINT32 fi;
fi.f = f;
return fi.u <= 0x80000000;
}
__inline int FLOAT_LEZ(FLOAT f)
{
FLOATINT32 fi;
fi.f = f;
return fi.i <= 0;
}
__inline int FLOAT_EQZ(FLOAT f)
{
FLOATINT32 fi;
fi.f = f;
return (fi.u & 0x7fffffff) == 0;
}
__inline int FLOAT_NEZ(FLOAT f)
{
FLOATINT32 fi;
fi.f = f;
return (fi.u & 0x7fffffff) != 0;
}
#endif // POINTER_CASTING
#else
#define FLOAT_GTZ(flt) ((flt) > g_fZero)
#define FLOAT_LTZ(flt) ((flt) < g_fZero)
#define FLOAT_GEZ(flt) ((flt) >= g_fZero)
#define FLOAT_LEZ(flt) ((flt) <= g_fZero)
#define FLOAT_EQZ(flt) ((flt) == g_fZero)
#define FLOAT_NEZ(flt) ((flt) != g_fZero)
#define FLOAT_CMP_POS(fa, op, fb) ((fa) op (fb))
#define FLOAT_CMP_PONE(flt, op) ((flt) op g_fOne)
#endif // _X86_
#ifdef __cplusplus
}
#endif
#endif // #ifndef _D3DFLT_H_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -