allocating a texture large enough to hold all font glyphs

Started by
10 comments, last by Cygon 14 years, 11 months ago
Another thing that you would maybe want to add to your dry run is make more efficient use of the available texture space by placing the glyphs in a less wasteful layout.

This is basically the same problem that a lightmap packer has to solve, which is usually done with some more or less complicated binary subdivision scheme.
However, you can get it 90% right and a lot easier simply by sorting glyphs by one dimension (for example height) and making the respective "line" only high enough to fit in the biggest glyph in that line. This is not optimal, but close, and it's fast and easy.
Advertisement
Quote:Original post by Vexator
any idea how to do this in a smarter way? thank you :)

I did it like this. Firstly, I do not insert characters that resolve to same glyph (your [?]) multiple times. I used same layout method: stepping y by max vertical delta.
Secondly, when making a texture (in memory), I keep width constant and double the height every time i run out of space (just like how std::vector grows). Then, when done, I create opengl texture and upload it to card. So that my texture could be 1024x128 for small font or 1024x2048 for large. Alternatively, you could even allocate in chunks and upload chunks with glTexSubImage2D .
I don't see a point in improving packing by maybe 20% by using more complex algorithms, especially if you prefer to only use power of 2 textures anyway.

I also have unicode support as option; for that I use extra part of texture as glyph cache for non-ASCII glyphs, replacing the least recently used glyph. Naturally, I have to allocate same size to all glyphs when using cache, which is somewhat wasteful, but not so much as for ASCII because the non-ASCII characters that I care about are letters in non-latin alphabets, not punctuation.
I use dynamic textures to cache not only glyphs from a single font but from all fonts, as well as GUI skin bitmaps and other things. To find the optimal placements of the bitmaps on the texture, I use a rectangle packing algorithm (description and source).

Whenever a bitmap is looked up, an internal MRU list is updated to keep track of which bitmaps are being used and in which order. Should too many texture switches occur in a frame (typically because characters from a single font got distributed to different dynamic textures due to space constraints), I move the bitmaps in the order of the MRU onto a new dynamic texture.

I've been thinking of using a time budget for the move (so I put the new dynamic texture together bit by bit, copying only as many bitmaps per frame as I can do in, say, 1 ms). Or doing in in a separate thread. But so far, the complete copy did the trick just fine.

Professional C++ and .NET developer trying to break into indie game development.
Follow my progress: http://blog.nuclex-games.com/ or Twitter - Topics: Ogre3D, Blender, game architecture tips & code snippets.

This topic is closed to new replies.

Advertisement