该代码可用于与DirectX 11或更高版本接口的版本创建的交换链,而这种模式是专旨在确保您使用的DXGI工厂实例是创建Direct3D 11设备时实际使用的实例。
基本上,当您第一次创建Direct3D 11设备时,您可以选择提供要使用的IDXGIAdapter
实例。大多数人在这里通过nullptr
或NULL
,并让它在系统中的默认适配器上创建一个设备。但是,要完成交换链的设置,您需要DXGI工厂实例。理论上你可以使用DXGICreateFactory1
自己创建一个,但是你可以通过使用DXGICreateFactory
或者DXGICreateFactory2
错误的标志来轻松搞定并得到'错误'。
相反,以最安全的做法是使用标准COM IUnknown::QueryInterface从你ID3D11Device
的IDXGIDevice
:
IDXGIDevice * dxgiDevice = 0;
HRESULT hr = mD3dDevice->QueryInterface(__uuidof(IDXGIDevice),(void **) & dxgiDevice);
if (SUCCEEDED(hr))
使用IDXGIObject::GetParent然后得到从IDXGIDevice
的IDXGIAdapter
:
IDXGIAdapter * dxgiAdapter = 0;
hr = dxgiDevice->GetParent(__uuidof(IDXGIAdapter),(void **) & dxgiAdapter);
if (SUCCEEDED(hr))
然后得到来自IDXGIAdapter
的IDXGIFactory
再次使用IDXGIObject::GetParent:
IDXGIFactory * dxgiFactory = 0;
hr = dxgiAdapter->GetParent(__uuidof(IDXGIFactory),(void **) & dxgiFactory);
if (SUCCEEDED(hr))
现在,无论您的Direct3D 11设备如何创建,现在您都可以使用与您的Direct3D 11设备关联的IDXGIFactory
。请记住,COM引用计数意味着你必须将所有这些对象的引用,现在你必须清理:
dxgiFactory->Release();
dxgiAdapter->Release();
dxgiDevice->Release();
注意IDXGIFactory::CreateSwapChain
是创建交换链的DirectX 11.0的方式,你会得到基本上如果同样的结果你首先使用了D3D11CreateDeviceAndSwapChain而不是D3D11CreateDevice。对于DirectX 11.1或更高版本的系统,您可以考虑使用IDXGIFactory2::CreateSwapChainForHwnd
代替Win32桌面应用程序。对于Windows应用商店应用,Windows Phone 8和Xbox One,您总是会使用IDXGIFactory2::CreateSwapChainForCoreWindow
。
对于一个Win32桌面应用程序,你会遵循上面的代码的东西,如:
IDXGIFactory2* dxgiFactory2 = 0;
hr = dxgiFactory->QueryInterface(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2));
if (SUCCEEDED(hr))
{
// This system has DirectX 11.1 or later installed, so we can use this interface
dxgiFactory2->CreateSwapChainForHwnd(/* parameters */);
dxgiFactory2->Release();
}
else
{
// This system only has DirectX 11.0 installed
dxgiFactory->CreateSwapChain(/* parameters */);
}
见Anatomy of Direct3D 11 Create Device和Direct3D的教程样本Win32 desktop app version或Windows store app version。
谢谢你的回答,但我仍然明白一件事。你能解释一下GetParent方法的工作原理吗? Parent对于IDXGI :: Device是IDXGIObject,因为IDXGIDevice从IDXGIObject继承。为什么作为一个参数我们给适配器接口的ID。请解释一下,这对我来说很难,我无法找到很好的解释 – user3818006 2014-12-04 23:09:35
这是为了简化API而完成的。 ''DXGIObject :: GetParent''总是可以返回一个''IUnknown''或者''DXGIObject'',并且你必须使用''QueryInterface''来获取任何有用的东西。因此,''GetParent''只需要你想要的UUID,所以它可以在同一个调用中为你执行相同的''QueryInterface''。这也提供了一种类型安全的措施,因为您正在使用它来对子女父母关系进行假设。 – 2014-12-05 04:13:29