这几天一直在做MS3D的骨骼动画,以前没写过骨骼动画,因为对微软的X格式不太喜欢,而且看到它写的N多的代码感觉非常难看。MS3D格式比较简单,目前的状况是已经可以读取关键帧并且插值了,问题就是如何放进去渲染,当然不可能像OpenGL那样glBeign()和glEnd()把所有顶点乘一次,只能用顶点混合,今天又弄了一下午,使用的是索引缓冲技术,其实原理很简单,顶点中包含几个权重值,包含一个DWORD的索引,DWORD是4个BYTE其实就是将4个矩阵的索引值打包成一个DWORD传进去,然后再用V*Matrix1*Weight1 + V*Matrix2*Weight2......。(我看到文档写的V1,V2...我的说法应该没错吧!)。
我打算使用固定管线来渲染,麻烦就来了,为了图简单,用的是FVF.可是我始终不太理解 D3DFVF_XYZB1 through D3DFVF_XYZB5的含义,以至于弄了3个多小时还是解决不了问题,最后还是调到Debug模式看了一下输出,每次都是
Stream 0 stride and vertex size, computed from the current vertex declaration or FVF, are different, which might not work with pre-DX8 drivers和
(ERROR) :The number of blend weights in the FVF should match what is set in D3DRS_VERTEXBLEND for indexed vertex blending
看到似乎是顶点的定义有问题
{
D3DXVECTOR3 m_verts; // 顶点
float m_weight;
DWORD m_index;
D3DXVECTOR3 m_normal; // 法线
} MS3D_VERT;
#define MS3D_VERT_FVF (D3DFVF_XYZB1|D3DFVF_LASTBETA_UBYTE4|D3DFVF_NORMAL) 错误!!!!!!!!!!!!!!!!!
这是开始的写法,其实问题就出在这里D3DFVF_XYZB2才表示的是有2个权重值,因为权重和为1.0f知道了一个就是到了另一个。
开始我的想法是只想用一个矩阵,不用混合,我把 float m_weight;删掉;将D3DFVF_XYZB1改为D3DFVF_XYZ。但是发现这样还是错误,为什么呢,难道D3DFVF_XYZB1没有什么意义吗???其实不然,你用了D3DFVF_LASTBETA_UBYTE4那么你必须使用D3DFVF_XYZB1其实(D3DFVF_XYZB1和D3DFVF_XYZ)表示的含义差不多的,这里表示权重为1.0f。
最后还有dev->SetRenderState( D3DRS_VERTEXBLEND, D3DVBF_1WEIGHTS ); D3DVBF_1WEIGHTS 其实表示有两个Weight分别使用DWORD的最末位和次末位。上述任何一个地方出问题都会导致混合的失败,这也是我讨厌固定管线的原因之所在。光学函数怎么用就要花去大把时间。