Пиксельный шейдер в отдельном окне темы - PullRequest
0 голосов
/ 07 февраля 2020

Я создал эффект пиксельного шейдера

public class AlphaEffect : ShaderEffect
{
    private static PixelShader _pixelShader = new PixelShader() { UriSource = new Uri(@"pack://application:,,,/AlphaEffect;component/AlphaEffect.ps") };

    public AlphaEffect()
    {
        PixelShader = _pixelShader;

        UpdateShaderValue(InputProperty);
        UpdateShaderValue(DesaturationFactorProperty);
    }

    public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(AlphaEffect), 0);
    public Brush Input
    {
        get { return (Brush)GetValue(InputProperty); }
        set { SetValue(InputProperty, value); }
    }

    public static readonly DependencyProperty DesaturationFactorProperty = DependencyProperty.Register("DesaturationFactor", typeof(double), typeof(AlphaEffect), new UIPropertyMetadata(0.0, PixelShaderConstantCallback(0), CoerceDesaturationFactor));
    public double DesaturationFactor
    {
        get { return (double)GetValue(DesaturationFactorProperty); }
        set { SetValue(DesaturationFactorProperty, value); }
    }

    private static object CoerceDesaturationFactor(DependencyObject d, object value)
    {
        AlphaEffect effect = (AlphaEffect)d;
        double newFactor = (double)value;

        if (newFactor < 0.0 || newFactor > 1.0)
        {
            return effect.DesaturationFactor;
        }

        return newFactor;
    }
}

Я хотел бы применить к окну, созданному в отдельном потоке

Thread newWindowThread = new Thread(new ThreadStart(() =>
{
    _playWindow = new PlayWindow(emulator, _demoMode, testRendering, multiMonitor, externalKey);
    _playWindow.Show();

    Dispatcher.Run();

}));
// Setup and start thread as before
// Set the apartment state
newWindowThread.SetApartmentState(ApartmentState.STA);
// Make the thread a background thread
newWindowThread.IsBackground = true;
// Start the thread
newWindowThread.Start();

, но у меня есть исключение: вызывающий поток не может получить доступ этот объект, потому что он принадлежит другому потоку

Это исключение было изначально выдано в стеке вызовов:

System.Windows.Threading.Dispatcher.VerifyAccess()
System.Windows.DependencyObject.GetValue(System.Windows.DependencyProperty)
System.Windows.Media.Effects.PixelShader.ShaderRenderMode.get()
System.Windows.Media.Effects.PixelShader.ManualUpdateResource(System.Windows.Media.Composition.DUCE.Channel, bool)
System.Windows.Media.Effects.PixelShader.UpdateResource(System.Windows.Media.Composition.DUCE.Channel, bool)
System.Windows.Media.Effects.PixelShader.System.Windows.Media.Composition.DUCE.IResource.AddRefOnChannel(System.Windows.Media.Composition.DUCE.Channel)
System.Windows.Media.Effects.ShaderEffect.AddRefOnChannelCore(System.Windows.Media.Composition.DUCE.Channel)
System.Windows.Media.Effects.Effect.System.Windows.Media.Composition.DUCE.IResource.AddRefOnChannel(System.Windows.Media.Composition.DUCE.Channel)
System.Windows.Media.Visual.UpdateEffect(System.Windows.Media.Composition.DUCE.Channel, System.Windows.Media.Composition.DUCE.ResourceHandle, System.Windows.Media.VisualProxyFlags, bool)
System.Windows.Media.Visual.RenderRecursive(System.Windows.Media.RenderContext)

Есть предложения? Thx

...