[D3D11] 顶点布局描述:D3D11_INPUT_ELEMENT_DESC

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/felicityWSH/article/details/71479740

在HLSL中定义了顶点结构体后,在C++代码中需要设置对应的顶点结构体布局,类似于D3D9的LPDIRECT3DDEVICE9::SetFVF函数。D3D11是通过D3D11_INPUT_ELEMENT_DESC来描述顶点的布局信息。

先定义两个不同的顶点结构体,文本后续的内容,均以这两个结构体举例说明。
struct Vertex1 
{
    XMFLOAT3 Pos : POSITION;  
    XMFLOAT4 Color : COLOR; 
}; 
struct Vertex2 
{ 
    XMFLOAT3 Pos : POSITION; 
    XMFLOAT3 Normal : NORMAL; 
    XMFLOAT2 Tex0 : TEXCOORD0;
    XMFLOAT2 Tex1 : TEXCOORD1;
};
D3D11_INPUT_ELEMENT_DESC 的定义如下所示:
typedef struct D3D11_INPUT_ELEMENT_DESC { 
    LPCSTR SemanticName; 
    UINT SemanticIndex; 
    DXGI_FORMAT Format; 
    UINT InputSlot; 
    UINT AlignedByteOffset 
    D3D11_INPUT_CLASSIFICATION InputSlotClass; 
    UINT InstanceDataStepRate; 
} D3D11_INPUT_ELEMENT_DESC;
SemanticName
一个描述语义的字符串,常见的有:
COLOR 颜色
NORMAL 法线
POSITION 图元的本地坐标
SV_POSITION 图元的齐次坐标(已经做过坐标转换了)
TEXCOORD 纹理
SemanticIndex
同一语义类型下的变量索引值,从0开始。以struct Vertex2为例:
Pos是第一个POSITION语义的变量,故SemanticIndex 应该是0,
Normal是第一个NORMAL语义的变量,故SemanticIndex 应该是0,
TEXCOORD0是第一个TEXCOORD语义的变量,故SemanticIndex 应该是0,
TEXCOORD1是第二个TEXCOORD语义的变量,故SemanticIndex 应该是1。
Format
用于指定元素格式的DXGI_FORMAT枚举类型成员,常用的有:
DXGI_FORMAT_R32_FLOAT // 1D 32-bit float scalar
DXGI_FORMAT_R32G32_FLOAT // 2D 32-bit float vector
DXGI_FORMAT_R32G32B32_FLOAT // 3D 32-bit float vector
DXGI_FORMAT_R32G32B32A32_FLOAT // 4D 32-bit float vector
DXGI_FORMAT_R8_UINT // 1D 8-bit unsigned integer scalar
DXGI_FORMAT_R16G16_SINT // 2D 16-bit signed integer vector
DXGI_FORMAT_R32G32B32_UINT // 3D 32-bit unsigned integer vector
DXGI_FORMAT_R8G8B8A8_SINT // 4D 8-bit signed integer vector
DXGI_FORMAT_R8G8B8A8_UINT // 4D 8-bit unsigned integer vector
InputSlot
指定当前元素来自于哪个输入槽(input slot)。Direct3D支持16个输入槽(索引依次为 0到15),通过这些输入槽我们可以向着色器传入顶点数据。例如,当一个顶点由位置元素和颜色元素组成时,我们既可以使用一个输入槽传送两种元素,也可以将两种元素分开,使用第一个输入槽传送顶点元素,使用第二个输入槽传送颜色元素。Direct3D可以将来自于不同输入槽的元素重新组合为顶点。一般只使用一个输入槽,设置为0即可。
AlignedByteOffset
对于单个输入槽来说,该参数表示从顶点结构体的起始位置到顶点元素的起始位置之间的字节偏移量。例如在上面的顶点结构体Vertex2中,元素Pos的字节偏移量为0,因为它的起始位置与顶点结构体的起始位置相同;元素Normal的字节偏移量为12,因为必须跳过由Pos占用的字节才能到达Normal的起始位置;元素Tex0的字节偏移量为24,因为必须跳过由Pos和Normal占用的字节才能到达Tex0的起始位置;元素Tex1的字节偏移量为32,因为必须跳过由Pos,Normal和Tex0占用的字节才能到达Tex1的起始位置。
	struct Vertex2
	{
		XMFLOAT3 Pos : POSITION; // 0-byte offset
		XMFLOAT3 Normal : NORMAL; // 12-byte offset
		XMFLOAT2 Tex0 : TEXCOORD0; // 24-byte offset
		XMFLOAT2 Tex1 : TEXCOORD1; // 32-byte offset
	};
InputSlotClass 设为D3D11_INPUT_PER_VERTEX_DATA
InstanceDataStepRate 设为0

对于顶点结构体Vertex1和Vertex2,对应的输入布局描述分别为:
	D3D11_INPUT_ELEMENT_DESC desc1[] =
	{
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
	};

	D3D11_INPUT_ELEMENT_DESC desc2[] =
	{
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT,0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0},
	};
指定了输入布局描述之后,我们就可以使用ID3D11Device::CreateInputLayout函数,创建一个表示输入布局的ID3D11InputLayout对象:
	D3D11_INPUT_ELEMENT_DESC layout[] =
	{
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
	};
	UINT numElements = ARRAYSIZE(layout);

	// ID3DBlob* pVSBlob可以通过D3DCompileFromFile获取
	// 定义全局变量ID3D11InputLayout* g_pVertexInputLayout = NULL;
	g_pD3DDevice->CreateInputLayout(layout, numElements, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &g_pVertexInputLayout);
	g_pD3DDeviceContext->IASetInputLayout(g_pVertexInputLayout);

猜你喜欢

转载自blog.csdn.net/felicityWSH/article/details/71479740
今日推荐