04.开始绘制3
创建顶点缓冲区
现在我们需要创建顶点缓冲区。我们首先使用“顶点”结构制作一个顶点数组。
在我们有了一个顶点数组后,我们将通过填充D3D11_BUFFER_DESC 结构来描述我们的顶点缓冲区,并通过调用ZeroMemory()来确保它是空的。D3D11_BUFFER_DESC如下所示:
typedef struct D3D11_BUFFER_DESC
{
UINT ByteWidth;
D3D11_USAGE Usage;
UINT BindFlags;
UINT CPUAccessFlags;
UINT MiscFlags;
UINT StructureByteStride;
}D3D11_BUFFER_DESC;
- ByteWidth :缓冲区总字节大小
- Usage :D3D11_USAGE类型,描述如何读取和写入缓冲区。
- BindFlags :我们指定D3D11_BIND_VERTEX_BUFFER,因为这是一个顶点缓冲区。
- CPUAccessFlags :这说明了CPU将如何使用我们的缓冲区。我们可以将其设置为NULL
- MiscFlags :额外的标识。我们不用,设置为NULL.
- StructureByteStride :我们不用,设为NULL.
现在我们有了缓冲区的描述,我们需要用缓冲区中所需的数据填充D3D11_SUBRESOURCE_DATA结构。结构如下所示:
typedef struct D3D11_SUBRESOURCE_DATA
{
const void *pSysMem;
UINT SysMemPitch;
UINT SysMemSlicePitch;
} D3D11_SUBRESOURCE_DATA;
- pSysMem :缓冲区指针
- SysMemPitch :这是纹理中从一行到下一行的距离(以字节为单位)。它仅用于2D和3D纹理。
- SysMemSlicePitch :在3D纹理中,从一个深度级别到下一深度级别的距离(以字节为单位)。仅用于3D纹理。
现在,我们终于可以使用刚才创建的缓冲区描述和缓冲区数据创建缓冲区了。要创建缓冲区,我们所要做的就是调用ID3D11Device::CreateBuffer()。函数如下所示:
HRESULT CreateBuffer(
[in] const D3D11_BUFFER_DESC *pDesc,
[in] const D3D11_SUBRESOURCE_DATA *pInitialData,
[in] ID3D11Buffer **ppBuffer
);
参数如下:
- pDesc :缓冲区描述结构体指针
- pInitialData:指向子资源数据结构的指针,该数据结构包含我们要放在此处的数据。如果以后要添加数据,我们可以将其设置为NULL。
- ppBuffer :缓冲区指针返回
Vertex v[] =
{
Vertex( 0.0f, 0.5f, 0.5f ),
Vertex( 0.5f, -0.5f, 0.5f ),
Vertex( -0.5f, -0.5f, 0.5f ),
};
D3D11_BUFFER_DESC vertexBufferDesc;
ZeroMemory( &vertexBufferDesc, sizeof(vertexBufferDesc) );
vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
vertexBufferDesc.ByteWidth = sizeof( Vertex ) * 3;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = 0;
vertexBufferDesc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA vertexBufferData;
ZeroMemory( &vertexBufferData, sizeof(vertexBufferData) );
vertexBufferData.pSysMem = v;
hr = d3d11Device->CreateBuffer( &vertexBufferDesc, &vertexBufferData, &triangleVertBuffer);
设置顶点缓冲
现在我们有了顶点缓冲区,我们需要将其绑定到IA。我们可以通过调用函数ID3D11Devicecontext::IASetVertexBuffers函数来实现这一点:
void IASetVertexBuffers(
[in] UINT StartSlot,
[in] UINT NumBuffers,
[in] ID3D11Buffer *const *ppVertexBuffers,
[in] const UINT *pStrides,
[in] const UINT *pOffsets
);
- StartSlot :这是我们可以将其绑定到的输入插槽。我们在此处设置0。
- NumBuffers :绑定的缓冲区数量。这里为1。
- ppVertexBuffers :顶点缓冲区指针
- pStrides :每个顶眯的大小
- pOffsets :缓冲区开始的偏移字节大小。
UINT stride = sizeof( Vertex );
UINT offset = 0;
d3d11DevCon->IASetVertexBuffers( 0, 1, &triangleVertBuffer, &stride, &offset );
创建顶点输入布局
顶点着色器需要顶点缓冲区布局与顶点建立联系。
顶点缓冲区布局使用函数ID3D11Device::CreateInputLayout()来完成此操作。
HRESULT CreateInputLayout(
[in] const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs,
[in] UINT NumElements,
[in] const void *pShaderBytecodeWithInputSignature,
[in] SIZE_T BytecodeLength,
[out] ID3D11InputLayout **ppInputLayout
);
- pInputElementDescs :包含顶点布局的D3D11_INPUT_ELEMENT_DESC元素的数组。
- NumElements :顶点布局中的元素数量。
- pShaderBytecodeWithInputSignature :这是一个指向“顶点着色器”起点的指针。
- BytecodeLength :这是顶点着色器的大小。
- ppInputLayout :这是返回的指向我们的输入(顶点)布局的指针。
hr = d3d11Device->CreateInputLayout( layout, numElements, VS_Buffer->GetBufferPointer(),
VS_Buffer->GetBufferSize(), &vertLayout );
设置顶点输入布局
已经创建了顶点布局,接下来要做的是将其绑定到IA作为活动输入(顶点)布局。
void STDMETHODCALLTYPE IASetInputLayout(
[in] ID3D11InputLayout *pInputLayout
);
这个函数只有一个参数,就是我们创建的输入布局。
d3d11DevCon->IASetInputLayout( vertLayout );
设置基本拓扑
这是我们告诉IA我们要发送的基元类型的地方。我们可以通过调用函数ID3D11DeviceContext::IASetPrimitiveTopology()来设置基元拓扑。这里唯一的参数是D3D11_PRIITIVE_TOPOLOGY枚举类型。以下是常见类型的列表:
D3D10_PRIMITIVE_TOPOLOGY_POINTLIST
D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP
D3D10_PRIMITIVE_TOPOLOGY_LINELIST
D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP
D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST
D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ
我们的是三角形列表,即每3个顶点组成一个三角形。
d3d11DevCon->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
详见:https://blog.csdn.net/qq826364410/article/details/103785437