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 verwenden wir die folgenden Schnittstellen und Klassen:
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;
Uniform Interface Parameters
Genau wie andere einheitliche Datentypen müssen im CompileShader-Aufruf einheitliche Schnittstellenparameter angegeben werden. Schnittstellenparameter können globalen Schnittstelleninstanzen oder globalen Klasseninstanzen zugewiesen werden. Wenn sie einer globalen Schnittstelleninstanz zugewiesen wird, hat der Shader eine Abhängigkeit von der Schnittstelleninstanz, was bedeutet, dass er auf eine Klasseninstanz festgelegt werden muss. Wenn sie globalen Klasseninstanzen zugewiesen ist, ist der Compiler auf den Shader (wie bei anderen uniform-Datentypen) spezialisiert, um diese Klasse zu verwenden. 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, viele kompilierte, spezialisierte Shader ohne dynamische Verknüpfung oder nur wenige kompilierte Shader mit dynamischer Verknüpfung zu haben.
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 beiden vorherigen 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 Effekt-API geändert wird (siehe Untenes Festlegen von Klasseninstanzen), kann sich das Verhalten des Pixelshadrs im zweiten Durchlauf ändern.
Parameter für nicht einheitliche Schnittstellen
Nicht einheitliche Schnittstellenparameter erstellen Schnittstellenabhängigkeiten für die Shader. Beim Anwenden eines Shaders mit Schnittstellenparametern müssen diese Parameter mit dem BindInterfaces-Aufruf 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 verwenden beide dynamische Verknüpfungen. Wenn pIColor2 über die Effekt-API geändert wird (siehe Untenes Festlegen von Klasseninstanzen), kann sich das Verhalten des Pixelshadrs im zweiten Durchlauf ändern.
Festlegen von Klasseninstanzen
Beim Festlegen eines Shaders mit dynamischer Shaderverknüpfung mit dem Direct3D 11-Gerät müssen auch Klasseninstanzen angegeben werden. Fehler beim Festlegen eines solchen Shaders mit einer NULL- Klasseninstanz. Daher müssen alle Schnittstelleninstanzen, auf die ein Shader verweist, über eine zugeordnete Klasseninstanz verfügen.
Das folgende Beispiel zeigt, wie Sie eine Klasseninstanzvariable aus einem Effekt abrufen und auf eine Schnittstellenvariable festlegen:
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 );
Verwandte Themen