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

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

这是为什么?

最佳答案 您指的是
MSDN Code Gallery上的Direct3D Win32教程.请注意,
GitHub上还有一个版本.

Disclaimer: This is all stuff I’ve mined from the 07002 so they are all unofficial samples. The official Windows SDK samples are for 07003 or 07004. While these samples are unofficial, as I’m the last developer to work on the legacy DirectX SDK, they are at least authoritative.

首先要说的是,这里的大部分复杂性是确保教程代码在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_pd3dDevice和g_pd3dDevice1对象实例实际上都是同一个对象,只是具有不同的接口.将QueryInterface视为C的dynamic_cast. g_pSwapChain和g_pSwapChain1也是如此.

抓取Direct3D 11.1设备和设备上下文(如果可用)的代码实际上可以在InitDevice函数中的任何位置.在Direct3D VS Win32 Game Template中,我在创建设备之后有这个,但在创建交换链之前,它们不需要捆绑在一起.我将此代码放在教程中的swapchain 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) 
                        );
 }

The code in the Win32 tutorial you are looking at is also a lot simpler in the VS Win32 Game template because I make use of Microsoft::WRL::ComPtr.

我使用g_pSwapChain作为Present,这样我就不需要为DirectX 11.0和DirectX 11.1提供两个不同的代码路径.除非您使用较新的DXGI 1.2方法,否则您可以在这里使用基本方法.

DXGI 1.0 was released for DirectX 10.0. DXGI 1.1 is for DirectX 11.0. DXGI 1.2 is DirectX 11.1.

Anatomy of Direct3D 11 Create Device,Direct3D Win32 Game Visual Studio templateDirectX Tool Kit Tutorials.

点赞