初始化Driect3D類:程序員
#include "Common\d3dApp.h" #include <DirectXColors.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& gt)override; virtual void Draw(const GameTimer& gt)override; }; InitDirect3DApp::InitDirect3DApp(HINSTANCE hInscance) :D3DApp(hInscance) { } InitDirect3DApp::~InitDirect3DApp() { } bool InitDirect3DApp::Initialize() { if (!D3DApp::Initialize()) { return false; } return true; } void InitDirect3DApp::OnResize() { D3DApp::OnResize(); } void InitDirect3DApp::Update(const GameTimer& gt) { } void InitDirect3DApp::Draw(const GameTimer& gt) { //重置命令分配器 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(), true, &DepthStencilView()); //再次對資源狀態進行轉變,將資源從渲染目標狀態轉變爲呈現狀態 mCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition( CurrentBackBuffer(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT )); //完成命令的記錄 ThrowIfFailed(mCommandList->Close()); //將命令列表的命令加入到命令隊列中 ID3D12CommandList* cmdsList[] = { mCommandList.Get() }; mCommandQueue->ExecuteCommandLists(_countof(cmdsList), cmdsList); //交換先後臺緩衝區 ThrowIfFailed(mSwapChain->Present(0, 0));; mCurrBackBuffer = (mCurrBackBuffer + 1) % SwapChainBufferCount; //等待此幀的命令執行完畢 FlushCommandQueue(); }
主函數:數組
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd) { //爲調試版本開啓運行時內存檢測,方便監督內存泄漏的狀況 #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(nullptr, e.ToString().c_str(), L"HR Failed", MB_OK); return 0; } }
運行結果ide
接下來咱們將介紹一些在前面沒有提到的方法:函數
一、ClearRenderTargetView():將指定的渲染目標清理爲給定的顏色工具
二、ClearDepthStencilView():清理指定的深度/模板緩衝區性能
三、OMSetRenderTargets():設置咱們但願在渲染流水線上使用的渲染目標和深度/模板緩衝區動畫
大多數的Direct3D函數會返回HRESULT錯誤碼,咱們的示例程序則採用簡單的錯誤處理機制檢測返回的HRESULT值,若是檢測失敗。則拋出異常,顯示調用出錯的錯誤碼,函數名,文件名以及發生錯誤的行號,這些操做都由d3dUtil.h中的代碼實現:spa
class DxException { public: DxException() = default; DxException(HRESULT hr, const std::wstring& functionName, const std::wstring& filName, int lineNumber); std::wstring ToString()const; HRESULT ErrorCode = S_OK; std::wstring FunctionName; std::wstring FileName; int LineNumber = -1; }; #ifndef ThrowIfFailed #define ThrowIfFailed(x) \ { \ HRESULT hr__ = (x); \ std::wstring wfn = AnsiToWString(__FILE__); \ if(FAILED(hr__)) { throw DxException(hr__, L#x, wfn, __LINE__); } \ } #endif
由上面的代碼能夠看出來,ThrowifFailed是一個宏而不是一個函數,若是ThrowifFailed是一個函數,那麼__FILE__和__LINE__將會定位到ThrowifFailed函數所在的文件和行,而不是出錯函數的文件和行。3d
L#x會將ThrowifFailed的參數轉換爲Unicode字符串,這樣一來,咱們就能夠將函數調用的錯誤信息輸出到消息框中。調試