Are your UWP Win2D offscreen bitmaps dull…?

Mine were until I discovered new COMMON SENSE!®

Image result for common sense

TL;DR: I did something stupid and realised my mistake – what follows is mainly for future reference and for those that are making the same mistake.

Win2D is great! So is the concept of UWP and the Windows Store. It means you can write a game for the Windows Store (for Windows 10), and with some minimal work, it can run on the XBox One (since that’s based on Windows 10 too).

So, I set about converting Pac-Man that I’d written in TypeScript (play it here), into C# and publishing it on the Windows Store.

Here’s the opening screen – note the text looks naff and the sprites have lost their intentionally pixelly look:

… compared to the TypeScript version:

I spent quite some time trying to fix this – thinking it was some nuance of Win2D and offscreen bitmaps. I didn’t get anywhere, so I set out to create a small reproducible project that I could use in a StackOverflow question (as an aside, I often find that just typing a StackOverflow question creates enough clarity of the problem that the answer just magically appears – as was the case here!). So with just a few lines of code, I had this monstrosity:

Here’s the relevant bit of the drawing code:

        void onCanvasDraw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventArgs args)
{
args.DrawingSession.Transform = _scale;

args.DrawingSession.Clear(Colors.Aquamarine);

using (var offscreenSession = _offscreenCanvas.CreateDrawingSession())
{
offscreenSession.Clear(Colors.Aquamarine);

offscreenSession.DrawText(Text, 0, 0, Colors.Red, _ctf);
offscreenSession.DrawLine(new Vector2(0,0), new Vector2(100,10), Colors.Black);
}

args.DrawingSession.DrawImage(_offscreenCanvas, 0,0);

args.DrawingSession.DrawText(Text, 0, 20, Colors.Red, _ctf);
args.DrawingSession.DrawLine(new Vector2(0, 20), new Vector2(100, 30), Colors.Black);
}

Even though I know how tolerant the StackOverflow community is (</sarcasm>), for completeness and to show that I did my homework before asking, I tried the same drawing (DrawImage) with multiple overloads and included a screen-shot for each.

So, I’m about 45 minutes into writing the StackOverflow question, and then it struck me:

I’m only scaling the main drawing session; what I really wanted to do is scale the off-screen drawing session too: in Win2D, when drawing, each instruction is queued and then blitted to the GPU asynchronously, so my flow is:

1. Scale up the main DrawingSession to make things looks bigger
2. Create an offscreen DrawingSession
3. Draw text and a line to the offscreen session
4. Draw the offscreen session to the main drawing session
5. Draw text and a line to the main session

Essentially, the offscreen canvas created in step 2 has its instructions drawn at 1x scale but blitted at 4x scale, rather than the instructions being drawn at 4x scale and blitted at 1x scale.

Here’s the corrected code:

        void onCanvasDraw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventArgs args)
{
args.DrawingSession.Clear(Colors.Aquamarine);

using (var offscreenSession = _offscreenCanvas.CreateDrawingSession())
{
offscreenSession.Transform = _scale;

offscreenSession.Clear(Colors.Aquamarine);

offscreenSession.DrawText(Text, 0, 0, Colors.Red, _ctf);
offscreenSession.DrawLine(new Vector2(0,0), new Vector2(100,10), Colors.Black);
}

args.DrawingSession.DrawImage(_offscreenCanvas, 0,0);

args.DrawingSession.Transform = _scale;

args.DrawingSession.DrawText(Text, 0, 20, Colors.Red, _ctf);
args.DrawingSession.DrawLine(new Vector2(0, 20), new Vector2(100, 30), Colors.Black);
}

… which produces this beautiful output:

Once common sense prevailed, I discarded the StackOverflow question, but put up this post for anyone who might see similar issues in their Win2D app.

🙏🙏🙏

Since you've made it this far, sharing this article on your favorite social media network would be highly appreciated 💖! For feedback, please 🦋 ping me on Bluesky! 🦋

Leave a comment

Comments are moderated, so there may be a short delays before you see it.

Published