次の方法で共有


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

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 シェーダーを使用します。 エフェクト API を使用して pIColor2 が変更された場合 (後述の「クラス インスタンスの設定」を参照)、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 つのパスは機能的に同等であり、両方とも動的リンケージを使用します。 エフェクト API を使用して pIColor2 が変更された場合 (後述の「クラス インスタンスの設定」を参照)、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)