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

标签 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 接口(interface):

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

从 IDXGIFactory1 接口(interface),我们请求 IDXGIFactory2 接口(interface):

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

如果 IDXGIFactory2 可用,我们请求 Direct3D11.1 设备接口(interface)。 同时获取 ID3D11DeviceContext1 接口(interface):

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版本的接口(interface),但是msdn示例代码是从IDXGISwapChain1接口(interface)获取IDXGISwapChain接口(interface):

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

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

g_pSwapChain->Present( 0, 0 );

这是为什么?

最佳答案

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

Disclaimer: This is all stuff I've mined from the legacy DirectX SDK so they are all unofficial samples. The official Windows SDK samples are for Windows 8 Store or universal Windows apps on Windows 10. 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_pd3dDeviceg_pd3dDevice1 对象实例实际上是同一个对象,只是接口(interface)不同。将 QueryInterface 视为类似于 C++ 的 dynamic_castg_pSwapChaing_pSwapChain1 也是如此。

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

关于c++ - 了解 DirectX11 和 Directx11.1 示例 msdn 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32045607/

相关文章:

windows - 是否需要从 Windows SDK 重新分发 DirectX?

c++ - 如何在 C++ 中将字节数组中的整数转换为数字

c++ - 从排序数组中删除重复项

C++ lambda指针/引用内存占用之争

DirectX SDK 的 C++ 链接器错误

crash - DirectX 应用程序导致计算机崩溃

c++ - D3D11 损坏:ID3D11DeviceContext::RSGetScissorRects

c++ - 找不到合适的阴影贴图深度偏差?

c++ - 有没有办法绕过不同编译器上的 printf 错误?

c++ - 静态常量变量在子类中不是常量