Category Archives: Fx

Animated gifs in XAML/C# :)


image

Someone the other day tweeted a link to some very cool animated gifs. I love animated gifs Smile !!

I have always wanted animated gifs in Silverlight/WPF BUT for reasons unknown they never came. They would have been perfect for A LOT of scenarios where creating storyboard animations would have been overkill.

Well turns out WinRT XAML, firmly rooted in Silverlight XAML, also doesn’t have GIF support nor will it probably ever get it. BUT it does have WinRT support and it has access to DirectX & WIC via SharpDx!!

And today on Twitter Jeremiah Morrill tweeted that WIC has support for GIF’s, this intrigued me. Can I build my own support for animated gifs in XAML using DirectX & WIC (via SharpDx) ?!

Challenge is on ……

This is the animated gif I will try to render…

Source : “Savannah Rain” (frommetoyou)

Default XAML/C# metro app project + SharpDx

I created an empty managed metro project and added the necessary SharpDx bits, basically like I have been over the last several posts.

As always this project has a effect renderer that will render to a (Direct2D or Direct3D) surface via a (SwapChainBackgroundPanel or SurfaceImageSource). Again this is what I’ve been doing in all my SharpDx posts to date so just go back to those or the samples if you’ve forgotten Smile

image

 

Animated GIF resource

Now just add the Animated GIF as a content resource to the project. I could load it in via a URI BUT I thought it would be easier to just include it for now .

image

 

Load GIF via WIC

Ok this is where it gets interesting, SharpDx gives us access to WIC from C#. Question is does it have the GIF bits.

As I’ve said many times before SharpDx is a very thin/performant wrapper over C++ libraries (but just to clarify there will always be an overhead to using WIC via this wrapper even thou it is small). This wrapper is a metadata mapping generated api so technically the GIF bits of WIC should have come across. Lets test it out.

Lets instantiate a WIC GIFDecoder that will be used to read the animated GIF resource. The “asset” is simple the internal uri to the gif content.

image

Next when we animate this gif we need to know how many frames to animate. The GIF spec defines this…

image

Now for each frame we want to get the bitmap of that layer and store it for rendering. There is a lot going on in this code BUT in a nutshell an object is created that lets us get at the bytes of data for a particular frame in the gif. (its easy to follow just step through the code , that’s how I learnt

image

As it turns out for GIFS the first layer normally has the entire bitmap contents of the GIF and all the other frames above that contain delta information.. Also the ‘delta’ frames are all offseted so we need to get the offset (left,top) of those frames and store them for rendering of that frame later on..

image

 

So assuming that SharpDx’s GIF WIC works fine that’s basically all we need information wise.. We just need a way to store those frames and render them to the UI.

…. hello SpriteBatch Smile

SpriteBatch

The best way to render a series of textures in the graphics world is via a spritebatch. Lets create a very very dirty one that will serve our purposes ..

I’m not going to go into too much detail of how this dirty spritebatch works, it’s not in the truest sense a spritebatch BUT it will do for now..

image

This spritebatch will keep a cache of the GIFs frames that I will render on a DirectX Surface. I’ve defined 2 lists to store the static frames ( 0 ) and the rotating frames ( 1 – 7 )

image

I’ve created a way to add sprites (frames) to my spritebatch via the methods

1. DrawAlways  – sprites that will always get rendered on each loop of the rendering pipeline eg. frame 0 of the aimated gif

2. DrawRotating – sprites that will rotate there appearance with each loop of the rendering pipeline eg. frames 1 to 7 of the animated gif

image

 

These methods are called when we are decoding our GIF (the section prior to this outlined this process)

image

The sprite batch, as expected, has the ability to render itself and all it’s sprites. In my example it will render on a D2D surface and will use the much loved BitmapEffect to render the layer Smile .

Also note that the offset(_texturesRotatedOffset) for the layer needs to be rendered for the 1-7 frames

image

Now if you don’t understand the above just step through the code, it will all make sense..

Does this all work ?!

Does SharpDx’s support for WIC GIF’s work for animated gifs ?!

 

Running the demo

 

Here’s some awesome gifs from a very cool site

 

Here’s the metro xaml/c# demo running one of those animated gifs. Note that the framerate is low because of the simultaneous video recording going on. Without it it runs buttery smooth at 65-70fps. Smile 

 

 

Sample code

 

image

 

Conclusion

 

I started out this experiment fully expecting it NOT to work… I was so surprised that it actually did Smile . Animated gifs in a XAML managed metro app!!! Damn!!

XAML/WinRT + DirectX/WIC (via SharpDx) is turning into a killer combination of features for building pretty amazing new experiences. I’m only now getting familiar with the frameworks, I can’t wait to see what I’ll be creating a month from now!

I’m loving XAML/DirectX …

Using FX effects in your managed metro apps


image

In the WPF and Silverlight “desktop” worlds we have the luxury of being able to use shader effects (fx) in our apps, this infrastructure is not available in the “Windows Phone” or “WinRT XAML/C#” worlds.

However thanks to SharpDx and the improved hlsl graphics features in VS11 we can now easily use these same fx effects. Let me show you how I consume fx files in my XAML/C# WinRT apps…

FX to CSO (HLSL)

Our goal is to turn the FX file into something we can use, and if you’ve followed my previous posts the best option we have in DX11.1 world is a custom shader (cso) and thanks to SharpDx we can do that Smile … So lets try to turn this fx file into a cso

Now the HLSL editor and the compile shader features in Visual Studio 11 shader works only in a DirectX/Cx project.

So first step is to create a DirectX/Cx project to host our FX files. In my case I created a Direct3D Application called “D3DFXConverter

image

image

Then copy across the fx files you want to convert into this new project, in my example I’m going to convert a “Pixelate.fx” . I took this fx file from the “wpf pixel shaders libarary” project on codeplex.

image

Now rename the “fx” extension to “hlsl”

image

We now get all the editor experience of an hlsl file for our fx file.

image

What we want to do is try to compile this as a pixelshader, so go to the compiler setting and set the “Shader Model” to “Shader Model 4 Level 9_1 (/4_0_level_9_1)” and “Shader Type” to “Pixel Shader (/ps)” . note that the fx file in WPF is a shader model 2 or 3.

image

Now if we try to compile the D2DFXConverter you’ll notice some errors

image

What these errors mean is that the hlsl code is not compliant with the shader model we’ve chosen, we need to make some minor alterations to the hlsl ..

The changes are very minor, I’ve actually converted several fx shaders and in ALL cases the following is all I needed to change

 

1. Wrap constants inside a cbuffer 

 

Before:

image

After :

image

 

2. Alter the Sampler Input

 

Before :

image

After :

image

 

3. Alter the interface of the main entry point to the shader

 

Before :

image

 

After :

image

 

4. Alter the text2D call

 

Before :

image

After :

image

 

Now if you compile the project ….

image

And if you check out the output directory for the successful build you’ll find the binary of the compiled custom shader (cso).

image

 

We’ve successfully converted our fx to a cso ready for consumption in our managed metro SharpDx app.

 

Consuming the CSO as a custom effect via SharpDx

To speed things up I’m going to reuse the D2DCustomPixelShaderEffect project I created a few posts ago, “Custom Effects – Ripple Effect (Pixel Shader)” .

Copy across the cso into the project …

image

Create a C# custom effect wrapper around the cso much like what we did in the above mentioned post for the RippleEffect. Basically I just copied the RippleEffect.cs and renamed it to PixelateEffect.cs and changed some of the internals, it was pretty obvious what needed to be changed. If you get confused just re-read the above mentioned post Smile

image

And the last step is to alter the EffectRenderer.cs to call the newly created custom effect PixelateEffect.cs .

The changes were simple, register the PixelEffect and wire up some gestures to alter the shaders 2 properties “HorizontalPixelCounts”, “VerticalPixelCounts”.

Again I won’t explain how to do that as it was covered in my earlier “custom effects” post.

image

 

Video of the demo

 

 

The frame rate is low and fluctuates quite a bit because of the video recording going on simultaneously.

 

Demo code

 

image

 

Conclusion

 

I’ve successfully converted 14 of the FX files from the WPF/SL codeplex project , the ones that weren’t so easy to convert I will cover in future posts.

SharpDx is turning into a great framework that fills a big hole in the XAML/C# stack.

As for the performance of SharpDx, the shader demo’s I’ve been doing consistently achieve frame rates in the 60+ range. It’s definitely performant  …

I look forward to seeing what others create on top of SharpDx!