Allegro fonts in AllegroGL
james_lohr

I've just finished writing a few useful functions for displaying allegro fonts in AllegroGL. (AllegroGL's font drawing routines are not working for displaying textured allegro fonts in anything other than monochrome).

If anyone else is having the same problem, you may find this very useful.

Here are the function prototypes:

JFONT *create_jfont(FONT *fnt);This generates a font from an allegro font. FONT *fnt must be an allegro font.

void destroy_jfont(JFONT *jfont);Destroys the generated font, deleting OpenGL textures.

void jprintf(JFONT *f, float x, float y, float z,float scale, char *format, ...);Draws the text as a series of quads (printf style). OpenGL's matrix transformations must be set appropriately before the text is drawn.

There :), nice and simple.

(note: the blurring around the edges is 'cause this is a .jpg screenshot.)
{"name":"fnt1.JPG","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/d\/0d473963939496b4f9a2581af789f644.jpg","w":800,"h":600,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/d\/0d473963939496b4f9a2581af789f644"}fnt1.JPG

JFONT *create_jfont(FONT *fnt) is actually quite complicated. It uses a packing algorithm to fit the glyphs into an appropriately sized texture:

Allegro font: (before packing)
{"name":"fnt2.JPG","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/8\/a8f965402b786972e9c4327c7b8daa05.jpg","w":958,"h":284,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/8\/a8f965402b786972e9c4327c7b8daa05"}fnt2.JPG

OpenGL (2^n,2^m) texture after packing:
{"name":"fnt3.JPG","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/9\/b9bfb84e4b992bd3b635099981ed6c44.jpg","w":513,"h":256,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/9\/b9bfb84e4b992bd3b635099981ed6c44"}fnt3.JPG

I won't post the code now, but if anyone wants it, I'll neaten it up a bit. (I can't be bothered at the moment 'cause, no doubt, Bob'll fix the problem tomorrow and all this will be a waste of time ::) )

Gnatinator: Thanks for your code, I found it useful for writing my own functions.

Bob

The other option would have been to send me a patch for AllegroGL...

james_lohr

That's what I spent the better part of today trying to do, but I just couldn't get my head around all your code let alone actually find the problem.

I'll give it another go over the weekend if you like :). Or maybe you could fix it ;)? Seriously I'm sure it would take you a tenth of the time it would take me...

Well if it is fixable (I gave up earlier today mainly because I was worried that it was an OpenGL limitation and not a bug) I don't mind trying again. It'd do me a lot of good to go through it all in detail, I'm sure :).

Kitty Cat

It looks good to me.. although you may want to, when creating the OpenGL texture, make it have as few vertical rows as possible and put a transparant pixel or two in between the glyphs. This will help when using linear filtering. :) Though I would think it'd be better to just fix AllegroGL.

james_lohr
Quote:

make it have as few vertical rows as possible

I don't understand ???.

Quote:

put a transparant pixel or two in between the glyphs

Already done.

Kitty Cat

Put as many glyphs on a single vertical row as possible. The fewer vertical rows you have, the less padding there'll be. More space-efficient.

james_lohr

The packing algorith I'm using doesn't work like that. If you look closely you'll see that there are no columns (vertical rows). The reason why there is padding at the bottom is because the OpenGL texture must be (2^n,2^m).

[EDIT] Implemented gradients for monochrone fonts. Look'n' pretty :).

These are drawn with the same monochrone font:
fnt1.bmp

Gnatinator

Looking good! Im glad to finally see a complete solution to the problem. :)

Quote:

Gnatinator: Thanks for your code, I found it useful for writing my own functions.

Hey hey, no problem

Quote:

These are drawn with the same monochrone font...

Cant see the picture

Bob

Gnatinator: I wonder if your texture packing code is better than AllegroGL's. If it is, and is also simpler, then it might be a good replacement.

Gnatinator
Quote:

Gnatinator: I wonder if your texture packing code is better than AllegroGL's. If it is, and is also simpler, then it might be a good replacement.

Heh, the texture isnt packed or unpacked. The code just loads a tga texture, cuts it up and displays characters according to the parameters you give the function.

If you want my code check out my post here.

The disadvantage to my system is that the font is displayed in quads of all the same size. So unless all your characters are the same width, your going to have a slight change of distance between each char.

At the moment I have a parameter that will adjust character distance and for now I just use that which is kind of a temporary fix.

Thomas Fjellstrom

The texture you posted shows characters of varying width, just use those widths. no?

Gnatinator

In that font (the parameters on the function could accomidate any char w/h as long as all are constant) the chars have 16 pixel hieght and 16 width box surrounding them. The function just blits that 16x16 box for whatever char you need, sometimes creating a little extra space.

EDIT:
To see the layout better, open it in PS or some other graphics program that support grids and turn on a 16x16 grid over the image then you will see.

Thomas Fjellstrom

Actually, You'll have to excuse me :( I was thinking about the one James posted :o the one all packed together.

james_lohr

This is the second time I've been confused with someone else also using a greyscale avatar in the same thread as me :(.

My code stores character offsets during packing so that the text is drawn exactly as it would look if drawn with allegro's text functions. It also means that it is faster because the quads are only as big as they need to be.

For example here's some text with texturing disabled to give you an idea of the quad size:

fnt1.PNG

[Edit]
Oh, and another thing I just added: When loading the font, there is now the option to enable anti-aliasing. This means that the font texture (the packed one shown in my first post) includes an alpha channel which is set so that when the font is drawn, it blends smoothly onto whatever it is drawn upon. This is pointless for small fonts (because of OpenGLs automatic masked texture anti-aliasing) but looks great for larger fonts where you need a more gradual gradient from opaque to transparent.

Gnatinator

Hey James maybe you could upload your code? ;)

james_lohr

Ok, just need some time to neaten it up a bit (add indents and some comments etc. ;)).

[EDIT]

Bob said:

I wonder if your texture packing code is better than AllegroGL's. If it is, and is also simpler, then it might be a good replacement.

Pahahahah. I'm almost too embarrassed to show my code it's such a mess. Sorry, there's not a hope in hell of anything I've written replacing your professional code.

All this is meant to be is something hacky that works until someone fixes AllegrGL. I wish I had the ability to fix it, but unfortunately it's beyond me.

So here it is:

jfont.h

1 
2 
3typedef struct JFONT_GLYPH { //each character width,height,texture offset and size offset
4 float w, h; //store as floats to avoid conversion during rendering
5 float offx,offy; //position on the font texture (top left)
6 float offxx,offyy; //position on the font texture (bottem right) - could be calculated from others, but faster to store it here
7 float px,py; //character postion modifier (e.g. so that _ is drawn at the bottem and not in the middle
8} JFONT_GLYPH;
9 
10typedef struct JFONT {
11 GLuint texture; //opengl texture with all font characters
12 JFONT_GLYPH glyph[96]; //character offsets, sizes etc.
13 float font_height; //height of tallest character in the font.
14} JFONT;
15 
16 
17//prototypes
18 
19JFONT *create_jfont(FONT *fnt);
20void destroy_jfont(JFONT *jfont);
21 
22//pre font loading, these are parameters set prior to loading the font:
23int enable_jfont_alpha(int x); //for anti-aliased font
24int enable_jfont_monochrome(int x); /* loads a colour allegro font as monochrome (could maybe do with some optimizing
25 - change the internal format of the OpenGL texture or something. I dunno :S )
26 Also, if optimisation is possible, it needs to be made automatic for allegro fonts
27 that are already monochrome.*/
28 
29 
30void jprintf(JFONT *f, float px, float py, float pz,float scale, char *format, ...);
31 
32//Pre text drawing:
33int enable_jfont_gradient(int x);
34 
35/* This function is very cumbersome at the moment :(.
36
370: top left of font
381: bottom left
392: bottem right
403: top right
41
42*/
43void set_jfont_gradient(float R0,float G0,float B0,float A0,
44 float R1,float G1,float B1,float A1,
45 float R2,float G2,float B2,float A2,
46 float R3,float G3,float B3,float A3);

jfont.c is attatched 'cause it's too big.

[EDIT 2] - fixed bug: create_jfont() was not working if allegro_gl_flip_texture() was set incorrectly. Now it works whatever allegro_gl_flip_texture() is set to and restores original value.

Thread #405734. Printed from Allegro.cc