本文简要的介绍了DirectX12 3D的绘制流程。
void InitDirect3DApp::Draw(const GameTimer& gt)
{
// 重复使用记录命令的相关内存,只有当与GPU关联的命令列表执行完成时,才将其重置
ThrowIfFailed(mDirectCmdListAlloc->Reset());
// 通过ExecuteCommandList方法将某命令列表加入命令队列后,便可以重置该命令列表,以此来复用命令列表及其内存
ThrowIfFailed(mCommandList->Reset(mDirectCmdListAlloc.Get(), nullptr));
//对资源的状态进行转换,从“呈现状态”转换为“渲染目标状态”
mCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(CurrentBackBuffer(),
D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET));
//设置视口(第一个参数视口数量,第二个参数指向视口数组的指针)命令列表一旦被重置,视口也就需要重置
mCommandList->RSSetViewports(1, &mScreenViewport);
//设置裁剪矩形(第一个参数裁剪矩形数量,第二个参数指向裁剪矩形数组的指针)命令列表一旦被重置,裁剪矩形也就需要重置
mCommandList->RSSetScissorRects(1, &mScissorRect);
//清除后台缓冲区和深度缓冲区
mCommandList->ClearRenderTargetView(CurrentBackBufferView(), //待清除资源
Colors::LightSteelBlue, //为RVT填充的颜色
0, //数组中元素的数量
nullptr); //数组,指定被清除的多个矩形区域。nullptr表示清除整个渲染目标
mCommandList->ClearDepthStencilView(DepthStencilView(), //待清除的深度/模板缓冲区
D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, //清除深度缓冲区或模板缓冲区
1.0f, //以此值清除深度缓冲区
0, //以此值清除模板缓冲区
0, //数组内元素数量
nullptr); //数组,指定清除的多个矩形区域。nullptr表示清除整个渲染目标
//指定将要渲染的缓冲区
mCommandList->OMSetRenderTargets(1, //待绑定的RTV数量
&CurrentBackBufferView(), //指向RTV数组的指针,指定想绑定到渲染流水线上的渲染目标
true, //数组中RTV对象在描述符堆中是否是连续存放。
&DepthStencilView()); //指向DSV数组的指针,指定想绑定到渲染流水线上的深度/模板缓冲区
//再次对资源的状态进行转换,从渲染目标状态转换为呈现状态
mCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(CurrentBackBuffer(),
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT));
//完成命令的记录
ThrowIfFailed(mCommandList->Close());
//将待执行的命令列表加入命令队列
ID3D12CommandList* cmdsLists[] = { mCommandList.Get() };
mCommandQueue->ExecuteCommandLists(_countof(cmdsLists), cmdsLists);
//交换前后台缓冲区
ThrowIfFailed(mSwapChain->Present(0, 0));
//更新索引,使之指向交换后的后台缓冲区
mCurrBackBuffer = (mCurrBackBuffer + 1) % SwapChainBufferCount;
//等待此帧的命令执行完毕
FlushCommandQueue();
}
当前代码实现了绘制流程,但没什么效率,也过于简单。后面文章会重新组织绘制的代码。