2
\$\begingroup\$

I am trying to draw text onto the screen but it always ends up being pixelated no matter what I try. A lot of people say that adding the Linear TextureFilter works or offer other solutions but they don't really work for me. This is what I have now (I'm also using a ttf font):

public BitmapFont generateFont(String path, double size)
{
    FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal(path));
    FreeTypeFontGenerator.FreeTypeFontParameter parameters = new FreeTypeFontGenerator.FreeTypeFontParameter();

    parameters.genMipMaps = true;
    parameters.color = Color.BLACK;
    parameters.size = (int) Math.ceil(size);
    parameters.magFilter = TextureFilter.Linear;
    parameters.minFilter = TextureFilter.Linear;
    generator.scaleForPixelHeight((int) size);

    return generator.generateFont(parameters);
}

I've also changed the parameter size to (int) Math.ceil(2 * Gdx.graphics.getWidth() / 9); and while that makes things a little bit smoother, it's nowhere near as crisp as some other texts are.

I'm wondering what I need to do in order to get smooth text along with how I can maintain that smoothness in different text sizes across different resolutions (I'm only targeting desktop right now since I'm really just messing around with Libgdx). It just seems like there are several different ways of doing this but I just want to know what's the best way to go about doing this.

\$\endgroup\$
10
  • \$\begingroup\$ Try minFilter MipMapLinearNearest and magFilter Nearest. \$\endgroup\$
    – Charanor
    Jun 30, 2017 at 15:03
  • \$\begingroup\$ That doesn't change anything. Still blurry. \$\endgroup\$
    – chip_s11
    Jun 30, 2017 at 15:06
  • \$\begingroup\$ What size do you use? \$\endgroup\$
    – Charanor
    Jun 30, 2017 at 15:06
  • \$\begingroup\$ I'm using 64 right now. However, if I change the size to 2 * Gdx.graphics.getWidth() / 9 it makes things a little bit smoother. However, I would like to be able to specify the size of the text and have it still be smooth regardless of size. \$\endgroup\$
    – chip_s11
    Jun 30, 2017 at 15:10
  • \$\begingroup\$ Try multiplying by Gdx.graphics.getDensity(). \$\endgroup\$
    – Charanor
    Jun 30, 2017 at 15:21

2 Answers 2

0
\$\begingroup\$

After doing some testing it seems the problem is caused by a large font size and a large viewport size. Luckily this is easily fixed by following these simple steps:

  1. Reduce Font size by half.
  2. Reduce Viewport size by half.
  3. Make sure the font minFilter is MipMapLinearNearest and the magFilter is Linear.
  4. If this doesn't work go to step 1.

(In your case though I think the font size is just fine so I would suggest just reducing viewport size at first. If that doesn't work follow the steps above.)

To be clear try reducing your font size to 32 and your viewport size to (500, 500 * aspectRatio), then if that doesn't work try 16 and (250, 250 * aspectRatio).

This method does require you to use a separate viewport to render text with unless you want to change the viewport size of your actual game as well, so just create a new viewport of any type and make sure to apply it before rendering text:

gameViewport.apply();
batch.setProjectionMatrix(gameViewport.getCamera().combined);
batch.begin();
// Draw game stuff

textViewport.apply(true); // Center camera
batch.setProjectionMatrix(textViewport.getCamera().combined);
// Draw text
batch.end();

For me this produces quite satisfactory results font showcase

\$\endgroup\$
6
  • \$\begingroup\$ Downvoter; care to explain your downvote? :) \$\endgroup\$
    – Charanor
    Jun 30, 2017 at 21:31
  • \$\begingroup\$ This still doesn't seem to help. Maybe my parameters are messed up? Or maybe the font I have isn't very good (I might change it to see)? I'm assuming you are multiplying the size by the pixel density, if not, let me know what you are doing and any other parameters you might have. \$\endgroup\$
    – chip_s11
    Jun 30, 2017 at 22:18
  • \$\begingroup\$ @chip_s11 According to the official wiki some fonts just won't work. Quote: Throwing just any font at FreeType is not a super awesome idea. Some fonts in the wild are just terrible, with bad or no hinting information and will look like poopoo. Perhaps you just happened to hit one of these fonts? Is there a link to your font? \$\endgroup\$
    – Charanor
    Jun 30, 2017 at 22:21
  • \$\begingroup\$ I'm using the Lato font I downloaded from here: 1001freefonts.com/lato.font \$\endgroup\$
    – chip_s11
    Jun 30, 2017 at 22:23
  • \$\begingroup\$ @chip_s11 Try using a standard font (Arial, Times New Roman, etc.) just to test it. If it works with those fonts you know your font is the problem. \$\endgroup\$
    – Charanor
    Jun 30, 2017 at 22:24
0
\$\begingroup\$

This is the only solution for LibGDX:

https://github.com/libgdx/libgdx/wiki/Distance-field-fonts

Once you get through all the possibilities of rendering huge text smoothly, you'll end up in this link.

Keep in mind that when you write a game, you have to think of all possible phone/tablet resolutions so you'll need to render a much bigger text on a tablet.

I had a great time with Distance Field Fonts. Here you can find a free generator:

https://evanw.github.io/font-texture-generator/

\$\endgroup\$
8
  • \$\begingroup\$ So what's the point of the FreeTypeFontGenerator then? \$\endgroup\$
    – chip_s11
    Jun 30, 2017 at 20:48
  • \$\begingroup\$ This is only true if you need really large fonts, otherwise standard MipMap should be just fine. And for your tablet comment you could multiply the size value by Gdx.graphics.getDensity() which will scale the font to the same size on every device :) \$\endgroup\$
    – Charanor
    Jun 30, 2017 at 21:37
  • \$\begingroup\$ For smaller text objects, buttons, labels (on phones). You asked for smoothness in different text sizes - DFF is the answer for all your problems. \$\endgroup\$
    – Jacob
    Jun 30, 2017 at 21:38
  • \$\begingroup\$ Yeah, try to scale the default GDX Arial to 100 * Density() to display a game title :v \$\endgroup\$
    – Jacob
    Jun 30, 2017 at 21:39
  • \$\begingroup\$ @Spectre That's not what I said. I said to simply multiply by the density so you get the same size for all devices. As in you already have a size 100 font and then you multiply the size by density. And DFF is definitely not the answer to all of your problems. DFF can be incredibly slow if you don't optimize the shader swaps. \$\endgroup\$
    – Charanor
    Jun 30, 2017 at 21:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .