効果のインターフェイスとクラス
Effects 11 でクラスとインターフェイスを使用する方法は多数あります。 インターフェイスとクラスの構文については、「 インターフェイスとクラス」を参照してください。
次のセクションでは、インターフェイスを使用するシェーダーにクラス インスタンスを指定する方法について詳しく説明します。 この例では、次のインターフェイスとクラスを使用します。
interface IColor
{
float4 GetColor();
};
class CRed : IColor
{
float4 GetColor() { return float4(1,0,0,1); }
};
class CGreen : IColor
{
float4 GetColor() { return float4(0,1,0,1); }
};
CRed pRed;
CGreen pGreen;
IColor pIColor;
IColor pIColor2 = pRed;
インターフェイス インスタンスはクラス インスタンスに初期化できることに注意してください。 クラス インスタンスとインターフェイス インスタンスの配列もサポートされており、次の例のように初期化できます。
CRed pRedArray[2];
IColor pIColor3 = pRedArray[1];
IColor pIColorArray[2] = {pRed, pGreen};
IColor pIColorArray2[2] = pRedArray;
均一インターフェイス パラメーター
他の均一なデータ型と同様に、CompileShader 呼び出しで均一インターフェイス パラメーターを指定する必要があります。 インターフェイス パラメーターは、グローバル インターフェイス インスタンスまたはグローバル クラス インスタンスに割り当てることができます。 グローバル インターフェイス インスタンスに割り当てられると、シェーダーはインターフェイス インスタンスに依存します。つまり、クラス インスタンスに設定する必要があります。 グローバル クラス インスタンスに割り当てられると、コンパイラはシェーダーを (他の均一なデータ型と同様に) そのクラスを使用するように特化します。 これは、次の 2 つのシナリオで重要です。
- 4_x ターゲットを持つシェーダーは、これらのパラメーターが統一され、グローバル クラス インスタンスに割り当てられている場合にインターフェイス パラメーターを使用できます (そのため、動的リンケージは使用されません)。
- ユーザーは、動的リンケージを使用しないコンパイル済みの特殊なシェーダーを多数持つことや、動的リンケージを持つコンパイル済みシェーダーをほとんど持たないことを決定できます。
float4 PSUniform( uniform IColor color ) : SV_Target
{
return color;
}
technique11
{
pass
{
SetPixelShader( CompileShader( ps_4_0, PSUniform(pRed) ) );
}
pass
{
SetPixelShader( CompileShader( ps_5_0, PSUniform(pIColor2) ) );
}
}
api を通じて pIColor2 が変更されない場合、前の 2 つのパスは機能的に同等ですが、1 つ目はps_4_0静的シェーダーを使用し、2 つ目は動的リンケージを持つps_5_0 シェーダーを使用します。 pIColor2 がエフェクト API を介して変更された場合 (後述の「クラス インスタンスの設定」を参照)、2 番目のパスでのピクセル シェーダーの動作が変わる可能性があります。
一様でないインターフェイス パラメーター
統一されていないインターフェイス パラメーターは、シェーダーのインターフェイス依存関係を作成します。 インターフェイス パラメーターを使用してシェーダーを適用する場合、これらのパラメーターは BindInterfaces 呼び出しで に割り当てる必要があります。 グローバル インターフェイス インスタンスとグローバル クラス インスタンスは、BindInterfaces 呼び出しで指定できます。
float4 PSAbstract( IColor color ) : SV_Target
{
return color;
}
PixelShader pPSAbstract = CompileShader( ps_5_0, PSAbstract(pRed) );
technique11
{
pass
{
SetPixelShader( BindInterfaces( pPSAbstract, pRed ) );
}
pass
{
SetPixelShader( BindInterfaces( pPSAbstract, pIColor2 ) );
}
}
API を通じて pIColor2 が変更されない場合、前の 2 つのパスは機能的に同等であり、両方とも動的リンケージを使用します。 pIColor2 がエフェクト API を介して変更された場合 (後述の「クラス インスタンスの設定」を参照)、2 番目のパスでのピクセル シェーダーの動作が変わる可能性があります。
クラス インスタンスの設定
Direct3D 11 デバイスへの動的シェーダー リンケージを持つシェーダーを設定する場合は、クラス インスタンスも指定する必要があります。 このようなシェーダーを NULL クラス インスタンスで設定するとエラーになります。 したがって、シェーダーが参照するすべてのインターフェイス インスタンスには、関連付けられたクラス インスタンスが必要です。
次の例は、効果からクラス インスタンス変数を取得し、インターフェイス変数に設定する方法を示しています。
ID3DX11EffectPass* pPass = pEffect->GetTechniqueByIndex(0)->GetPassByIndex(1);
ID3DX11EffectInterfaceVariable* pIface = pEffect->GetVariableByName( "pIColor2" )->AsInterface();
ID3DX11EffectClassInstanceVariable* pCI = pEffect->GetVariableByName( "pGreen" )->AsClassInstance();
pIface->SetClassInstance( pCI );
pPass->Apply( 0, pDeviceContext );
// Apply the same pass with a different class instance
pCI = pEffect->GetVariableByName( "pRedArray" )->GetElement(1)->AsClassInstance();
pIface->SetClassInstance( pCI );
pPass->Apply( 0, pDeviceContext );
関連トピック