[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