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

Pix*_*ord 5 c++ directx-11

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

   ID3D11Device*           g_pd3dDevice = nullptr;
   ID3D11Device1*          g_pd3dDevice1 = nullptr;
Run Code Online (Sandbox Code Playgroud)

然后获取设备,如:

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;
Run Code Online (Sandbox Code Playgroud)

然后我们获取DXGIDevice:

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

然后我们得到适配器:

IDXGIAdapter* adapter = nullptr;
hr = dxgiDevice->GetAdapter(&adapter);
Run Code Online (Sandbox Code Playgroud)

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

 hr = adapter->GetParent( __uuidof(IDXGIFactory1), 
                          reinterpret_cast<void**>(&dxgiFactory) );
Run Code Online (Sandbox Code Playgroud)

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

IDXGIFactory2* dxgiFactory2 = nullptr;
hr = dxgiFactory->QueryInterface( __uuidof(IDXGIFactory2),
                                   reinterpret_cast<void**>(&dxgiFactory2)
                                 );
Run Code Online (Sandbox Code Playgroud)

如果 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) 
                        );
    }
Run Code Online (Sandbox Code Playgroud)

然后我们创建交换链:

hr = dxgiFactory2->CreateSwapChainForHwnd( g_pd3dDevice, 
                                           g_hWnd, 
                                           &sd, 
                                           nullptr, 
                                           nullptr, 
                                           &g_pSwapChain1 );
Run Code Online (Sandbox Code Playgroud)

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

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

hr = g_pSwapChain1->QueryInterface( __uuidof(IDXGISwapChain),
                             reinterpret_cast<void**>(&g_pSwapChain) );
Run Code Online (Sandbox Code Playgroud)

并在当前调用中使用该版本的交换链:

g_pSwapChain->Present( 0, 0 );
Run Code Online (Sandbox Code Playgroud)

这是为什么?

Chu*_*urn 2

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

免责声明:这些都是我从旧版 DirectX SDK中挖掘的内容,因此它们都是非官方示例。官方 Windows SDK 示例适用于Windows 8 应用商店Windows 10 上的通用 Windows 应用程序。虽然这些示例是非官方的,但由于我是最后一个使用旧版 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 或更高版本)。Windows 8 应用商店或通用 Windows 应用程序不需要这样做,因为它们可能依赖于从不在 DirectX 11.0 系统上运行。

实例g_pd3dDeviceg_pd3dDevice1对象实例实际上是同一个对象,只是具有不同的接口。可以将其视为QueryInterface类似于 C++ 的dynamic_cast. g_pSwapChain和也是如此g_pSwapChain1

用于获取 Direct3D 11.1 设备和设备上下文(如果可用)的代码实际上可以位于函数中的任何位置InitDevice。在Direct3D VS Win32 游戏模板中,我在创建设备之后、创建交换链之前有此模板,因此它们不需要捆绑在一起。我将此代码放在教程中的交换链 if 语句中,以适应两种注释的情况:“DirectX 11.1 或更高版本”和“DirectX 11.0”,这对于 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) 
                        );
 }
Run Code Online (Sandbox Code Playgroud)

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

我使用g_pSwapChainfor ,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。

请参阅Direct3D 11 创建设备剖析Direct3D Win32 游戏 Visual Studio 模板DirectX 工具包教程