以下代码在vc 7.1(vs.net2003)下编译通过。
使用模板偏特化实现
#ifndef _AI_D3DFVF_H_ #define _AI_D3DFVF_H_ //D3d9Fvf struct generate templates //Author Kevinqing <[email protected]> // #include <d3d9.h> //-----------posoition------------- namespace _D3DFvf{ template <bool b>struct pos_t; template <> struct pos_t<true>{ union { D3DVECTOR v; struct{ float x,y,z; }; }; }; //-----------RHW------------------- template <bool b>struct rhw_t; template <> struct rhw_t<false>{}; template <> struct rhw_t<true>{ float rhw; }; //-----------W--------------------- template <bool b>struct w_t; template <> struct w_t<false>{}; template <> struct w_t<true>{ DWORD w; }; //-----------normal---------------- template <bool b>struct n_t; template <> struct n_t<false>{}; template <> struct n_t<true>{ D3DVECTOR n; };
//-----------psize----------------- template <bool b>struct psize_t; template <> struct psize_t<false>{}; template <> struct psize_t<true>{ float psize; }; //-----------diff------------------- template <bool b>struct diff_t; template <> struct diff_t<false>{}; template <> struct diff_t<true>{ D3DCOLOR diff; };
//-----------spec------------------- template <bool b>struct spec_t; template <> struct spec_t<false>{}; template <> struct spec_t<true>{ D3DCOLOR spec; };
#define TestFlag(a,b,m) (bool((a&m)==b)) #define tp(a,b) TestFlag(a,b,D3DFVF_POSITION_MASK)
#define TestMask(a,b) (bool((a&b)!=0)) //----------b/i---------------------- #define IsXYZBn(a) (tp(a,D3DFVF_XYZB1)||\ tp(a,D3DFVF_XYZB2)||\ tp(a,D3DFVF_XYZB3)||\ tp(a,D3DFVF_XYZB4)||\ tp(a,D3DFVF_XYZB5))
#define XYZBn(a) (tp(a,D3DFVF_XYZB1)? 1:(\ tp(a,D3DFVF_XYZB2)? 2:(\ tp(a,D3DFVF_XYZB3)? 3:(\ tp(a,D3DFVF_XYZB4)? 4:(\ tp(a,D3DFVF_XYZB5)? 5:0)))))
template <bool b,int i>struct b_t; template <int i>struct b_t<false,i>{}; template <>struct b_t<true,1>{ union{ float b; DWORD i; }; }; template <>struct b_t<true,2>{ union{ float b[2]; DWORD i[2]; }; }; template <>struct b_t<true,3>{ union{ float b[3]; DWORD i[3]; }; }; template <>struct b_t<true,4>{ union{ float b[4]; DWORD i[4]; }; }; template <>struct b_t<true,5>{ union{ float b[5]; DWORD i[5]; }; };
//--------------TEX----------- #define TEXn(a) ((a&D3DFVF_TEXCOUNT_MASK)>>D3DFVF_TEXCOUNT_SHIFT) #define _D3DFVF_TEXFMT(a,l) ((a>>(l*2+16))&3) #define TEX_CORDn(a,l) ((_D3DFVF_TEXFMT(a,l)==D3DFVF_TEXTUREFORMAT1) ?1:(\ (_D3DFVF_TEXFMT(a,l)==D3DFVF_TEXTUREFORMAT2) ?2:(\ (_D3DFVF_TEXFMT(a,l)==D3DFVF_TEXTUREFORMAT3) ?3:4)))
#define DECL_TEXCORD_T(N) \ template <bool b,int n>struct texcord ## N ##_t;\ template <int n>struct texcord##N##_t<false,n>{};\ template <>struct texcord##N##_t<true,1>{\ float tu##N;\ };\ template <>struct texcord##N##_t<true,2>{\ float tu##N;\ float tv##N;\ };\ template <>struct texcord##N##_t<true,3>{\ float tu##N;\ float tv##N;\ float ta##N;\ };\ template <>struct texcord##N##_t<true,4>{\ float tu##N;\ float tv##N;\ float ta##N;\ float tb##N;\ };
DECL_TEXCORD_T(0) DECL_TEXCORD_T(1) DECL_TEXCORD_T(2) DECL_TEXCORD_T(3) DECL_TEXCORD_T(4) DECL_TEXCORD_T(5) DECL_TEXCORD_T(6) DECL_TEXCORD_T(7) template <const DWORD flag> struct tex_t: public texcord0_t<(TEXn(flag)>0),TEX_CORDn(flag,0)>, public texcord1_t<(TEXn(flag)>1),TEX_CORDn(flag,1)>, public texcord2_t<(TEXn(flag)>2),TEX_CORDn(flag,2)>, public texcord3_t<(TEXn(flag)>3),TEX_CORDn(flag,3)>, public texcord4_t<(TEXn(flag)>4),TEX_CORDn(flag,4)>, public texcord5_t<(TEXn(flag)>5),TEX_CORDn(flag,5)>, public texcord6_t<(TEXn(flag)>6),TEX_CORDn(flag,6)>, public texcord7_t<(TEXn(flag)>7),TEX_CORDn(flag,7)> {
};
};//end of _D3DFvf
template <const DWORD Flags> struct D3DFvf: public _D3DFvf::pos_t<TestMask(Flags,D3DFVF_POSITION_MASK)>, public _D3DFvf::rhw_t<tp(Flags,D3DFVF_XYZRHW)>, public _D3DFvf::w_t<tp(Flags,D3DFVF_XYZW)>, public _D3DFvf::b_t<IsXYZBn(Flags),XYZBn(Flags)>, public _D3DFvf::n_t<TestMask(Flags,D3DFVF_NORMAL)>, public _D3DFvf::psize_t<TestMask(Flags,D3DFVF_PSIZE)>, public _D3DFvf::diff_t<TestMask(Flags,D3DFVF_DIFFUSE)>, public _D3DFvf::spec_t<TestMask(Flags,D3DFVF_SPECULAR)>, public _D3DFvf::tex_t<Flags>
{
}; #undef TestFlag #undef TestMask #undef tp #undef XYZBn #undef IsXYZBn #undef TEXn #undef _D3DFVF_TEXFMT #undef TEX_CORDn #undef DECL_TEXCORD_T
#endif

|