顶点格式


弹性顶点格式(FVF)码描述了交叉存储在单个数据流中顶点的内容。它通常说明了要被固定功能顶点处理流水线处理的数据。

Microsoft® Direct3D®应用程序能以几种不同的方式定义建模的顶点。对弹性顶点定义(也叫弹性顶点格式或弹性顶点格式码)的支持使用应用程序只使用必需的顶点成员成为可能,这样就消除了无用的成员。通过只使用必需的顶点成员,应用程序可以节省内存并最小化渲染建模需要的处理带宽。应用程序通过使用D3DFVF的组合来定义顶点格式。

FVF规范包含了点的大小的格式,由D3DFVF_PSIZE指定。对非TL顶点而言,这个大小表示的是摄像机空间中的单位,对TL顶点而言,则是设备空间中的单位。

IDirect3DDevice9接口给C++应用程序提供了一些方法,可以接收这些标志的组合,并使用它们决定如何渲染图元。基本上,这些标志告诉系统应用程序使用哪些顶点成员——位置,顶点混合加权值,法向,颜色,纹理坐标的数量和格式——并且间接地说明要使用渲染流水线中的哪些部分。另外,某个特定顶点格式标志的存在与否会通知系统哪些顶点成员域存在于内存中,而哪些被省略了。

要测定设备的限制,可以查询设备是否具有D3DFVFCAPS_DONOTSTRIPLELEMENTS和D3DVFVCAPS_TEXCOORDCOUNTMASK弹性顶点格式标志。更多信息,请参阅D3DCAPS9结构的FVFCaps成员

系统对如何安排顶点有一个重要规定,那就是数据出现的顺序。下图描绘了所有可能的顶点成员在内存中规定的顺序,以及它们相应的数据类型。

纹理坐标可以被声明为不同的格式,这使纹理可以用最少一个坐标或最多四个坐标(二维投影纹理坐标)进行寻址。更多信息,请参阅纹理坐标格式。应该用D3DFVF_TEXCOORDSIZEn系列宏创建应用程序使用的顶点格式中的纹理坐标格式。

没有哪个应用程序会使用每个成员——齐次坐标W的倒数(RHW)和顶点法向这两个域是互斥的。大多数应用程序也不会使用所有八组纹理坐标,但Direct3D具有这种能力。对于应用程序如何使用标志有一些限制。例如,不能同时使用D3DFVF_XYZ和D3DFVF_XYZRHW标志,同时使用意味着应用程序描述的是一个既未经变换又经过变换的顶点位置。

要使用索引顶点混合,D3DFVF_LASTBETA_UBYTE4标志应该出现在FVF的最后。这个标志的出现表示第五个混合加权值将被解释为DWORD类型而非浮点数。更多信息,请参阅索引顶点混合

以下示例代码显示了使用和不使用D3DFVF_LASTBETA_UBYTE4标志的FVF码之间的区别。下面定义的FVF码没有使用D3DFVF_LASTBETA_UBYTE4标志。当使用四个混合索引值时,会用到D3DFVF_XYZB3标志,这是因为应用程序使用的第四个值总是等于(1 - 前三个的和)。

#define D3DFVF_BLENDVERTEX (D3DFVF_XYZB3|D3DFVF_NORMAL|D3DFVF_TEX1)

 

struct BLENDVERTEX

{

    D3DXVECTOR3 v;       // 被作为顶点着色器中的v0引用

    FLOAT       blend1;  // 被作为顶点着色器中的v1.x引用

    FLOAT       blend2;  // 被作为顶点着色器中的v1.y引用

    FLOAT       blend3;  // 被作为顶点着色器中的v1.z引用

                         // v1.w = 1.0 - (v1.x + v1.y + v1.z)

    D3DXVECTOR3 n;       // 被作为顶点着色器中的v3引用

    FLOAT       tu, tv;  // 被作为顶点着色器中的v7引用

};

下面定义的FVF码使用了D3DFVF_LASTBETA_UBYTE4标志。

#define D3DFVF_BLENDVERTEX (D3DFVF_XYZB4 | D3DFVF_LASTBETA_UBYTE4 |D3DFVF_NORMAL|D3DFVF_TEX1)

 

struct BLENDVERTEX

{

    D3DXVECTOR3 v;       // 被作为顶点着色器中的v0引用

    FLOAT       blend1;  // 被作为顶点着色器中的v1.x引用

    FLOAT       blend2;  // 被作为顶点着色器中的v1.y引用

    FLOAT       blend3;  // 被作为顶点着色器中的v1.z引用

                         // v1.w = 1.0 - (v1.x + v1.y + v1.z)

    DWORD       indices; // 被作为顶点着色器中的v2.xyzw引用

    D3DXVECTOR3 n;       // 被作为顶点着色器中的v3引用

    FLOAT       tu, tv;  // 被作为顶点着色器中的v7引用

};