介绍
本文,将在上文的基础上,绘制矩形区域。一般 direct3D 通过绘制三角形,拼成其他图像,对于矩形,本文将绘制两个三角形,以拼成一个矩形。
代码
主要修改点
输入装配阶段
一个是输入的坐标点数,之前是3个点,本文输入的 4个点。
绘制2个三角形,有两种方式,一种是输入6个点,其中有2对点是一样的。
另外一种方式是输入4个点,在加上6个索引点。
绘制命令
针对两种输入方式,有两个对应的绘制命令。
- m_pContext->Draw(6, 0); 通过输入顶点绘制6个点绘制图形
- m_pContext->DrawIndexed(6, 0, 0); 通过4个顶点和6个索引绘制图形
主要代码介绍
IASetIndexBuffer
设置索引的缓存
DrawIndexed
通过索引的方式绘制点
具体代码
void Graphics::InitEffect()
{
/************************************* 顶点着色器阶段 **************************************/
ID3DBlob* pBlob = NULL;
D3DReadFileToBlob(L"HLSL/vs.cso", &pBlob);
m_pDevice->CreateVertexShader(pBlob->GetBufferPointer(), pBlob->GetBufferSize(), nullptr, &m_pVertexShader);
m_pDevice->CreateInputLayout(layout,
1,
pBlob->GetBufferPointer(), // 该 shader 有 layout 中定义的 SemanticName
pBlob->GetBufferSize(),
&m_inputLayout);
/************************************* 像素着色器阶段 **************************************/
D3DReadFileToBlob(L"HLSL/ps.cso", &pBlob);
m_pDevice->CreatePixelShader(pBlob->GetBufferPointer(), pBlob->GetBufferSize(), nullptr, &m_pPixelShader);
}
void Graphics::DrawTriangle()
{
InitEffect();
/************************************* 输入装配阶段 **************************************/
//创建顶点缓存
struct SimpleVertex
{
DirectX::XMFLOAT3 pos;
};
SimpleVertex vertices[] =
{
/********* 使用顶点方式 *******/
//DirectX::XMFLOAT3(-0.5f, -0.5f, 0.5f),
//DirectX::XMFLOAT3(-0.5f, 0.5f, 0.5f),
//DirectX::XMFLOAT3(0.5f, 0.5f, 0.5f),
//DirectX::XMFLOAT3(-0.5f, -0.5f, 0.5f),
//DirectX::XMFLOAT3(0.5f, 0.5f, 0.5f),
//DirectX::XMFLOAT3(0.5f, -0.5f, 0.5f)
/********* 使用索引方式 *******/
DirectX::XMFLOAT3(-0.5f, -0.5f, 0.5f),
DirectX::XMFLOAT3(-0.5f, 0.5f, 0.5f),
DirectX::XMFLOAT3( 0.5f, 0.5f, 0.5f),
DirectX::XMFLOAT3( 0.5f, -0.5f, 0.5f)
};
D3D11_BUFFER_DESC verticsDesc = {};
verticsDesc.ByteWidth = sizeof(vertices) * 3; // 字节数
// 将 usage 设为 D3D11_USAGE_IMMUTABLE D3D11_USAGE_DEFAULT 可行
verticsDesc.Usage = D3D11_USAGE_IMMUTABLE; // 资源的使用,gpu和cpu 的读写权限
verticsDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; // 标识如何将资源绑定到 pipeline
verticsDesc.CPUAccessFlags = 0; // CPU 的读写权限
verticsDesc.MiscFlags = 0;
verticsDesc.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA resourceData = {};
resourceData.pSysMem = vertices;
resourceData.SysMemPitch = 0;
resourceData.SysMemSlicePitch = 0;
ID3D11Buffer* verticesBuffer = NULL;
m_pDevice->CreateBuffer(&verticsDesc, &resourceData, &verticesBuffer);
UINT strider = sizeof(SimpleVertex);
UINT offset = 0;
m_pContext->IASetVertexBuffers(
0, // start slot
1, // buffer 数量 (start slot ~ start slot + buffer number
&verticesBuffer,// 顶点缓存
&strider, // 每组数据的字节数
&offset); // 偏移量
DirectX::XMUINT3 index[] = {
{0, 1, 2},
{0, 2, 3}};
D3D11_BUFFER_DESC indexDesc = {};
indexDesc.ByteWidth = sizeof(index) * 2; // 字节数
// 将 usage 设为 D3D11_USAGE_IMMUTABLE D3D11_USAGE_DEFAULT 可行
indexDesc.Usage = D3D11_USAGE_IMMUTABLE; // 资源的使用,gpu和cpu 的读写权限
indexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; // 标识如何将资源绑定到 pipeline
indexDesc.CPUAccessFlags = 0; // CPU 的读写权限
indexDesc.MiscFlags = 0;
indexDesc.StructureByteStride = 0;
resourceData.pSysMem = index;
resourceData.SysMemPitch = 0;
resourceData.SysMemSlicePitch = 0;
ID3D11Buffer* indexBuffer = NULL;
m_pDevice->CreateBuffer(&indexDesc, &resourceData, &indexBuffer);
// 设置所引缓存
m_pContext->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0);
// 输入布局
m_pContext->IASetInputLayout(m_inputLayout);
// 图元拓扑结构
m_pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
/************************************* 顶点着色器阶段 **************************************/
m_pContext->VSSetShader(m_pVertexShader, nullptr, 0);
/************************************* 像素着色器阶段 **************************************/
m_pContext->PSSetShader(m_pPixelShader, nullptr, 0);
/************************************* 输出阶段 **************************************/
// 设置渲染目标
m_pContext->OMSetRenderTargets(1, &m_pRenderTargetView, NULL);
// 设置视口
D3D11_VIEWPORT viewPort = {};
viewPort.TopLeftX = 0;
viewPort.TopLeftY = 0;
viewPort.Width = 800;
viewPort.Height = 600;
viewPort.MinDepth = 0.0f;
viewPort.MaxDepth = 1.0f;
m_pContext->RSSetViewports(1, &viewPort);
// 开始绘制
/********* 使用顶点方式 *******/
//m_pContext->Draw(6, 0);
/********* 使用索引方式 *******/
m_pContext->DrawIndexed(6, 0, 0);
}