Schnittstellen und Klassen in Effekten
Es gibt viele Möglichkeiten, Klassen und Schnittstellen in Effects 11 zu verwenden. Informationen zur Schnittstellen- und Klassensyntax finden Sie unter Schnittstellen und Klassen.
In den folgenden Abschnitten wird beschrieben, wie Klasseninstanzen für einen Shader angegeben werden, der Schnittstellen verwendet. In den Beispielen werden die folgenden Schnittstellen und Klassen verwendet:
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;
Beachten Sie, dass Schnittstelleninstanzen in Klasseninstanzen initialisiert werden können. Arrays von Klassen- und Schnittstelleninstanzen werden ebenfalls unterstützt und können wie im folgenden Beispiel initialisiert werden:
CRed pRedArray[2];
IColor pIColor3 = pRedArray[1];
IColor pIColorArray[2] = {pRed, pGreen};
IColor pIColorArray2[2] = pRedArray;
Einheitliche Schnittstellenparameter
Wie bei anderen einheitlichen Datentypen müssen einheitliche Schnittstellenparameter im CompileShader-Aufruf angegeben werden. Schnittstellenparameter können globalen Schnittstelleninstanzen oder globalen Klasseninstanzen zugewiesen werden. Wenn er einer globalen Schnittstelle instance zugewiesen wird, hat der Shader eine Abhängigkeit von der Schnittstelle instance, was bedeutet, dass er auf eine Klasse instance festgelegt werden muss. Wenn er globalen Klasseninstanzen zugewiesen wird, spezialisiert der Compiler den Shader (wie bei anderen einheitlichen Datentypen) auf die Verwendung dieser Klasse. Dies ist für zwei Szenarien wichtig:
- Shader mit einem 4_x Ziel können Schnittstellenparameter verwenden, wenn diese Parameter einheitlich sind und globalen Klasseninstanzen zugewiesen sind (sodass keine dynamische Verknüpfung verwendet wird).
- Benutzer können sich entscheiden, über viele kompilierte, spezialisierte Shader ohne dynamische Verknüpfung oder wenige kompilierte Shader mit dynamischer Verknüpfung zu verfügen.
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) ) );
}
}
Wenn pIColor2 über die API unverändert bleibt, sind die vorherigen beiden Durchläufe funktional gleichwertig, aber der erste verwendet einen ps_4_0 statischen Shader, während der zweite einen ps_5_0-Shader mit dynamischer Verknüpfung verwendet. Wenn pIColor2 über die Effekte-API geändert wird (siehe Festlegen von Klasseninstanzen unten), kann sich das Verhalten des Pixel-Shaders im zweiten Durchlauf ändern.
Nicht einheitliche Schnittstellenparameter
Nicht einheitliche Schnittstellenparameter erstellen Schnittstellenabhängigkeiten für die Shader. Beim Anwenden eines Shaders mit Schnittstellenparametern müssen diese Parameter mit dem BindInterfaces-Aufruf in zugewiesen werden. Globale Schnittstelleninstanzen und globale Klasseninstanzen können im BindInterfaces-Aufruf angegeben werden.
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 ) );
}
}
Wenn pIColor2 über die API unverändert bleibt, sind die beiden vorherigen Durchläufe funktional gleichwertig, und beide verwenden dynamische Verknüpfungen. Wenn pIColor2 über die Effekte-API geändert wird (siehe Festlegen von Klasseninstanzen unten), kann sich das Verhalten des Pixel-Shaders im zweiten Durchlauf ändern.
Festlegen von Klasseninstanzen
Beim Festlegen eines Shaders mit dynamischer Shader-Verknüpfung mit dem Direct3D 11-Gerät müssen auch Klasseninstanzen angegeben werden. Es ist ein Fehler, einen solchen Shader mit einer NULL-Klasse instance festzulegen. Daher müssen alle Schnittstelleninstanzen, auf die ein Shader verweist, über eine zugeordnete Klasse instance.
Im folgenden Beispiel wird gezeigt, wie eine Klasse instance Variable aus einem Effekt abgerufen und auf eine Schnittstellenvariable festgelegt wird:
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 );
Zugehörige Themen