How to draw smooth text in libgdx?

前端 未结 10 1270
暖寄归人
暖寄归人 2020-12-01 00:01

I try to draw simple text in my android game on libgdx, but it\'s look sharp. How to make text look smooth in different resolutions? My Code:



        
相关标签:
10条回答
  • 2020-12-01 00:40

    Bitmap fonts are textures and if you want to make smaller textures look smoother when you are resizing them to bigger sizes you need to make sure you use the right texture filter.

    This blog post deals with such issues

    0 讨论(0)
  • 2020-12-01 00:41
    • Create a .fnt file using hiero which is provided by libgdx website.
    • Set the size of font to 150; it will create a .fnt file and a .png file.
    • Copy both files into your assets folder.
    • Now declare the font:

      BitmapFont font;
      
    • Now in create method:

      font = new BitmapFont(Gdx.files.internal("data/100.fnt"), false); // 100 is the font name you can give your font any name
      
    • In render:

      font.setscale(.2f);
      
      font.draw(batch, "whatever you want to write", x,y);
      
    0 讨论(0)
  • 2020-12-01 00:44

    In general you don't get sharp text because you are designing your game for a certain resolution and when you move to a different device, Libgdx scales everything to match the new resolution. Even with linear filtering scaling is bad on text because round corners are easily distorted. In a perfect world you would create the content dynamically at runtime according to the number of pixels available to you and not a single automatic scale would be used.

    This is the approach I'm using: Building everything for small screen (480 x 320), and when you open it on a bigger resolution, I load the BitmapFont with a higher size and apply and inverse scale to the one that Libgdx will later do automatically.

    Here's an example to make things clearer:

        public static float SCALE;
        public static final int VIRTUAL_WIDTH = 320;
        public static final int VIRTUAL_HEIGHT = 480;
    
    
        public void loadFont(){
    
         // how much bigger is the real device screen, compared to the defined viewport
         Screen.SCALE = 1.0f * Gdx.graphics.getWidth() / Screen.VIRTUAL_WIDTH ;
    
         // prevents unwanted downscale on devices with resolution SMALLER than 320x480
         if (Screen.SCALE<1)
            Screen.SCALE = 1;
    
         FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("data/Roboto-Regular.ttf"));
    
         // 12 is the size i want to give for the font on all devices
         // bigger font textures = better results
         labelFont = generator.generateFont((int) (12 * SCALE));
    
         // aplly the inverse scale of what Libgdx will do at runtime
         labelFont.setScale((float) (1.0 / SCALE));
         // the resulting font scale is: 1.0 / SCALE * SCALE = 1
    
         //Apply Linear filtering; best choice to keep everything looking sharp
         labelFont.getRegion().getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
    }
    
    0 讨论(0)
  • 2020-12-01 00:47

    In scene2d, if you want apply antialiasing to all your labels, put this on constructor of your first screen:

    skin.getFont("default-font").getRegion().getTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
    

    This is the first screen in my game:

    ...
    public class MainMenuScreen implements Screen {    
        public MainMenuScreen() {
            ...
            skin.getFont("default-font").getRegion().getTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
        }
    }
    

    Font name is in ui.json file, check for BitmapFont and Label$LabelStyle section:

    "com.badlogic.gdx.graphics.g2d.BitmapFont": {
        "default-font": {
          "file": "default.fnt"
        }
      },
    "com.badlogic.gdx.scenes.scene2d.ui.Label$LabelStyle": {
        "default": {
          "font": "default-font",
          "fontColor": "white",
        }
      },
    
    0 讨论(0)
  • 2020-12-01 00:50

    You should definitly have a quick look on custom font shaders and/or DistanceField-Fonts. They're easy to understand and similarly easy to implement:

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

    DistanceFieldFonts stay smooth, even when you upscale them:

    enter image description here

    0 讨论(0)
  • 2020-12-01 00:53

    One solution is to use the FreeType extension to libgdx, as described here. This allows you to generate a bitmap font on the fly from a .ttf font. Typically you would do this at startup time once you know the target resolution.

    Here's an example:

    int viewportHeight;
    BitmapFont titleFont;
    BitmapFont textFont;
    
    private void createFonts() {
        FileHandle fontFile = Gdx.files.internal("data/Roboto-Bold.ttf");
        FreeTypeFontGenerator generator = new FreeTypeFontGenerator(fontFile);
        FreeTypeFontParameter parameter = new FreeTypeFontParameter();
        parameter.size = 12;
        textFont = generator.generateFont(parameter);
        parameter.size = 24;
        titleFont = generator.generateFont(parameter);
        generator.dispose();
    }
    
    0 讨论(0)
提交回复
热议问题