Interfaces et classes dans les effets

Il existe de nombreuses façons d’utiliser des classes et des interfaces dans Effets 11. Pour connaître la syntaxe d’interface et de classe, consultez Interfaces et classes.

Les sections suivantes expliquent en détail comment spécifier des instances de classe dans un nuanceur qui utilise des interfaces. Nous allons utiliser l’interface et les classes suivantes dans les exemples :

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;

Notez que les instances d’interface peuvent être initialisées dans des instances de classe. Les tableaux d’instances de classe et d’interface sont également pris en charge et peuvent être initialisés comme dans l’exemple suivant :

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

Paramètres d’interface uniforme

Tout comme les autres types de données uniformes, les paramètres d’interface uniforme doivent être spécifiés dans l’appel CompileShader. Les paramètres d’interface peuvent être attribués à des instances d’interface globales ou à des instances de classe globale. Lorsqu’il est affecté à une instance d’interface globale, le nuanceur a une dépendance sur l’interface instance, ce qui signifie qu’il doit être défini sur une classe instance. Lorsqu’il est affecté à des instances de classe globale, le compilateur spécialise le nuanceur (comme avec d’autres types de données uniformes) pour utiliser cette classe. Cela est important pour deux scénarios :

  1. Les nuanceurs avec une cible 4_x peuvent utiliser des paramètres d’interface si ces paramètres sont uniformes et affectés à des instances de classe globale (aucune liaison dynamique n’est donc utilisée).
  2. Les utilisateurs peuvent décider d’avoir de nombreux nuanceurs compilés et spécialisés sans liaison dynamique ou quelques nuanceurs compilés avec liaison dynamique.
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) ) );
  }
}

Si pIColor2 reste inchangé via l’API, les deux passes précédentes sont fonctionnellement équivalentes, mais la première utilise un nuanceur statique ps_4_0 tandis que la seconde utilise un nuanceur ps_5_0 avec liaison dynamique. Si pIColor2 est modifié via l’API d’effets (voir Définition des instances de classe ci-dessous), le comportement du nuanceur de pixels au deuxième passage peut changer.

Paramètres d’interface non uniformes

Les paramètres d’interface non uniformes créent des dépendances d’interface pour les nuanceurs. Lors de l’application d’un nuanceur avec des paramètres d’interface, ces paramètres doivent être attribués dans avec l’appel BindInterfaces. Les instances d’interface globale et les instances de classe globale peuvent être spécifiées dans l’appel 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 ) );
  }
}

Si pIColor2 reste inchangé via l’API, les deux passes précédentes sont fonctionnellement équivalentes et utilisent toutes deux une liaison dynamique. Si pIColor2 est modifié via l’API d’effets (voir Définition des instances de classe ci-dessous), le comportement du nuanceur de pixels au deuxième passage peut changer.

Définition d’instances de classe

Lors de la définition d’un nuanceur avec une liaison de nuanceur dynamique à l’appareil Direct3D 11, les instances de classe doivent également être spécifiées. La définition d’un tel nuanceur avec une classe NULL instance est une erreur. Par conséquent, toutes les instances d’interface auxquelles un nuanceur fait référence doivent avoir une classe instance associée.

L’exemple suivant montre comment obtenir une classe instance variable à partir d’un effet et la définir sur une variable d’interface :

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

Effets (Direct3D 11)