Partager via


Interfaces et classes dans les effets

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

Les sections suivantes expliquent comment spécifier des instances de classe à 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 en 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 d’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 affecté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’instance d’interface, ce qui signifie qu’il doit être défini sur une instance de classe. Lorsqu’il est affecté à des instances de classe globales, 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 (donc aucune liaison dynamique n’est utilisée).
  2. Les utilisateurs peuvent décider d’avoir de nombreux nuanceurs compilés et spécialisés sans liaison dynamique ou peu de nuanceurs compilés avec une 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é par le biais de l’API, les deux passes précédentes sont fonctionnellement équivalentes, mais la première utilise un nuanceur statique ps_4_0 tandis que le second utilise un nuanceur de ps_5_0 avec une liaison dynamique. Si pIColor2 est modifié par le biais de l’API d’effets (voir Définition d’instances de classe ci-dessous), le comportement du nuanceur de pixels dans la deuxième passe peut changer.

Paramètres d’interface non uniforme

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 affectés 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é par le biais de l’API, les deux passes précédentes sont fonctionnellement équivalentes et utilisent la liaison dynamique. Si pIColor2 est modifié par le biais de l’API d’effets (voir Définition d’instances de classe ci-dessous), le comportement du nuanceur de pixels dans la deuxième passe peut changer.

Définition d’instances de classe

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

L’exemple suivant montre comment obtenir une variable d’instance de classe à 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)