创建顶点声明

来源:互联网 发布:学历证书制作软件 编辑:程序博客网 时间:2024/06/05 03:12
我们已经使用自由顶点格式(flexible vertex format,FVF)来描述顶点结构中的各分量。但是,在可编程管线中,顶点数据包含的数据比用FVF所能表达的多很多。因此,我们通常使用更具表达性并且更强大的顶点声明(vertex declaration)。注意:如果FVF能够描述我们的顶点格式我们仍然可以在可编程管线中使用它。不管用何种方法,只是为了方便,同样FVF会在内部被转换为一个顶点声明。
一个顶点声明描述为一个D3DVERTEXELEMENT9结构的数组.D3DVERTEXELEMENT9数组中的每个成员描述了一个顶点分量.所以,如果你的顶点分量有2个(例如:位置,颜色),那么其相应的顶点声明将描述3个D3DVERTEXELEMENT9结构的数组。这个D3DVERTEXELEMENT9结构定义如下:

typedef struct _D3DVERTEXELEMENT9 {

BYTE Stream;

BYTE Offset;

BYTE Type;

BYTE Method;

BYTE Usage;

BYTE UsageIndex;

} D3DVERTEXELEMENT9;

Stream——指定与顶点分量相关联的流

offset——偏移,按字节,相对于顶点结构成员的顶点分量的开始。

Type——指定数据类型。它可以是D3DDECLTYPE枚举类型的任意成员;完整列表请参见文档。常用类型如下:

D3DDECLTYPE_FLOAT1——浮点数值

D3DDECLTYPE_FLOAT2——2D浮点向量

D3DDECLTYPE_FLOAT3——3D浮点向量

D3DDECLTYPE_FLOAT4——4D浮点向量

D3DDECLTYPE_D3DCOLOR—D3DCOLOR类型,它扩展为RGBA浮点颜色向量(r g b a),其每一分量都是归一化到区间[0, 1]了的.

Method——指定网格化方法。我们认为这个参数是高级的,因此我们使用默认值,标识为D3DDECLMETHOD_DEFAULT.。

Usage——指定已计划的对顶点分量的使用。例如,它是否准备用于一个位置向量、法线向量、纹理坐标等?有效的用途标识符(usage identifier)是D3DDECLUSAGE枚举类型的:

typedef enum _D3DDECLUSAGE {

D3DDECLUSAGE_POSITION = 0, // Position.

D3DDECLUSAGE_BLENDWEIGHTS = 1, // Blending weights.

D3DDECLUSAGE_BLENDINDICES = 2, // Blending indices.

D3DDECLUSAGE_NORMAL = 3, // Normal vector.

D3DDECLUSAGE_PSIZE = 4, // Vertex point size.

D3DDECLUSAGE_TEXCOORD = 5, // Texture coordinates.

D3DDECLUSAGE_TANGENT = 6, // Tangent vector.

D3DDECLUSAGE_BINORMAL = 7, // Binormal vector.

D3DDECLUSAGE_TESSFACTOR = 8, // Tessellation factor.

D3DDECLUSAGE_POSITIONT = 9, // Transformed position.

D3DDECLUSAGE_COLOR = 10, // Color.

D3DDECLUSAGE_FOG = 11, // Fog blend value.

D3DDECLUSAGE_DEPTH = 12, // Depth value.

D3DDECLUSAGE_SAMPLE = 13 // Sampler data.

} D3DDECLUSAGE;

UsageIndex——用于标识多个相同用途的顶点分量。这个用途索引是位于区间[0, 15]间的一个整数。例如,假设我们有三个用途为D3DDECLUSAGE_NORMAL的顶点分量。我们可以为第一个指定用途索引为0,为第二个指定用途索引为1,并且为第三个指定用途索引为2。按这种方式,我们可以通过其用途索引标识每个特定的法线。

顶点描述声明的例子:假设我们想要描述的顶点格式由位置向量和三个法线向量组成。顶点声明可以指定如下:

D3DVERTEXELEMENT9 decl[] =

{

{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},

{0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},

{0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 1},

{0, 36, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 2},

D3DDECL_END()

};

D3DDECL_END宏用于初始化D3DVERTEXELEMENT9数组的最后一个顶点元素。同样的,注意法向量的用途索引标签。

************************************************************************************************************************

 

一旦你描述了一个顶点声明为D3DVERTEXELEMENT9数组,我们就可以使用下面的方法获得一个IDirect3DVertexDeclaration9接口指针:

HRESULT IDirect3DDevice9::CreateVertexDeclaration(

CONST D3DVERTEXELEMENT9* pVertexElements,

IDirect3DVertexDeclaration9** ppDecl

);

pVertexElements——D3DVERTEXELEMENT9结构数组,它描述我们想要创建的顶点声明。

ppDecl——用于返回创建的IDirect3DVertexDeclaration9接口指针

 

例子调用:

创建:

D3DVERTEXELEMENT9 decl[] =
{
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, 12, D3DDECLTYPE_D3DCOLOR,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_COLOR,0 },
D3DDECL_END()
};

_renderDeviceHandle->CreateVertexDeclaration(decl, &_decl);

_renderDeviceHandle为LPDIRECT3DDEVICE9.

_decl为 IDirect3DVertexDeclaration9接口指针。

使用:

_renderDeviceHandle->SetVertexDeclaration(_decl);

 

当然,在SHADER里我们需要一种方式,来定义一个顶点声明的元素到顶点着色器的Input结构的数据成员的映射。我们在Input结构中通过指定每个数据成员的语义(: usage-type [usage-index])定义这个映射。

例如,对应于前面的顶点声明的输入结构是:

struct VS_INPUT
{
vector pos : POSITION;
vector diffuse : COLOR0;
};

受支持的顶点着色器输入用途(input usage)是:

POSITION [n]——位置

BLENDWEIGHTS [n]——混合权重

BLENDINDICES [n]——混合索引

NORMAL [n]——法线向量

PSIZE[n]——顶点大小

DIFFUSE [n]——散射颜色

SPECULAR [n]——镜面颜色

TEXCOORD [n]——纹理坐标

其中,n是一个位于区间[0, 15]的可选整数。

 

此外,对于输出结构,我们必须指定每个成员是用来做什么的。例如,数据成员应该被作为位置向量、颜色、纹理坐标等对待吗?图形卡没主意,除非你强制的告诉它。这也需要通过语法的语义来完成:

struct VS_OUTPUT
{
vector pos : POSITION;
float4 diffuse : COLOR0;
};

受支持的顶点着色器输出用途是:

POSITION—位置

PSIZE—顶点大小

FOG—雾混合值

COLOR [n]—顶点颜色。注意:可以有多个顶点颜色被输出,并且这些颜色可以被混合在一起以产生最终的颜色。

TEXCOORD [n]—顶点纹理坐标。注意:多个顶点纹理坐标可以被输出。

其中,n是一个位于区间[0, 15]的可选整数。