完成了初始化工作就需要加载渲染时需要的资源。
加载资源
- 首先需要使用ID3D12Device的CreateRootSignature方法创建RootSignature,这是D3D12里一个重要的接口。他将所有pipeline使用的资源联系在一起。为了区分不同APP所使用的资源,每一个APP使用一个RootSignature。之后会将使用的CommandList关联上创建出来的RootSignature.
- 之后就需要创建ID3D12PipelineState接口。该接口包含了D3D12里面所定义的Pipeline的关键状态数据, 例如Shader.和深度星际,图元描述等。创建完之后就需要从CommandAllocator接口创建出绑定与该Pipeline的ID3D12GraphicsCommandList接口, 并且创建时会将状态赋值给该Pipeline.
- 最后需要输入的资源就是顶点资源VertexBuffer接口为ID3D12Resource。里面组织方式根据之前PipelineState里面指定类型决定。创建好之后就通过CommandList中的各种方法来向CommandList里面添加各种命令。
- 最后创建ID3D12Fence用来与GPU 任务同步。并且在绘制完成之后能够收到通知来绘制下一帧。
循环渲染
在初始化好Pipeline和使用到的相关资源之后就能开始进行绘制。在实际程序开发中,在这个循环中会更新画面中的模型或者视角的位置等。之后再将修改好的资源load到Pipeline准备进行渲染了。
- 渲染的主要过程就是向CommandList里面填充命令的过程。 而填充的命令本身是通过调用接口里面的方法来实现的。例如设置RootSignature,设置Viewport,DrawInstanced等。
- 填充完之后就可以关掉CommandList即停止记录command。随后调用ExecuteCommandLists来执行CommandList里面的命令。
- 最后进行Present, 即将BackBuffer替换为FrontBuffer。
- 最后一个就是等待Fence返回,就说明之前的Frame被绘制以及Flip。之后就能正常使用BackBuffer进行渲染,进入下一轮绘制。
销毁对象
这里是最简单的部分。在确认最后一帧渲染完毕之后就可以对之前创建的一系列COM接口进行Release。
到此可以套用这个流程来进行简单的D3D12的程序的编写。