天天看點

DX9與DX11shader編寫中SV_POSITION與POSITION和SV_Target與COLOR之間的差別(二)

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

繼續閱讀