[World] Making of an album

Daniel Phillips phillips at phunq.net
Wed May 23 00:39:20 PDT 2012


An initial prototype of a "font strike" generator landed in the freetype demo.  
This renders selected characters of a typeface into a texture album at a given 
point size. In other words, it makes a bitmap font from a Truetype outline 
font. Everything about this is crude and incomplete, but there we are, it 
looks like text.

I loaded the texture album into the ground plane texture just to be lazy, but 
it kind of cool with a Matrixy feel. The texture album format is extremely 
primitive. There is just one column of characters and the same width for every 
glyph. The widest glyph (usually W) determines the album width. This wastes a 
lot of texels but we can revisit that at any time. Memory is cheap right?

Actually, no. GPU texture memory is really precious. It is relatively small 
and more expensive than ordinary DRAM. And there are an awful lot of different 
things we want to load into it. So we need to be miserly with passing it out, 
especially when there can be quite a few typefaces at different sizes loaded at 
once.

I'm torn about what memory format to use. I laid it out this for now with X 
increasing towards higher memory, which requires flipping Freetype's row layout 
upside down, and the album shows up with 'a' below 'b'. OpenGL has a slight 
preference for thinking about things that way, and it pushes the annoying flip 
down into the loading code, otherwise it has to be done when mapping texture 
coodinates to the screen, making that messy thing even messier. If I did it 
the other way, the glyph album would read with 'b' above 'a', perhaps a little 
more natural. A tiny point indeed, but it does need to be settled because the 
effects are pretty far reaching.

At least I don't waste much vertical space - each glyph has only as many rows 
as it needs. This was easy to do, so I did it. Later I have in mind a 
multicolumn album format where a wide glyph can span several columns, with the 
column width chosen so the most narrow glyphs lying in a single column do not 
waste much space. This will require an actual allocator for the album but I 
think it can be pretty simple relative to the considerable amount of texture 
memory saved. We also need a glyph directory to find its texture coordinates, 
baseline position, amount of leading whitespace, etc, which does not exist at 
all yet.

For the high level organization I was able to repurpose some texture loading 
machinery I had created earlier to solve the problem of how to manage image 
assets on program start, before a GPU surface actually exists. Then images 
can't just be loaded straight into texture memory as is typical for an OpenGL 
program. Instead, we park loaded images in a big vector and reference them by 
index later when it is time to upload to the GPU. (This has the immediate 
desirable effect that if some file turns out to be missing or misspelled, the 
program just reports it and exits in a civilized way instead of popping up a 
GL window and doing the usual annoying big-flash-kaboom effect.)

So we end up with image index numbers, a lot like OpenGL texture numbers, and 
that looks like a pretty good way to keep track of lots of images. A nice 
benefit is, its easy to avoid memory leaks because all the images are 
referenced from a well known location. Well, we can leak resource indexes but 
somehow that doesn't seem quite as bad. The best thing is, no pointer 
segfaults. It seems like a good idea.

Now I am thinking, we can actually manage all kinds of things that way, not 
just images, so I renamed image map API as "asset map" with a view to 
supporting all kinds of different objects, which might not be images or 
textures at all. Now we have one new kind of asset, a texture album. It can 
have various properties to make it smart, in particular the ability to render 
text. I can see it acquiring other abilities as time goes by, such as the 
ability to re-rasterize its glyphs if the window size changes. it could 
respond to texture cache pressure by automatically releasing its texture 
resources and reloading from main memory if necessary, and it could rasterize 
glyphs on demand instead of all at once, to support really big character sets 
like Unicode. And it is friendly to introspection, like "how much total memory 
is devoted to render assets right now". I think this concept is a keeper.

This very first bitmapped text rendering is not the most beautiful in the 
world. The characters are splotchier than I expected. I attached a image with 
text rendered by GLC for comparison, which is even uglier. Now I don't feel so 
bad. Anyway, we will see how it looks when rendered accurately onto a 
rectalinear pixel grid instead of being a crude bilinear scaling of a low res 
texture as now. A lot of the challenge of text rendering is about dealing 
reasonably with small point sizes, like the 12 point here. It should be 
possible to go right down to about 6 point and still be readable, so there is 
a lot of room for improvement. But this is a starting point. A usable 
replacement for GLC just got a little closer.

Regards,

Daniel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://phunq.net/pipermail/world/attachments/20120523/a053b8f9/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: font3.png
Type: image/png
Size: 204645 bytes
Desc: not available
URL: <http://phunq.net/pipermail/world/attachments/20120523/a053b8f9/attachment-0002.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mesh90.png
Type: image/png
Size: 135988 bytes
Desc: not available
URL: <http://phunq.net/pipermail/world/attachments/20120523/a053b8f9/attachment-0003.png>


More information about the World mailing list