Newbie font questions -- please help!

Started by Robin, October 08, 2004, 19:40:23

Previous topic - Next topic

Robin

Hi :)

Being a complete novice at programming in general, i've found LWJGL to be relative easy to pick up. (I come from a flash background)

That said, i'm curious as to whther it's possible to display proportional-width fonts well in LWJGL? I know that you need to create a bitmap beforehand and reference that -- but having seen Thom Wetzel's bitmap font builder which allows for the saving of font metrics in an external file -- i'm really really hoping that it can be done.

Additionally, with fonts in LWJGL (fixed-width or otherwise) is it easy to
- scale / rotate them easily in 2d?
- adjust opacity?

I've seen a number of tutorials on fonts in LWJGL, but they appear to be biased towards fixed-width outcomes.

Thanks for reading. I love everything about LWJGL so far, just this darn font thing which is getting in the way :)

princec

Fonts are actually really hard to do. But I've solved the problem completely! ... provided you can cope with a big pile of loosely connected code without any documentation :/

The code can be found at sourceforge: http://www.sf.net/projects/spgl - it's called the Shaven Puppy Game Library.

The gist of how it works is:

At development time, I use Java to render a specified font in a specified size. I draw every single glyph in the font and pack them into an image with power-of-two sized dimensions (which I guess depending on the fontsize). I record for each glyph where its physical bounds are and where its baseline coordinates are and all the other glyph metrics I get.

The clever bit is where I work out kerning. I then draw every single glyph next to every single other glyph. This takes quite a while even on a fast CPU! But currently it's the only way to find out if the advance between two glyphs is nonzero because of kerning.

I then save my own special Font instance (com.shavenpuppy.jglib.Font) which contains all these Glyphs and the bitmap image of the font.

This is all taken care of by the SPGL FontConverter (com.shavenpuppy.jglib.tools.FontConverter)

That's part 1!

The next part which is no less fiddly is that you need to load the serialized Font object into your game, and then you need to create a GLFont using it (com.shavenpuppy.jglib.opengl.GLFont).

GLFonts are nice and easy to use with a pair of classes: GLString (for drawing simple bits of text) and GLTextArea (for drawing formatted paragraphs of text). Prior to rendering the strings of course you will need to enable GL_TEXTURE_2D and make sure you're using GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA blending for normal text rendering. To change the text colour you'd use GL_TEXTURE_ENV_MODE, GL_MODULATE and set the colour with glColor4f() (so you could do transparent text for example).

Keep asking questions, this will probably end up being a FAQ...
...and it might end up being more properly supported in the LWJGL utils packages.

Cas :)

Robin

Cas,

I could certainly ask a million questions (and i certainly hope i'm not overstaying my welcome here) but do you (or anyone else for that matter) have any simple working examples which utilise your Font Converter that i could i have a poke around?

I feel bad because i am only a learning Java progammer, and all your hard work (at spgl) seemingly goes over my head.

Thanks for reading

Orangy Tang

Because I'm lazy, I don't bother with all that serialisation lark and just do the thing at app startup, its not nearly as long as Cas will have you belive.

FontConverter fc;
			Font theFont;
			fc = new FontConverter("Impact-PLAIN-18", 127);
			theFont = fc.getFont();
			GLFont defaultFont = new GLFont("MainFont", theFont, true);
			defaultFont.create();

The string name for the font converter has to be the name of an avalible font, or you'll get an exception. Then create a GLString thats long enough and set the text and font.

princec

Ah, but you're only doing 127 glyphs, and a really small font. I do a few thousand glyphs for several fonts of 18, 24, and 36 points and it tends to take quite a while :) (Also removes an AWT dependency of course!)

Cas :)

Uli

Font rendering is a very common problem, especially for beginners.  I think Spaghettis's font converter and rendering classes are very powerful, so it would be a big help for many people if you'd put it into the LWJGL util package. Same with image converter and texture loading classes (I don't know if there are already texture loading classes in .92, but I always liked Cas' idea of having an own image format and not using AWT classes for loading .png images)
So PLEASE, put these 2 into the util package!

princec

A lot of SPGL has already migrated its way into the LWJGL util package... I'm a bit concerned that my resource management code is crap though and nearly everything hinges off of it. Anybody care to peer review the concepts behind it? (I can get it tidied up and commented properly without any trouble...)

Cas :)

Uli

I had a closer look at SPGL some time ago. I decided not to use it that time, because the code for the GUI stuff was to much mingled with the basic resource management code I thought, and I didn't want my own game look to much like Alien Flux  :) So I wrote my own resource management code, using many of your concepts. I liked the idea of having a human-readable resource file in XML and a resource compiler to translate it into a better machine-readable format, so you don't need an XML-parser at game-runtime (I also had a look at Clanlib, they do it very similar, except they dont't use XML). I also used your image format and still use it today. At first I didn't use your font stuff, because I wanted multicolor fonts with shadow effects and such, but later I found out that there are a lot of situations where a  good readable mono font is a better choice.
As to your source code I can say it looks a lot tidier than mine usually looks  :roll:

indiana

I would love to see your font code make it's way into LWJGL itself, the util package seems the logical place for it.  :D

Orangy Tang

Dang it, you can't just keep moving stuff over, I can't tinker with it if its no longer in the SPGL! :cry:

Robin

Thanks for the help! I got some nice text working a while ago, and it's working wonderfully :) I've still got alot to learn -- but i was getting awfully put off by the fixed-width alternatives.

Right now, i've stacked all my Type 1 fonts into "Java/jre1.5.0/lib/fonts".

How would i go about packaging the fonts used in my application so i could use it on other machines that wouldn't have that font installed -- should i not be placing my fonts in the directory specified above to begin with?

Cheers,
Rob.

princec

Ah, now that you are generally not allowed to do, because of copyright. You actually need to distribute the processed font files (so Orangy Tang's trick of generating them at runtime won't work for a real deployment).

Cas :)

PlanetMongo

Of course, an alternative is to become a fontagrapher and make your own cheesy fonts.. Distribute those all ya want.  But then, I mean, erm, why?
ife sucks, kill yourself.