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);
}