创建顶点声明比较麻烦,下面的类封装了顶点声明
class VertexDeclaration { public: enum { Element_Pos = 0, Element_Normal, Element_TexCoord }; public: VertexDeclaration(); virtual ~VertexDeclaration(); public: void CreateDecl(const int *elems, int len, bool useVec4 = false); IDirect3DVertexDeclaration9 * GetDecl(); protected: void SetVertexElement(D3DVERTEXELEMENT9 &e, BYTE type, BYTE usage); protected: IDirect3DVertexDeclaration9 *mDecl; std::vector<D3DVERTEXELEMENT9> mElements; };
VertexDeclaration::VertexDeclaration() { mDecl = NULL; } VertexDeclaration::~VertexDeclaration() { SAFE_RELEASE(mDecl); } void VertexDeclaration::CreateDecl(const int *elems, int len, bool useVec4) { if (mDecl != NULL) return; WORD offset = 0; for (int i = 0; i < len; ++i) { D3DVERTEXELEMENT9 e; BYTE type = 0; BYTE usage = 0; if (i == 0) e.Offset = 0; else e.Offset = offset; if (elems[i] == Element_Pos) { if (useVec4) { type = D3DDECLTYPE_FLOAT4; offset += sizeof(float) * 4; } else { type = D3DDECLTYPE_FLOAT3; offset += sizeof(float) * 3; } usage = D3DDECLUSAGE_POSITION; } else if (elems[i] == Element_Normal) { type = D3DDECLTYPE_FLOAT3; usage = D3DDECLUSAGE_NORMAL; offset += sizeof(float) * 2; } else if (elems[i] == Element_TexCoord) { type = D3DDECLTYPE_FLOAT2; usage = D3DDECLUSAGE_TEXCOORD; offset += sizeof(float) * 2; } else { assert(false); } SetVertexElement(e, type, usage); mElements.push_back(e); } // 加上结束标记 D3DVERTEXELEMENT9 end = D3DDECL_END(); mElements.push_back(end); gDevice->CreateVertexDeclaration((const D3DVERTEXELEMENT9 *) &mElements[0], &mDecl); } IDirect3DVertexDeclaration9 * VertexDeclaration::GetDecl() { return mDecl; } void VertexDeclaration::SetVertexElement(D3DVERTEXELEMENT9 &e, BYTE type, BYTE usage) { e.Stream = 0; e.Method = D3DDECLMETHOD_DEFAULT; e.UsageIndex = 0; e.Type = type; e.Usage = usage; }
使用
const int elements[] = { VertexDeclaration::Element_Pos, VertexDeclaration::Element_Normal, VertexDeclaration::Element_TexCoord, VertexDeclaration::Element_TexCoord }; mDecl.CreateDecl(elements, sizeof(elements) / sizeof(int), false);