bitmap fonts in iminib3d

BlitzMax Forums/MiniB3D Module/bitmap fonts in iminib3d

jhocking(Posted 2010) [#1]
Part of any game is of course displaying text, so one of the first things I did when I started my game was write code for handling bitmap fonts. Well for the past several hours I'd been making some extremely useful adjustments and additions to my code (now I can center and right justify the text) and it occurred to me that I should share the code here.

Mind you, this is far from a completely robust bitmap font system, because it's currently pretty sensitive to exactly how the camera is setup in my game. Still, this would get you 95% of the way there as far as implementing text in your games. Plus the code I wrote today for aligning text looks extremely kludgy, so I would love to have someone improve my code and then post the improved version here.

Anyway, here's what I did...

The first step is of course to get the font that you'll be using. Bitmap fonts are basically an image with all the letters in a grid to cut up and display; here's a free online tool to generate bitmap fonts http://www.boxofrats.com/content/bitmap-font-machine-released

This tool generates both an image to display and an xml file with information about all the characters in the image. For example, I used it to generate these files:



The next steps are to setup everything in XCode for the project to run. First create an empty iminib3d project as simon's instructions in iminib3d.h explain. Add the bitmap font image and xml files to the project. Now you have to add the library for reading XML files. XCode comes with libxml for working with XML files in C++. There are two things to do for linking that:

Put $(SDKROOT)/usr/include/libxml2/ in the target's header search path. You right-click on the target and select Get Info, and then scroll down to Header Search Paths to paste in the text.

Add the libxml framework to the target. XCode comes with multiple versions of the library. Any should do, but the framework I use is libxml2.2.dylib



Alright, now add a new code file to the project and name the file BitmapText.mm (BitmapText.h is added too when you do that.) Paste the following code into those documents:

BitmapText.h


BitmapText.mm


I'm not going to explain every thing in the code, hopefully you can figure most of it out by reading the code, but there are a couple important and/or interesting things I want to point out:

simon added a few features into iminib3d that are not part of Blitz3D but are very helpful for doing bitmap fonts. One of those features is SpriteRenderMode(2), to batch render sprites sharing a texture. Whereas every sprite in Blitz3D is it's own surface, really killing performance, using SpriteRenderMode(2) is a single-surface sprite system.

He also added a file command called ResourceFilePath. That is an iPhone specific command, which locates files in the somewhat arcane iPhone file system. That command isn't necessary for loading graphics files, but it saved my bacon when loading XML files.

The destructor is pretty ridiculous; it doesn't do anything! You would want to release all the resources in memory; I just haven't gotten around to programming that in my own project. (Is that necessary in this case though? All the sprites and pivots and what not will be released when you call ClearWorld, so I just don't know if the vector and associative map need to be released in the destructor.)

Oh, and in the Position method the X and Y positions are swapped because the camera was rotated 90 degrees for the iPhone screen. If you don't rotate the camera in order to have a portrait view, then obviously you'll want to swap the X and Y positions.



Finally, include BitmapText.h in Game.h and then put this test code into Game.mm in order to display some text:



Beaker(Posted 2010) [#2]
I've had some success getting this working with Fontext (in my sig).

How it works: converts the fontext ini file to an xml file similar to that posted above. (Don't forget to rename your font image from ".png" to ".fnt" after you use this tool).

You need this BlitzMax file:


You will need this. Save as "ini.bmx". (originally by Leigh Bowers - slightly adapted, I think):


You will also need to build Bruceys libxml module, available here.

It all seems to work quite nicely although I'm sure it can be improved. If you make any nice amendments please post them here.

Thanks to jhocking for the inspiration and code in the original post.


jhocking(Posted 2010) [#3]
Fontext is a great tool, I bought it back when you first released it! The main reason I used that free online tool this time is because I do most of my developing on a Mac now.

Incidentally, for anyone who uses the code I posted, note that I've already adjusted it slightly in my own project (eg. the camera is now a static value I pass in at initialization, instead of with each call to the constructor,) plus I've noticed a bug where the text behaves differently in the simulator and on device (I never noticed before because I only tested it in the simulator; it works fine there, but there are issues on device.)


Also, I completely forgot that I renamed the font image "aliased.fnt" so thanks for pointing that out. I rename all my 2D display images .gui or .fnt so they won't have mipmapping.


jhocking(Posted 2010) [#4]
I've figured out the bug that was causing the text to display incorrectly on device. There seems to be a memory issue that was being triggered by this chunk in ChangeText:
char buffer[3];
sprintf(buffer, "%i", posX);
charSprites.at(count)->NameEntity(buffer);


After those lines the value of "count" was sometimes reset to 0 (in a predictable way that's somewhat roundabout to explain.) I don't know exactly what that was doing to the memory, but the problem went away when I switched that to use the convenience function simon provides in iminib3d:
charSprites.at(count)->NameEntity(ToString(posX));



jhocking(Posted 2010) [#5]
I just programmed this destructor, will this cause a memory leak?

BitmapText::~BitmapText() {
	for (int i = 0; i < charSprites.size(); i++) {
		charSprites.at(i)->FreeEntity();
	}
	handle->FreeEntity();
}


In particular, I don't know if I need to free the charSprites vector somehow; I loop through it to free all the sprites stored in the vector, but do I need to release the vector itself? I'm pretty new to C++ so I'm paranoid about this.


ADDITION: The line at the bottom of this page says "if you didn't new it, don't delete it"
http://bytes.com/topic/c/answers/138376-deleteing-objects-std-vector

Is that correct?


Robert Cummings(Posted 2010) [#6]
Thats correct... at least its what I do. Btw apple dont check your game for leaks, it can piss memory if it wants so long as it behaves and never crashes or seemingly degrades.

When the app ends the sandbox will clean up.

As a rule I don't use those but just have an start and end function for every section of the game (load and unload) and do it manually. I know I'm not doing it right but its something my brain's happy and predictable with :P


jhocking(Posted 2010) [#7]
Thanks for the information! I guess it makes sense that Apple wouldn't care too much about memory leaks because that'll clear up as soon as the app ends, but obviously I care because careless memory leaks in the beginning could cause mysterious problems later in the game.

Also, now that there's multitasking Apple might start to care more about an app's memory footprint. Memory leaks only affect you if you're the only program running, but multiple programs running at the same time can affect each other...


Boiled Sweets(Posted 2010) [#8]
So just wondering, would it not be cool for Simon to add this bitmap font code into iminiB3D....?


jhocking(Posted 2010) [#9]
It's probably not a good idea because it's far from completely robust finished code (eg. I mentioned in the first post how it is sensitive to how you have your camera setup, camerazoom in particular.)

Anyway it goes against the spirit of "Blitz3D on iPhone" since Blitz3D doesn't have a built-in bitmap fonts system, although it's kinda silly to hold technology back just because of nostalgia. I mean, it's already got a number of features Blitz3D does not.


Boiled Sweets(Posted 2010) [#10]
Good points, I would really like to see a more complete or even perhaps collaborative project for iminiB3D. Perhaps some more examples etc, but I guess thats Simons call.

Anyhow thanks Simon for all your hard word and letting us use iminiB3D.


Sledge(Posted 2010) [#11]
So just wondering, would it not be cool for Simon to add this bitmap font code into iminiB3D....?
I'd agree not. The first order of business, where fonts are concerned, is surely to get the system fonts rendering as they are international. How are you going to localise for Russia or Japan etc with this?


simonh(Posted 2010) [#12]
Yep, I'll leave bitmaps fonts up to the user to implement.


Boiled Sweets(Posted 2010) [#13]
And how does one get system fonts rendered?


jhocking(Posted 2010) [#14]
The first order of business, where fonts are concerned, is surely to get the system fonts rendering as they are international.


I don't know if that's really a good idea. Sounds pretty inefficient for processing, and using the system fonts wouldn't integrate well with everything else being done in a single view in OpenGL.


Sledge(Posted 2010) [#15]
That's because you're assuming I wrote something other than I did. When I say there should be an impetus for system font rendering I simply mean the ability to draw the full character sets they provide -- you can do that with OpenGL (see Cocos2D).

I'm not trying to knock your generosity here, on the contrary I appreciate you sharing the code. I am saying, though, that if iMiniB3D gets font rendering then it should render fonts not just a sub-set of Roman characters. Otherwise it's just one more reason why Jobs is right about intermediary technologies.


Leto(Posted 2010) [#16]
Thanks heaps for the class, jhocking. It pretty much worked straight-up for me, but also a nice base to build on. I'd really like to expand it to load multiple fonts too.

The online font tool has moved here now: http://www.bitmapfontmachine.com/



Last edited 2010


Rob Pearmain(Posted 2012) [#17]
*Typo*

Last edited 2012