1
0
mirror of https://github.com/microsoft/DirectXMath synced 2024-11-22 04:10:06 +00:00

Code cleanup and reformat

This commit is contained in:
Chuck Walbourn 2017-12-18 14:04:23 -08:00
parent 8a90e9383b
commit f06583a3e1
3 changed files with 2305 additions and 2298 deletions

View File

@ -1,4 +1,4 @@
//-------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
// DirectXSH.cpp -- C++ Spherical Harmonics Math Library
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
@ -17,24 +17,26 @@
using namespace DirectX;
#pragma warning( disable : 4619 4456 )
// C4619 #pragma warning warnings
// C4456 declaration hides previous local declaration
namespace
{
#pragma prefast(disable:246, "generated code by maple (nested const variable definitions)")
static const float fExtraNormFac[XM_SH_MAXORDER] = { 2.0f*sqrtf(XM_PI), 2.0f/3.0f*sqrtf(3.0f*XM_PI), 2.0f/5.0f*sqrtf(5.0f*XM_PI), 2.0f/7.0f*sqrtf(7.0f*XM_PI), 2.0f/3.0f*sqrtf(XM_PI), 2.0f/11.0f*sqrtf(11.0f*XM_PI) };
const float fExtraNormFac[XM_SH_MAXORDER] = { 2.0f*sqrtf(XM_PI), 2.0f / 3.0f*sqrtf(3.0f*XM_PI), 2.0f / 5.0f*sqrtf(5.0f*XM_PI), 2.0f / 7.0f*sqrtf(7.0f*XM_PI), 2.0f / 3.0f*sqrtf(XM_PI), 2.0f / 11.0f*sqrtf(11.0f*XM_PI) };
// computes the integral of a constant function over a solid angular
// extent. No error checking - only used internaly. This function
// only returns the Yl0 coefficients, since the rest are zero for
// circularly symmetric functions.
static const float ComputeCapInt_t1 = sqrtf(0.3141593E1f);
static const float ComputeCapInt_t5 = sqrtf(3.0f);
static const float ComputeCapInt_t11 = sqrtf(5.0f);
static const float ComputeCapInt_t18 = sqrtf(7.0f);
static const float ComputeCapInt_t32 = sqrtf(11.0f);
const float ComputeCapInt_t1 = sqrtf(0.3141593E1f);
const float ComputeCapInt_t5 = sqrtf(3.0f);
const float ComputeCapInt_t11 = sqrtf(5.0f);
const float ComputeCapInt_t18 = sqrtf(7.0f);
const float ComputeCapInt_t32 = sqrtf(11.0f);
static inline void ComputeCapInt(const size_t order, float angle, float *pR)
inline void ComputeCapInt(const size_t order, float angle, float *pR)
{
const float t2 = cosf(angle);
const float t3 = ComputeCapInt_t1*t2;
@ -73,7 +75,7 @@ namespace
// input pF only consists of Yl0 values, normalizes coefficients for directional
// lights.
static inline float CosWtInt(const size_t order)
inline float CosWtInt(const size_t order)
{
const float fCW0 = 0.25f;
const float fCW1 = 0.5f;
@ -94,8 +96,8 @@ namespace
return fRet;
}
static const float SHEvalHemisphereLight_fSqrtPi = sqrtf(XM_PI);
static const float SHEvalHemisphereLight_fSqrtPi3 = sqrtf(XM_PI/3.0f);
const float SHEvalHemisphereLight_fSqrtPi = sqrtf(XM_PI);
const float SHEvalHemisphereLight_fSqrtPi3 = sqrtf(XM_PI / 3.0f);
typedef float REAL;
#define CONSTANT(x) (x ## f)
@ -104,7 +106,7 @@ namespace
// inputs (x,y,z) are a point on the sphere (i.e., must be unit length)
// output is vector b with SH basis evaluated at (x,y,z).
//
inline static void sh_eval_basis_1(REAL x,REAL y,REAL z,REAL b[4])
inline void sh_eval_basis_1(REAL x, REAL y, REAL z, REAL b[4])
{
/* m=0 */
@ -131,7 +133,7 @@ namespace
// inputs (x,y,z) are a point on the sphere (i.e., must be unit length)
// output is vector b with SH basis evaluated at (x,y,z).
//
inline static void sh_eval_basis_2(REAL x,REAL y,REAL z,REAL b[9])
inline void sh_eval_basis_2(REAL x, REAL y, REAL z, REAL b[9])
{
const REAL z2 = z*z;
@ -179,7 +181,7 @@ namespace
// inputs (x,y,z) are a point on the sphere (i.e., must be unit length)
// output is vector b with SH basis evaluated at (x,y,z).
//
static void sh_eval_basis_3(REAL x,REAL y,REAL z,REAL b[16])
void sh_eval_basis_3(REAL x, REAL y, REAL z, REAL b[16])
{
const REAL z2 = z*z;
@ -249,7 +251,7 @@ namespace
// inputs (x,y,z) are a point on the sphere (i.e., must be unit length)
// output is vector b with SH basis evaluated at (x,y,z).
//
static void sh_eval_basis_4(REAL x,REAL y,REAL z,REAL b[25])
void sh_eval_basis_4(REAL x, REAL y, REAL z, REAL b[25])
{
const REAL z2 = z*z;
@ -345,7 +347,7 @@ namespace
// inputs (x,y,z) are a point on the sphere (i.e., must be unit length)
// output is vector b with SH basis evaluated at (x,y,z).
//
static void sh_eval_basis_5(REAL x,REAL y,REAL z,REAL b[36])
void sh_eval_basis_5(REAL x, REAL y, REAL z, REAL b[36])
{
const REAL z2 = z*z;
@ -467,48 +469,48 @@ namespace
b[35] = p_5_5*c5; // l=5,m=+5
}
static const REAL M_PIjs = (REAL) (4.0*atan(1.0));
static const REAL maxang = (REAL) (M_PIjs/2);
static const int NSH0 = 1;
static const int NSH1 = 4;
static const int NSH2 = 9;
static const int NSH3 = 16;
static const int NSH4 = 25;
static const int NSH5 = 36;
static const int NSH6 = 49;
static const int NSH7 = 64;
static const int NSH8 = 81;
static const int NSH9 = 100;
static const int NL0 = 1;
static const int NL1 = 3;
static const int NL2 = 5;
static const int NL3 = 7;
static const int NL4 = 9;
static const int NL5 = 11;
static const int NL6 = 13;
static const int NL7 = 15;
static const int NL8 = 17;
static const int NL9 = 19;
const REAL M_PIjs = (REAL)(4.0*atan(1.0));
const REAL maxang = (REAL)(M_PIjs / 2);
const int NSH0 = 1;
const int NSH1 = 4;
const int NSH2 = 9;
const int NSH3 = 16;
const int NSH4 = 25;
const int NSH5 = 36;
const int NSH6 = 49;
const int NSH7 = 64;
const int NSH8 = 81;
const int NSH9 = 100;
const int NL0 = 1;
const int NL1 = 3;
const int NL2 = 5;
const int NL3 = 7;
const int NL4 = 9;
const int NL5 = 11;
const int NL6 = 13;
const int NL7 = 15;
const int NL8 = 17;
const int NL9 = 19;
static inline void rot(REAL ct,REAL st,REAL x,REAL y,REAL &xout,REAL &yout)
inline void rot(REAL ct, REAL st, REAL x, REAL y, REAL &xout, REAL &yout)
{
xout = x*ct - y*st;
yout = y*ct + x*st;
}
static inline void rot_inv(REAL ct,REAL st,REAL x,REAL y,REAL &xout,REAL &yout)
inline void rot_inv(REAL ct, REAL st, REAL x, REAL y, REAL &xout, REAL &yout)
{
xout = x*ct + y*st;
yout = y*ct - x*st;
}
static inline void rot_1(REAL ct,REAL st,REAL ctm[1],REAL stm[1])
inline void rot_1(REAL ct, REAL st, REAL ctm[1], REAL stm[1])
{
ctm[0] = ct;
stm[0] = st;
}
static inline void rot_2(REAL ct,REAL st,REAL ctm[2],REAL stm[2])
inline void rot_2(REAL ct, REAL st, REAL ctm[2], REAL stm[2])
{
REAL ct2 = CONSTANT(2.0)*ct;
ctm[0] = ct;
@ -517,7 +519,7 @@ namespace
stm[1] = ct2*st;
}
static inline void rot_3(REAL ct,REAL st,REAL ctm[3],REAL stm[3])
inline void rot_3(REAL ct, REAL st, REAL ctm[3], REAL stm[3])
{
REAL ct2 = CONSTANT(2.0)*ct;
ctm[0] = ct;
@ -528,7 +530,7 @@ namespace
stm[2] = ct2*stm[1] - st;
}
static inline void rot_4(REAL ct,REAL st,REAL ctm[4],REAL stm[4])
inline void rot_4(REAL ct, REAL st, REAL ctm[4], REAL stm[4])
{
REAL ct2 = CONSTANT(2.0)*ct;
ctm[0] = ct;
@ -541,7 +543,7 @@ namespace
stm[3] = ct2*stm[2] - stm[1];
}
static inline void rot_5(REAL ct,REAL st,REAL ctm[5],REAL stm[5])
inline void rot_5(REAL ct, REAL st, REAL ctm[5], REAL stm[5])
{
REAL ct2 = CONSTANT(2.0)*ct;
ctm[0] = ct;
@ -556,20 +558,20 @@ namespace
stm[4] = ct2*stm[3] - stm[2];
}
static inline void sh_rotz_1(REAL ctm[1],REAL stm[1],REAL y[NL1],REAL yr[NL1])
inline void sh_rotz_1(REAL ctm[1], REAL stm[1], REAL y[NL1], REAL yr[NL1])
{
yr[1] = y[1];
rot_inv(ctm[0], stm[0], y[0], y[2], yr[0], yr[2]);
}
static inline void sh_rotz_2(REAL ctm[2],REAL stm[2],REAL y[NL2],REAL yr[NL2])
inline void sh_rotz_2(REAL ctm[2], REAL stm[2], REAL y[NL2], REAL yr[NL2])
{
yr[2] = y[2];
rot_inv(ctm[0], stm[0], y[1], y[3], yr[1], yr[3]);
rot_inv(ctm[1], stm[1], y[0], y[4], yr[0], yr[4]);
}
static inline void sh_rotz_3(REAL ctm[3],REAL stm[3],REAL y[NL3],REAL yr[NL3])
inline void sh_rotz_3(REAL ctm[3], REAL stm[3], REAL y[NL3], REAL yr[NL3])
{
yr[3] = y[3];
rot_inv(ctm[0], stm[0], y[2], y[4], yr[2], yr[4]);
@ -577,7 +579,7 @@ namespace
rot_inv(ctm[2], stm[2], y[0], y[6], yr[0], yr[6]);
}
static inline void sh_rotz_4(REAL ctm[4],REAL stm[4],REAL y[NL4],REAL yr[NL4])
inline void sh_rotz_4(REAL ctm[4], REAL stm[4], REAL y[NL4], REAL yr[NL4])
{
yr[4] = y[4];
rot_inv(ctm[0], stm[0], y[3], y[5], yr[3], yr[5]);
@ -586,7 +588,7 @@ namespace
rot_inv(ctm[3], stm[3], y[0], y[8], yr[0], yr[8]);
}
static inline void sh_rotz_5(REAL ctm[5],REAL stm[5],REAL y[NL5],REAL yr[NL5])
inline void sh_rotz_5(REAL ctm[5], REAL stm[5], REAL y[NL5], REAL yr[NL5])
{
yr[5] = y[5];
rot_inv(ctm[0], stm[0], y[4], y[6], yr[4], yr[6]);
@ -598,30 +600,30 @@ namespace
// rotation code generated programmatically by rotatex (2000x4000 samples, eps=1e-008)
static REAL fx_1_001 = (REAL) ( sqrt(1.0)/1.0); // 1
static REAL fx_1_002 = (REAL) (-sqrt(1.0)/1.0); // -1.00000030843
const REAL fx_1_001 = (REAL)(sqrt(1.0) / 1.0); // 1
const REAL fx_1_002 = (REAL)(-sqrt(1.0) / 1.0); // -1.00000030843
static inline void sh_rotx90_1(REAL y[],REAL yr[])
inline void sh_rotx90_1(REAL y[], REAL yr[])
{
yr[0] = fx_1_001*y[1];
yr[1] = fx_1_002*y[0];
yr[2] = fx_1_001*y[2];
};
static inline void sh_rotx90_inv_1(REAL y[],REAL yr[])
inline void sh_rotx90_inv_1(REAL y[], REAL yr[])
{
yr[0] = fx_1_002*y[1];
yr[1] = fx_1_001*y[0];
yr[2] = fx_1_001*y[2];
}
static REAL fx_2_001 = (REAL) ( sqrt(4.0)/2.0); // 1
static REAL fx_2_002 = (REAL) (-sqrt(4.0)/2.0); // -1
static REAL fx_2_003 = (REAL) (-sqrt(1.0)/2.0); // -0.500000257021
static REAL fx_2_004 = (REAL) (-sqrt(3.0)/2.0); // -0.866025848959
static REAL fx_2_005 = (REAL) ( sqrt(1.0)/2.0); // 0.5
const REAL fx_2_001 = (REAL)(sqrt(4.0) / 2.0); // 1
const REAL fx_2_002 = (REAL)(-sqrt(4.0) / 2.0); // -1
const REAL fx_2_003 = (REAL)(-sqrt(1.0) / 2.0); // -0.500000257021
const REAL fx_2_004 = (REAL)(-sqrt(3.0) / 2.0); // -0.866025848959
const REAL fx_2_005 = (REAL)(sqrt(1.0) / 2.0); // 0.5
static inline void sh_rotx90_2(REAL y[],REAL yr[])
inline void sh_rotx90_2(REAL y[], REAL yr[])
{
yr[0] = fx_2_001*y[3];
yr[1] = fx_2_002*y[1];
@ -630,7 +632,7 @@ namespace
yr[4] = fx_2_004*y[2] + fx_2_005*y[4];
};
static inline void sh_rotx90_inv_2(REAL y[],REAL yr[])
inline void sh_rotx90_inv_2(REAL y[], REAL yr[])
{
yr[0] = fx_2_002*y[3];
yr[1] = fx_2_002*y[1];
@ -639,16 +641,16 @@ namespace
yr[4] = fx_2_004*y[2] + fx_2_005*y[4];
}
static REAL fx_3_001 = (REAL) (-sqrt(10.0)/4.0); // -0.790569415042
static REAL fx_3_002 = (REAL) ( sqrt(6.0)/4.0); // 0.612372435696
static REAL fx_3_003 = (REAL) (-sqrt(16.0)/4.0); // -1
static REAL fx_3_004 = (REAL) (-sqrt(6.0)/4.0); // -0.612372435695
static REAL fx_3_005 = (REAL) (-sqrt(1.0)/4.0); // -0.25
static REAL fx_3_006 = (REAL) (-sqrt(15.0)/4.0); // -0.968245836551
static REAL fx_3_007 = (REAL) ( sqrt(1.0)/4.0); // 0.25
static REAL fx_3_008 = (REAL) ( sqrt(10.0)/4.0); // 0.790569983984
const REAL fx_3_001 = (REAL)(-sqrt(10.0) / 4.0); // -0.790569415042
const REAL fx_3_002 = (REAL)(sqrt(6.0) / 4.0); // 0.612372435696
const REAL fx_3_003 = (REAL)(-sqrt(16.0) / 4.0); // -1
const REAL fx_3_004 = (REAL)(-sqrt(6.0) / 4.0); // -0.612372435695
const REAL fx_3_005 = (REAL)(-sqrt(1.0) / 4.0); // -0.25
const REAL fx_3_006 = (REAL)(-sqrt(15.0) / 4.0); // -0.968245836551
const REAL fx_3_007 = (REAL)(sqrt(1.0) / 4.0); // 0.25
const REAL fx_3_008 = (REAL)(sqrt(10.0) / 4.0); // 0.790569983984
static inline void sh_rotx90_3(REAL y[],REAL yr[])
inline void sh_rotx90_3(REAL y[], REAL yr[])
{
yr[0] = fx_3_001*y[3] + fx_3_002*y[5];
yr[1] = fx_3_003*y[1];
@ -659,7 +661,7 @@ namespace
yr[6] = fx_3_006*y[4] + fx_3_007*y[6];
};
static inline void sh_rotx90_inv_3(REAL y[],REAL yr[])
inline void sh_rotx90_inv_3(REAL y[], REAL yr[])
{
yr[0] = fx_3_008*y[3] + fx_3_004*y[5];
yr[1] = fx_3_003*y[1];
@ -670,21 +672,21 @@ namespace
yr[6] = fx_3_006*y[4] + fx_3_007*y[6];
}
static REAL fx_4_001 = (REAL) (-sqrt(56.0)/8.0); // -0.935414346694
static REAL fx_4_002 = (REAL) ( sqrt(8.0)/8.0); // 0.353553390593
static REAL fx_4_003 = (REAL) (-sqrt(36.0)/8.0); // -0.75
static REAL fx_4_004 = (REAL) ( sqrt(28.0)/8.0); // 0.661437827766
static REAL fx_4_005 = (REAL) (-sqrt(8.0)/8.0); // -0.353553390593
static REAL fx_4_006 = (REAL) ( sqrt(36.0)/8.0); // 0.749999999999
static REAL fx_4_007 = (REAL) ( sqrt(9.0)/8.0); // 0.37500034698
static REAL fx_4_008 = (REAL) ( sqrt(20.0)/8.0); // 0.559017511622
static REAL fx_4_009 = (REAL) ( sqrt(35.0)/8.0); // 0.739510657141
static REAL fx_4_010 = (REAL) ( sqrt(16.0)/8.0); // 0.5
static REAL fx_4_011 = (REAL) (-sqrt(28.0)/8.0); // -0.661437827766
static REAL fx_4_012 = (REAL) ( sqrt(1.0)/8.0); // 0.125
static REAL fx_4_013 = (REAL) ( sqrt(56.0)/8.0); // 0.935414346692
const REAL fx_4_001 = (REAL)(-sqrt(56.0) / 8.0); // -0.935414346694
const REAL fx_4_002 = (REAL)(sqrt(8.0) / 8.0); // 0.353553390593
const REAL fx_4_003 = (REAL)(-sqrt(36.0) / 8.0); // -0.75
const REAL fx_4_004 = (REAL)(sqrt(28.0) / 8.0); // 0.661437827766
const REAL fx_4_005 = (REAL)(-sqrt(8.0) / 8.0); // -0.353553390593
const REAL fx_4_006 = (REAL)(sqrt(36.0) / 8.0); // 0.749999999999
const REAL fx_4_007 = (REAL)(sqrt(9.0) / 8.0); // 0.37500034698
const REAL fx_4_008 = (REAL)(sqrt(20.0) / 8.0); // 0.559017511622
const REAL fx_4_009 = (REAL)(sqrt(35.0) / 8.0); // 0.739510657141
const REAL fx_4_010 = (REAL)(sqrt(16.0) / 8.0); // 0.5
const REAL fx_4_011 = (REAL)(-sqrt(28.0) / 8.0); // -0.661437827766
const REAL fx_4_012 = (REAL)(sqrt(1.0) / 8.0); // 0.125
const REAL fx_4_013 = (REAL)(sqrt(56.0) / 8.0); // 0.935414346692
static inline void sh_rotx90_4(REAL y[],REAL yr[])
inline void sh_rotx90_4(REAL y[], REAL yr[])
{
yr[0] = fx_4_001*y[5] + fx_4_002*y[7];
yr[1] = fx_4_003*y[1] + fx_4_004*y[3];
@ -697,7 +699,7 @@ namespace
yr[8] = fx_4_009*y[4] + fx_4_011*y[6] + fx_4_012*y[8];
};
static inline void sh_rotx90_inv_4(REAL y[],REAL yr[])
inline void sh_rotx90_inv_4(REAL y[], REAL yr[])
{
yr[0] = fx_4_013*y[5] + fx_4_005*y[7];
yr[1] = fx_4_003*y[1] + fx_4_004*y[3];
@ -710,31 +712,31 @@ namespace
yr[8] = fx_4_009*y[4] + fx_4_011*y[6] + fx_4_012*y[8];
}
static REAL fx_5_001 = (REAL) ( sqrt(126.0)/16.0); // 0.70156076002
static REAL fx_5_002 = (REAL) (-sqrt(120.0)/16.0); // -0.684653196882
static REAL fx_5_003 = (REAL) ( sqrt(10.0)/16.0); // 0.197642353761
static REAL fx_5_004 = (REAL) (-sqrt(64.0)/16.0); // -0.5
static REAL fx_5_005 = (REAL) ( sqrt(192.0)/16.0); // 0.866025403784
static REAL fx_5_006 = (REAL) ( sqrt(70.0)/16.0); // 0.522912516584
static REAL fx_5_007 = (REAL) ( sqrt(24.0)/16.0); // 0.306186217848
static REAL fx_5_008 = (REAL) (-sqrt(162.0)/16.0); // -0.795495128835
static REAL fx_5_009 = (REAL) ( sqrt(64.0)/16.0); // 0.5
static REAL fx_5_010 = (REAL) ( sqrt(60.0)/16.0); // 0.484122918274
static REAL fx_5_011 = (REAL) ( sqrt(112.0)/16.0); // 0.661437827763
static REAL fx_5_012 = (REAL) ( sqrt(84.0)/16.0); // 0.572821961867
static REAL fx_5_013 = (REAL) ( sqrt(4.0)/16.0); // 0.125
static REAL fx_5_014 = (REAL) ( sqrt(42.0)/16.0); // 0.405046293649
static REAL fx_5_015 = (REAL) ( sqrt(210.0)/16.0); // 0.905711046633
static REAL fx_5_016 = (REAL) ( sqrt(169.0)/16.0); // 0.8125
static REAL fx_5_017 = (REAL) (-sqrt(45.0)/16.0); // -0.419262745781
static REAL fx_5_018 = (REAL) ( sqrt(1.0)/16.0); // 0.0625
static REAL fx_5_019 = (REAL) (-sqrt(126.0)/16.0); // -0.701561553415
static REAL fx_5_020 = (REAL) ( sqrt(120.0)/16.0); // 0.684653196881
static REAL fx_5_021 = (REAL) (-sqrt(10.0)/16.0); // -0.197642353761
static REAL fx_5_022 = (REAL) (-sqrt(70.0)/16.0); // -0.522913107945
static REAL fx_5_023 = (REAL) (-sqrt(60.0)/16.0); // -0.48412346577
const REAL fx_5_001 = (REAL)(sqrt(126.0) / 16.0); // 0.70156076002
const REAL fx_5_002 = (REAL)(-sqrt(120.0) / 16.0); // -0.684653196882
const REAL fx_5_003 = (REAL)(sqrt(10.0) / 16.0); // 0.197642353761
const REAL fx_5_004 = (REAL)(-sqrt(64.0) / 16.0); // -0.5
const REAL fx_5_005 = (REAL)(sqrt(192.0) / 16.0); // 0.866025403784
const REAL fx_5_006 = (REAL)(sqrt(70.0) / 16.0); // 0.522912516584
const REAL fx_5_007 = (REAL)(sqrt(24.0) / 16.0); // 0.306186217848
const REAL fx_5_008 = (REAL)(-sqrt(162.0) / 16.0); // -0.795495128835
const REAL fx_5_009 = (REAL)(sqrt(64.0) / 16.0); // 0.5
const REAL fx_5_010 = (REAL)(sqrt(60.0) / 16.0); // 0.484122918274
const REAL fx_5_011 = (REAL)(sqrt(112.0) / 16.0); // 0.661437827763
const REAL fx_5_012 = (REAL)(sqrt(84.0) / 16.0); // 0.572821961867
const REAL fx_5_013 = (REAL)(sqrt(4.0) / 16.0); // 0.125
const REAL fx_5_014 = (REAL)(sqrt(42.0) / 16.0); // 0.405046293649
const REAL fx_5_015 = (REAL)(sqrt(210.0) / 16.0); // 0.905711046633
const REAL fx_5_016 = (REAL)(sqrt(169.0) / 16.0); // 0.8125
const REAL fx_5_017 = (REAL)(-sqrt(45.0) / 16.0); // -0.419262745781
const REAL fx_5_018 = (REAL)(sqrt(1.0) / 16.0); // 0.0625
const REAL fx_5_019 = (REAL)(-sqrt(126.0) / 16.0); // -0.701561553415
const REAL fx_5_020 = (REAL)(sqrt(120.0) / 16.0); // 0.684653196881
const REAL fx_5_021 = (REAL)(-sqrt(10.0) / 16.0); // -0.197642353761
const REAL fx_5_022 = (REAL)(-sqrt(70.0) / 16.0); // -0.522913107945
const REAL fx_5_023 = (REAL)(-sqrt(60.0) / 16.0); // -0.48412346577
static inline void sh_rotx90_5(REAL y[],REAL yr[])
inline void sh_rotx90_5(REAL y[], REAL yr[])
{
yr[0] = fx_5_001*y[5] + fx_5_002*y[7] + fx_5_003*y[9];
yr[1] = fx_5_004*y[1] + fx_5_005*y[3];
@ -749,7 +751,7 @@ namespace
yr[10] = fx_5_015*y[6] + fx_5_017*y[8] + fx_5_018*y[10];
};
static inline void sh_rotx90_inv_5(REAL y[],REAL yr[])
inline void sh_rotx90_inv_5(REAL y[], REAL yr[])
{
yr[0] = fx_5_019*y[5] + fx_5_020*y[7] + fx_5_021*y[9];
yr[1] = fx_5_004*y[1] + fx_5_005*y[3];
@ -764,7 +766,7 @@ namespace
yr[10] = fx_5_015*y[6] + fx_5_017*y[8] + fx_5_018*y[10];
}
static inline void sh_rot_1(REAL m[3*3],REAL y[NL1],REAL yr[NL1])
inline void sh_rot_1(REAL m[3 * 3], REAL y[NL1], REAL yr[NL1])
{
REAL yr0 = m[4] * y[0] - m[5] * y[1] + m[3] * y[2];
REAL yr1 = m[8] * y[1] - m[7] * y[0] - m[6] * y[2];
@ -775,13 +777,13 @@ namespace
yr[2] = yr2;
}
static inline void sh_roty_1(REAL ctm[1],REAL stm[1],REAL y[NL1],REAL yr[NL1])
inline void sh_roty_1(REAL ctm[1], REAL stm[1], REAL y[NL1], REAL yr[NL1])
{
yr[0] = y[0];
rot_inv(ctm[0], stm[0], y[1], y[2], yr[1], yr[2]);
}
static inline void sh_roty_2(REAL ctm[2],REAL stm[2],REAL y[NL2],REAL yr[NL2])
inline void sh_roty_2(REAL ctm[2], REAL stm[2], REAL y[NL2], REAL yr[NL2])
{
REAL ytmp[NL2];
sh_rotx90_2(y, yr);
@ -789,7 +791,7 @@ namespace
sh_rotx90_inv_2(ytmp, yr);
}
static inline void sh_roty_3(REAL ctm[3],REAL stm[3],REAL y[NL3],REAL yr[NL3])
inline void sh_roty_3(REAL ctm[3], REAL stm[3], REAL y[NL3], REAL yr[NL3])
{
REAL ytmp[NL3];
sh_rotx90_3(y, yr);
@ -797,7 +799,7 @@ namespace
sh_rotx90_inv_3(ytmp, yr);
}
static inline void sh_roty_4(REAL ctm[4],REAL stm[4],REAL y[NL4],REAL yr[NL4])
inline void sh_roty_4(REAL ctm[4], REAL stm[4], REAL y[NL4], REAL yr[NL4])
{
REAL ytmp[NL4];
sh_rotx90_4(y, yr);
@ -805,7 +807,7 @@ namespace
sh_rotx90_inv_4(ytmp, yr);
}
static inline void sh_roty_5(REAL ctm[5],REAL stm[5],REAL y[NL5],REAL yr[NL5])
inline void sh_roty_5(REAL ctm[5], REAL stm[5], REAL y[NL5], REAL yr[NL5])
{
REAL ytmp[NL5];
sh_rotx90_5(y, yr);
@ -819,7 +821,7 @@ namespace
Finds cosine,sine pairs for zyz rotation (i.e. rotation R_z2 R_y R_z1 v).
The rotation is one which maps mx to (1,0,0) and mz to (0,0,1).
*/
static inline void zyz(REAL m[3*3],REAL &zc1,REAL &zs1,REAL &yc,REAL &ys,REAL &zc2,REAL &zs2)
inline void zyz(REAL m[3 * 3], REAL &zc1, REAL &zs1, REAL &yc, REAL &ys, REAL &zc2, REAL &zs2)
{
REAL cz = m[8];
@ -836,14 +838,15 @@ namespace
REAL len25inv = 1.0f / sqrtf(m[2] * m[2] + m[5] * m[5]);
zc2 = m[2] * len25inv;
zs2 = m[5] * len25inv;
} else { // m[6],m[7],m[8] already aligned to (0,0,1)
}
else { // m[6],m[7],m[8] already aligned to (0,0,1)
zc1 = 1.0; zs1 = 0.0; // identity
yc = cz; ys = 0.0; // identity
zc2 = m[0] * cz; zs2 = -m[1]; // align x axis (mx[0],mx[1],0) to (1,0,0)
}
}
static inline void sh_rotzyz_2(REAL zc1m[2],REAL zs1m[2],REAL ycm[2],REAL ysm[2],REAL zc2m[2],REAL zs2m[2],REAL y[NL2],REAL yr[NL2])
inline void sh_rotzyz_2(REAL zc1m[2], REAL zs1m[2], REAL ycm[2], REAL ysm[2], REAL zc2m[2], REAL zs2m[2], REAL y[NL2], REAL yr[NL2])
{
REAL ytmp[NL2];
sh_rotz_2(zc1m, zs1m, y, yr);
@ -851,7 +854,7 @@ namespace
sh_rotz_2(zc2m, zs2m, ytmp, yr);
}
static inline void sh_rotzyz_3(REAL zc1m[3],REAL zs1m[3],REAL ycm[3],REAL ysm[3],REAL zc2m[3],REAL zs2m[3],REAL y[NL3],REAL yr[NL3])
inline void sh_rotzyz_3(REAL zc1m[3], REAL zs1m[3], REAL ycm[3], REAL ysm[3], REAL zc2m[3], REAL zs2m[3], REAL y[NL3], REAL yr[NL3])
{
REAL ytmp[NL3];
sh_rotz_3(zc1m, zs1m, y, yr);
@ -859,7 +862,7 @@ namespace
sh_rotz_3(zc2m, zs2m, ytmp, yr);
}
static inline void sh_rotzyz_4(REAL zc1m[4],REAL zs1m[4],REAL ycm[4],REAL ysm[4],REAL zc2m[4],REAL zs2m[4],REAL y[NL4],REAL yr[NL4])
inline void sh_rotzyz_4(REAL zc1m[4], REAL zs1m[4], REAL ycm[4], REAL ysm[4], REAL zc2m[4], REAL zs2m[4], REAL y[NL4], REAL yr[NL4])
{
REAL ytmp[NL4];
sh_rotz_4(zc1m, zs1m, y, yr);
@ -867,7 +870,7 @@ namespace
sh_rotz_4(zc2m, zs2m, ytmp, yr);
}
static inline void sh_rotzyz_5(REAL zc1m[5],REAL zs1m[5],REAL ycm[5],REAL ysm[5],REAL zc2m[5],REAL zs2m[5],REAL y[NL5],REAL yr[NL5])
inline void sh_rotzyz_5(REAL zc1m[5], REAL zs1m[5], REAL ycm[5], REAL ysm[5], REAL zc2m[5], REAL zs2m[5], REAL y[NL5], REAL yr[NL5])
{
REAL ytmp[NL5];
sh_rotz_5(zc1m, zs1m, y, yr);
@ -875,7 +878,7 @@ namespace
sh_rotz_5(zc2m, zs2m, ytmp, yr);
}
static inline void sh3_rot(REAL m[3*3],REAL zc1,REAL zs1,REAL yc,REAL ys,REAL zc2,REAL zs2,REAL y[NSH3],REAL yr[NSH3])
inline void sh3_rot(REAL m[3 * 3], REAL zc1, REAL zs1, REAL yc, REAL ys, REAL zc2, REAL zs2, REAL y[NSH3], REAL yr[NSH3])
{
REAL zc1m[3], zs1m[3];
rot_3(zc1, zs1, zc1m, zs1m);
@ -890,7 +893,7 @@ namespace
sh_rotzyz_3(zc1m, zs1m, ycm, ysm, zc2m, zs2m, y + NSH2, yr + NSH2);
}
static inline void sh4_rot(REAL m[3*3],REAL zc1,REAL zs1,REAL yc,REAL ys,REAL zc2,REAL zs2,REAL y[NSH4],REAL yr[NSH4])
inline void sh4_rot(REAL m[3 * 3], REAL zc1, REAL zs1, REAL yc, REAL ys, REAL zc2, REAL zs2, REAL y[NSH4], REAL yr[NSH4])
{
REAL zc1m[4], zs1m[4];
rot_4(zc1, zs1, zc1m, zs1m);
@ -906,7 +909,7 @@ namespace
sh_rotzyz_4(zc1m, zs1m, ycm, ysm, zc2m, zs2m, y + NSH3, yr + NSH3);
}
static inline void sh5_rot(REAL m[3*3],REAL zc1,REAL zs1,REAL yc,REAL ys,REAL zc2,REAL zs2,REAL y[NSH5],REAL yr[NSH5])
inline void sh5_rot(REAL m[3 * 3], REAL zc1, REAL zs1, REAL yc, REAL ys, REAL zc2, REAL zs2, REAL y[NSH5], REAL yr[NSH5])
{
REAL zc1m[5], zs1m[5];
rot_5(zc1, zs1, zc1m, zs1m);
@ -951,7 +954,7 @@ namespace
}
// simple matrix vector multiply for a square matrix (only used by ZRotation)
static inline void SimpMatMul(size_t dim, const float *matrix, const float *input, float *result)
inline void SimpMatMul(size_t dim, const float *matrix, const float *input, float *result)
{
for (size_t iR = 0; iR < dim; ++iR)
{
@ -966,17 +969,16 @@ namespace
}; // anonymous namespace
namespace DirectX
{
//-------------------------------------------------------------------------------------
// Evaluates the Spherical Harmonic basis functions
//
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb205448.aspx
//-------------------------------------------------------------------------------------
float* XM_CALLCONV XMSHEvalDirection( _Out_writes_(order*order) float *result,
_In_ size_t order,
_In_ FXMVECTOR dir )
_Use_decl_annotations_
float* XM_CALLCONV DirectX::XMSHEvalDirection(
float *result,
size_t order,
FXMVECTOR dir)
{
if (!result)
return nullptr;
@ -1024,10 +1026,12 @@ float* XM_CALLCONV XMSHEvalDirection( _Out_writes_(order*order) float *result,
//
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb204992.aspx
//-------------------------------------------------------------------------------------
float* XM_CALLCONV XMSHRotate( _Out_writes_(order*order) float *result,
_In_ size_t order,
_In_ FXMMATRIX rotMatrix,
_In_reads_(order*order) const float *input )
_Use_decl_annotations_
float* XM_CALLCONV DirectX::XMSHRotate(
float *result,
size_t order,
FXMMATRIX rotMatrix,
const float *input)
{
if (!result || !input)
return nullptr;
@ -1159,10 +1163,12 @@ float* XM_CALLCONV XMSHRotate( _Out_writes_(order*order) float *result,
//
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb205461.aspx
//-------------------------------------------------------------------------------------
float* XMSHRotateZ( _Out_writes_(order*order) float *result,
_In_ size_t order,
_In_ float angle,
_In_reads_(order*order) const float *input )
_Use_decl_annotations_
float* DirectX::XMSHRotateZ(
float *result,
size_t order,
float angle,
const float *input)
{
if (!result || !input)
return nullptr;
@ -1331,10 +1337,12 @@ float* XMSHRotateZ( _Out_writes_(order*order) float *result,
//
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb205438.aspx
//-------------------------------------------------------------------------------------
float* XMSHAdd( _Out_writes_(order*order) float *result,
_In_ size_t order,
_In_reads_(order*order) const float *inputA,
_In_reads_(order*order) const float *inputB )
_Use_decl_annotations_
float* DirectX::XMSHAdd(
float *result,
size_t order,
const float *inputA,
const float *inputB)
{
if (!result || !inputA || !inputB)
return nullptr;
@ -1355,10 +1363,12 @@ float* XMSHAdd( _Out_writes_(order*order) float *result,
//
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb204994.aspx
//-------------------------------------------------------------------------------------
float* XMSHScale( _Out_writes_(order*order) float *result,
_In_ size_t order,
_In_reads_(order*order) const float *input,
_In_ float scale )
_Use_decl_annotations_
float* DirectX::XMSHScale(
float *result,
size_t order,
const float *input,
float scale)
{
if (!result || !input)
return nullptr;
@ -1379,7 +1389,11 @@ float* XMSHScale( _Out_writes_(order*order) float *result,
//
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb205446.aspx
//-------------------------------------------------------------------------------------
float XMSHDot( _In_ size_t order, _In_reads_(order*order) const float *inputA, _In_reads_(order*order) const float *inputB )
_Use_decl_annotations_
float DirectX::XMSHDot(
size_t order,
const float *inputA,
const float *inputB)
{
if (!inputA || !inputB)
return 0.f;
@ -1407,10 +1421,12 @@ float XMSHDot( _In_ size_t order, _In_reads_(order*order) const float *inputA, _
// that the product commutes (f*g == g*f) but doesn't associate
// (f*(g*h) != (f*g)*h.
//-------------------------------------------------------------------------------------
float* XMSHMultiply( _Out_writes_(order*order) float *result,
_In_ size_t order,
_In_reads_(order*order) const float *inputF,
_In_reads_(order*order) const float *inputG )
_Use_decl_annotations_
float* DirectX::XMSHMultiply(
float *result,
size_t order,
const float *inputF,
const float *inputG)
{
switch (order)
{
@ -1439,9 +1455,11 @@ float* XMSHMultiply( _Out_writes_(order*order) float *result,
//-------------------------------------------------------------------------------------
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb205454.aspx
//-------------------------------------------------------------------------------------
float* XMSHMultiply2( _Out_writes_(4) float *y,
_In_reads_(4) const float *f,
_In_reads_(4) const float *g )
_Use_decl_annotations_
float* DirectX::XMSHMultiply2(
float *y,
const float *f,
const float *g)
{
if (!y || !f || !g)
return nullptr;
@ -1480,9 +1498,11 @@ float* XMSHMultiply2( _Out_writes_(4) float *y,
//-------------------------------------------------------------------------------------
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb232906.aspx
//-------------------------------------------------------------------------------------
float* XMSHMultiply3( _Out_writes_(9) float *y,
_In_reads_(9) const float *f,
_In_reads_(9) const float *g )
_Use_decl_annotations_
float* DirectX::XMSHMultiply3(
float *y,
const float *f,
const float *g)
{
if (!y || !f || !g)
return nullptr;
@ -1600,9 +1620,11 @@ float* XMSHMultiply3( _Out_writes_(9) float *y,
//-------------------------------------------------------------------------------------
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb232907.aspx
//-------------------------------------------------------------------------------------
float* XMSHMultiply4( _Out_writes_(16) float *y,
_In_reads_(16) const float *f,
_In_reads_(16) const float *g )
_Use_decl_annotations_
float* DirectX::XMSHMultiply4(
float *y,
const float *f,
const float *g)
{
if (!y || !f || !g)
return nullptr;
@ -1933,9 +1955,11 @@ float* XMSHMultiply4( _Out_writes_(16) float *y,
//-------------------------------------------------------------------------------------
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb232908.aspx
//-------------------------------------------------------------------------------------
float* XMSHMultiply5( _Out_writes_(25) float *y,
_In_reads_(25) const float *f,
_In_reads_(25) const float *g )
_Use_decl_annotations_
float* DirectX::XMSHMultiply5(
float *y,
const float *f,
const float *g)
{
if (!y || !f || !g)
return nullptr;
@ -2747,9 +2771,11 @@ float* XMSHMultiply5( _Out_writes_(25) float *y,
//-------------------------------------------------------------------------------------
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb232909.aspx
//-------------------------------------------------------------------------------------
float* XMSHMultiply6( _Out_writes_(36) float *y,
_In_reads_(36) const float *f,
_In_reads_(36) const float *g )
_Use_decl_annotations_
float* DirectX::XMSHMultiply6(
float *y,
const float *f,
const float *g)
{
if (!y || !f || !g)
return nullptr;
@ -4441,12 +4467,14 @@ float* XMSHMultiply6( _Out_writes_(36) float *y,
//
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb204988.aspx
//-------------------------------------------------------------------------------------
bool XM_CALLCONV XMSHEvalDirectionalLight( _In_ size_t order,
_In_ FXMVECTOR dir,
_In_ FXMVECTOR color,
_Out_writes_(order*order) float *resultR,
_Out_writes_opt_(order*order) float *resultG,
_Out_writes_opt_(order*order) float *resultB )
_Use_decl_annotations_
bool XM_CALLCONV DirectX::XMSHEvalDirectionalLight(
size_t order,
FXMVECTOR dir,
FXMVECTOR color,
float *resultR,
float *resultG,
float *resultB)
{
if (!resultR)
return false;
@ -4506,13 +4534,15 @@ bool XM_CALLCONV XMSHEvalDirectionalLight( _In_ size_t order,
//
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb205451.aspx
//-------------------------------------------------------------------------------------
bool XM_CALLCONV XMSHEvalSphericalLight( _In_ size_t order,
_In_ FXMVECTOR pos,
_In_ float radius,
_In_ FXMVECTOR color,
_Out_writes_(order*order) float *resultR,
_Out_writes_opt_(order*order) float *resultG,
_Out_writes_opt_(order*order) float *resultB )
_Use_decl_annotations_
bool XM_CALLCONV DirectX::XMSHEvalSphericalLight(
size_t order,
FXMVECTOR pos,
float radius,
FXMVECTOR color,
float *resultR,
float *resultG,
float *resultB)
{
if (!resultR)
return false;
@ -4634,13 +4664,15 @@ bool XM_CALLCONV XMSHEvalSphericalLight( _In_ size_t order,
//
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb204986.aspx
//-------------------------------------------------------------------------------------
bool XM_CALLCONV XMSHEvalConeLight( _In_ size_t order,
_In_ FXMVECTOR dir,
_In_ float radius,
_In_ FXMVECTOR color,
_Out_writes_(order*order) float *resultR,
_Out_writes_opt_(order*order) float *resultG,
_Out_writes_opt_(order*order) float *resultB )
_Use_decl_annotations_
bool XM_CALLCONV DirectX::XMSHEvalConeLight(
size_t order,
FXMVECTOR dir,
float radius,
FXMVECTOR color,
float *resultR,
float *resultG,
float *resultB)
{
if (!resultR)
return false;
@ -4753,13 +4785,15 @@ bool XM_CALLCONV XMSHEvalConeLight( _In_ size_t order,
//
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb204989.aspx
//-------------------------------------------------------------------------------------
bool XM_CALLCONV XMSHEvalHemisphereLight( _In_ size_t order,
_In_ FXMVECTOR dir,
_In_ FXMVECTOR topColor,
_In_ FXMVECTOR bottomColor,
_Out_writes_(order*order) float *resultR,
_Out_writes_opt_(order*order) float *resultG,
_Out_writes_opt_(order*order) float *resultB )
_Use_decl_annotations_
bool XM_CALLCONV DirectX::XMSHEvalHemisphereLight(
size_t order,
FXMVECTOR dir,
FXMVECTOR topColor,
FXMVECTOR bottomColor,
float *resultR,
float *resultG,
float *resultB)
{
if (!resultR)
return false;
@ -4864,5 +4898,3 @@ bool XM_CALLCONV XMSHEvalHemisphereLight( _In_ size_t order,
return true;
}
}; // namespace DirectX

View File

@ -15,7 +15,7 @@
#pragma once
#endif
#define DIRECTX_SHMATH_VERSION 102
#define DIRECTX_SHMATH_VERSION 103
#include <DirectXMath.h>

View File

@ -21,42 +21,22 @@
#include <memory>
#include <malloc.h>
#pragma warning( disable : 4619 4626 )
// C4619 #pragma warning warnings
// C4626 assignment operator was implicitly defined as deleted
#include <wrl/client.h>
using namespace DirectX;
using Microsoft::WRL::ComPtr;
namespace
{
struct aligned_deleter { void operator()(void* p) { _aligned_free(p); } };
typedef std::unique_ptr<DirectX::XMVECTOR, aligned_deleter> ScopedAlignedArrayXMVECTOR;
template<class T> class ScopedObject
{
public:
explicit ScopedObject( T *p = 0 ) : _pointer(p) {}
~ScopedObject()
{
if ( _pointer )
{
_pointer->Release();
_pointer = nullptr;
}
}
bool IsNull() const { return (!_pointer); }
T& operator*() { return *_pointer; }
T* operator->() { return _pointer; }
T** operator&() { return &_pointer; }
void Reset(T *p = 0) { if ( _pointer ) { _pointer->Release(); } _pointer = p; }
T* Get() const { return _pointer; }
private:
ScopedObject(const ScopedObject&);
ScopedObject& operator=(const ScopedObject&);
T* _pointer;
};
//-------------------------------------------------------------------------------------
// This code is lifted from DirectXTex http://directxtex.codeplex.com/
// If you need additional DXGI format support, see DirectXTexConvert.cpp
@ -105,13 +85,12 @@ private:
#pragma warning(push)
#pragma warning(disable : 6101)
_Success_(return)
static bool _LoadScanline( _Out_writes_(count) DirectX::XMVECTOR* pDestination, _In_ size_t count,
bool _LoadScanline(_Out_writes_(count) DirectX::XMVECTOR* pDestination, _In_ size_t count,
_In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DXGI_FORMAT format)
{
assert(pDestination && count > 0 && (((uintptr_t)pDestination & 0xF) == 0));
assert(pSource && size > 0);
using namespace DirectX;
using namespace DirectX::PackedVector;
XMVECTOR* __restrict dPtr = pDestination;
@ -179,20 +158,19 @@ static bool _LoadScanline( _Out_writes_(count) DirectX::XMVECTOR* pDestination,
}; // namespace anonymous
namespace DirectX
{
//-------------------------------------------------------------------------------------
// Projects a function represented in a cube map into spherical harmonics.
//
// http://msdn.microsoft.com/en-us/library/windows/desktop/ff476300.aspx
//-------------------------------------------------------------------------------------
HRESULT SHProjectCubeMap( _In_ ID3D11DeviceContext *context,
_In_ size_t order,
_In_ ID3D11Texture2D *cubeMap,
_Out_writes_opt_(order*order) float *resultR,
_Out_writes_opt_(order*order) float *resultG,
_Out_writes_opt_(order*order) float* resultB )
_Use_decl_annotations_
HRESULT DirectX::SHProjectCubeMap(
ID3D11DeviceContext *context,
size_t order,
ID3D11Texture2D *cubeMap,
float *resultR,
float *resultG,
float* resultB)
{
if (!context || !cubeMap)
return E_INVALIDARG;
@ -228,7 +206,7 @@ HRESULT SHProjectCubeMap( _In_ ID3D11DeviceContext *context,
//--- Create a staging resource copy (if needed) to be able to read data
ID3D11Texture2D* texture = nullptr;
ScopedObject<ID3D11Texture2D> staging;
ComPtr<ID3D11Texture2D> staging;
if (!(desc.CPUAccessFlags & D3D11_CPU_ACCESS_READ))
{
D3D11_TEXTURE2D_DESC sdesc = desc;
@ -236,9 +214,8 @@ HRESULT SHProjectCubeMap( _In_ ID3D11DeviceContext *context,
sdesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
sdesc.Usage = D3D11_USAGE_STAGING;
ScopedObject<ID3D11Device> device;
ComPtr<ID3D11Device> device;
context->GetDevice(&device);
assert( !device.IsNull() );
HRESULT hr = device->CreateTexture2D(&sdesc, nullptr, &staging);
if (FAILED(hr))
@ -386,5 +363,3 @@ HRESULT SHProjectCubeMap( _In_ ID3D11DeviceContext *context,
return S_OK;
}
}; // namespace DirectX