Directx11学习笔记【四】 封装一个简单的Dx11DemoBase

时间:2023-03-08 23:16:29
Directx11学习笔记【四】 封装一个简单的Dx11DemoBase

根据前面两个笔记的内容,我们来封装一个简单的基类,方便以后的使用。 代码和前面类似,没有什么新的内容,直接看代码吧(由于代码上次都注释了,这次代码就没怎么写注释o(╯□╰)o) Dx11DemoBase.h

Dx11DemoBase.h

#pragma once
#include <d3d11.h>
#include <D3DX11.h>
#include <DxErr.h> class Dx11DemoBase
{
public:
Dx11DemoBase();
virtual ~Dx11DemoBase(); bool Initialize(HINSTANCE hInstance, HWND hWnd);
void ShutDown();//释放内存 virtual bool LoadContent();//载入具体的Demo自己的内容,如纹理,几何体,着色器
virtual void UnLoadContent();//释放具体Demo中的内容 virtual void Update(float dt) = ;
virtual void Render() = ; protected:
HINSTANCE m_hInstance;
HWND m_hWnd; D3D_DRIVER_TYPE m_driverType;
D3D_FEATURE_LEVEL m_featureLevel; ID3D11Device* m_pd3dDevice;
ID3D11DeviceContext* m_pImmediateContext;
IDXGISwapChain* m_pSwapChain;
ID3D11RenderTargetView* m_pRenderTargetView;
};

Dx11DemoBase.cpp

#include "Dx11DemoBase.h"

Dx11DemoBase::Dx11DemoBase() :m_driverType(D3D_DRIVER_TYPE_NULL), m_featureLevel(D3D_FEATURE_LEVEL_11_0),
m_pd3dDevice(NULL), m_pImmediateContext(NULL), m_pSwapChain(NULL), m_pRenderTargetView(NULL){} Dx11DemoBase::~Dx11DemoBase()
{
ShutDown();
} bool Dx11DemoBase::LoadContent()
{
return true;
} void Dx11DemoBase::UnLoadContent()
{ } void Dx11DemoBase::ShutDown()
{
UnLoadContent();
if (m_pRenderTargetView) m_pRenderTargetView->Release();
if (m_pSwapChain) m_pSwapChain->Release();
if (m_pd3dDevice) m_pd3dDevice->Release();
if (m_pImmediateContext) m_pImmediateContext->Release(); m_pRenderTargetView = NULL;
m_pSwapChain = NULL;
m_pd3dDevice = NULL;
m_pImmediateContext = NULL;
} //初始化
bool Dx11DemoBase::Initialize(HINSTANCE hInstance, HWND hWnd)
{
HRESULT result;
m_hInstance = hInstance;
m_hWnd = hWnd;
RECT rc;
GetClientRect(m_hWnd, &rc);
UINT width = rc.right - rc.left;
UINT height = rc.bottom - rc.top; D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE
};
UINT numDriverTypes = ARRAYSIZE(driverTypes); D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0
};
UINT numFeatureLevels = ARRAYSIZE(featureLevels); DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = ;
sd.BufferDesc.Width = width;
sd.BufferDesc.Height = height;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = ;
sd.BufferDesc.RefreshRate.Denominator = ;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = m_hWnd;
sd.SampleDesc.Count = ;
sd.SampleDesc.Quality = ;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
sd.Windowed = true; UINT createDeviceFlags = ;
#ifdef _DEBUG
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif for (UINT driverTypeIndex = ; driverTypeIndex < numDriverTypes; ++driverTypeIndex)
{
result = D3D11CreateDeviceAndSwapChain(
NULL,
driverTypes[driverTypeIndex],
NULL,
createDeviceFlags,
featureLevels,
numFeatureLevels,
D3D11_SDK_VERSION,
&sd,
&m_pSwapChain,
&m_pd3dDevice,
&m_featureLevel,
&m_pImmediateContext
);
if (SUCCEEDED(result))
{
m_driverType = driverTypes[driverTypeIndex];
break;
}
} if (FAILED(result))
{
return result;
} ID3D11Texture2D *pBackBuffer = NULL;
result = m_pSwapChain->GetBuffer(, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); if (FAILED(result))
{
return result;
} result = m_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &m_pRenderTargetView);
if (pBackBuffer)
pBackBuffer->Release(); if (FAILED(result))
{
return result;
} m_pImmediateContext->OMSetRenderTargets(, &m_pRenderTargetView, NULL); D3D11_VIEWPORT vp;
vp.Height = static_cast<float>(width);//用c++的static_cast转换类型是个好习惯
vp.Width = static_cast<float>(height);
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0.0f;
vp.TopLeftY = 0.0f; m_pImmediateContext->RSSetViewports(, &vp); return LoadContent();
}

下面新建一个空白Demo类,这个类没有做什么特别的事,只是用d3d清除了屏幕而已,除了渲染函数,其他所有重写函数都是空的

BlankDemo.h

#pragma once
#include "Dx11DemoBase.h" class BlankDemo : public Dx11DemoBase
{
public:
BlankDemo();
virtual ~BlankDemo(); bool LoadContent();
void UnLoadContent(); void Update(float dt);
void Render();
};

BlankDemo.cpp

#include "BlankDemo.h"

BlankDemo::BlankDemo()
{
} BlankDemo::~BlankDemo()
{
} bool BlankDemo::LoadContent()
{
return true;
} void BlankDemo::UnLoadContent()
{ } void BlankDemo::Update(float dt)
{ } void BlankDemo::Render()
{
if (!m_pImmediateContext)
m_pImmediateContext = NULL;
float clearColors[] = { 0.0f, 0.0f, 0.5f, 1.0f };
m_pImmediateContext->ClearRenderTargetView(m_pRenderTargetView, clearColors); m_pSwapChain->Present(, );
}

main.cpp

#include <windows.h>
#include <memory>
#include "BlankDemo.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
{
WNDCLASSEX wcex;
wcex.cbClsExtra = ;
wcex.cbSize = sizeof(wcex);
wcex.cbWndExtra = ;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + );
wcex.hCursor = LoadCursor(NULL,IDC_ARROW);
wcex.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wcex.hIconSm = wcex.hIcon;
wcex.hInstance = hInstance;
wcex.lpfnWndProc = WndProc;
wcex.lpszClassName = L"BlankDemo";
wcex.lpszMenuName = L"BlankDemo";
wcex.style = CS_HREDRAW | CS_VREDRAW; if (!RegisterClassEx(&wcex))
return -; RECT rc = { , , , };
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, false); HWND hwnd = CreateWindowEx(WS_EX_APPWINDOW, L"BlankDemo", L"BlankDemo", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL); if (!hwnd)
return -; ShowWindow(hwnd, nShowCmd); std::auto_ptr<Dx11DemoBase> demo(new BlankDemo());//使用智能指针 bool result = demo->Initialize(hInstance, hwnd);
if (!result)
return -; MSG msg;
ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, , , PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
} demo->Update(0.0f);
demo->Render();
} demo->ShutDown();
return static_cast<int>(msg.wParam);
} LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT paintStruct;
HDC hDc;
switch (message)
{
case WM_PAINT:
hDc = BeginPaint(hWnd, &paintStruct);
EndPaint(hWnd, &paintStruct);
break;
case WM_DESTROY:
PostQuitMessage();
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return ;
}

运行结果同上次相同

Directx11学习笔记【四】 封装一个简单的Dx11DemoBase