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"}
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"}
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"}
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.
The other option would have been to send me a patch for AllegroGL...
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
.
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.
make it have as few vertical rows as possible
I don't understand
.
put a transparant pixel or two in between the glyphs
Already done.
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.
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:
Looking good! Im glad to finally see a complete solution to the problem. 
Gnatinator: Thanks for your code, I found it useful for writing my own functions.
Hey hey, no problem
These are drawn with the same monochrone font...
Cant see the picture
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: 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.
The texture you posted shows characters of varying width, just use those widths. no?
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.
Actually, You'll have to excuse me
I was thinking about the one James posted
the one all packed together.
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:

[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.
Hey James maybe you could upload your code?
Ok, just need some time to neaten it up a bit (add indents and some comments etc.
).
[EDIT]
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 | |
| 3 | typedef 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 | |
| 10 | typedef 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 | |
| 19 | JFONT *create_jfont(FONT *fnt); |
| 20 | void destroy_jfont(JFONT *jfont); |
| 21 | |
| 22 | //pre font loading, these are parameters set prior to loading the font: |
| 23 | int enable_jfont_alpha(int x); //for anti-aliased font |
| 24 | int 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 | |
| 30 | void jprintf(JFONT *f, float px, float py, float pz,float scale, char *format, ...); |
| 31 | |
| 32 | //Pre text drawing: |
| 33 | int enable_jfont_gradient(int x); |
| 34 | |
| 35 | /* This function is very cumbersome at the moment :(. |
| 36 | |
| 37 | 0: top left of font |
| 38 | 1: bottom left |
| 39 | 2: bottem right |
| 40 | 3: top right |
| 41 | |
| 42 | */ |
| 43 | void 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.