効果のインターフェイスとクラス

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 つのシナリオで重要です。

  1. 4_x ターゲットを持つシェーダーは、これらのパラメーターが統一され、グローバル クラス インスタンスに割り当てられている場合にインターフェイス パラメーターを使用できます (そのため、動的リンケージは使用されません)。
  2. ユーザーは、動的リンケージを使用しないコンパイル済みの特殊なシェーダーを多数持つことや、動的リンケージを持つコンパイル済みシェーダーをほとんど持たないことを決定できます。
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 );

効果 (Direct3D 11)