共用方式為


效果中的介面和類別

在 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 呼叫中指定統一介面參數。 介面參數可以指派給全域介面實例或全域類別實例。 指派給全域介面實例時,著色器會相依于介面實例,這表示它必須設定為類別實例。 指派給全域類別實例時,編譯器會將著色器特製化 (,如同其他統一資料類型一樣,) 使用該類別。 這在兩個案例中很重要:

  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) ) );
  }
}

如果 pIColor2 透過 API 維持不變,則前兩個階段的功能相等,但第一個會使用ps_4_0靜態著色器,而第二個則使用具有動態連結的ps_5_0著色器。 如果 pIColor2 透過效果 API 變更, (請參閱) 下方的設定類別實例,則第二階段中的圖元著色器行為可能會變更。

非統一介面參數

非統一介面參數會建立著色器的介面相依性。 使用介面參數套用著色器時,必須使用 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 ) );
  }
}

如果 pIColor2 透過 API 維持不變,則前兩個階段的功能相等,而且兩者都使用動態連結。 如果 pIColor2 透過效果 API 變更, (請參閱) 下方的設定類別實例,則第二階段中的圖元著色器行為可能會變更。

設定類別實例

使用 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 (效果)