3
votes

I've been searching and testing around with new ways to render text with OpenGL, loading the its textures with SDL, but every technic I test it seems to be expensive and slow.

Thinking about it I realized that maybe the best way to implement it is by loading a texture with every character needed (just like a spritesheet), getting the relevant data about it (width, height, advance, line skip...) and when rendering it (basically we would do it after all the other rendering on the scene), we would need only one glBindTexture() to print every string needed on the screen.

I'm assuming here that the expensive part of it is the texture creation and binding, correct? Every code tested by me seem to use separated texture to each glyph, or each string.

How do you guys render text? Is it a good way to render it? If so, is there any lib that already does it?

3
You need to use shifting texcoords to render different parts of the texture. Each glyph should be a quad with appropriate coords for its cell on the atlas.ssube
I do it in exactly the same way. However, I used DirectX. If you're interested in the technique, though, take a look at sdxspritetext.codeplex.comNico Schertler

3 Answers

4
votes

Rendering text by using a "spritesheet like" texture with every letter on it will certainly work and is a very common way of doing it.

While don't know of any libraries to render text like this (I'm sure there are though) it really should not be to difficult to just write the code for it yourself. If you want to write your own code to do it, you will need some way to generate a texture containing every letter you need on it. BMFont is one program that can generate such textures. In addition, BMFont produces an accompanying ".fnt" file indicating where each letter is located in the texture.

Here is what a texture generated by BMFont might look like:

BMFont texture for size 22 Times New Roman

and the .fnt file:

info face="Times New Roman" size=-22 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0
common lineHeight=25 base=20 scaleW=256 scaleH=256 pages=1 packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4
page id=0 file="Times22.png"
chars count=191
char id=32   x=253   y=37    width=1     height=1     xoffset=0     yoffset=20    xadvance=6     page=0  chnl=15
char id=33   x=253   y=21    width=2     height=15    xoffset=2     yoffset=5     xadvance=6     page=0  chnl=15
char id=34   x=195   y=118   width=6     height=6     xoffset=2     yoffset=5     xadvance=9     page=0  chnl=15
char id=35   x=72    y=42    width=11    height=16    xoffset=0     yoffset=4     xadvance=11    page=0  chnl=15
char id=36   x=17    y=43    width=9     height=17    xoffset=1     yoffset=4     xadvance=11    page=0  chnl=15
...
0
votes

Use FreeType to generate glyph bitmaps on the fly and stuff those into one (or more) large textures using the box packing algorithm of your choice.

As you said that way most strings only require one, maybe two texture binds.

0
votes

Here's another one that can build compact font bitmaps, optionally including kerning, and includes source code to load and display the fonts

https://github.com/SudoMike/SudoFont