为了准备DirectX11,我们需要完成以下步骤
(1)定义我们想检查的设备类型和层级
(2)创建设备, 渲染环境和交换链
(3)创建渲染对象
(4)设置视口观察区
我们定义了一个驱动类型和特性级别的表:
通过循环去选取最合适的类型和级别
RECT dimensions;
GetClientRect(hWnd, &dimensions); //获取客户端大小 用于指标判断
unsigned int Width = dimensions.right - dimensions.left;
unsigned int height = dimensions.bottom - dimensions.top;
D3D_DRIVER_TYPE driverTypes[] = { //四种驱动类型,选择最合适的驱动类型
D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE, D3D_DRIVER_TYPE_SOFTWARE
};
unsigned int totalDriverTypes = ARRAYSIZE(driverTypes); //得出类型数
D3D_FEATURE_LEVEL featureLeverls[] = { //三种版本依赖 迭代选择最合适的版本依赖
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0
};
unsigned int totalFeatureLevels = ARRAYSIZE(featureLeverls); //得出版本数
设备交换链的创建:
Direct3D中的交换链是设备中的渲染目标的集合
每个设备至少有一个交换链,而多个交换链能够被多个设备创建.一个渲染目标可以有一个已经渲染好显示在屏幕的颜色缓存,一个深度缓存,一个模板缓存等
游戏中有两种颜色缓存,主缓存和辅助缓存: 就是所谓的前向缓存和后向缓存,主缓存是显示在屏幕上的,辅助缓存被用于下一帧的绘制
游戏中切换缓存,一个用于写入,一个用于显示输出
对象:DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
swapChainDesc.BufferCount = 1; //缓存页的数量
swapChainDesc.BufferDesc.Width = Width; //宽度
swapChainDesc.BufferDesc.Height = Height; //高度
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; //缓存格式
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; //刷新率
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; //使用60/1表示60Hz的刷新率
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; //交换链中的缓存用法,能够用于输出以及渲染
swapChainDesc.OutputWindow = hwnd; //窗口句柄
swapChainDesc.Windowed = true; //是全屏还是原来的尺寸resize?
swapChainDesc.SampleDesc.Count = 1; //取样描述:数量
swapChainDesc.SampleDesc.Quality = 0; //取样描述:质量
创建渲染环境 设备和交换链:
Direct3D设备是一种用于自身与硬件通信的设备, Direct3D渲染环境一种告诉设备怎样绘制渲染环境 包换渲染状态和其他绘制信息.
Direct3D设备类:ID3D11Device
渲染环境类型:ID3D11DeviceContext
交换链类型:IDXGISwapChain
用于创建的函数名:
D3D11CreateDeviceAndSwapChain:
D3D11_CREATE_DEVICE_DEBUG:创建可供调试的设备
参数设置如下:
视频适配器的指针
我们希望创建的驱动设备类型
实现软件渲染设备的动态库句柄
创建标志
我们所希望创建的特征级别
特征级别数组中的特征数量
#ifndef _DEBUG
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
for (unsigned int driver = 0; driver < totalDriverTypes; ++driver) {
result = D3D11CreateDeviceAndSwapChain(0, driverTypes[driver], 0, creationFlags, featureLeverls, totalFeatureLevels, D3D11_SDK_VERSION, &swapChainDesc, &swapChain_,
&d3dDevice_, &featureLevel_, &d3dContext_);
if (SUCCEEDED(result)) {
driverType_ = driverTypes[driver];
break;
}
}
if (FAILED(result))
{
DXTRACE_MSG("Failed to create the Direct3D device!");
return false;
}
//创建渲染目标视图
ID3D11Texture2D* backBufferTexture;
result = swapChain_->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferTexture);
if (FAILED(result)) {
DXTRACE_MSG("Failed to get the swap chain back buffer");
return false;
}
}
渲染目标视图: 是写入联合输出阶段的一种Direct3D资源
交换链中的主缓存和辅助缓存其实是一种颜色贴图
可以通过函数GetBuffer来获得它的指针
swapChain_->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferTexture);
//创建渲染目标视图
result = d3dDevice_->CreateRenderTargetView(backBufferTexture, 0, &backBufferTarget_); //贴图名,渲染目标描述,贴图地址
//释放贴图
if (backBufferTexture) {
backBufferTexture->Release(); //释放内容
}
if (FAILED(result)) {
DXTRACE_MSG("FAILED TO Create the render target view!!");
return false;
}
viewport.Width = static_cast<float>(Width);
viewport.Height = static_cast<float>(height);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
viewport.TopLeftX = 0.0f;
viewport.TopLeftY = 0.0f;
d3dContext_->RSSetViewports(1, &viewport);
RSSetViewports函数来设置它作为渲染环境:该函数参数有我们设置的视口数量和视口对象列表
参数:如果同步区间是0表示立即绘制, 1,2,3,4表示在第n个垂直消音之后绘制
//清楚渲染目标和显示新的渲染场景
float clearColor[4] = { 0.0f, 0.0f, 0.25f, 1.0f };
d3dContext_->ClearRenderTargetView(backBufferTarget_, clearColor);
swapChain_->Present(0, 0);
if (backBufferTarget_)
backBufferTarget_->Release();
if (swapChain_)
swapChain_->Release();
if (d3dContext_)
d3dContext_->Release();
if (d3dDevice_)
d3dDevice_->Release();