在使用固定管道的顶点混合时候,会出现种种问题,比如:在指定D3DFVF_XYZBn的时候,权重是写n个还是n-1个,矩阵的索引该怎么设置才正确,DWORD类型的索引值应该跟在谁后面,还有D3DFVF_LASTBETA_UBYTE4这个FVF到底该怎么使用才正确,矩阵面板上的256个索引怎么才能随心所欲的使用,接下来就根据程序一一解决这些疑惑。
一 问题以及答案
1 权重到底该写几个?
答案是如果FVF中包含D3DFVF_XYZBn,那么权重就只需要n-1个即可,如果再多写一个,或许能显示出来并且位置正常,但是有可能其他不正常,例如颜色不是你想要的。
2 矩阵的索引该怎么设置才对?
这个要分情况,当FVF中包含D3DFVF_XYZBn并且不包含D3DFVF_LASTBETA_UBYTE4的时候,这个时候矩阵索引的设置要根据渲染状态来确定。
首先开启顶点混合,需要下面的状态:
g_pDevice->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE,TRUE );
g_pDevice->SetRenderState(D3DRS_VERTEXBLEND,D3DVBF_2WEIGHTS );
第一句是开启顶点索引混合,第二个开启顶点混合,注意D3DVBF_2WEIGHTS这个东西,可以在D3DVERTEXBLENDFLAGS枚举中看到相关的定义
typedef enum D3DVERTEXBLENDFLAGS {
D3DVBF_DISABLE = 0,
D3DVBF_1WEIGHTS = 1,
D3DVBF_2WEIGHTS = 2,
D3DVBF_3WEIGHTS = 3,
D3DVBF_TWEENING = 255,
D3DVBF_0WEIGHTS = 256
} D3DVERTEXBLENDFLAGS, *LPD3DVERTEXBLENDFLAGS;
这里令人比较气愤的是微软真他妈的误导人,D3DVBF_2WEIGHTS
的这里的真实意思索引为0,1,2的矩阵参与顶点混合,而不是我们理所当然的认为是就2个权重(也就是2个矩阵参与顶点混合)
自然我们会想到既然矩阵的索引已经规定的那么死了,索引范围顶多是0-3,那么后面的DWORD再去规定矩阵的索引有意义吗?还有没有必要加上DWORD类型的矩阵索引?
答案是这个DWORD表示的矩阵索引是完全没意义的,也就是说我们可以随便给DWORD赋值。但是这个DWORD还必须得加这也是感觉微软设计蛋疼得地方。
3 DWORD
类型的矩阵索引值要跟在哪?
DWORD
是个32bit的整形,32位分成了每8bit一个小组,从低字节到高字节一共4个字节,低字节的8bit指定了第一个权重的矩阵索引,依次类推。
DWORD
类型的矩阵索引必须跟在最后一个权重的后面。这是严格的,必须遵守的。
4 D3DFVF_LASTBETA_UBYTE4它到底是干啥的?
这个东西要说有用也有用,没用也可以不用。当有D3DFVF_LASTBETA_UBYTE4的时候,在指定矩阵索引值的时候我们可以突破0-3的限制,可以在0-255之间随意些,并且此时DWORD指定的矩阵索引就是真正的矩阵索引值,你不可以像之前那么乱写。
二 验证
1 第三个权重的验证
struct BoneVertex1
{
floatx,y,z;
floatw1,w2;
DWORD dwInd;
DWORD dwC;
BoneVertex1(floatx1,float y1,floatz1,float f1,floatf2,DWORD dwI,DWORD dwL)
{
x = x1;y = y1;z = z1;
w1 = f1;w2 = f2;
dwInd = dwI;dwC = dwL;
}
};
#define D3DFVF_BONE1 (D3DFVF_XYZB3 | D3DFVF_DIFFUSE)
struct BoneVertex2
{
floatx,y,z;
floatw1,w2,w3;
DWORD dwInd;
DWORD dwC;
BoneVertex2(floatx1,float y1,floatz1,float f1,floatf2,float f3,DWORD dwI,DWORD dwL)
{
x = x1;y = y1;z = z1;
w1 = f1;w2 = f2;w3=f3;
dwInd = dwI;dwC = dwL;
}
};
#define D3DFVF_BONE2 (D3DFVF_XYZB3 | D3DFVF_DIFFUSE)
BoneVertex1和BoneVertex2的区别是BoneVertex2多了一个权重,在这里验证的第三个权重到底有用没?
顶点缓存初始化:
DWORD dwF = (0x0) +(0x1<<8) + (0x2<<16);
//DWORD dwF =(0x1) + (0x3<<8) + (0x7<<16);
g_pDevice->CreateVertexBuffer(2*sizeof(BoneVertex1),0,D3DFVF_BONE1,D3DPOOL_MANAGED,&g_pVB1,NULL);
BoneVertex1* pV1 = NULL;
g_pVB1->Lock(0,0,(void**)&pV1,0);
pV1[0] = BoneVertex1(-5.0f,0.0f,0.0f, 0.2f,0.3f, dwF,D3DCOLOR_XRGB(255,0,0));
pV1[1] = BoneVertex1(5.0f,-3.0f,0.0f, 0.2f,0.3f, dwF,D3DCOLOR_XRGB(255,0,0));
g_pVB1->Unlock();
g_pDevice->CreateVertexBuffer(sizeof(BoneVertex2)*2,0,D3DFVF_BONE2,D3DPOOL_MANAGED,&g_pVB2,NULL);
BoneVertex2* pV2 = NULL;
g_pVB2->Lock(0,0,(void**)&pV2,0);
pV2[0] =BoneVertex2(-5.0f,0.0f,0.0f, 0.2f,0.3f,0.2f, dwF,D3DCOLOR_XRGB(255,0,0));
pV2[1] =BoneVertex2(5.0f,-3.0f,0.0f, 0.2f,0.3f,0.2f, dwF,D3DCOLOR_XRGB(255,0,0));
g_pVB2->Unlock();
BoneVertex1的图:
BoneVertex2的图