Archive

Archive for the ‘Useful’ Category

Convert a font to a bitmap and an array of rectangles

June 4th, 2009 3 comments

Recently I’ve been working on adding text to my game. It turns out that you hit a few speedbumps when you attempt to add text output to your OpenGL game on the iPhone:

  • OpenGL ES does not have any support for rendering text. Bummer.
  • If you use Core Graphics or Cocoa Touch to draw your text over the top of an OpenGL view, your performance goes down the tubes.
  • If you resort to using Core Graphics, you can only use the inbuilt iPhone fonts. At the time of writing there does not appear to be any easy way for a developer to install new fonts, or even use a font file included in the app’s bundle.

As far as I was concerned, the only respectable approach for a game was to use OpenGL to render the text. The standard approach is to put all the characters from the font into a texture, then render each character of your text as a textured quad. To do this you need to know the rectangle that each character occupies within the texture. If you had an array of these rectangles, you could compute the offset into the array using the ASCII code of the character itself and easily write a little function to draw a text string,  using the rectangle widths to proportionally-space the characters.

I found a funky free font at dafont.com then started searching for a tool that would produce the texture image and rectangles automatically. There are lots of ad hoc solutions out there but nothing fit the bill exactly.

I wanted my font in a standard bitmapped image format so I could post-process it in Photoshop for gradients, drop-shadows and other effects. This meant that I needed to be able to add user-definable padding space around each character. I also wanted to be able to copy-paste the font characters into the same texture as my other game elements, so my game could avoid a texture-swap operation. And naturally I wanted each character’s bounding rectangle in a form I could easily paste into my Objective C code.

I ended up writing a Windows utility called Font Scraper. It lets you choose a font on your system and produces two files – a nice anti-aliased PNG containing characters in a colour of your choice over a transparent background, and a text file containing the rectangles which is suitable for pasting into a statically-initialized array in C, C++, C# or Objective C. The actual source code that makes use of these resources is left up to you!

Here’s a sample of a suitably game-like font, processed with Font Scraper then tweaked in Photoshop.

I’m aware that proper kerning requires more information than just the bounding rectangle of each character, but I think that’s getting overly complicated for game use. If you need the best-possible rendering, then look at FreeType instead. The rectangles produced by Font Scraper let you display simple proportionally-spaced type in your game.

When you display the string, your code may need to use an appropriate tracking value to increase or decrease the space between characters. For example, if you use an italic or script-like font or you add padding, you will need to reduce your character spacing so that they overlap. Otherwise the characters will appear too far apart.

Unfortunately Font Scraper is for Microsoft Windows only, which I acknowledge might be frustrating when you consider that all iPhone developers have Macs. But I’m a Windows developer and my interest in programming for Apple platforms currently extends only to the iPhone, so now might be the time to check out Bootcamp!

Please leave any comments specific to Font Scraper itself on the Font Scraper download page.

Categories: iPhone, Useful

Reducing your game’s power consumption

May 6th, 2009 Comments off

Battery life is the one major thing I hope improves with the next generation of iPhones and iPod Touches. My wife and I use our Touches almost exclusively for gaming, and nothing sucks juice like my wife playing games. She will typically drain a full battery in one gaming session – we’re talking about less than two hours here.

Don’t tell her, but I’ve just bought her a USB charger for Mother’s Day (no, I’m not married to my mother, but my wife is a mother and she thinks that entitles her to presents from everybody). She can hopefully then just sit in bed plugged in to the mains and stop bugging me to recharge the thing.

So this brings us to the topic of the day. What are the things that we developers can do to reduce battery usage and the carbon footprint of our games? I have three suggestions, and they are all related to frame rate.

1) Use the minimum frame rate that looks good

The iPhone and Touch can update their screens at a maximum of 60 frames a second. So there’s no point going faster than that – give your app little microsleeps. With people, microsleeps can make you feel more refreshed. Conversely, the idea with games is that they will make your screen less refreshed. (Did I just make that lame joke? Slap me!)

Don’t stop there, though. Try running your app at 30 frames a second. If it still looks smooth enough, then cap it there. Your app is now napping for about half the time. Obviously this won’t make the battery last twice as long, but since your game is using the CPU and graphics half as much, this will make a big difference.

2) Don’t draw frames if nothing changed

Suppose we are running our game at 30 FPS. The logic will be updating at this rate, but if nothing is moving or animating then there’s no point compositing the scene again. Give the graphics chip a rest.

3) Use Variable Framerate Technology for Games

The first two suggestions were pretty obvious, but I’m really excited about this one, although its probably only suited to 2D games. Variable Framerate Technology for Games, or VFRG is a cool (IMHO) idea I just came up with.

The basic idea is to dynamically adjust your framerate based on how fast your objects are moving or animating. Some video compression schemes do a similar thing.

Here’s an example:

  • Firstly, work out how smooth you absolutely need your motion to be. Let’s say we are happy to move our objects in 4-pixel jumps.
  • At the top of your game loop, store the current time (accurate to at least milliseconds)
  • After you’ve done all your game logic, find the fastest moving object on screen. Suppose this object is travelling at a speed of 100 pixels per second. Divide this by 4 to get a target rate of 25 FPS.
  • Then find the fastest animating object on screen (assuming a flip-book style of animation). For this example, let’s assume that this object is animating at a speed less than 25FPS, so we won’t consider it. But if it was animating faster, we would increase the target rate accordingly.
  • Divide 1000 by the target rate, to get an update interval of 40 milliseconds in this case.
  • Draw your scene.
  • Using the time you stored earlier and the current time, work out how many milliseconds have passed. Subtract this from 40, and go to sleep for the result (assuming the result is non-negative!).
  • Rinse and repeat.

I’ve got this working with my game at the moment, in conjunction with an upper framerate cap of 30FPS. I have a little overlay display that shows me the number of frames drawn each second, and can see this drop from 30 down to as low as 10 depending on how fast things are moving.

The only area where this all comes unstuck is in responding to user input. For reasons of responsiveness, chances are you don’t want to detect changes in finger position at a rate of 10 times a second or less. You can compensate for this by putting a lower threshold on frame rate (e.g. 15FPS) and perhaps override VFRG and run at your upper rate limit whenever a finger is in contact with the screen.

Now I’m just going to fire up Photoshop and design a funky little green logo for VFRG to stick on my loading screen! I’m only half joking – if you’re smart you can use low battery consumption as a major selling point for your game.

Categories: iPhone, Useful

How to fix OSX mouse acceleration

May 5th, 2009 Comments off

As a long-time Windows developer new to the Mac, it took all of five seconds before I realized something felt horribly wrong with the mouse on OSX. The pointer would consistently stop short of the spot I was aiming for. As my hand slowed down, the pointer slowed down even faster, making those final few pixels a chore to traverse.

Apparently Apple changed this between OS9 and OSX and there is no official way to configure it more to your liking. I find it really quite amazing that they could screw up the fundamental core of the whole Macintosh user experience and leave it completely busted for numerous revisions since.

Oh dear, this isn’t really setting the right tone. Apple-bashing on an iPhone developer’s blog, in only the second post? I can almost feel the mighty fist of Steve Jobs hovering over me, ready to smite my provisioning profile into tiny pieces and banish me back to the bowels of Windows from whence I came.

To be fair, I’m sure there are lots of people who are happy with the mouse acceleration in OSX. But they’re probably all using trackpads.

For those people who are less than happy, rejoice for help is at hand. And it comes from the most benign and benevolent of sources – Microsoft!

Just download the IntelliPoint driver and make your Mac usable. You don’t need to be using a Microsoft mouse. Thankyou thankyou thankyou Bill!

(See this article at TidBITS for a more detailed analysis and some less optimal solutions)

Categories: Useful