API ではステート ブロックの概念に対してラッパーが導入されています。DirectX を使用している場合は既にこの概念を詳しく理解していることでしょう。しかし OpenGL を使用している場合、特に古いバージョンのこのインタフェースを使用している場合は、新しいものです。
ステート ブロックは状態変化の論理的なグループです。作成後は、これらのブロックは固定 GPU リソースであると仮定されます。
GPU ステート ブロックは、次のクラスによって API に反映されます。
他の GPU リソースと同様に、これらはリソース管理システムによって管理されます。これらのリソースの API インタフェースは MStateManager です。
ステート ブロックを使用するプロセスは次のとおりです。
ステート ブロックの新しい記述が必要です。各ステート ブロック クラスには、次のように対応する記述子クラスがあります。
記述子はリソースではなく、プラグインによって所有されます。
サンプラ状態(MSamplerState)は、シェーダ ステージおよびサンプラのインデックスの両方によってスコープされます。たとえば、サンプラはピクセル シェーダ ステージの 2 番目のサンプラに対して設定できます。
次の図では、状態とレンダリング コンテキスト全体の間の論理的な接続を示します。ブレンディングは、カラー ターゲットのプロパティです。深度とステンシルの状態は、深度 + ステンシル ターゲット ステージのプロパティです。サンプリングは、シェーダ ステージごとのプロパティです。ラスタライゼーションは、レンダー コンテキスト プロパティです。
図 33: 2 つのブレンド状態が 2 つの異なるカラー ターゲットに対して示され、深度 + ステンシル状態が深度 + ステンシル ターゲットに対して示されています。各シェーダは異なるサンプラ状態を持つ場合があり、コンテキスト ラスタライゼーション状態の関係があります。
次に示すのは、透明度をレンダリングするためによく行われるアルファ ブレンディングを実行するステート ブロックを作成するための簡単なコード例です。ステート ブロックを最初から作成する最初のアプローチを示します。
// Create a new blend state descriptor. Set it to be (alpha, 1-alpha) blending and enable // blending. MHWRender::MBlendStateDesc desc; unsigned int i=0; // Set state for first render target desc.targetBlends[i].blendEnable = true; desc.targetBlends[i].destinationBlend = MHWRender::MBlendState::kSourceAlpha; desc.targetBlends[i].alphaDestinationBlend = MHWRender::MBlendState::kInvSourceAlpha; desc.targetBlends[i] blendOperation = MHWRender::MBlendState::kAdd; desc.targetBlends[i].alphaSourceBlend = MHWRender::MBlendState::kOne; desc.targetBlends[i].alphaDestinationBlend = MHWRender::MBlendState::kInvSourceAlpha; desc.targetBlends[i].alphaBlendOperation = MHWRender::MBlendState::kAdd; // Use the state manager to acquire a new blend state and then enable it. MHWRender::MStateManager* stateMgr; const MHWRender::MBlendState* blendState = stateMgr->acquireBlendState(desc); stateMgr->setBlendState(blendState);
この API を使用して状態をコントロールする必要はありませんが、レンダリング フレームワークと密接に統合されているので、このインタフェースには多くのメリットがあります。これには、次のものが含まれます。
これらのインスタンスを作成して保持することは簡単ですが、GPU に固有のパフォーマンス コストのため、次のことをお勧めします。
状態を変更するすべてのプラグインは、プラグインが描画を終了した後は前の状態を復元する必要があるというガイドラインに従う必要があります。これは状態が永続的であるためです。
実際の GPU リソースがあるので、DirectX11 を使用してリソース ハンドルを取得できます。これらは読み込み専用のリソースとして使用できます。リソース マネージャは何が変化したかわからないので、これらは変更できません。たとえば、ID3D11RasterizerState は resourceHandle() メソッドを使用して MRasterizerState から取得できます。