首页 > 代码库 > DX11学习一-初始化D3D
DX11学习一-初始化D3D
初始化D3D我们需要以下几步步
一.创建driver type,feature level
driver type分为3种类-hardware,warp以及reference,代表GPU,CPU模拟和软件模拟,性能依次下降
feature level代表dx的等级,从11到10依次下调
按driver type以及feature level,从高到低遍历,找到合适的跳出.
//Specifying the driver type and feature levels 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_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; UINT numFeatureLevels = ARRAYSIZE( featureLevels ); for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ) { g_driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); if ( hr == E_INVALIDARG ) { // DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1, D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); } if( SUCCEEDED( hr ) ) break; } if( FAILED( hr ) ) return hr;
二.创建交换链
Direct3D 11 包含一个称为 DirectX 图形基础结构 (DXGI) 的设备 API。使用 DXGI 接口,我们可以控制交换链的配置方式,并可设置共享设备。初始化 Direct3D 时,我们会在这一步骤中使用 DXGI 来创建交换链。创建设备之后,我们便可以跟随一个接口链回到 DXGI 适配器。
Direct3D 设备为 DXGI 实现一个接口。首先,我们需要获取该接口并使用该接口来请求托管设备的 DXGI 适配器。然后,我们使用 DXGI 适配器来创建 DXGI 工厂。
// Obtain DXGI factory from device (since we used nullptr for pAdapter above) IDXGIFactory1* dxgiFactory = nullptr; { IDXGIDevice* dxgiDevice = nullptr; //为 DXGI 实现一个接口 hr = g_pd3dDevice->QueryInterface( __uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice) ); if (SUCCEEDED(hr)) { IDXGIAdapter* adapter = nullptr; hr = dxgiDevice->GetAdapter(&adapter); //DXGI 适配器 if (SUCCEEDED(hr)) { hr = adapter->GetParent( __uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory) );//使用 DXGI 适配器来创建 DXGI 工厂。 adapter->Release(); } dxgiDevice->Release(); } } if (FAILED(hr)) return hr;
一条交换链是一个设备渲染目标的集合,每个设备至少有一条交换链
渲染目标可以是颜色缓冲区,深度缓冲区或者模版缓冲区
一般来说有两个颜色缓冲区-屏幕缓冲区和背景缓冲区(双缓冲)
交换链结构体有这些成员:
sd.BufferCount = 1;//不知道为什么是1 sd.BufferDesc.Width = width;//client area的长宽 sd.BufferDesc.Height = height; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;//格式 sd.BufferDesc.RefreshRate.Numerator = 60;//刷新率 sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;//可输出渲染 sd.OutputWindow = g_hWnd;//本窗口句柄 sd.SampleDesc.Count = 1;//抗锯齿 sd.SampleDesc.Quality = 0;//抗锯齿 sd.Windowed = TRUE;
代码:
// Create swap chain IDXGIFactory2* dxgiFactory2 = nullptr; hr = dxgiFactory->QueryInterface( __uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2) ); if ( dxgiFactory2 ) { // DirectX 11.1 or later hr = g_pd3dDevice->QueryInterface( __uuidof(ID3D11Device1), reinterpret_cast<void**>(&g_pd3dDevice1) ); if (SUCCEEDED(hr)) { (void) g_pImmediateContext->QueryInterface( __uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&g_pImmediateContext1) ); } DXGI_SWAP_CHAIN_DESC1 sd; ZeroMemory(&sd, sizeof(sd)); sd.Width = width; sd.Height = height; sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 1; hr = dxgiFactory2->CreateSwapChainForHwnd( g_pd3dDevice, g_hWnd, &sd, nullptr, nullptr, &g_pSwapChain1 ); if (SUCCEEDED(hr)) { hr = g_pSwapChain1->QueryInterface( __uuidof(IDXGISwapChain), reinterpret_cast<void**>(&g_pSwapChain) ); } dxgiFactory2->Release(); } else { // DirectX 11.0 systems DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd, sizeof(sd)); sd.BufferCount = 1; sd.BufferDesc.Width = width; sd.BufferDesc.Height = height; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = g_hWnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; hr = dxgiFactory->CreateSwapChain( g_pd3dDevice, &sd, &g_pSwapChain ); } // Note this tutorial doesn‘t handle full-screen swapchains so we block the ALT+ENTER shortcut dxgiFactory->MakeWindowAssociation( g_hWnd, DXGI_MWA_NO_ALT_ENTER ); dxgiFactory->Release(); if (FAILED(hr)) return hr;
三 创建Render Target View
// Create a render target view ID3D11Texture2D* pBackBuffer = nullptr; hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast<void**>( &pBackBuffer ) ); if( FAILED( hr ) ) return hr; hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, nullptr, &g_pRenderTargetView ); pBackBuffer->Release(); if( FAILED( hr ) ) return hr; g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, nullptr );
四 设置ViewPort
设置渲染视图,双人的可以设置两个视图之类的
// Setup the viewport D3D11_VIEWPORT vp; vp.Width = (FLOAT)width; vp.Height = (FLOAT)height; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0; vp.TopLeftY = 0; g_pImmediateContext->RSSetViewports( 1, &vp );
五 渲染到屏幕
g_pImmediateContext->ClearRenderTargetView( g_pRenderTargetView, Colors::MidnightBlue ); g_pSwapChain->Present( 0, 0 );
六 释放
if( g_pImmediateContext ) g_pImmediateContext->ClearState(); if( g_pRenderTargetView ) g_pRenderTargetView->Release(); if( g_pSwapChain1 ) g_pSwapChain1->Release(); if( g_pSwapChain ) g_pSwapChain->Release(); if( g_pImmediateContext1 ) g_pImmediateContext1->Release(); if( g_pImmediateContext ) g_pImmediateContext->Release(); if( g_pd3dDevice1 ) g_pd3dDevice1->Release(); if( g_pd3dDevice ) g_pd3dDevice->Release();
DX11学习一-初始化D3D
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。