C++言語でDirectX 11を使ったアプリケーションを開発してみよう。
まずはDirectXを初期化するところから。
DirectX 9の時と比べると、ビデオカードがどの機能に対応しているかというのが「機能レベル」というもので明確にされている事で、細かい部分を気にせず初期化できるという点で楽になっているようです。
機能レベル
Dierect3D 9の時は GetDeviceCapsメソッドを使ってビデオカードの性能をチェックして実行できない機能を確認していました。
Direct3D 11では機能レベルという概念があり、このレベル毎にビデオカードがどのような機能を持つかが保証されるようになっています。
機能レベル毎の使用可能な機能一覧については下記を参照
https://msdn.microsoft.com/ja-jp/library/ee422086(v=vs.85).aspx
D3D11CreateDeviceAndSwapChainで初期化
D3D11CreateDeviceAndSwapChainメソッドはデバイスの作成とスワップチェーンの作成を1度に行ってくれます。
HRESULT D3D11CreateDeviceAndSwapChain( IDXGIAdapter* pAdapter, //アダプターのポインタ。NULLだと規定のアダプタ D3D_DRIVER_TYPE DriverType, //ハードウェアを使うD3D_DRIVER_TYPE_HARDWAREを指定 HMODULE Software, //DeviceTypeがハードウェアの場合NULL UINT Flags, //有効にするランタイムレイヤー CONST D3D_FEATURE_LEVEL* pFeatureLevels, //作成を試みる機能レベルの順序を指定する配列 UINT FeatureLevels, //作成を試みる機能レベルの順序を指定する配列の数 UINT SDKVersion, //D3D11_SDK_VERSIONを指定 CONST DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, //スワップチェーンの初期化パラメーター IDXGISwapChain** ppSwapChain, //作成されるスワップチェーン ID3D11Device** ppDevice, //作成されるデバイス D3D_FEATURE_LEVEL* pFeatureLevel, //作成されたデバイスの機能レベル ID3D11DeviceContext** ppImmediateContext //作成されるデバイスコンテキスト );
デバイスタイプ(第2引数)
指定できるタイプは D3D_DEVICE_TYPE を参照
最適なパフォーマンスを得るためにはGPUを使う必要があるのでほとんどの場合D3D_DRIVER_TYPE_HARDWAREを指定する事になるかと思います。
有効にするランタイムレイヤー(第4引数)
指定できるタイプは D3D11_CREATE_DEVICE_FLAG を参照
スワップチェーンの初期化パラメータ(第8引数)
指定例は以下のような感じ。
CRect rect; DXGI_SWAP_CHAIN_DESC scDesc; ::GetClientRect( hwnd, &rect ); ::ZeroMemory( &scDesc, sizeof( scDesc ) ); // 構造体を0クリア scDesc.BufferCount = 1; // スワップチェーンのバッファ数 scDesc.BufferDesc.Width = rect.Width(); // スワップチェーンのバッファサイズ scDesc.BufferDesc.Height = rect.Height(); // スワップチェーンのバッファサイズ scDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // スワップチェーンのバッファフォーマット scDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // バッファをレンダーターゲットとして使用 scDesc.OutputWindow = hwnd; // HWNDハンドル scDesc.SampleDesc.Count = 1; // マルチサンプリングのピクセル単位の数 scDesc.SampleDesc.Quality = 0; // マルチサンプリングの品質 scDesc.Windowed = TRUE; // ウィンドウモード
ImmediateContextとDeferredContext
DirectX11はマルチスレッドに対応しています。
対応はしてるけど、ID3D11DeviceContextをマルチスレッドで利用しようとした場合注意が必要です。
1つのDeviceContextオブジェクトに対して複数のスレッドからアクセスしてはいけません。
ID3D11DeviceContextにはImmediateContextとDeferredContextの2つのタイプがあり、複数のスレッドから描画命令を行いたい場合2つのタイプを正しく使い分ける必要があります。
ImmediateContext
ImmediateContextは1つしか存在しません。
D3D11CreateDevice等の初期化メソッドで得られるDeviceContextはImmediateタイプです。
ImmediateContextで実行した描画命令は直ちにGPUへ発行されます。
DeferredContext
ID3D11Device::CreateDeferredContextメソッドを使って生成され、ImmediateContextをもつスレッドではない別スレッドから描画命令を実行したい場合に利用します。
DeferredContextで実行した描画命令はコマンドリスト(D3D11CommandList)へ保存され、ImmediateContextからExecuteCommandListを実行してもらう事で描画が開始されます。
- ~プログラミング~ DirectX 11を始めよう
- ~プログラミング~ DirectX 11はDirectX 9と何が違うか その1
- ~プログラミング~ DirectX 11はDirectX 9と何が違うか その2
- ~プログラミング~ DirectX 11の初期化をしよう その1
- ~プログラミング~ DirectX 11の初期化をしよう その2
- ~プログラミング~ DirectX 11で深度/ステンシルバッファを準備しよう
- ~プログラミング~ DirectX 11でシェーダーをコンパイルしよう
- ~プログラミング~ DirectX 11で三角形を表示しよう
- ~プログラミング~ DirectX 11の頂点バッファとインデックスバッファ
- ~プログラミング~ DirectX 11で立体を表示しよう その1
- ~プログラミング~ DirectX 11で立体を表示しよう その2
- ~プログラミング~ DirectX 11で平行光源ライティング
- ~プログラミング~ DirectX 11で点光源ライティング
- ~プログラミング~ DirectX 11で拡散反射 (Diffuse reflection)
- ~プログラミング~ DirectX 11で鏡面反射 (Specular reflection)
- ~プログラミング~ DirectX 11で環境反射 (Ambient reflection)
- ~プログラミング~ DirectX 11でフォン反射モデル
- ~プログラミング~ DirectXTexライブラリを導入しよう
- ~プログラミング~ DirectX 11でテクスチャマッピング
コメントをお書きください