Mahdi Ghiasi
Mahdi Ghiasi

Reputation: 15301

WritableBitmap high speed drawing on Windows Phone

I'm experimenting with WritableBitmapEx on Windows Phone. I created a simple example, a simple box moving up and down.

There's a draw function which redraws the rectangle each frame:

    int y = 0;
    int dy = 15;
    public void draw()
    {
        y += dy;

        if (y > 500 || y < 0)
            dy = -dy;

        writeableBmp.Clear(System.Windows.Media.Colors.Black);
        writeableBmp.FillRectangle(0, y, 100, y + 100, System.Windows.Media.Colors.Green);
    }

and the Loaded event which creates the Writable bitmap and also calls draw() on each frame.

    WriteableBitmap writeableBmp;
    private async void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
    {
        writeableBmp = BitmapFactory.New((int)ContentPanel.ActualWidth, (int)ContentPanel.ActualHeight);
        image.Source = writeableBmp;
        writeableBmp.GetBitmapContext();
        CompositionTarget.Rendering += CompositionTarget_Rendering;
    }

    private void CompositionTarget_Rendering(object sender, EventArgs e)
    {
        draw();
    }

But this is giving my ~30FPS at most, so the animation is not smooth.

I know that there are some better ways of creating such animations in xaml (creating a rectangle object and animating using xaml animations for example), but there's a game (in another language) that redraws each frame this way, and my ultimate goal is porting that code to Windows Phone. So finding a way to redraw fast enough makes porting really easier.

So, is there a way to improve performance of this? or is there a better way to draw each frame manually, but fast enough (60fps)?

Upvotes: 2

Views: 628

Answers (2)

Mahdi Ghiasi
Mahdi Ghiasi

Reputation: 15301

Thanks to Chubosaurus Software who suggested Microsoft Win2D.

I'm gonna explain a little more about what I did in my case.

There's a control called CanvasAnimatedControl in Win2D, which is specially designed for this purpose.

After getting the package from NuGet and adding it to the page, you can use two events Draw and Update.

Update for the logic, and Draw is where you render the frame.

So, this is the code for the moving rectangle which described in the question:

    private void Page_Loaded(object sender, RoutedEventArgs e)
    {
        cvs.Update += Cvs_Update;
        cvs.Draw += Cvs_Draw;
    }

    int y = 0;
    int dy = 15;
    private void Cvs_Draw(Microsoft.Graphics.Canvas.UI.Xaml.ICanvasAnimatedControl sender, Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedDrawEventArgs args)
    {
        args.DrawingSession.Clear(Windows.UI.Colors.Blue);
        args.DrawingSession.FillRectangle(new Rect(0, y, 100, 100), Windows.UI.Colors.Green);
    }

    private void Cvs_Update(Microsoft.Graphics.Canvas.UI.Xaml.ICanvasAnimatedControl sender, Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedUpdateEventArgs args)
    {
        y += dy;

        if (y > 500 || y < 0)
            dy = -dy;
    }

This code runs great (~60fps) on my phone.

The only downside is, Win2D supports Windows Phone 8.1 and higher. So by using this library, you'll lose Windows Phone 8 compatibility.

Upvotes: 0

Chubosaurus Software
Chubosaurus Software

Reputation: 8161

Try out Microsoft Win2D. You can get it using NuGet or their GitHub here: Microsoft Win2D GitHub. It's basically a wrapper over Direct2D and very simple to use.

Features (Copied from : https://github.com/Microsoft/Win2D/wiki/Features)

Easy-to-use Windows Runtime API

•Available from .NET and C++

•Supports Windows 10, Windows 8.1, and Windows Phone 8.1

Immediate mode 2D graphics rendering with GPU acceleration

•Implemented as a layer on top of Direct2D, DirectImage, and DirectWrite

•Interop to and from underlying types, so you can mix & match Win2D with native D2D

Bitmap graphics

•Load, save, and draw bitmap images

•Render to texture

•Use bitmaps as opacity masks

•Sprite batch API for efficiently drawing large numbers of bitmaps

•Use block compressed bitmap formats to save memory

•Load, save, and draw virtual bitmaps, which can be larger than the maximum GPU texture size and are automatically split into tiles

Vector graphics

•Draw primitive shapes (lines, rectangles, circles, etc.) or arbitrarily complex geometry

•Fill shapes using solid colors, image brushes, or linear and radial gradients

•Draw lines of any width with flexible stroke styles (dotted, dashed, etc.)

•High quality antialiasing

•Rich geometry manipulation (union, intersect, compute point on path, tessellate, etc.)

•Clip drawing to arbitrary geometric regions

•Capture drawing operations in command lists for later replay

•Rasterize ink strokes (from a stylus)

Powerful image processing effects

•Blurs

•Blends

•Color adjustments (brightness, contrast, exposure, highlights & shadows, etc.)

•Filters (convolve, edge detection, emboss, sharpen)

•Lighting

•Custom pixel shaders

•And many more...

Text

•Fully internationalized Unicode text rendering

•Text layouts can be drawn, measured, or hit-tested against

•Convert text outlines to geometry

•Enumerate fonts and query their metrics

•Draw or manipulate individual glyph runs to create custom text layouts

UI integration

•XAML CanvasControl make it easy to get up and running

•Can also create advanced things like owner-draw XAML controls

•XAML CanvasAnimatedControl provides Update/Draw game loop programming model

•XAML CanvasVirtualControl for drawing to very large virtualized surfaces

•Draw onto Windows.UI.Composition drawing surfaces and swapchains

•Can also draw directly to a CoreWindow

•Printing

Upvotes: 3

Related Questions