天天看点

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

继续阅读