Dela via


Gränssnitt och klasser i effekter

Det finns många sätt att använda klasser och gränssnitt i Effekter 11. För gränssnitts- och klasssyntax, se Gränssnitt och klasser.

I följande avsnitt beskrivs hur du anger klassinstanser till en skuggning som använder gränssnitt. Vi använder följande gränssnitt och klasser i exemplen:

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;

Observera att gränssnittsinstanser kan initieras till klassinstanser. Matriser med klass- och gränssnittsinstanser stöds också och de kan initieras som i följande exempel:

CRed pRedArray[2];
IColor pIColor3 = pRedArray[1];
IColor pIColorArray[2] = {pRed, pGreen};
IColor pIColorArray2[2] = pRedArray;

Enhetliga gränssnittsparametrar

Precis som andra enhetliga datatyper måste enhetliga gränssnittsparametrar anges i CompileShader-anropet. Gränssnittsparametrar kan tilldelas till globala gränssnittsinstanser eller globala klassinstanser. När den tilldelas till en global gränssnittsinstans har skuggningen ett beroende av gränssnittsinstansen, vilket innebär att den måste vara inställd på en klassinstans. När den tilldelas till globala klassinstanser specialiserar kompilatorn skuggningen (som med andra enhetliga datatyper) för att använda den klassen. Detta är viktigt för två scenarier:

  1. Skuggningar med ett 4_x mål kan använda gränssnittsparametrar om dessa parametrar är enhetliga och tilldelade till globala klassinstanser (så ingen dynamisk länkning används).
  2. Användare kan välja att ha många kompilerade, specialiserade skuggor utan dynamisk länkning eller få kompilerade skuggningar med dynamisk länkning.
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) ) );
  }
}

Om pIColor2 förblir oförändrat via API:et är de två föregående passen funktionellt likvärdiga, men den första använder en ps_4_0 statisk skuggning medan den andra använder en ps_5_0 skuggning med dynamisk länkning. Om pIColor2 ändras via api:et för effekter (se Ange klassinstanser nedan) kan beteendet för pixelskuggningen i det andra passet ändras.

Icke-enhetliga gränssnittsparametrar

Icke-enhetliga gränssnittsparametrar skapar gränssnittsberoenden för skuggningarna. När du använder en skuggning med gränssnittsparametrar måste dessa parametrar tilldelas med BindInterfaces-anropet. Globala gränssnittsinstanser och globala klassinstanser kan anges i BindInterfaces-anropet.

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

Om pIColor2 förblir oförändrat via API:et är de två föregående passen funktionellt likvärdiga och båda använder dynamisk länkning. Om pIColor2 ändras via api:et för effekter (se Ange klassinstanser nedan) kan beteendet för pixelskuggningen i det andra passet ändras.

Ange klassinstanser

När du ställer in en skuggning med dynamisk skuggningslänkning till Direct3D 11-enheten måste även klassinstanser anges. Det är ett fel att ange en sådan skuggning med en NULL--klassinstans. Därför måste alla gränssnittsinstanser som en skuggning refererar till ha en associerad klassinstans.

I följande exempel visas hur du hämtar en klassinstansvariabel från en effekt och anger den till en gränssnittsvariabel:

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

effekter (Direct3D 11)