Compartir a través de


Interfaces y clases en efectos

Hay muchas maneras de usar clases e interfaces en Efectos 11. Para obtener información sobre la sintaxis de interfaz y clase, consulte Interfaces y clases.

En las secciones siguientes se detalla cómo especificar instancias de clase en un sombreador que usa interfaces. Usaremos la siguiente interfaz y clases en los ejemplos:

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;

Tenga en cuenta que las instancias de interfaz se pueden inicializar en instancias de clase. También se admiten matrices de instancias de clase e interfaz y se pueden inicializar como en el ejemplo siguiente:

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

Parámetros uniformes de interfaz

Al igual que otros tipos de datos uniformes, los parámetros de interfaz uniforme deben especificarse en la llamada a CompileShader. Los parámetros de interfaz se pueden asignar a instancias de interfaz globales o a instancias de clase globales. Cuando se asigna a una instancia de interfaz global, el sombreador tendrá una dependencia en la instancia de interfaz, lo que significa que debe establecerse en una instancia de clase. Cuando se asigna a instancias de clase global, el compilador especializa el sombreador (como con otros tipos de datos uniformes) para usar esa clase. Esto es importante para dos escenarios:

  1. Los sombreadores con un destino de 4_x pueden usar parámetros de interfaz si estos parámetros son uniformes y se asignan a instancias de clase globales (por lo que no se usa ninguna vinculación dinámica).
  2. Los usuarios pueden decidir tener muchos sombreadores compilados y especializados sin vinculación dinámica ni pocos sombreadores compilados con vinculación 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) ) );
  }
}

Si pIColor2 permanece sin cambios a través de la API, los dos pasos anteriores son funcionalmente equivalentes, pero el primero usa un sombreador estático ps_4_0 mientras que el segundo usa un sombreador ps_5_0 con vinculación dinámica. Si pIColor2 se cambia a través de la API de efectos (consulte Configuración de instancias de clase a continuación), el comportamiento del sombreador de píxeles en el segundo paso puede cambiar.

Parámetros de interfaz no uniformes

Los parámetros de interfaz no uniformes crean dependencias de interfaz para los sombreadores. Al aplicar un sombreador con parámetros de interfaz, estos parámetros se deben asignar con la llamada a BindInterfaces. Las instancias de interfaz global y las instancias de clase global se pueden especificar en la llamada a 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 permanece sin cambios a través de la API, los dos pasos anteriores son funcionalmente equivalentes y ambos usan vinculación dinámica. Si pIColor2 se cambia a través de la API de efectos (consulte Configuración de instancias de clase a continuación), el comportamiento del sombreador de píxeles en el segundo paso puede cambiar.

Establecer instancias de clase

Al establecer un sombreador con vinculación dinámica del sombreador al dispositivo Direct3D 11, también se deben especificar instancias de clase. Es un error establecer este sombreador con una instancia de clase NULL . Por lo tanto, todas las instancias de interfaz a las que hace referencia un sombreador deben tener una instancia de clase asociada.

En el ejemplo siguiente se muestra cómo obtener una variable de instancia de clase de un efecto y establecerla en una variable de interfaz:

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

Efectos (Direct3D 11)