Slick Forums

Discuss the Slick 2D Library
It is currently Thu Jun 20, 2013 10:22 am

All times are UTC




Post new topic Reply to topic  [ 11 posts ] 
Author Message
PostPosted: Fri Feb 24, 2012 11:11 am 
Offline

Joined: Thu Nov 05, 2009 3:38 pm
Posts: 21
Hi,

searched the forum already, but found nothing that fits my situtation.

First of all I have a question: Is it right that there are two main ways of rendering fonts in Slick:
* UnicodeFont which renders all needed chars (glyphs?) to textures at the beginning (or always when I do a loadGlyphs()) and then the textured quads are rendered (this is the way I found out via a LWJGL tutorial which covered TrueTypeFont, which is now deprecated so I ported the code to UnicodeFont)
* Hiero, which does nearly the same but the char rendering is done with a tool at design time, not runtime and then loaded let's say at program start from a font file

I'm using Slick UnicodeFont im my game now and tried to give it an outline. This is my code (big size numbers for testing reasons):

Code:
            Font awtFont = loadMyAwtFontFromSomwhere();
            awtFont = awtFont.deriveFont(100f);
            font = new UnicodeFont(awtFont);
            font.addAsciiGlyphs();
            font.getEffects().add(new OutlineEffect(25, Color.black));
            font.getEffects().add(new ColorEffect(Color.white));
            font.loadGlyphs();

Code:
font.drawString(150, 150, "Slick UnicodeFont!");


This code produces the following output, where you can see, that the outline is generally working, but it seems to be cropped at some texture end (?):
Did I make something wrong?

Thanks in advance for help!

Image
http://genialix-spiele.de/Slick-Outline.png


Top
 Profile  
 
PostPosted: Mon Feb 27, 2012 6:06 pm 
Offline

Joined: Thu Nov 05, 2009 3:38 pm
Posts: 21
Did I miss some tutorial or documentation covering this topic?

(I updated the link to the image, hence it seemed to be broken...)


Top
 Profile  
 
PostPosted: Tue Feb 28, 2012 12:36 am 
Offline
Slick Zombie

Joined: Sat Jan 27, 2007 7:10 pm
Posts: 1477
Seems like a bug/limitation of UnicodeFont; effects aren't adjusting the size of the glyph sub-image.

I personally tend to use AngelCodeFonts -- they load and render much quicker than UnicodeFonts. If I want to add fill/outline effects (which, no offense, generally look tacky), I can easily add them in Hiero or Photoshop, or in the code itself. If I'm trying to make a large header "banner" with fancy doodads and text effects, a simple Image would be more efficient.

Quote:
* UnicodeFont which renders all needed chars (glyphs?) to textures at the beginning (or always when I do a loadGlyphs()) and then the textured quads are rendered (this is the way I found out via a LWJGL tutorial which covered TrueTypeFont, which is now deprecated so I ported the code to UnicodeFont)
* Hiero, which does nearly the same but the char rendering is done with a tool at design time, not runtime and then loaded let's say at program start from a font file

Pretty much.

UnicodeFont loads an AWT font, renders each glyph and all of its effects to an AWT image, then copies the resulting pixels to an OpenGL texture (imagine it as a sprite sheet). The glyph is saved with Image.getSubImage, and later rendered with Image.drawEmbedded. If the glyphs don't all fit on a single texture (defined by a Hiero settings file; default page size is 512x512), then multiple OpenGL textures will need to be used.

AngelCodeFont simply loads an image into a single OpenGL texture and uses getSubImage/drawEmbedded to render each glyph. It assumes that all your glyphs were able to fit on the same page (page size defined by Hiero).

Maybe you can see why the latter is so much more efficient...


Top
 Profile  
 
PostPosted: Tue Feb 28, 2012 1:02 am 
Offline
Slick Zombie

Joined: Fri Jan 29, 2010 7:02 pm
Posts: 1190
Instead of Hiero you could also use the TWL Theme Editor to create fonts which offer better font quality and also a large set of effects to choose from. Make sure to save the generated font in TEXT format so that Slick can use read it.

_________________
TWL - The Themable Widget Library


Top
 Profile  
 
PostPosted: Tue Feb 28, 2012 9:04 am 
Offline

Joined: Thu Nov 05, 2009 3:38 pm
Posts: 21
Thanks for the answers!

Just one more question before I start to dive into the different possibilities:
Am I right that the bitmap font ways you described have only one texture-subimage for each char? A String like "slick" so would rendered with 5 passes, for "s", "l", "i", "c" and "k"... and the tools you mentioned can apply various effects, including outline, to this subimages. If I understood that correctly then an outline of a rendered character would "overpaint" the previous rendered character. This is what I saw the advantage of UnicodeFont in, which can render 10 chars, if I set the effects accordingly. First 5 for the outline, then another 5 for the actual font...

Btw: @davedes: Ok, no offense, but why should outlines look tacky? Its the only way in my opinion to make text looking readable on arbitrary undergrounds:

http://www.pcgameshardware.de/screensho ... ollard.jpg

Image


Top
 Profile  
 
PostPosted: Thu Mar 01, 2012 5:18 pm 
Offline
Oldbie
User avatar

Joined: Thu Jan 13, 2011 4:42 pm
Posts: 349
I'm not sure what the advantage your describing is. Is it that the UnicodeFont renders in two passes per letter instead of one?

Quote:
If I understood that correctly then an outline of a rendered character would "overpaint" the previous rendered character


perhaps this is where I get confused. I don't use font too often, but I believe that in a bitmap font, each letters texture should already have all of the effects applied to it. Thus the outline would not be rendered separately. It would be built into the texture.

ps. I think you're right about outlined text readability on an arbitrary background.

_________________
"Artificial intelligence will never be a match for human stupidity" - "Jamos Kennedynos"


Top
 Profile  
 
PostPosted: Thu Mar 01, 2012 5:49 pm 
Offline
Slick Zombie

Joined: Sat Jan 27, 2007 7:10 pm
Posts: 1477
shadow wrote:
Am I right that the bitmap font ways you described have only one texture-subimage for each char? A String like "slick" so would rendered with 5 passes, for "s", "l", "i", "c" and "k"... and the tools you mentioned can apply various effects, including outline, to this subimages. If I understood that correctly then an outline of a rendered character would "overpaint" the previous rendered character. This is what I saw the advantage of UnicodeFont in, which can render 10 chars, if I set the effects accordingly. First 5 for the outline, then another 5 for the actual font...

Why is 10 characters better than 5? That's twice the amount of rendering needed for the same string. Thankfully that's not how it works.

In short, here's how Slick renders fonts using OpenGL:
  • When you call drawString, we start QUAD rendering with glBegin -- as if we called Image.startUse on the font texture.
  • Then, for each glyph, we specify four vertices with proper texture coordinates -- as if calling Image.drawEmbedded or SpriteSheet.renderInUse
  • We finish rendering by calling glEnd, which sends the vertex data to the GPU and renders the various quads on screen -- as if we called Image.endUse

For bitmap fonts, all of the effects are applied to the texture already (i.e. look at the PNG file and you'll see the outline).
For unicode fonts, the effects are applied to the texture during runtime, when you load the glyphs (this is why it takes so much longer to load a unicode font).

So in both cases, the effects will already have been applied -- rendering the text "slick" would be rendered in one 'pass' by drawing 5 textured quads.

Quote:
Btw: @davedes: Ok, no offense, but why should outlines look tacky? Its the only way in my opinion to make text looking readable on arbitrary undergrounds:

Yeah, in that case I can see its use. I figured you were using outlines as decoration for a large logo/banner/header text. In that instance, (IMO) it would be better to add decorations in Photoshop or a similar program.


Top
 Profile  
 
PostPosted: Thu Mar 01, 2012 6:21 pm 
Offline

Joined: Thu Nov 05, 2009 3:38 pm
Posts: 21
I created an image with my favourite graphic program to better explain what I mean:

Image

Variant 1 and 2 are what imho is possible with rendering the word "font" with 4 render passes for "f", "o", "n" and "t". Either the outline of a char "overpaints" the last char, or the chars must be drawn with such big distance that it will look ugly.
Variant 3 is what I want to have it like and this is possible with rendering the (black) outline for "f", "o", "n" and "t" first, and then draw "f", "o", "n" and "t" normal (white)...
I forgot the 4th variant, like it's now with cut off outline...

I of course understand that double amout of render passes is worse then half, and I don't want to be ungrateful at all, but when I discover that there is an "OutlineEffect" then I wonder what would be an useful working example?

I hope it became a little clearer...


Top
 Profile  
 
PostPosted: Thu Mar 01, 2012 7:38 pm 
Offline
Oldbie
User avatar

Joined: Thu Jan 13, 2011 4:42 pm
Posts: 349
Ooooh! I see now. well... dang. that may require you to use a custom class that takes a set of letter outlines and, like you said, renders them before rendering your font on top.

_________________
"Artificial intelligence will never be a match for human stupidity" - "Jamos Kennedynos"


Top
 Profile  
 
PostPosted: Thu Mar 01, 2012 9:26 pm 
Offline
Slick Zombie

Joined: Sat Jan 27, 2007 7:10 pm
Posts: 1477
The OutlineEffect is intended for smaller outlines; and what you're trying to do (rendering glyphs in multiple passes) can't be achieved very easily with UnicodeFont.

Here's the simplest solution IMO:
  • Open up Hiero or TWL's bitmap font generator. Choose your font and glyph set.
  • Change the page size so that your glyphs all fit on a single texture/page. In Hiero, select the "Glyph Cache" radio button, then increase the page width/height as necessary.
  • Increase the padding by a given amount, depending on how large you plan your outline to be. I used a padding of 10.
  • Save the image and font file (File > Save BMFont in Hiero, or save as text in TWL) somewhere.
  • Open the image up in your graphic editor. (If you're using Hiero, and the resulting image is vertically flipped, flip it right-side up. That's a bug that should be fixed soon.)
  • Add your stroke/glow/outline effects on a separate layer.
  • Ideally, if you can fit them both in a single image under 2048x2048, you should; it will increase rendering time and result in fewer texture binds. (Same idea as a sprite sheet.)
  • Use the MultiPassFont class (link below) to render. It's pretty much a full copy-paste of AngelCodeFont with very minor changes to allow for multiple image passes.

Result:
Image

fontfill.png (1024x512 image)
Image

fontfill.fnt
http://www.mediafire.com/?w3ug1jo7o16i629

MultiPassBMFont.java:
http://pastebin.com/F5BcPDjR (mirror)

Usage:
Code:
      Image fontSheet = new Image("res/fonts/fontfill.png");
      
      Image fontOutline = fontSheet.getSubImage(0, 0, 512, 512);
      Image fontFill = fontSheet.getSubImage(512, 0, 512, 512);
      
      //will render images in order given; will first render fontOutline, then fontFill
      font = new MultiPassBMFont("res/fonts/fontfill.fnt", 10, fontOutline, fontFill);


Then use the drawString method as usual. You'll have to add Font.getWidth/getYOffset/getHeight yourself; this should be pretty easy with AngelCodeFont source. You can also make changes to the drawString method to allow for multiple color filters; i.e. one per pass.

The MultiPassBMFont class is exactly the same as AngelCodeFont except that it allows for multiple images and renders each glyph offset by padding*2. You can pass lower padding values to space out the text. Also, this class doesn't use DisplayList caching -- though for the most part you aren't losing much.

Hopefully AngelCodeFont/UnicodeFont will be updated to make glyph info more visible; meaning we won't need to re-write the class just to add this kind of functionality. ;)


Top
 Profile  
 
PostPosted: Tue Mar 06, 2012 10:24 am 
Offline

Joined: Thu Nov 05, 2009 3:38 pm
Posts: 21
Thank you very much for this detailed answer !

I'll give it a try...


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 11 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group