HLSL ShaderEffect on two usercontrols simultaneously

질문 HLSL ShaderEffect on two usercontrols simultaneously

  • 2012년 5월 1일 화요일 오후 10:07
     
      코드 있음

    Hi all,

    I tried to apply a HLSL Shader effect on 2 UserControls simultaneously. As long as only one effect is rendered everything is ok, but if both effects are runnig I got on control1 (PictureSlideShowControl) the image form control2 (PictureSlideShowControlRev). The only difference between the controls is that the second is initialized fom 10 to 0.

    The mainWindow.xaml looks like

    <Window x:Class="BrowserAnimations.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:BrowserAnimations="clr-namespace:BrowserAnimations" Title="MainWindow" Height="800" Width="1500">
        <Window.Resources>
    
        </Window.Resources>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <BrowserAnimations:PictureSlideShowControl Grid.Column="0"/>
            <BrowserAnimations:PictureSlideShowControlRev Grid.Column="1" />
        </Grid>
    </Window>
    

    the usercontrol xaml

    <UserControl x:Class="BrowserAnimations.PictureSlideShowControl"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="75" />
    
            </Grid.RowDefinitions>
            <Canvas x:Name="canvas" Grid.Row="0">
                <Image x:Name="Child01" Height="{Binding ActualHeight, ElementName=canvas}" Width="{Binding ActualWidth, ElementName=canvas}" Canvas.ZIndex="98" Stretch="Fill" Opacity="1" />
                <Image x:Name="Child02" Width="{Binding ActualWidth, ElementName=canvas}" Height="{Binding ActualHeight, ElementName=canvas}" Canvas.ZIndex="99"  Stretch="Fill" />
                <Image x:Name="Child03" Width="{Binding ActualWidth, ElementName=canvas}" Height="{Binding ActualHeight, ElementName=canvas}" Canvas.ZIndex="97"  Stretch="Fill" />
            </Canvas>
            <StackPanel Grid.Row="1" >
                <TextBlock x:Name="txtState" />
                <TextBlock x:Name="txtOldChild" />
                <TextBlock x:Name="txtCurrentChild" />
                <TextBlock x:Name="txtNextChild" />
            </StackPanel>
        </Grid>
    </UserControl>

    and the codebehind .cs

    {
        /// <summary>
        /// Interaktionslogik für PictureSlideShowControl.xaml
        /// </summary>
        public partial class PictureSlideShowControl
        {
            #region Variables
    
            private int _state;
            private const int STATES = 3;
    
            private readonly DispatcherTimer _timer;
            private readonly PictureSlideShow _pictureSlideShow = new PictureSlideShow();
            private int _nextEffect;
    
    
            //ToDo as Template
    
    
            #endregion
            public PictureSlideShowControl()
            {
                InitializeComponent();
                Loaded += PictureSlideShowControlLoaded;
                _timer = new DispatcherTimer(TimeSpan.FromSeconds(15), DispatcherPriority.Input, OnTimerTick, Dispatcher);
                _timer.Stop();
            }
    
            void PictureSlideShowControlLoaded(object sender, RoutedEventArgs e)
            {
                List<BitmapSource> images = new List<BitmapSource>();
                for (int x = 0; x < 10; x++)
                {
                    BitmapSource bs = new BitmapImage(new Uri("TransitionImages/" + x + ".jpg", UriKind.Relative));
                    // BitmapSource bs = new BitmapImage(new Uri( @"C:\Windows\Web\Wallpaper\img" + x.ToString() + ".jpg", UriKind.Absolute));                
                    // bs.Freeze(); 
                    images.Add(bs);
                }
    
                _pictureSlideShow.Images = images;
    
                _pictureSlideShow.MoveFirst();
                //_pictureSlideShow = new PictureSlideShow();
                
                Child01.Source = _pictureSlideShow.PreviousPhoto;
                Child02.Source = _pictureSlideShow.CurrentPhoto;
                Child03.Source = _pictureSlideShow.NextPhoto;
    
                _timer.Start();
                ChangePhoto(true);
                
            }
    
            private void OnTimerTick(object sender, EventArgs e)
            {
                if (_pictureSlideShow != null)
                {
                    _pictureSlideShow.MoveNext();
                }
    
                ChangePhoto(true);
            
            }
    
            private void ChangePhoto(bool applyTransitionEffect)
            {
                if (_pictureSlideShow != null)
                {
                    if (applyTransitionEffect)
                    {
                        SwapChildren();
                        NextEffect();
                    }
                    else
                    {
                        SwapChildren();
                    }
                }
            }
    
            private void SwapChildren()
            {
                //Child02.Source = _pictureSlideShow.CurrentPhoto;
                //Child01.Source = _pictureSlideShow.PreviousPhoto;
                //Child03.Source = _pictureSlideShow.NextPhoto;
    
                switch (_state)
                {
                    case 0:
                        Panel.SetZIndex(Child01, 37);
                        Panel.SetZIndex(Child02, 38);
                        Panel.SetZIndex(Child03, 36);
                        break;
    
                    case 1:
                        Panel.SetZIndex(Child02, 37);
                        Panel.SetZIndex(Child03, 38);
                        Panel.SetZIndex(Child01, 36);
                        break;
    
                    case 2:
                        Panel.SetZIndex(Child03, 37);
                        Panel.SetZIndex(Child01, 38);
                        Panel.SetZIndex(Child02, 36);
    
                        break;
    
                }
                
    
            }
    
    
            private void ApplyTransitonEffect(string effectName)
            {
               
                try
                {
                    EffectsDefinitions.EffectRunnig = true;
                    VisualBrush vb1;
                    TransitionEffect effect = EffectsDefinitions.TransitionEffects[effectName];
    
                    //txtEffectName.Text = effectName;
    
                    DoubleAnimation da = new DoubleAnimation(0.0, 1.0, new Duration(TimeSpan.FromSeconds(7.0)), FillBehavior.HoldEnd);
                    da.AccelerationRatio = 0.5;
                    da.DecelerationRatio = 0.5;
                    da.Completed += PictureTransitionCompleted;
                    effect.BeginAnimation(TransitionEffect.ProgressProperty, da);
    
                    switch (_state)
                    {
                        case 0:
                            vb1 = new VisualBrush(Child01);
                            vb1.Viewbox = new Rect(0, 0, Child01.ActualWidth, Child01.ActualHeight);
                            vb1.ViewboxUnits = BrushMappingMode.Absolute;
    
                            effect.OldImage = vb1;
    
                            Child02.Effect = effect;
    
                            txtState.Text = "State :" + _state;
                            txtOldChild.Text = "old: " + Child01.Source + Child01.Opacity + " ZIndex: " + Panel.GetZIndex(Child01);
                            txtCurrentChild.Text = "current: " + Child02.Source + Child02.Opacity + " ZIndex: " + Panel.GetZIndex(Child02);
                            txtNextChild.Text = "next: " + Child03.Source + Child03.Opacity + " ZIndex: " + Panel.GetZIndex(Child03);
    
                            break;
    
                        case 1:
                            vb1 = new VisualBrush(Child02);
                            vb1.Viewbox = new Rect(0, 0, Child02.ActualWidth, Child02.ActualHeight);
                            vb1.ViewboxUnits = BrushMappingMode.Absolute;
    
                            effect.OldImage = vb1;
    
                            Child03.Effect = effect;
    
                            txtState.Text = "State :" + _state;
                            txtOldChild.Text = "old: " + Child02.Source + Child02.Opacity + " ZIndex: " + Panel.GetZIndex(Child02);
                            txtCurrentChild.Text = "current: " + Child03.Source + Child03.Opacity + " ZIndex: " + Panel.GetZIndex(Child03);
                            txtNextChild.Text = "next: " + Child01.Source + Child01.Opacity + " ZIndex: " + Panel.GetZIndex(Child01);
    
                            break;
    
                        case 2:
                            vb1 = new VisualBrush(Child03);
                            vb1.Viewbox = new Rect(0, 0, Child03.ActualWidth, Child03.ActualHeight);
                            vb1.ViewboxUnits = BrushMappingMode.Absolute;
    
                            effect.OldImage = vb1;
    
                            Child01.Effect = effect;
    
                            txtState.Text = "State :" + _state;
                            txtOldChild.Text = "old: " + Child03.Source + Child03.Opacity + " ZIndex: " + Panel.GetZIndex(Child03);
                            txtCurrentChild.Text = "current: " + Child01.Source + Child01.Opacity + " ZIndex: " + Panel.GetZIndex(Child01);
                            txtNextChild.Text = "next: " + Child02.Source + Child02.Opacity + " ZIndex: " + Panel.GetZIndex(Child02);
                            break;
    
                    }
    
                    txtState.Text = txtState.Text + " Effect läuft";
    
                    
                }
                catch (KeyNotFoundException)
                {
                    //ToDo Apply no effect
                }
    
            }
    
    
            void PictureTransitionCompleted(object sender, EventArgs e)
            {
                txtState.Text = txtState.Text + " Effect beendet";
    
                switch (_state)
                {
                    case 0:
                        Child02.Effect = null;
                        if (_pictureSlideShow != null)
                        {
                            Child03.Source = _pictureSlideShow.NextPhoto;
                        }
                        break;
    
                    case 1:
                        Child03.Effect = null;
                        if (_pictureSlideShow != null)
                        {
                            Child01.Source = _pictureSlideShow.NextPhoto;
                        }
                        break;
    
                    case 2:
                        Child01.Effect = null;
                        if (_pictureSlideShow != null)
                        {
                            Child02.Source = _pictureSlideShow.NextPhoto;
                        }
                        break;
                }
    
                
                NextState();
    
                //_timer.Start(); 
    
                EffectsDefinitions.EffectRunnig = false;
    
            }
    
            private void NextEffect()
            {
                if (_nextEffect == EffectsDefinitions.EffectIndexTable.Length)
                {
                    _nextEffect = 0;
                }
    
                string effectName;
    
                try
                {
                    effectName = EffectsDefinitions.EffectIndexTable[_nextEffect];
                }
                catch (Exception)
                {
                    effectName = EffectsDefinitions.EffectIndexTable[0];
                }
    
                ApplyTransitonEffect(effectName);
    
                _nextEffect++;
    
            }
    
            private void NextState()
            {
                _state++;
                _state %= STATES;
            }
    
           
        }
    }
    

    the only difference between the controls is the PictureSlideShowControlLoaded method

     void PictureSlideShowControlLoaded(object sender, RoutedEventArgs e)
            {
                List<BitmapSource> images = new List<BitmapSource>();
                for (int x = 10; x > 0; x--)
                {
                    BitmapSource bs = new BitmapImage(new Uri("TransitionImages/" + x + ".jpg", UriKind.Relative));
                    // BitmapSource bs = new BitmapImage(new Uri( @"C:\Windows\Web\Wallpaper\img" + x.ToString() + ".jpg", UriKind.Absolute));                
                    // bs.Freeze(); 
                    images.Add(bs);
                }
    
                _pictureSlideShow.Images = images;
    
                _pictureSlideShow.MoveFirst();
                //_pictureSlideShow = new PictureSlideShow();
                
                Child01.Source = _pictureSlideShow.PreviousPhoto;
                Child02.Source = _pictureSlideShow.CurrentPhoto;
                Child03.Source = _pictureSlideShow.NextPhoto;
    
                _timer.Start();
                ChangePhoto(true);
                
            }

    Does anyone have an Idea, how to get is working ?

    Michael

모든 응답

  • 2012년 5월 2일 수요일 오후 9:45
     
     

    I just figured out if you put the code into a window rather than into a usercontrol everythng is ok. I think RenderTarget has to be different. Is there a possibilty to create a RenderTarget for a UserControl ?

    Michael,..,

     
  • 2012년 5월 3일 목요일 오전 5:39
    중재자
     
      코드 있음

    Hi mmuehr,

    If you want to create a RenderTarget, you could refer to "RenderTarget2D"class, for example:

     renderTarget = new RenderTarget2D(
                graphics, width, height, false,
                SurfaceFormat.Color,
                DepthFormat.Depth24Stencil8);
            buffer = new byte[width * height * 4];
            writeableBitmap = new WriteableBitmap(
                width, height, 96, 96,
                PixelFormats.Bgra32, null);

    Because of my limited knowledge on this topic, I am not sure if it could fix your issue, if your issue persists, please feel free to let me know, I will do my best to help you.

    Best regards,


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

  • 2012년 5월 13일 일요일 오후 12:31
     
     

    Hi Sheldon,

    thanks for your hint. But the RenderTarget2D refers to the XNA-Framework and I don´´t know how to set up a sepratate RenderTarget for each WPF UserControl as done in a WPF WindowControl (I think).

    Michael,..,

  • 2012년 5월 17일 목요일 오전 8:53
     
     
    Maybe you can use D2D in WPF

    NEU_ShieldEdge