在为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 );
为什么?
答案 0 :(得分:2)
您指的是MSDN Code Gallery上的 Direct3D Win32教程。请注意,GitHub上还有一个版本。
免责声明:这是我从legacy DirectX SDK开采的所有内容,因此它们都是非正式的样本。官方Windows SDK示例适用于Windows 8 Store或universal 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_pd3dDevice
和g_pd3dDevice1
对象实例实际上是同一个对象,只是具有不同的接口。可以认为QueryInterface
类似于C ++ dynamic_cast
。 g_pSwapChain
和g_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 Device,Direct3D Win32 Game Visual Studio template和DirectX Tool Kit Tutorials。