3

I was following along this tutorial about how to include Pixel Shader Effects in the form of an animation within a WPF application.

Background

I felt like things were going smoothly, however I wanted to make a change to the application. In the tutorial the author has a separate GrayscaleEffect project and in his XAML does the following:

xmlns:effect="clr-namespace:GrayscaleEffect;assembly=GrayscaleEffect"

Later he has this:

DataTemplate x:Key="itemTemplate">
        <Grid Width="225" Margin="3">
            <Border BorderBrush="White" BorderThickness="2">
                <Image Source="{Binding}" HorizontalAlignment="Center" VerticalAlignment="Center">
                    <Image.Effect>
                        <local:GrayscaleEffectTest x:Name="grayscaleEffect"/>
                    </Image.Effect>
                    <Image.Triggers>
                        <EventTrigger RoutedEvent="Mouse.MouseEnter">
                            <BeginStoryboard>
                                <Storyboard>
<!--HERE-->                         <DoubleAnimation To="1.0" Duration="0:0:0.3" AccelerationRatio="0.10" DecelerationRatio="0.25" Storyboard.TargetName="grayscaleEffect" Storyboard.TargetProperty="(local:GrayscaleEffectTest.DesaturationFactor)" />
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>
                        <EventTrigger RoutedEvent="Mouse.MouseLeave">
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation To="0.0"  Duration="0:0:4" AccelerationRatio="0.10" DecelerationRatio="0.25" Storyboard.TargetName="grayscaleEffect" Storyboard.TargetProperty="(local:GrayscaleEffectTest.DesaturationFactor)" />
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>
                    </Image.Triggers>
                </Image>
            </Border>
        </Grid>
    </DataTemplate>

The key point here is the very long line <DoubleAnimation ....:

Storyboard.TargetProperty="(effect:GrayscaleEffect.DesaturationFactor)" />

My Approach

I wanted to make the same thing, except I wanted to keep all of my code in the same project, rather than having two projects.

So, I don't include the ;assembly=GrayscaleEffect. Furthermore my <DoubleAnimation ... line reads as:

<DoubleAnimation ... Storyboard.TargetName="grayscaleEffect" Storyboard.TargetProperty="(local:GrayscaleEffectTest.DesaturationFactor)" />

However the WPF designer throws an initializer exception. The program runs but no animation ever gets triggered when I mouse over...

Anyone have any ideas? I feel confident that WPF should be able to run a pixel shader from within the same project...My project has the pre-build event, and other than renaming as GrayscaleEffect Test and having both projects combined into one, my project should be identical to the tutorial. I've tried a number of other failure approaches, mainly setting Storyboard.TargetProeprty = every damn thing under the sun. Also tried to hack together something to set up the animation in code behind in hopes I could at least walk through with a debugger and try to see what is going on. Obviously, nothing worked :(.

Any help would be greatly appreciated. Cheers.

mwjohnson
  • 661
  • 14
  • 26
  • Is your own `GrayscaleEffectTest` in the namespace `GrayscaleEffect` or have you adjusted the xmlns definition? Is the class public? Is there more information on the error in the output? Have you registered the Dependency Property? Try to set a break point in the class' default constructor and see if the class can be found. – Nico Schertler Oct 04 '13 at 11:02
  • Namespace is correct. The class is public. The constructor is called, and the property is registered. When I get back to my machine on Monday I can post these relevant parts. The error just acts like the binding is incorrect. – mwjohnson Oct 04 '13 at 11:20

1 Answers1

4

Slightly embarrassing but the error was between chair and keyboard. So, the code was working just fine. To maybe help others I'll explain my debugging process, then explain what the problem was.

First I changed the pixel shader to just go from Red to Red and Green. That is:

 result.r = 255;
 result.g = 0;
 result.b = 255 * factor;

Factor is the data variable that gets sent to the graphics card. Once I did this, I noticed that things were kind of working. The transition is a step-function, not a linear interpolation, but colors were changing. Then, I figured pixel color range must be [0 to 1.0]. This gave me the effect I was supposed to be getting.

 result.r = 1.0;
 result.g = 0;
 result.b = 1.0 * factor;

Lastly, I loaded a new penguin picture instead of the original test image I was using and I realized my major mistake. The penguin picture was working just fine and I thought, what the hell?! Then I looked at my test image, which was a black and white image!!! (Dumb, dumb dumb dumb). The shame of having to post this "solution" will hopefully prevent me from making such a mistake again. Thank you for the help @Nico Schertler.

mwjohnson
  • 661
  • 14
  • 26