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:53Maybe you can use D2D in WPF
NEU_ShieldEdge

