主菜终于来了。这个d3dclass主要做的工作是dx11图形程序的初始化工作,它将创建显示表面交换链,d3d设备,d3d设备上下文,渲染目标表面,深度模板缓存;设置视口,生成投影矩阵。
- D3D设备:可以看成是一个接口,获得这个接口后就能创建各种d3d对象
- D3D设备上下文:应该也可以看成是渲染环境的接口吧,使用它就能定制各种渲染环境,对绘制环境进行配置
- 显示表面交换链:显示表面的集合,显示表面是什么?是当前屏幕内容的内存映射,这或许应该说是主显示表面,与主显示表面同在交换链里的是副显示表面。它们的出现是为了实现平滑的绘制效果
- 渲染目标表面:就是交换链当前处于后台的表面(副表面)
- 深度模板缓存:一个存储当前绘制了的像素对应的Z值的数据块,通过这个缓存块可以决定我们是否能看到模型。就像我们把两张纸放在我们的眼前,我们只能看到离我们近的那张,离我们远的那张被离的近的挡住了,这个远近的量化就是Z值。
- 视口:显示图形的矩形,如果是全屏,那么视口就是当前屏幕
- 投影矩阵:3d渲染管线中一个重要的矩阵,他能将相机看到的内容投影到视口上
代码:
d3dclass.h
1 #pragma once 2 3 #include <d3d11.h> 4 #include <d3dcompiler.h> 5 #include <D3DX11.h> 6 #include <xnamath.h> 7 8 #pragma comment(lib,"d3dx11.lib") 9 #pragma comment(lib,"d3d11.lib") 10 #pragma comment(lib,"d3dcompiler.lib") 11 12 class d3dclass 13 { 14 public: 15 d3dclass(); 16 ~d3dclass(); 17 18 private: 19 ID3D11Device *m_d3ddevice; 20 ID3D11DeviceContext *m_d3dcontext; 21 IDXGISwapChain *m_d3dswapchain; 22 ID3D11RenderTargetView *m_d3dtargetview; 23 ID3D11Texture2D* m_d3ddepthStencil; 24 ID3D11DepthStencilView* m_d3ddepthStencilView; 25 XMMATRIX m_pro; 26 27 public: 28 bool Initialize(HWND hwnd); 29 void Shutdown(); 30 void Getdevice(ID3D11Device*& device); 31 void Getcontext(ID3D11DeviceContext*& context); 32 void Beginrender(float r, float g, float b, float a); 33 void Endrender(); 34 void Getpromtrx(XMMATRIX& pro); 35 };
m_d3ddevice:d3d设备对象
m_d3dcontext:d3d设备上下文
m_d3dswapchain:d3d交换链
m_d3dtargetview:渲染目标表面
m_d3ddepthStencil:深度缓存
m_d3ddepthStencilView:深度缓存表面
m_pro:投影矩阵
公有方法作用:
Initialize():初始化directx的各种对象
Shutdown():释放各种对象
Getdevice():获取设备指针以供使用
Getcontext():获取设备上下文指针以供使用
Beginrender():在模型渲染前调用
Endrender():在模型渲染后调用
Getpromatrx():获取投影矩阵以供使用
d3dclass.cpp
1 #include "d3dclass.h" 2 3 4 d3dclass::d3dclass() 5 { 6 } 7 8 9 d3dclass::~d3dclass() 10 { 11 } 12 13 14 bool d3dclass::Initialize(HWND hwnd) 15 { 16 HRESULT hr = S_OK; 17 D3D_DRIVER_TYPE drivertype; 18 D3D_FEATURE_LEVEL featurelevel; 19 20 RECT rc; 21 GetClientRect(hwnd, &rc); 22 int width = rc.right - rc.left; 23 int height = rc.bottom - rc.top; 24 25 UINT createDeviceFlags = 0; 26 #ifdef _DEBUG 27 createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; 28 #endif 29 30 D3D_DRIVER_TYPE driverTypes[] = 31 { 32 D3D_DRIVER_TYPE_HARDWARE, 33 D3D_DRIVER_TYPE_WARP, 34 D3D_DRIVER_TYPE_REFERENCE, 35 }; 36 UINT numDriverTypes = ARRAYSIZE(driverTypes); 37 38 D3D_FEATURE_LEVEL featureLevels[] = 39 { 40 D3D_FEATURE_LEVEL_11_0, 41 D3D_FEATURE_LEVEL_10_1, 42 D3D_FEATURE_LEVEL_10_0, 43 }; 44 UINT numFeatureLevels = ARRAYSIZE(featureLevels); 45 46 DXGI_SWAP_CHAIN_DESC sd; 47 ZeroMemory(&sd, sizeof(sd)); 48 sd.BufferCount = 1;/////////////// 49 sd.BufferDesc.Width = width; 50 sd.BufferDesc.Height = height; 51 sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 52 sd.BufferDesc.RefreshRate.Numerator = 60; 53 sd.BufferDesc.RefreshRate.Denominator = 1; 54 sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; 55 sd.OutputWindow = hwnd; 56 sd.SampleDesc.Count = 1;////////////// 57 sd.SampleDesc.Quality = 0;///////////// 58 sd.Windowed = TRUE; 59 60 for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++) 61 { 62 drivertype = driverTypes[driverTypeIndex]; 63 hr=D3D11CreateDeviceAndSwapChain(NULL, drivertype, NULL, createDeviceFlags, featureLevels, numFeatureLevels, 64 D3D11_SDK_VERSION, &sd, &m_d3dswapchain, &m_d3ddevice, &featurelevel, &m_d3dcontext); 65 if (SUCCEEDED(hr)) 66 { 67 break; 68 } 69 } 70 if (FAILED(hr)) 71 { 72 return false; 73 } 74 75 ID3D11Texture2D* pBackBuffer = NULL; 76 hr = m_d3dswapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); 77 if (FAILED(hr)) 78 { 79 return false; 80 } 81 82 hr = m_d3ddevice->CreateRenderTargetView(pBackBuffer, NULL, &m_d3dtargetview); 83 84 pBackBuffer->Release(); 85 if (FAILED(hr)) 86 { 87 return false; 88 } 89 90 D3D11_TEXTURE2D_DESC descDepth; 91 ZeroMemory(&descDepth, sizeof(descDepth)); 92 descDepth.Width = width; 93 descDepth.Height = height; 94 descDepth.MipLevels = 1; 95 descDepth.ArraySize = 1; 96 descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; 97 descDepth.SampleDesc.Count = 1; 98 descDepth.SampleDesc.Quality = 0; 99 descDepth.Usage = D3D11_USAGE_DEFAULT; 100 descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; 101 descDepth.CPUAccessFlags = 0; 102 descDepth.MiscFlags = 0; 103 hr = m_d3ddevice->CreateTexture2D(&descDepth, NULL, &m_d3ddepthStencil); 104 if (FAILED(hr)) 105 { 106 return false; 107 } 108 109 D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; 110 ZeroMemory(&descDSV, sizeof(descDSV)); 111 descDSV.Format = descDepth.Format; 112 descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; 113 descDSV.Texture2D.MipSlice = 0; 114 hr = m_d3ddevice->CreateDepthStencilView(m_d3ddepthStencil, &descDSV, &m_d3ddepthStencilView); 115 if (FAILED(hr)) 116 { 117 return false; 118 } 119 120 m_d3dcontext->OMSetRenderTargets(1, &m_d3dtargetview, m_d3ddepthStencilView); 121 122 D3D11_VIEWPORT vp; 123 vp.Width = (FLOAT)width; 124 vp.Height = (FLOAT)height; 125 vp.MinDepth = 0.0f; 126 vp.MaxDepth = 1.0f; 127 vp.TopLeftX = 0; 128 vp.TopLeftY = 0; 129 m_d3dcontext->RSSetViewports(1, &vp); 130 131 m_pro = XMMatrixPerspectiveFovLH(XM_PIDIV2, (float)width / (float)height, 0.01f, 1000.0f); 132 133 return true; 134 } 135 136 137 void d3dclass::Shutdown() 138 { 139 if (m_d3dtargetview) 140 { 141 m_d3dtargetview->Release(); 142 } 143 if (m_d3ddepthStencilView) 144 { 145 m_d3ddepthStencilView->Release(); 146 } 147 if (m_d3ddepthStencil) 148 { 149 m_d3ddepthStencil->Release(); 150 } 151 if (m_d3dswapchain) 152 { 153 m_d3dswapchain->Release(); 154 } 155 if (m_d3dcontext) 156 { 157 m_d3dcontext->Release(); 158 } 159 if (m_d3ddevice) 160 { 161 m_d3ddevice->Release(); 162 } 163 } 164 165 166 void d3dclass::Getdevice(ID3D11Device*& device) 167 { 168 device = m_d3ddevice; 169 } 170 171 172 void d3dclass::Getcontext(ID3D11DeviceContext*& context) 173 { 174 context = m_d3dcontext; 175 } 176 177 178 179 void d3dclass::Beginrender(float r,float g,float b,float a) 180 { 181 float color[] = { r, g, b, a }; 182 m_d3dcontext->ClearRenderTargetView(m_d3dtargetview,color); 183 m_d3dcontext->ClearDepthStencilView(m_d3ddepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0); 184 } 185 186 187 void d3dclass::Endrender() 188 { 189 m_d3dswapchain->Present(0, 0); 190 } 191 192 193 void d3dclass::Getpromtrx(XMMATRIX& pro) 194 { 195 pro = m_pro; 196 }
具体来看这几个方法。
Initialize():
- 先罗列设备类型与特征层级,填充交换链描述数据结构,然后for循环测试使用哪个设备类型与特征层级,创建交换链,设备,设备上下文;
- 再获取一个二维内存,创建渲染目标表面;
- 再填充一个二维内存描述数据结构,创建一个二维内存,填充一个深度模板缓存描述数据结构,创建深度模板缓存,并设置之;
- 创建视口数据结构,填充各个字段,并设置;
- 最后生成投影矩阵
至于各个描述数据结构的各个字段含义,大家可以去查阅dx11的文档
(本函数没有进行设备性能检测,所以是不安全的代码,大家如果要深入学习,还是要多参考其他资料)
Shutdown():依前是释放对象时做扫尾工作
Beginrender():用指定颜色清理渲染目标表面,并清理深度缓存
Endrender():交换交换链的显示表面