Partilhar via


Interfaces e classes em efeitos

Há muitas maneiras de usar classes e interfaces no Effects 11. Para obter a sintaxe de interface e classe, consulte Interfaces e classes.

As seções a seguir detalham como especificar instâncias de classe para um sombreador que usa interfaces. Usaremos a seguinte interface e classes nos exemplos:

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;

Observe que as instâncias de interface podem ser inicializadas para instâncias de classe. Matrizes de instâncias de classe e interface também são suportadas e podem ser inicializadas como no exemplo a seguir:

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

Parâmetros de interface uniformes

Assim como outros tipos de dados uniformes, os parâmetros de interface uniformes devem ser especificados na chamada CompileShader. Os parâmetros de interface podem ser atribuídos a instâncias de interface global ou instâncias de classe global. Quando atribuído a uma instância de interface global, o sombreador terá uma dependência na instância de interface, o que significa que ele deve ser definido como uma instância de classe. Quando atribuído a instâncias de classe global, o compilador especializa o sombreador (como com outros tipos de dados uniformes) para usar essa classe. Isso é importante para dois cenários:

  1. Os sombreadores com um destino 4_x podem usar parâmetros de interface se esses parâmetros forem uniformes e atribuídos a instâncias de classe global (portanto, nenhuma ligação dinâmica é usada).
  2. Os usuários podem decidir ter muitos sombreadores compilados e especializados sem vinculação dinâmica ou poucos sombreadores compilados com vinculação dinâmica.
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) ) );
  }
}

Se pIColor2 permanecer inalterado através da API, então as duas passagens anteriores são funcionalmente equivalentes, mas a primeira usa um sombreador estático ps_4_0 enquanto a segunda usa um sombreador ps_5_0 com ligação dinâmica. Se pIColor2 for alterado por meio da API de efeitos (consulte Definindo instâncias de classe abaixo), o comportamento do sombreador de pixel na segunda passagem poderá mudar.

Parâmetros de interface não uniformes

Parâmetros de interface não uniformes criam dependências de interface para os sombreadores. Ao aplicar um sombreador com parâmetros de interface, esses parâmetros devem ser atribuídos com a chamada BindInterfaces. Instâncias de interface global e instâncias de classe global podem ser especificadas na chamada 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 ) );
  }
}

Se pIColor2 permanecer inalterado através da API, então as duas passagens anteriores são funcionalmente equivalentes e ambas usam ligação dinâmica. Se pIColor2 for alterado por meio da API de efeitos (consulte Definindo instâncias de classe abaixo), o comportamento do sombreador de pixel na segunda passagem poderá mudar.

Definindo instâncias de classe

Ao definir um sombreador com ligação de sombreador dinâmico para o dispositivo Direct3D 11, as instâncias de classe também devem ser especificadas. É um erro definir esse sombreador com uma instância de classe NULL. Portanto, todas as instâncias de interface às quais um sombreador faz referência devem ter uma instância de classe associada.

O exemplo a seguir mostra como obter uma variável de instância de classe de um efeito e defini-la como uma variável de 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 );

Effects (Direct3D 11)