最近打算做几款2-D小游戏,当然是用Direct3D来做的,所以就要使用Direct3D提供的2D顶点了。说是2D顶点,其实却有4个分量!而正是因为这种矛盾性,所以使用起来有不少注意事项。这些是我浪费了很多的青春而发现的,希望大家吸取教训啊!
具体来说,有这么几个方面的注意事项:
1、 2-D顶点结构的定义
比如,要定义一个带纹理坐标的2-D顶点结构,那么应该定义如下:
struct Vertex2DTex
{
Vertex2DTex():pos2D(0.0f, 0.0f, 1.0f, 1.0f), texCoord(0.0f, 0.0f){}
Vertex2DTex(floatx, float y, float u, float v) :
pos2D(x,y, 1.0f, 1.0f), texCoord(u, v) {}
Vertex2DTex(floatx, float y, float z, float rhw, float u, float v) :
pos2D(x,y, z, rhw), texCoord(u, v){}
Vertex2DTex(const D3DXVECTOR4& thePos2D, const D3DXVECTOR2& uv) :
pos2D(thePos2D),texCoord(uv){}
inline Vertex2DTex& operator=(const Vertex2DTex& rhs)
{
if(this != &rhs)
{
pos2D= rhs.pos2D;
texCoord= rhs.texCoord;
}
return*this;
}
D3DXVECTOR4 pos2D;
D3DXVECTOR2 texCoord;
static IDirect3DVertexDeclaration9* Decl;
};
2、 2-D顶点的声明
比如,针对上述顶点结构,那么声明如下:
IDirect3DVertexDeclaration9* Vertex2DTex::Decl= 0;
//===============================================================
// Vertex2DTex
D3DVERTEXELEMENT9 Vertex2DTexElements[]=
{
{0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0 },
{ 0,sizeof(D3DXVECTOR4), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,0 },
D3DDECL_END()
};
gd3dDevice->CreateVertexDeclaration(Vertex2DTexElements, &Vertex2DTex::Decl);
当然,最后不要忘了释放 Vertex2DTex::Decl 对象。
PS:我们用一个4维向量来表示一个2-D坐标。如果用的是以前的FVF格式的顶点声明的话,那么会看到这个2-D坐标是x, y, z, rhw。其中,x, y是顶点的屏幕坐标,z表示顶点的深度信息(这样可以实现Z-Buffer 测试),而rhw似乎总是设为1.0。
3、 使用2-D顶点结构时,在设置D3DPRESENT_PARAMETERS时的注意事项
设md3dPP 是一个D3DPRESENT_PARAMETERS 对象,那么除非有特殊需要,否则这样设值:
md3dPP.EnableAutoDepthStencil = false;
这样,不论2-D坐标的z值为0.0和1.0之间的哪个值,都可以在屏幕上显示出来(除非被遮挡)。
4、 针对2-D顶点使用effect
使用2-D顶点时,也可以使用effect file,但是这时候的technique 只由PixelShader 组成,因为2-D顶点是变换后的顶点了,不能够对其再进行变换了。所以,事实上,除非你想要对颜色本身做一些处理(比如说转换成黑白画面),否则基本上是不需要对2-D顶点使用effect file 的。
不过,如果一定要使用的话,那么PixelShader 的参数为2-D顶点结构中除了2-D坐标以外的那些成分。