wstring 初始化_DX12初始化篇:重构代码

初始化工作在上一篇中其实已经结束,这篇主要是重构代码。我们将新建两个头文件以及他们的.cpp文件。其中一个命名为ToolFunc,主要声明和实现ThrowIfFailed宏的一系列类和函数。另一个命名为D3D12App,主要声明和实现D3D12App类及其函数,是我们这次封装的重中之重。

首先是ToolFunc.h和ToolFunc.cpp,这个比较简单,直接复制之前的工具类和函数即可,需要注意的是,宏定义和内联函数一样可以在头文件中直接定义。由于D3D12APP类也将引用这个文件,所以还要将所有的包含头文件拷入。头文件代码如下所示:

#pragma once
#include <Windows.h>
#include <wrl.h>
#include <dxgi1_4.h>
#include <d3d12.h>
#include <d3dcompiler.h>
#include <DirectXMath.h>
#include <DirectXPackedVector.h>
#include <DirectXColors.h>
#include <DirectXCollision.h>
#include <string>
#include <memory>
#include <algorithm>
#include <vector>
#include <array>
#include <unordered_map>
#include <cstdint>
#include <fstream>
#include <sstream>
#include <windowsx.h>
#include <comdef.h>

//AnsiToWString函数(转换成宽字符类型的字符串,wstring)
//在Windows平台上,我们应该都使用wstring和wchar_t,处理方式是在字符串前+L
inline std::wstring AnsiToWString(const std::string& str)
{
	WCHAR buffer[512];
	MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, buffer, 512);
	return std::wstring(buffer);
}

class DxException
{
public:
	DxException() = default;
	DxException(HRESULT hr, const std::wstring& functionName, const std::wstring& filename, int lineNumber);

	std::wstring ToString()const;

	HRESULT ErrorCode = S_OK;
	std::wstring FunctionName;
	std::wstring Filename;
	int LineNumber = -1;
};

//宏定义ThrowIfFailed
#ifndef ThrowIfFailed
#define ThrowIfFailed(x)                                              
{                                                                     
    HRESULT hr__ = (x);                                               
    std::wstring wfn = AnsiToWString(__FILE__);                       
    if(FAILED(hr__)) { throw DxException(hr__, L#x, wfn, __LINE__); } 
}
#endif

接下来我们新建D3D12App.h文件,然后新建一个类,创建构造和析构后,基本就是将之前声明的函数和变量复制进去,需要注意的是,Draw函数不属于初始化范畴,所以将其定义成虚函数(其实包括Init在内的众多初始化函数也应该定义成虚函数,由于这次案例比较简单,所以没定义,之后碰到实际问题再实际处理)。头文件代码如下:

#pragma once
#include "ToolFunc.h"
#include "GameTime.h"
#include "d3dx12.h"
using namespace Microsoft::WRL;

#pragma comment(lib, "d3dcompiler.lib")
#pragma comment(lib, "D3D12.lib")
#pragma comment(lib, "dxgi.lib")

class D3D12App
{
protected:
	D3D12App();
	virtual ~D3D12App();
public:
	int Run();
	bool Init(HINSTANCE hInstance, int nShowCmd);
	bool InitWindow(HINSTANCE hInstance, int nShowCmd);
	bool InitDirect3D();
	virtual void Draw();

	void CreateDevice();
	void CreateFence();
	void GetDescriptorSize();
	void SetMSAA();
	void CreateCommandObject();
	void CreateSwapChain();
	void CreateDescriptorHeap();
	void CreateRTV();
	void CreateDSV();
	void CreateViewPortAndScissorRect();

	void FlushCmdQueue();
	void CalculateFrameState();
protected:
	HWND mhMainWnd = 0;
	
	//指针接口和变量声明
	ComPtr<ID3D12Device> d3dDevice;
	ComPtr<IDXGIFactory4> dxgiFactory;
	ComPtr<ID3D12Fence> fence;
	ComPtr<ID3D12CommandAllocator> cmdAllocator;
	ComPtr<ID3D12CommandQueue> cmdQueue;
	ComPtr<ID3D12GraphicsCommandList> cmdList;	
	ComPtr<ID3D12Resource> depthStencilBuffer;
	ComPtr<ID3D12Resource> swapChainBuffer[2];
	ComPtr<IDXGISwapChain> swapChain;
	ComPtr<ID3D12DescriptorHeap> rtvHeap;
	ComPtr<ID3D12DescriptorHeap> dsvHeap;

	D3D12_VIEWPORT viewPort;
	D3D12_RECT scissorRect;

	UINT rtvDescriptorSize = 0;
	UINT dsvDescriptorSize = 0;
	UINT cbv_srv_uavDescriptorSize = 0;

	//GameTime类实例声明
	GameTime gt;

	UINT mCurrentBackBuffer = 0;
};

在D3D12App.cpp文件的实现中,要注意MainWndProc函数是个回调函数,在创建窗口时会调用,所以它是个全局函数,不需要封装在类中,直接放在全局作用域下即可。其他代码直接复制。代码太多,这里就不贴了。

然后来到我们的主文件中,新建一个D3D12InitApp类继承自D3D12App类,实例化后直接主函数中调用即可。其实这个文件,除了WinMain函数外就是被复写的Draw函数了。类声明代码如下:

class D3D12InitApp : public D3D12App
{
public:
	D3D12InitApp();
	~D3D12InitApp();
private:
	virtual void Draw()override;
};

主函数代码如下:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int nShowCmd)
{
#if defined(DEBUG) | defined(_DEBUG)
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
	try
	{
		D3D12InitApp theApp;
		if ( !theApp.Init(hInstance, nShowCmd) )
			return 0;

		return theApp.Run();
	}
	catch (DxException& e)
	{
		MessageBox(nullptr, e.ToString().c_str(), L"HR Failed", MB_OK);
		return 0;
	}
}

运行画面和之前一样。

549c7549d0a1aeed3ee8ccf31cef55e7.png

至此我们完成了所有的DX12初始化。接下来我们将进入下一篇章《绘制几何体》。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值