Mailing List

Archive for August, 2009


Texture Atlases and Bitmap Fonts
Thursday, August 27th, 2009

I realise that I haven’t been posting a lot of text posts about the new game’s progress since I started posting video blogs (or “vlogs” as the kids call them these days). However, I spent the last two days working on some code that doesn’t really feel appropriate for the vlog, so I thought I’d write about it here. Hooray!

I decided to take a bit of a break from gameplay coding and instead focus on some performance stuff. I want the game to run at 60 fps, even on a 1st gen iPod touch, if I can. On Monday I took at look at the frame rate and it was around 40 fps on my iPod. I booted up Shark (a performance analysis tool for Mac OS X and iPhone) and took at look at what was slowing things down. The game’s not doing a whole lot right now, so there’s no reason it shouldn’t be running at 60 Hz. Plus, the physics engine uses a fixed time-step, so the frame rate needs to maintain 60 fps as much as possible to keep the physics in check.

What Shark told me was that my font rendering was taking up about 40% of my frame time! At 40 fps, each frame is taking about 25 ms, which means about 10 ms was devoted to rendering text on the screen! That’s insane! Especially since I was rendering two strings: “Score: 5″ and “Debug”.

The code I was using for text rendering is pretty inefficient, and I had always intended on replacing it. I just hadn’t realised how inefficient it was. The code was from the old CrashLander example app that Apple pulled off the dev site a long time ago (because of stuff like this). It was using CoreGraphics to dynamically render the text out to a texture, which was then used as an alpha mask to render the text to the screen. This was all extremely slow.

So, it looked like I needed to implement my bitmap font system sooner than I had planned. A bitmap font is a fast way of drawing text, but that has some drawbacks. A bitmap font is created by rendering out the character of a font at a particular size to a texture (the big downside of using a bitmap font is that it doesn’t scale well, since the font is rendered out at a specific size). This is all done on your computer. You end up with a texture atlas (more on that in a minute) that contains all the characters you want to be able to render on one big texture (or several small textures, if you want).

So what’s a texture atlas, you ask? A texture atlas is when you cram a bunch of smaller textures into one big texture. You end up with one large texture (that has power of 2 dimensions for optimal video memory usage) that has all the smaller textures laid out next to each other. A texture atlas also requires a data file that describes the atlas. The data file will contain information on where each sub-texture lives in the atlas. This data can be used in the game to determine which small portion of the atlas to draw onto a polygon that gets drawn to the screen.

The reason this is done is that every time OpenGL has to change which texture it’s currently drawing with, it takes time. So if you draw, say, 100 different little sprites every frame, and each one is in it’s own texture, OpenGL has to change which texture it’s using 100 times. This can lead to a lot of inefficiency and can actually significantly slow your rendering code. But if you put those 100 sprites into one big texture atlas, then OpenGL doesn’t need to swap textures, it just changes the coordinates of the current texture each time.

So for texture atlases to really work, you want sprites that need to be drawn together grouped into the same atlas. You lose all the efficiency gains if you have two atlases and every alternating draw call is in a different atlas. In huge 3D games, this usually means putting all of a character model’s textures in one atlas (so a soldier gets his uniform textures, facial textures, etc all put into one atlas), since the character is rendered all at once. In a small game like mine, I can generally fit all the sprites I need into one texture atlas.

Finally, the other big benefit of texture atlases is that they can be more video memory efficient. You can do a much better job of fitting non-power of 2 textures into one giant power of 2 atlas, than padding out each smaller texture to a power of 2. This means you’ll have more VRAM available for other things.

Building a texture atlas creation and rendering system was the first thing I did this week. I actually use a Python tool that my friend Noel pointed me to, to do the packing of the texture:

  • AtlasGen (atlasgen.svn.sourceforge.net)

Then I parse the atlas data into a plist which I can load at runtime. Writing all this code would allow me to speed up the rendering of my sprites in general, but I could reuse the rendering code for my font rendering system.

So, back to the bitmap font system. I considered building my own bitmap font generation system, but that seemed silly. I poked around on the internet looking for Mac tools available, but couldn’t find any. Then Noel pointed me at some tools for Windows. Earlier this year I bought a copy of VMWare Fusion, so I can run Windows programs on my Mac. Hooray, it’s coming in handy! I did some more poking around and found this tool, which I quite like:

One of the nice things about this tool is that it seems to handle kerning (the distance between adjacent characters) quite nicely, even for italic fonts. This tool allows me to export a font texture and also generates the data file for me. Then it was just a matter of parsing the data file in the game and using the existing texture atlas code I had already written. Finally, to render the string, it’s just a matter of iterating over the string to render, grab each character, look up into the font data, and draw the appropriate part of the texture onto an appropriately sized quad.

The net result of this? My frame rate is holding at 60fps most of the time now. I still get some spikes, but it’s good enough for now. Shark tells me that my font rendering now takes about 9% of my frame time. On a 16.7 ms frame (60 Hz), that’s about 1.5 ms. And digging further into the profile, it looks like a significant portion of that time is actually spent inside NSString operations. The actual rendering is about half the time. That’s a huge reduction in render time! On an iPhone 3GS, this thing will fly!

So things are looking good. The frame rate is back to a point where it matches the physics system, which means I can do some proper tuning of the physics now. Thanks for sticking with me through such a technical post. Look for another video blog episode in the next day or two.

Owen

Fun with [redacted]
Friday, August 21st, 2009

So the whole [redacted] thing is a joke in the Mac/iPhone dev community. Whenever someone wants to talk about something covered under NDA by Apple, they put [redacted] in its place. Hehe

I thought I’d write up a quick post on my experiences upgrading to a pre-release build of the new Mac OS X, Snow Leopard. We were given pre-release copies of the OS and WWDC this year. Because the details of the OS are covered by NDA, I won’t talk about any of the cool new stuff I’ve been playing with (I’m such a tease). But I when I started thinking about doing the install, I couldn’t find any good resources on how to do it properly.

This all started because of a bug in Xcode. There’s a fun bug that sometimes crops up when you assign different project names to different build configs. I do this so that I can call my debug build “DappleDebug” and my release build “DappleRelease”. This is useful when you’ve got 4 different builds on your test device and you’re trying to remember which is which. At any rate, when OS 3.0 came out, something broke in Xcode and now sometimes when you change the project name, Xcode tries to use something else. Very annoying!

I had found a work around which involves duplicating your build config, deleting the old one, then renaming the duplicate. It makes the problem go away temporarily (but it always comes back at some point!) Yesterday this problem cropped up again, except this time my work-around didn’t work, for some reason. The result being that I couldn’t deploy my build to my device at all! After a few hours of trying to get things to work (and rebooting, etc), I said “Screw it! I’m installing Snow Leopard!”

My biggest concern with updating to a pre-release OS was preserving my data, so I spent a couple of hours backing up all my important data to my server and offsite repo. My next biggest concern was making sure that all my user settings trasnfered over. This was the part I couldn’t find any information on. The installation instructions didn’t mention anything, so I assumed it would “just work”. Ha!

I started the installation process off the disk from WWDC (the dev site has a newer release, but it’s a massive download, so I figured I’d just use software updates to update after installing). After it installed, it asked me to create a user account. Huh? Where’s my old one? Hmmm…bizarre. Maybe it will pull it across when I create a new account? Maybe I’d better call it the same thing as the old one. What was the old one called? Crap! I can’t remember!

I created a username that I thought was what I had before. Oops. Wrong. It created a new user. So now I’m in a new OS with no data. Crap! Trying to avoid panicking, I decided to poke around the hard drive and look for my files. Ok, they were still there in the Users folder. Ohhhhh, that’s what my username was. Hmmm…

The installation instructions had mentioned using a tool called “Migration Assistant” to move old user profiles over. I booted that up and discovered that this tool only works to retrieve a user account from another computer or partition, not the same computer and drive.

Trying not to panick, I decided I’d run software update to get the latest build of the OS. Hmmm…and again…and again…and again…and again. Maybe I should have just bit the bullet and downloaded the newest build to start with. 4 or 5 or 10 updates (I lost count) later (each one 500MB to 1.5GB), I ran out of updates.

At this point, I was running out of options. I figured, what the hell, I might as well try creating a new user with the same name as the old one. Maybe that will work? I tried it and it did! When it detected a user folder of the same name, it asked me if I wanted to restore that user. Success!

So now I’m running the new OS, with all my old data intact. Hooray! So while it wasn’t that hard to get working, it certainly feels that way while you’re in the middle of it thinking all your data is gone.

To summarize, the lessons from this story are the following:

  • If you’re going to install a pre-release build, just download the latest gigantic build off the dev site and start with that.
  • Go into the System Prefs -> User Accounts and record your user account info so that you can just restore it properly the first time.

Other than those two mistakes, things went smoothly. So if you’re going to do this at home, good luck to you!

Owen

Video Blog Episode 5
Wednesday, August 19th, 2009

Yes, it’s that time again: time for another entry in the video blog! Episode 5 is very exciting because it features gameplay footage! Disclaimer: this is not final art, nor is it final behaviour. This is the game in an extremely early state and the final game might look and behave quite differently than it does now.

The main thing I wanted to show in-game is the debug rendering code I wrote (based on the Box2D example code) to draw the state of the physics world. It’s been very helpful having this available for debugging some of the weird physics bugs I encountered during the integration of the physics engine.

Have a gander:

Owen

Video Blog Episode 4
Thursday, August 13th, 2009

Yes, the Streaming Colour Video Blog, Episode 4 is now available from your local YouTube! In this episode I talk a little bit about the ongoing integration of the physics engine, as well as changes to the control scheme based on some early feedback. Check it out:

Owen

No Aug Toronto iPhone Dev Meetup
Tuesday, August 11th, 2009

After speaking with James we’ve decided to cancel the August meet-up for the Toronto Mobile Developer and Designer group. Regular monthly meetings should resume in September. We’re hoping to do it close to the Toronto FITC (Flash in the Can) event. More details on that closer to the date.

However, if you’re looking for some good iPhone times this week, come on out to the IGDA meeting this Thursday evening for discussion on iPhone games development. It’s sure to be swell! You can find full details in my previous blog entry, and on the IGDA site.

Owen

Home | News | Games | Store | Press | Blog | About | Contact
©2008 Streaming Colour Studios

Powered by WordPress with Streaming Colour Studios theme designed by Chris Picheca.
Entries and comments feeds.