了解DirectX11和Directx11.1示例msdn代码

时间:2015-08-17 08:15:00

标签: c++ directx-11

在为win32初始化DirectX 11.1时,我遵循MSDN示例代码。 代码声明了两个Direct3d设备:

   ID3D11Device*           g_pd3dDevice = nullptr;
   ID3D11Device1*          g_pd3dDevice1 = nullptr;

然后获取类似的设备:

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 );


hr = D3D11CreateDevice( 
                        nullptr, 
                        D3D_DRIVER_TYPE_HARDWARE, 
                        nullptr, 
                        createDeviceFlags, 
                        featureLevels, 
                        numFeatureLevels,
                        D3D11_SDK_VERSION, 
                        &g_pd3dDevice, 
                        &g_featureLevel, 
                       &g_pImmediateContext );

if ( hr == E_INVALIDARG )
{

    hr = D3D11CreateDevice( 
                            nullptr, 
                            D3D_DRIVER_TYPE_HARDWARE, 
                            nullptr, 
                            createDeviceFlags, 
                            &featureLevels[1], 
                            numFeatureLevels - 1,
                            D3D11_SDK_VERSION, 
                            &g_pd3dDevice, 
                            &g_featureLevel, 
                            &g_pImmediateContext );
}

if( FAILED( hr ) )
    return hr;

然后我们获得DXGIDevice:

IDXGIFactory1* dxgiFactory = nullptr;
IDXGIDevice* dxgiDevice = nullptr;
hr = g_pd3dDevice->QueryInterface( __uuidof(IDXGIDevice),
                                   reinterpret_cast<void**>(&dxgiDevice) 
                                  );

然后我们得到适配器:

IDXGIAdapter* adapter = nullptr;
hr = dxgiDevice->GetAdapter(&adapter);

从适配器我们得到IDXGIFactory1接口:

 hr = adapter->GetParent( __uuidof(IDXGIFactory1), 
                          reinterpret_cast<void**>(&dxgiFactory) );

从IDXGIFactory1接口,我们请求IDXGIFactory2接口:

IDXGIFactory2* dxgiFactory2 = nullptr;
hr = dxgiFactory->QueryInterface( __uuidof(IDXGIFactory2),
                                   reinterpret_cast<void**>(&dxgiFactory2)
                                 );

如果IDXGIFactory2可用,我们请求Direct3D11.1设备接口。 还得到ID3D11DeviceContext1接口:

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) 
                        );
    }

然后我们创建交换链:

hr = dxgiFactory2->CreateSwapChainForHwnd( g_pd3dDevice, 
                                           g_hWnd, 
                                           &sd, 
                                           nullptr, 
                                           nullptr, 
                                           &g_pSwapChain1 );

我的第一个问题是为什么此代码在创建交换链时使用DirectX11版本的设备?我们应该使用g_pd3dDevice1而不是g_pd3dDevice吗?

我的第二个问题是,即使我们可以获得directx11.1版本的接口,msdn示例代码从IDXGISwapChain1接口获取IDXGISwapChain接口:

hr = g_pSwapChain1->QueryInterface( __uuidof(IDXGISwapChain),
                             reinterpret_cast<void**>(&g_pSwapChain) );

并在当前通话中使用该版本的swapchain:

g_pSwapChain->Present( 0, 0 );

为什么?

1 个答案:

答案 0 :(得分:2)

您指的是MSDN Code Gallery上的 Direct3D Win32教程。请注意,GitHub上还有一个版本。

  

免责声明:这是我从legacy DirectX SDK开采的所有内容,因此它们都是非正式的样本。官方Windows SDK示例适用于Windows 8 Storeuniversal Windows apps on Windows 10。虽然这些示例都是非正式的,但作为最后一位使用旧版DirectX SDK的开发人员,他们至少具有权威性。

首先要说的是,这里的大部分复杂性是确保教程代码在DirectX 11.0系统(Windows Vista SP2 + KB971644,Windows 7 RTM,不带KB2670838的Windows 7 SP1)上正常运行,以及DirectX 11.1或更高版本(Windows 7 SP1 + KB2670838,Windows 8或更高版本)。对于依赖于从不在DirectX 11.0系统上运行的Windows 8商店或通用Windows应用程序,这不是必需的。

g_pd3dDeviceg_pd3dDevice1对象实例实际上是同一个对象,只是具有不同的接口。可以认为QueryInterface类似于C ++ dynamic_castg_pSwapChaing_pSwapChain1也是如此。

获取Direct3D 11.1设备和设备上下文的代码(如果可用)实际上可以在InitDevice函数中的任何位置。在Direct3D VS Win32 Game Template我在创建设备后有这个,但在创建交换链之前,他们不需要捆绑在一起。我将此代码放在教程中的swapchain if语句中,以适应两个注释案例:&#34; DirectX 11.1或更高版本&#34;和&#34; DirectX 11.0&#34;这与DXGI 1.1与DXGI 1.2 +不同。

 // 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) 
                        );
 }
  

您正在查看的Win32教程中的代码在VS Win32游戏模板中也更简单,因为我使用了Microsoft::WRL::ComPtr

我对g_pSwapChain使用Present,因此我不需要为DirectX 11.0与DirectX 11.1提供两种不同的代码路径。除非您使用较新的DXGI 1.2方法,否则您可以在这里使用基本方法。

  

DXGI 1.0已针对DirectX 10.0发布。 DXGI 1.1适用于DirectX 11.0。 DXGI 1.2是DirectX 11.1。

请参阅Anatomy of Direct3D 11 Create DeviceDirect3D Win32 Game Visual Studio templateDirectX Tool Kit Tutorials