以下代码在vc 7.1(vs.net2003)下编译通过。
使用模板偏特化实现
#ifndef _AI_D3DFVF_H_#define _AI_D3DFVF_H_//D3d9Fvf struct generate templates//Author Kevinqing <qingzl@cdgwbn.com.cn>//#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 _D3DFvftemplate <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