D3D顶点混合时FVF的一些问题以及对微软的一些批评

在使用固定管道的顶点混合时候,会出现种种问题,比如:在指定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的图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值