在学习了Direct3D的应用程序框架之后,我们可以直接继承它(前面提供的学习书籍作者编写的D3DAPP类),并直接使用其中提供的方法,其中已经帮助我们完成了大部分任务,我们对其中的部分进行重写,实现一个Direct3D简单应用程序初始化模板
#include"d3dApp.h"
#include<DirectXColors.h>
#include<windows.h>
using namespace DirectX;
class InitDirect3DApp :public D3DApp
{
public:
InitDirect3DApp(HINSTANCE hInstance);
~InitDirect3DApp();
virtual bool Initialize() override;
private:
virtual void OnResize() override;
virtual void Update(const GameTimer>) override;
virtual void Draw(const GameTimer>) override;
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, PSTR szCmd, int nShowCmd)
{
#if defined(DEBUG)|defined(_DEBUG)
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
try
{
InitDirect3DApp theApp(hInstance);
if (!theApp.Initialize())
return 0;
return theApp.Run();
}
catch (DxException &e)
{
::MessageBox(NULL, e.ToString().c_str(), L"HR Failed", MB_OK);
return 0;
}
}
InitDirect3DApp::InitDirect3DApp(HINSTANCE hInstance):D3DApp(hInstance)
{}
InitDirect3DApp::~InitDirect3DApp() {}
bool InitDirect3DApp::Initialize()
{
if (!D3DApp::Initialize())
{
return false;
}
return true;
}
void InitDirect3DApp::OnResize()
{
D3DApp::OnResize();
}
void InitDirect3DApp::Update(const GameTimer&)
{}
void InitDirect3DApp::Draw(const GameTimer>)
{
//重复使用记录命令的相关内存
ThrowIfFailed(mDirectCmdListAlloc->Reset());
//复用命令列表及其内存
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, 0, nullptr);
mCommandList->ClearDepthStencilView(DepthStencilView()/*返回深度缓冲区资源描述符句柄*/, D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, 1.0f, 0, 0, nullptr);
//指定将要渲染的缓冲区
mCommandList->OMSetRenderTargets(1, &CurrentBackBufferView()/*RTV描述符数组,这里只有一个后台缓冲区*/, true, &DepthStencilView()/*DSV描述符数组,这里一个*/);
//再次对资源状态进行转换,将资源从渲染目标状态转换回呈现状态
mCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(CurrentBackBuffer(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT));
//完成命令的记录,即关闭命令列表
ThrowIfFailed(mCommandList->Close());
//将待执行的命令列表加入命令队列
ID3D12CommandList*cmdLists[] = { mCommandList.Get() };
mCommandQueue->ExecuteCommandLists(_countof(cmdLists), cmdLists);
//交换后台缓冲区和前台缓冲区
ThrowIfFailed(mSwapChain->Present(0, 0));
mCurrBackBuffer = (mCurrBackBuffer + 1) % SwapChainBufferCount;
//等待此帧的命令执行完
FlushCommandQueue();
}
运行之后,即会出现浅蓝色(LightSteelBlue)窗口,成功完成了整个Direct3D的初始化流程