4输入布局(input layout)
设置输入布局主要是为了指定GPU按特定格式读取顶点缓存中的Void*数据,在未定义输入布局之前,顶点缓存中的所有数据都为Void*类型,即为GPU对其是陌生的。
在顶点结构中,针对每个成员,我们要定义一个相应的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;
具体信息见Direct11参数列表中的条目1;
接下来我们就对每一个顶点的参数成员定义一个D3DD_INPUT_ELEMENT_DESC,并组成数组
D3D11_INPUT_ELEMENT_DESC inputDesc[2] =
{
{ "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 }
};
接下来创建这个input layout
HRESULT ID3D11Device::CreateInputLayout(
[in] const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs,
[in] UINT NumElements,
[in] const void *pShaderBytecodeWithInputSignature,
[in] SIZE_T BytecodeLength,
[out] ID3D11InputLayout **ppInputLayout
);
4,顶点缓存和索引缓存
对于顶点,我们需要为其设定一个缓存,即buffer。当然,指定顶点索引的数组也需要为其设定一个索引缓存。
建立缓存前,我们需要设计一个缓存描述符来描述缓存格式,所有的缓存都可以用D3D11_BUFFER_DESC
typedef struct D3D11_BUFFER_DESC {
UINT ByteWidth;
D3D11_USAGE Usage;
UINT BindFlags;
UINT CPUAccessFlags;
UINT MiscFlags;
UINT StructureByteStride;
} D3D11_BUFFER_DESC;
具体的属性介绍参见DirectX11参数列表条目2
接下来,我们用到D3D11_SUBRESOURCE_DATA来之定缓存的数据源
typedef struct D3D11_SUBRESOURCE_DATA {
const void *pSysMem;
UINT SysMemPitch;
UINT SysMemSlicePitch;
} D3D11_SUBRESOURCE_DATA;
有关D3D11_SUBRESOURCE_DATA参数介绍见Direct11参数列表条目3
这样,物体顶点数据的准备工作就全部完成了,接下来就是相关渲染的准备
5.渲染阶段
一般为下几个步骤:
1,清屏
2,指定inputlayout,顶点缓存,索引缓存,图元拓扑类型
3,宣传technique11,逐步进行pass渲染
g_deviceContext->IASetInputLayout(g_inputLayout);
//指定顶点缓存
UINT stride = sizeof(Vertex);
UINT offset = 0;
g_deviceContext->IASetVertexBuffers(0,1,&g_VB,&stride,&offset);
//指定索引缓存
g_deviceContext->IASetIndexBuffer(g_IB,DXGI_FORMAT_R32_UINT,0);
//指定图元拓扑类型
g_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
最后运用Effect接口获取目标technique11中的pass,设定该pass方式,然后正式渲染。
ID3DX11EffectTechnique *tech = g_effect->GetTechniqueByName("BasicDraw");
D3DX11_TECHNIQUE_DESC techDesc;
tech->GetDesc(&techDesc);
for(UINT i=0; i<techDesc.Passes; ++i)
{
tech->GetPassByIndex(i)->Apply(0,g_deviceContext);
g_deviceContext->DrawIndexed(36,0,0);
}