情報
要求されたトピックは次のとおりです。しかし、このトピックはこのライブラリには含まれていません。

Windows Phone 8 用の Direct3D デバイスおよびスワップ チェーンの作成

2014/06/18

このトピックでは、Windows Phone 用の Direct3D グラフィックス デバイスおよびスワップ チェーンを作成する正しい方法を示します。Windows Phone SDK 8.0 に付属する Direct3D アプリ プロジェクト テンプレートには、開発者に代わってこれらのタスクを実行するコードが含まれています。このトピックの目的は、電話用のスワップ チェーンを作成する際のいくつかの必要条件について注意を促すことであり、Windows Phone 8 Emulator を使用する場合、より正確にアプリをテストするのに有益な、グラフィックス デバイスを作成するコードのわずかな変更を提案します。

ID3D11Device は、Direct3D 開発の基本的なインターフェイスです。テクスチャ、頂点バッファー、シェーダーなど、開発者が使用するその他のグラフィックス リソースの大部分は、このインターフェイスを使用して作成します。デバイスを作成するコードは、Direct3D アプリ プロジェクト テンプレートで Direct3Dbase クラスの CreateDeviceResources メソッドにあります。


	D3D_FEATURE_LEVEL featureLevels[] = 
	{
		D3D_FEATURE_LEVEL_11_1,
		D3D_FEATURE_LEVEL_11_0,
		D3D_FEATURE_LEVEL_10_1,
		D3D_FEATURE_LEVEL_10_0,
		D3D_FEATURE_LEVEL_9_3
	};

	// Create the Direct3D 11 API device object and a corresponding context.
	ComPtr<ID3D11Device> device;
	ComPtr<ID3D11DeviceContext> context;
	DX::ThrowIfFailed(
		D3D11CreateDevice(
			nullptr, // Specify nullptr to use the default adapter.
			D3D_DRIVER_TYPE_HARDWARE,
			nullptr,
			creationFlags, // Set set debug and Direct2D compatibility flags.
			featureLevels, // List of feature levels this app can support.
			ARRAYSIZE(featureLevels),
			D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION.
			&device, // Returns the Direct3D device created.
			&m_featureLevel, // Returns feature level of device created.
			&context // Returns the device immediate context.
			)
		);

	// Get the Direct3D 11.1 API device and context interfaces.
	DX::ThrowIfFailed(
		device.As(&m_d3dDevice)
		);

	DX::ThrowIfFailed(
		context.As(&m_d3dContext)
		);



featureLevels 配列に、特定のデバイスでサポートされる、さまざまなデバイス機能レベルを表す定数のリストが含まれています。CreateD3D11Device を呼び出すと、この配列に含まれる機能レベルのうち、現在のデバイスでサポートされる最初の機能レベルでデバイスが作成されます。Windows Phone がサポートするのは機能レベル 9_3 だけなので、物理デバイスで実行した場合に返されるのは、このレベルのデバイスだけです。一方、Windows Phone 8 Emulator では、より高い機能レベルのデバイスの作成が可能です。デバイス上またはエミュレーター上のどちらで実行するのかを問わず、正しい機能レベルでアプリを確実にテストするために、機能レベル 9_3 だけを要求するよう、このコードを更新することをお勧めします。それには、featureLevels 配列を次のように変更します。


	D3D_FEATURE_LEVEL featureLevels[] = 
	{
		D3D_FEATURE_LEVEL_9_3
	};


9_3 機能レベルのサポートの詳細については、「Windows Phone 8 の Direct3D 機能レベル 9_3」を参照してください。

Direct3D アプリではスワップ チェーンを使用して、Back バッファーの内容を画面にコピーします。スワップ チェーンは IDXGIFactory2 インターフェイスを使用して作成します。電話でサポートされるのは、このインターフェイスで公開されるメソッドのサブセットだけです。サポートされる API の全一覧については、「Supported Direct3D APIs for Windows Phone」を参照してください。

電話では一部の DXGI メソッドが完全に使用不可能であるという事実に加えて、Windows Phone 8 上の DXGI には、サポート対象の API にもいくつかの重要な違いがあります。その違いとは主に、IDXGIFactory2::CreateSwapChainForCoreWindow によるスワップ チェーンおよび関連する Back バッファーの作成に関するものです。次のリストに、これらの重要な違いを示します。

  1. DXGI_SWAP_CHAIN_DESC1.Format - Windows Phone 8 では、サポートされる表示形式は DXGI_FORMAT_B8G8R8A8_UNORM のみです。

  2. DXGI_SWAP_CHAIN_DESC1.BufferCount - Windows Phone 8 では、スワップ チェーンのバッファー カウントは 1 でなければなりません。1 より大きい値を指定すると、DXGI により既定で 1 が使用されます。

  3. DXGI_SWAP_CHAIN_DESC1.SwapEffect - Windows Phone 8 では、サポートされるスワップ効果は DXGI_SWAP_EFFECT_DISCARD のみです。つまり、DXGI はプレゼンテーション後に Back バッファーの内容を保持しません。

  4. DXGI_SWAP_CHAIN_DESC1.Scaling - Windows Phone 8 では、サポートされるスケーリング モードは、DXGI_SCALING_STRETCH および DXGI_SCALING_ASPECT_RATIO_STRETCH のみです。Back バッファーのサイズがターゲット出力と等しくない場合、DXGI_SCALING_STRETCH では縦横比にかかわらず Back バッファーの内容がターゲット出力に合わせて拡大されるのに対し、DXGI_SCALING_ASPECT_RATIO_STRETCH は縦横比を保つスケーリングを実行し、必要に応じてコンテンツをレターボックス化します。

次のコードは、Direct3D アプリ プロジェクト テンプレートでのスワップ チェーンの作成を示しています。


	m_windowBounds = m_window->Bounds;

	// Calculate the necessary swap chain and render target size in pixels.
	m_renderTargetSize.Width = ConvertDipsToPixels(m_windowBounds.Width);
	m_renderTargetSize.Height = ConvertDipsToPixels(m_windowBounds.Height);

	DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
	swapChainDesc.Width = static_cast<UINT>(m_renderTargetSize.Width); // Match the size of the window.
	swapChainDesc.Height = static_cast<UINT>(m_renderTargetSize.Height);
	swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // This is the most common swap chain format.
	swapChainDesc.Stereo = false;
	swapChainDesc.SampleDesc.Count = 1; // Don't use multi-sampling.
	swapChainDesc.SampleDesc.Quality = 0;
	swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swapChainDesc.BufferCount = 1; // On phone, only single buffering is supported.
	swapChainDesc.Scaling = DXGI_SCALING_STRETCH; // On phone, only stretch and aspect-ratio stretch scaling are allowed.
	swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // On phone, no swap effects are supported.
	swapChainDesc.Flags = 0;

	ComPtr<IDXGIDevice1> dxgiDevice;
	DX::ThrowIfFailed(
		m_d3dDevice.As(&dxgiDevice)
		);

	ComPtr<IDXGIAdapter> dxgiAdapter;
	DX::ThrowIfFailed(
		dxgiDevice->GetAdapter(&dxgiAdapter)
		);

	ComPtr<IDXGIFactory2> dxgiFactory;
	DX::ThrowIfFailed(
		dxgiAdapter->GetParent(
			__uuidof(IDXGIFactory2), 
			&dxgiFactory
			)
		);

	Windows::UI::Core::CoreWindow^ window = m_window.Get();
	DX::ThrowIfFailed(
		dxgiFactory->CreateSwapChainForCoreWindow(
			m_d3dDevice.Get(),
			reinterpret_cast<IUnknown*>(window),
			&swapChainDesc,
			nullptr, // Allow on all displays.
			&m_swapChain
			)
		);


表示: