Sunday, March 27, 2011

A follow-on to "IC Game Design – A Key Tip for Success"

Michael Quandt posted a good tip about entering your WP7 app into Imagine Cup Game Design: basically, don't put your game in the Games Hub! The emulator doesn't include the Games Hub, which means when your .xap file gets deployed to the emulator, your game won't be accessible.

But how to actually fix this? Luckily, it's a simple change: in your project, find the WMAppManifest.xml file and change Genre="Apps.Games" to Genre="Apps.Normal". Now when you deploy your .xap to the emulator, it'll show up in the app list rather than the Games Hub.

Thursday, March 3, 2011

High Quality Dithering for Windows Phone 7

In my last post I showed how to use a 32bpp backbuffer to prevent banding in XNA games. But as it turns out, the WP7 hardware specifications only specify a 16-bit LCD at minimum - and that there are devices out there which only have a 16-bit LCD. (I've heard, but have not been able to confirm, that the Samsung devices suffer especially from this).

In that case, if a device only has an LCD capable of 16bpp, setting a 32bpp backbuffer isn't going to help. Instead, you need to dither your images, which will reduce the bit-depth to 16bpp but in a way which reduces visible banding.

I stumbled across this blog post "Photoshop Action for Windows Phone Dithering", which provides a photoshop script to dither images. It gets the job done, but I noticed that it produces a fairly low-quality dither - the end result is very grainy to my eyes.

A while back when I worked on Metropolitan Melbourne, I wrote my own little tool to dither images because WM6.5 only supported 16-bit colour graphics and I couldn't find any other simple tools for high-quality dithering. My tool is called ReduceBitDepthCPP, and takes an input 24-bit/32-bit image in .png or .bmp format, and reduces it to 16-bit (R5G6B5) colour using the Floyd-Steinberg algorithm. The Floyd-Steinberg algorithm eliminates banding while minimising quantisation error. Here's a comparison picture:


As expected, the undithered gradient has extreme banding. The "Photoshop" image was produced by using the script mentioned earlier. If you look closely, the Photoshop image does get rid of banding but also introduces a lot of noise - which makes the image very grainy.

On the top right is the Floyd-Steinberg algorithm produced by my tool, ReduceBitDepthCPP. It also eliminates banding but does so in a way that doesn't introduce a lot of noise, and the end result looks very close to the original.

You can download ReduceBitDepthCPP below, with source as well. It's free for any use, and the source code is distributed under the MIT license.


Instructions

ReduceBitDepthCPP is a command-line tool, which makes it easier to integrate into your build. To use it:
  1. Extract the files somewhere (eg. C:\Temp\ReduceBitDepth\)
  2. Open up a command prompt by pressing [win]+[r] and typing in "cmd"
  3. Navigate to the directory where you extracted the files
  4. Run ReduceBitDepthCPP.exe using the following syntax:
    ReduceBitDepthCPP.exe infile outfile
Sample:

ReduceBitDepthCPP.exe C:\Temp\meow_orig.png C:\Temp\meow_dithered.png

If you found this useful, don't forget to follow me on Twitter, and check out some of the stuff on my website!

Happy coding!