2014-12-03 66 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