Text not rendering well

Hey everyone:

I tried to add black text, but it is gray and pixelated, take a look at this screen shot:

Any suggestions on how to get a better result?

Here is my test code:

package jme3;

import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapFont;
import com.jme3.font.BitmapText;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Node;
import com.jme3.scene.debug.WireBox;

public class TextTest extends SimpleApplication {
  @Override
  public void simpleInitApp() {
    viewPort.setBackgroundColor(ColorRGBA.White);

    Node box = createNumberedBox();
    rootNode.attachChild(box);
    
    cam.setLocation(new Vector3f(0,0,500));
  }

  private Node createNumberedBox() {
    Node node = new Node("Box");

    Mesh m = new WireBox(100, 100, 100);
    Geometry geom = new Geometry("WireBox", m);
    Material mat = new Material(assetManager,"Common/MatDefs/Misc/Unshaded.j3md");
    mat.getAdditionalRenderState().setLineWidth(2);
    mat.setColor("Color", ColorRGBA.Black);
    geom.setMaterial(mat);
    node.attachChild(geom);
    
    BitmapFont font = assetManager.loadFont("Interface/Fonts/Default.fnt");
    BitmapText text = new BitmapText(font);
    text.setColor(ColorRGBA.Black);
    text.setSize(25);
    text.setText("Test");
    text.setLocalTranslation(-98, 95, 100.01f);
    node.attachChild(text);

    return node;
  }
  
  public static void main(String[] args) {
    new TextTest().start();
  }  
}

It looks to me like your font was rendered at a smaller pixel size - these are bitmapped fonts, which means that a set of images are saved with the letters pre-rendered along with a lookup table. If you use those images at the same display size as they were rendered, your text will be pretty crisp (though not quite as high quality as a hinted vector font would render). If you use them at a larger display size than they were rendered, the quality drops very quickly - text is very sensitive to how it is displayed (hence why font hinting is so important).

Pretty much your only options (short of switching to something that renders vector fonts, which is going to be quite labor intensive) are to get a font file that’s rendered for display at 25 points or to set your text display size much smaller.

If you want to generate your own fonts, I think there is still a font generator in the SDK.

There is also a tool you can find on the internet called Hiero which is very nice.

As a last resort, there is also the original bitmap font creator BMFont by Angelcode.
https://www.angelcode.com/products/bmfont/

1 Like

I came across the JME-TTF user contributed project https://github.com/ATryder/jME-TTF and I think it is going to give me a good solution.

Here is my new screenshot:

Here is the code:

package jme3;

import com.atr.jme.font.TrueTypeBMP;
import com.atr.jme.font.TrueTypeFont;
import com.atr.jme.font.asset.TrueTypeKeyBMP;
import com.atr.jme.font.asset.TrueTypeLoader;
import com.atr.jme.font.shape.TrueTypeNode;
import com.atr.jme.font.util.Style;
import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapFont;
import com.jme3.font.BitmapText;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Node;
import com.jme3.scene.debug.WireBox;

public class TextTest extends SimpleApplication {
  @Override
  public void simpleInitApp() {
    assetManager.registerLoader(TrueTypeLoader.class, "ttf");

    TrueTypeKeyBMP ttk = new TrueTypeKeyBMP(
        "fonts/LeagueGothic-1.601/static/TTF/LeagueGothic-Regular.ttf",
        Style.Plain, 100);
    @SuppressWarnings({ "unchecked", "rawtypes" })
    TrueTypeFont ttf = (TrueTypeBMP)assetManager.loadAsset(ttk);
    ttf.setScale(25f/100f);
    
    viewPort.setBackgroundColor(ColorRGBA.White);

    Node box = createNumberedBox(ttf);
    rootNode.attachChild(box);
    
    cam.setLocation(new Vector3f(0,0,500));
  }

  @SuppressWarnings("rawtypes")
  private Node createNumberedBox(TrueTypeFont ttf) {
    Node node = new Node("Box");

    Mesh m = new WireBox(100, 100, 100);
    Geometry geom = new Geometry("WireBox", m);
    Material mat = new Material(assetManager,"Common/MatDefs/Misc/Unshaded.j3md");
    mat.getAdditionalRenderState  ().setLineWidth(2);
    mat.setColor("Color", ColorRGBA.Black);
    geom.setMaterial(mat);
    node.attachChild(geom);
    
    TrueTypeNode<?> trueNode = ttf.getText("Test", 0, ColorRGBA.Black);
    trueNode.setLocalTranslation(-98, 95, 100.01f);
    node.attachChild(trueNode);
    
    return node;
  }
  
  public static void main(String[] args) {
    new TextTest().start();
  }  
}

The font is release with an open license at https://github.com/theleagueof/league-gothic

Tryder stopped maintaining JME-TTF back in May 2021. For the latest version, please see GitHub - stephengold/jME-TTF: A TrueType font rendering subsystem for jMonkeyEngine.

2 Likes

That is good to know, thanks for the link!

1 Like