顶点声明


从概念上讲,顶点声明是对顶点直接内存访问(DMA)以及图形流水线的tessellator引擎进行编程的一种方法。顶点声明简要地表示了数据的布局及tessellator操作。为了解决Microsoft® DirectX® 8.x中顶点声明的复杂性和可扩展性,9.0版引入了用来表示顶点数据流的新格式。

顶点着色器和顶点声明不再是在CreateVertexShader的时候绑定在一起。对着色器的验证已经被分成两部分,一部分在顶点着色器创建时执行,另一部分在DrawPrimitive时执行。顶点着色器和顶点声明都由相应的对象表示。

Decls不再用DWORD流表示。它们现在用一个D3DVERTEXELEMENT9结构的数组表示。数组中的每个元素描述一个顶点元素。

另外,为了解决API的可用性问题,9.0版增加了一个与SetVertexDeclaration调用等价的SetFVF调用。这是一个有用的函数,当调用这个函数时,新的FVF会取代当前的顶点声明,反之亦然。如果驱动程序是DirectX 8.0之前的版本(NumStream为0),那么对于那些不能被转换成弹性顶点格式(FVF)的顶点声明,SetVertexDeclaration可能会失败并返回错误码。SetFVF既能用于固定功能顶点流水线,又能用于可编程顶点流水线。在内部,系统会根据把FVF映射到DirectX 9.0中的Decl中定义的规则,把FVF码转换为顶点着色器声明。在编写顶点着色器函数中的DCL命令时,应该紧记这一点。因为这个转换的关系,所有后面的讨论将仅限于顶点声明。

D3DVERTEXELEMENT9结构

以下是D3DVERTEXELEMENT9结构中的域以及说明。

以下这些都是允许的。

语义,用途索引

特殊解释

(D3DDECLUSAGE_POSITION, 0 )

固定功能着色器和N-patch中未经变换的位置。

(D3DDECLUSAGE_POSITION, 1)

固定功能着色器中用于蒙皮的未经变换的位置。

(D3DDECLUSAGE_BLENDWEIGHT, 0)

在固定功能顶点着色器中的混合加权。

(D3DDECLUSAGE_BLENDINDICES, 0)

固定功能顶点着色器中indexed paletted skinning的矩阵索引

(D3DDECLUSAGE_NORMAL, 0)

固定功能顶点着色器和N-patch tessellator中的顶点法向

(D3DDECLUSAGE_NORMAL, 1)

固定功能顶点着色器中用于蒙皮的顶点法向。

(D3DDECLUSAGE_PSIZE, 0)

为实现point sprite功能,给光栅化器的设置引擎使用的点的大小属性,用来把一个点扩展成一个四边形。

(D3DDECLUSAGE_TEXCOORD, n)

固定功能顶点着色器和3.0版以前的像素着色器中的纹理坐标。可以用来传递用户定义的数据。

(D3DDECLUSAGE_TANGENT, n)

正切值。没有特别的解释。

(D3DDECLUSAGE_BINORMAL, n)

副法线(Binormal)。没有特别的解释。

(D3DDECLUSAGE_TESSFACTOR, 0)

tessellation单元中使用的tessellation因子,用来控制tessellation比率。

(D3DDECLUSAGE_POSITIONT, 0)

变换后的位置。当设置了包含该语义的声明时,顶点处理会被跳过。

(D3DDECLUSAGE_COLOR, 0)

固定功能顶点着色器和3.0版以前的像素着色器中的漫反射色。

(D3DDECLUSAGE_COLOR, 1)

固定功能顶点着色器和3.0版以前的像素着色器中的镜面反射色。

(D3DDECLUSAGE_FOG, 0)

当设置了3.0版以前的像素着色器时,在像素着色器处理之后使用的雾混合值。

(D3DDECLUSAGE_DEPTH, n)

深度。没有特别的解释。

(D3DDECLUSAGE_SAMPLE, n)

查找得到的位移值。只能和D3DDECLMETHOD_LOOKUP或D3DDECLMETHOD_LOOKUPPRESAPLED一起使用。

有一个特殊的顶点元素值被视为顶点着色器声明的结束。这个值是#define D3DDECL_END() {0xFF,0,0,0,0,0}。

UsageIndexUsage连用用来指定一个顶点元素的语义。现在用户可以指定Usage为D3DDECLUSAGE_POSITION以及UsageIndex = 1,而不是像Microsoft DirectX® 8.x中那样使用D3DVSDE_POSITION2。

一个Decl指定tessellator引擎(或者万一没有使用tessellator引擎的话,就直接是顶点处理引擎,)的输入和输出,顶点元素中的类型域指定输入到decl的数据类型。输出类型由方法隐式决定。

顶点着色器中有如下形式的前缀{semantic, semantic index, register number}。运行库会把声明的语义与着色器的语义信息进行匹配,这样就把输入寄存器和数据流中的字节偏移量配成一对。

FVF映射到DirectX 9.0Decl

FVF

数据类型

用途

用途索引

D3DFVF_XYZ

D3DDECLTYPE_FLOAT3

D3DDECLUSAGE_POSITION

0

D3DFVF_XYZRHW

D3DDECLTYPE_FLOAT4

D3DDECLUSAGE_POSITIONT

0

D3DFVF_XYZW

D3DDECLTYPE_FLOAT4

D3DDECLUSAGE_POSITION

0

D3DFVF_XYZB5 and D3DFVF_LASTBETA_UBYTE4

D3DVSDT_FLOAT3

D3DVSDT_FLOAT4

D3DVSDT_UBYTE4

D3DDECLUSAGE_POSITION

D3DDECLUSAGE_BLENDWEIGHT

D3DDECLUSAGE_BLENDINDICES

0

D3DFVF_XYZB5 and D3DFVF_LASTBETA_D3DCOLOR

D3DVSDT_FLOAT3

D3DVSDT_FLOAT4

D3DVSDT_D3DCOLOR

D3DDECLUSAGE_POSITION

D3DDECLUSAGE_BLENDWEIGHT

D3DDECLUSAGE_BLENDINDICES

0

D3DFVF_XYZB5

D3DDECLTYPE_FLOAT3

D3DDECLTYPE_FLOAT4

D3DDECLTYPE_FLOAT1

D3DDECLUSAGE_POSITION

D3DDECLUSAGE_BLENDWEIGHT

D3DDECLUSAGE_BLENDINDICES

0

D3DFVF_XYZBn (n=1..4)

D3DDECLTYPE_FLOAT3

D3DDECLTYPE_FLOATn

D3DDECLUSAGE_POSITION

D3DDECLUSAGE_BLENDWEIGHT

0

D3DFVF_XYZBn (n=1..4) and D3DFVF_LASTBETA_UBYTE4

D3DDECLTYPE_FLOAT3

D3DDECLTYPE_FLOAT(n-1)

D3DDECLTYPE_UBYTE4

D3DDECLUSAGE_POSITION

D3DDECLUSAGE_BLENDWEIGHT

D3DDECLUSAGE_BLENDINDICES

0

D3DFVF_XYZBn (n=1..4) and D3DFVF_LASTBETA_D3DCOLOR

D3DDECLTYPE_FLOAT3

D3DDECLTYPE_FLOAT(n-1)

D3DDECLTYPE_D3DCOLOR

D3DDECLUSAGE_POSITION

D3DDECLUSAGE_BLENDWEIGHT

D3DDECLUSAGE_BLENDINDICES

0

D3DFVF_NORMAL

D3DDECLTYPE_FLOAT3

D3DDECLUSAGE_NORMAL

0

D3DFVF_PSIZE

D3DDECLTYPE_FLOAT1

D3DDECLUSAGE_PSIZE

0

D3DFVF_DIFFUSE

D3DDECLTYPE_D3DCOLOR

D3DDECLUSAGE_COLOR

0

D3DFVF_SPECULAR

D3DDECLTYPE_D3DCOLOR

D3DDECLUSAGE_COLOR

1

D3DFVF_TEXCOORDSIZEm(n)

D3DDECLTYPE_FLOATm

D3DDECLUSAGE_TEXCOORD

n

使用了D3DDECLUSAGE_POSITIONT的顶点声明

 (D3DUSAGE_POSITIONT, 0)顶点元素的存在用来告诉设备输入的顶点数据已经经过了顶点处理(和FVF中设置了D3DFVF_XYZRHW位相似)。在绘制时,如果当前设置的顶点声明中的某一元素具有(D3DUSAGE_POSITIONT, 0)语义,那么整个顶点处理会被略过(就和FVF中设置了D3DFVF_XYZRHW位相似)。

使用(D3DDECLUSAGE_POSITIONT, 0)的顶点声明有一些限制:

此外,此类声明还有一些与驱动程序版本有关的限制。这些限制的存在是因为Direct3D直接把此类声明传送给驱动程序而没有做任何转换。

DirectX 9.0之前的驱动程序

不支持3.0版本像素着色器的DirectX 9.0驱动程序

支持3.0版本像素着色器的DirectX 9.0驱动程序

允许更通用的声明。

未使用D3DDECLUSAGE_POSITIONT的顶点声明

运行库会在创建声明时进行验证。以下是一些通用的规则,用来判断声明的合法性。

用于可编程顶点流水线

当在一个DirectX 8.x驱动程序上使用硬件顶点处理时,还有其它的限制:

如果提供的声明无法被转换为DirectX 8.x风格的声明,那么CreateVertexDeclaration可能会失败。对混合模式设备来说,这种失败会发生在Draw*时刻,因为只有这时候才能知道着色器是被用于硬件还是软件顶点处理。

用于固定功能顶点流水线

只能使用符合以下规则的声明:

当声明和DirectX 8.x驱动程序的硬件顶点处理一起使用时,Direct3D运行库会根据以下规则把它转换为DirectX 8.x风格的声明。

DirectX 9.0声明映射到DirectX 8.x声明

DirectX 9.0用途

DirectX 9.0用途索引

DirectX 8.0

D3DDECLUSAGE_POSITION

0

D3DVSDE_POSITION

D3DDECLUSAGE_POSITION

1

D3DVSDE_POSITION2

D3DDECLUSAGE_NORMAL

0

D3DVSDE_NORMAL

D3DDECLUSAGE_NORMAL

1

D3DVSDE_NORMAL2

D3DDECLUSAGE_BLENDWEIGHT

0

D3DVSDE_BLENDWEIGHT

D3DDECLUSAGE_BLENDINDICES

0

D3DVSDE_BLENDINDICES

D3DDECLUSAGE_PSIZE

0

D3DVSDE_PSIZE

D3DDECLUSAGE_COLOR

0

D3DVSDE_DIFFUSE

D3DDECLUSAGE_COLOR

1

D3DVSDE_SPECULAR

D3DDECLUSAGE_TEXCOORD

n

D3DVSDE_TEXCOORDn

当声明和DirectX 7.0驱动程序上的硬件顶点处理一起使用时,Direct3D运行库会根据以下规则把它转换为FVF。