2014-12-03 55 views
3

在我的书中,我创建交换链的代码。directX创建交换链

IDXGIDevice * dxgiDevice = 0; 
mD3dDevice->QueryInterface(__uuidof(IDXGIDevice),(void **) & dxgiDevice); 

IDXGIAdapter * dxgiAdapter = 0; 
dxgiDevice->GetParent(__uuidof(IDXGIAdapter),(void **) & dxgiAdapter); 

IDXGIFactory * dxgiFactory = 0; 
dxgiAdapter->GetParent(__uuidof(IDXGIFactory),(void **) & dxgiFactory); 

dxgiFactory->CreateSwapChain(mD3dDevice, & sd, & mSwapChain); 

对于这段代码没有任何解释,我检查了几本书,并且对这段代码也没有解释。

请帮助mi与此。 我真的不明白什么做GetParent方法。 idxgiDevice扩展idxgiObject。 idxgiDevice的父类是idxgiObject,为什么它们使用指向idxgiFacory的指针作为参数。

,我不知道我理解的QueryInterface好

请帮助MI与此

回答

8

该代码可用于与DirectX 11或更高版本接口的版本创建的交换链,而这种模式是专旨在确保您使用的DXGI工厂实例是创建Direct3D 11设备时实际使用的实例。

基本上,当您第一次创建Direct3D 11设备时,您可以选择提供要使用的IDXGIAdapter实例。大多数人在这里通过nullptrNULL,并让它在系统中的默认适配器上创建一个设备。但是,要完成交换链的设置,您需要DXGI工厂实例。理论上你可以使用DXGICreateFactory1自己创建一个,但是你可以通过使用DXGICreateFactory或者DXGICreateFactory2错误的标志来轻松搞定并得到'错误'。

相反,以最安全的做法是使用标准COM IUnknown::QueryInterface从你ID3D11DeviceIDXGIDevice

IDXGIDevice * dxgiDevice = 0; 
HRESULT hr = mD3dDevice->QueryInterface(__uuidof(IDXGIDevice),(void **) & dxgiDevice); 
if (SUCCEEDED(hr)) 

使用IDXGIObject::GetParent然后得到从IDXGIDeviceIDXGIAdapter

IDXGIAdapter * dxgiAdapter = 0; 
hr = dxgiDevice->GetParent(__uuidof(IDXGIAdapter),(void **) & dxgiAdapter); 
if (SUCCEEDED(hr)) 

然后得到来自IDXGIAdapterIDXGIFactory再次使用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 versionWindows store app version

+0

谢谢你的回答,但我仍然明白一件事。你能解释一下GetParent方法的工作原理吗? Parent对于IDXGI :: Device是IDXGIObject,因为IDXGIDevice从IDXGIObject继承。为什么作为一个参数我们给适配器接口的ID。请解释一下,这对我来说很难,我无法找到很好的解释 – user3818006 2014-12-04 23:09:35

+0

这是为了简化API而完成的。 ''DXGIObject :: GetParent''总是可以返回一个''IUnknown''或者''DXGIObject'',并且你必须使用''QueryInterface''来获取任何有用的东西。因此,''GetParent''只需要你想要的UUID,所以它可以在同一个调用中为你执行相同的''QueryInterface''。这也提供了一种类型安全的措施,因为您正在使用它来对子女父母关系进行假设。 – 2014-12-05 04:13:29