Category Archives: XNA

Lightning (SharpDx/XAML/C#/WinRT)


image

The other day I came across a very cool XNA demo, Michael Hoffman’s ‘How to Generate Shockingly Good 2D Lightning Effects’ .

I needed to redo this in my current favourite UI stack XAML/SharpDx/C# .

1 hour later i was done, thanks to the SharpDx toolkit it’s a breeze to bring across demos like this.

Here is the video of the Win8 lightning demo app :

 

Technologies used

1. SharpDx Toolkit – this is built ontop of SharpDx and it helps abstract out some of the hard concepts that can confuse new starters in the directx space. It shares a lot of ideas with XNA (Game/GraphicsDevice/Content Pipeline etc).

2. XAML – Using a Swap Chain Background Panel to render the Dx content

3. C#

4. WinRT – this is a modern app, uses the new API’s from the Windows team.

 

Interesting Techniques

1. Making SpriteFonts – I used MakeSpriteFont from the DirectX Toolkit to create the Lightning Font used in the Lightning Text.

2. SpriteFont to Point– the demo makes use of SpriteFonts, and getting the point information from a sprite and rendering each point as a lightning position. There are about 1000+ points created from the word “Lightning”, and its these points that are rendered in 3D using the Lightning technique.

3. 2 render targets to render the Lightning Text. The demo shows creating 2 render targets (currentFrame, lastFrame) that are used to push the 1000+ points and lightning textures on. We then push the currentFrame into the backbuffer of the device for rendering..

 

Sample Code

can be found on Skydrive

 

Final words …

I highly recommend looking at some of the techniques employed in this demo. Its a pretty cool lightning effect Michael came up with..

Have fun …

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!

A mesmerizing burst of circles (Silverlight 5 & XNA)


image

Let’s give some love to Silverlight and in particular Silverlight 5’s 3DApi, which happens to be XNA.

I want to draw something cool on this XNA DrawingSurface BUT then also replicate it in DirectX. I’ve honestly never done a DirectX/C++ project so this will be very risky and a completely new experience for me….

This post will concentrate on the Silverlight 5 part, and the next post will be the DirectX part. Smile

The IDEA

I want to experiment mixing UIElement’s that sit in the visual tree and sprites that sit in the XNA “DrawingSurface” . Below is a very simplified pic of how the UI will be layered…

image

  • XAML UIElements sitting in the top layer (Retained Mode UIElements)

     

    1. As the user moves the mouse around the screen I will draw a nice ‘UserControl’ that gives us the x,y position of the mouse in a visual way.
    2. This UserControl will also have a “Dot” to represent the exact mouse location

image

  • “DrawingSurface” Sprites  (Immediate Mode Sprites)

     

    1. A bunch of purple sprites will follow the mouse around the screen
    2. When the user clicks someone on the screen a bunch of green sprites will burst at that location
    3. The circles fade over time
    4. The circles move with random velocities, in random directions from the mouse-point

image

The Top Layer

What we want is a special shape that follows the cursor around as you move the mouse. And this shape needs to hold the x,y position of the mouse. Also this is all rendered in the XAML’s visual tree.

Blend ships with some awesome shapes, one of those is exactly what we need

image

I cannot begin to tell you how useful the shapes are in Blend, and I really hope that a lot of these blend libraries are available in WinRT-XAML apps in beta.

Silverlight and Blend are mature, WinRT isn’t and that is my main concern with WinRT. I really hope we don’t need to wait 3 more years for WinRT to reach the maturity of Silverlight 5 and Blend 4 Sad smile

Basically I am going to use this “Rectangular Callout”, add it to the visual tree then move it around as the cursor moves. I’m also going to add a small dot to signify the center of the mouse-point.

image

To animate these 2 controls (Ellipse, Callout) I am going to use a storyboard, which has some great easing rules built into it which will allow me to give it a nice eased motion.

image

The code that actually wires up the MouseMove and triggers the storyboard is self-contained in a class I called “CalloutCursor.cs” . I won’t go into the details of how that works, just know that it executes the storyboard, plugging in values where the mouse currently is. It also has the calculations to make sure the pointy bit of the callout is in the correct orientation.

image

So this is what the TOP layer looks like when all the above pieces are running … Pretty simple, and that’s the beauty of Silverlight & Blend, it’s so easy to do stuff like this Smile (once you know your way around that is) ..

 

 

The Bottom Layer

This is where it get’s interesting … We are going to use the XNA bits in Silverlight 5 to draw a burst of circles where the current mouse position is.

First step is to place the XNA surface in the XAML where we will render our sprites.

image

Notice that we wired up the “Draw” event of the DrawingSurface. This triggers 60 times a second and it’s during these events that we draw the sprites on the surface.

For those that haven’t written much XNA code before there is this concept of a “scene”, we wrap the XNA animation inside of this scene. I have created a scene class that wraps all the logic of rendering the sprites when the mouse moves..

 

image

The actual SceneBurst class is here : Scene.Burst.cs

In the scene there is this concept of a sprite, and in my case I created a sprite called “BurstingCircles”, and as the name suggests it wraps up all the logic to draw the sprites on the surface.

I create 2 instances of these “BurstingCircles” sprites, one follows the mouse around and the other appears where the mouse is clicked

image

image

And these sprites are actually drawn in the “DRAW” method..

image

 

Now the actual “BurstingCircles” sprites code is here if your interested :

Sprite.BurstingCircles.cs

The BurstingCircles sprite is made up of 100 circles that randomly spray in 360 degree directions from a central point. These 100 circles appear one after the other, not all in one go.

image

Each circle is made up of 2 triangle primitives which is made up of 6 vertexes (each triangle is made up of 3 vertex).

image

Notice that I use a VertexPositionTexture to represent each vertex, the operative word here is “texture”. We are going to use a texture to draw on each triangle.

The texture that we are going to use is dynamically created. This is pretty cool … Silverlights WriteableBitmap lets us take a snap of a visual element and create a bitmap out of it, it is this bitmap that we are going to use as the texture Smile

image 

The texture I dynamically create is based on an ellipse and i create it with a dynamically defined colour. You can do some damn interesting things when we mix the power of Silverlight’’s mature framework and the XNA immediate mode graphics pipeline.

The draw routine is pretty straight forward, generate the 100 circles over time and re-calculate the velocity information during each cycle. This is pretty standard when dealing with pipeline graphics rendering … It’s really low level, to the metal … love it Smile

I should briefly mention that we use simple (not complex) pixel & vertex shader’s. There’s nothing special about them, their purpose is to get pixels onto the surface and draw non-complex vertexes of the triangles.. No morphing of complex pixel effects for us yet !!!

image

 

So this is what the bottom layer looks like, it’s pretty simple once you get the hang of how the XNA pipeline works and how to draw in this pipeline..

 

The Install Experience

The 3DAPI (XNA) bits require GPU and Elevated Trust. So getting the user to give you these permissions is tricky.

I’ve gone with some simple graphics and I won’t go into how I did this as it’s pretty common knowledge how to wire up these setup/install screens, if you really want to see code just download the sample Smile

This is what the user sees to ask for their permission to run the GPU demo and to install the app as an “out of browser” app. I chose to make this OOB because it’s easier to give this elevated trust than keep it in browser and getting the user to go into the dialogs and give manual permission to the Graphics card.

image

These are the Silverlight standard dialogs explaining that we want “elevated trust” for our app …

image

This is what the APP looks like in browser once it is installed ..

image

This is what the APP looks like when it is running Out Of Browser, having been manually installed by the user.

image

 

 

The Result

Here is what it looks like when everything is pulled together

 

Or try out the demo, you need Silverlight 5 to run it Smile

image

 

image

 

The Silverlight 5 XNA Api’s are damn awesome, the CPU hit on this is less than 5% and memory footprint is small. My mind is exploding with ideas around 3D animations to compliment Visual Tree UI elements.

I really hope that every developer out there that has invested time to learn Silverlight/WPF and/or XAML, takes the time to learn XNA and/or graphics pipeline immediate mode programming. It seriously opens up your mind in a whole new direction Smile

The next step is to reproduce this in DirectX-WinRT .. off to do just that  … stay tuned!!!