Text on Texture

I tried searching, but it's hard when "text" searches produce results with "texture".



I'm trying to apply some text onto a surface of a disc. There is a texture in place on the disc, but we also want numbers to indicate the current value that disc is. This number can change over time and I was hoping that we could just change the number instead of having to have all possible numbers on the texture and loading the appropriate one. If it has to be that way but can be done on the fly, i'll at least take that instead. The number should be visible as if it was actually written on the disc.



Thanks.

Try a search for multitexturing - you can use that to apply a base texture then either blend the number with it or apply it as a decal. You could perhaps modify one of the text label classes out there if you need to generate the number textures on the fly.

I modified the util from hevee a bit http://www.jmonkeyengine.com/jmeforum/index.php?topic=6485.0



The two essential methods:


  private float blurIntensity = 0.03f;

  private int kernelSize = 5;

  private ConvolveOp blur;

  private Color foreground = new Color(1f, 1f, 1f);

  private Color background = new Color(0f, 0f, 0f);

  private float fontResolution = 512;

  private int imageWidth = 512;

  private int imageHeight = 512;

  private int shadowOffsetX = 2;

  private int shadowOffsetY = 2;

  private Font font;

  private boolean drawShadow;

  private BufferedImage getImage() {
    BufferedImage tmp0 = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB);
    Graphics2D g2d = (Graphics2D)tmp0.getGraphics();
    Font drawFont = font.deriveFont(fontResolution);
    g2d.setFont(drawFont);
    Rectangle2D b = g2d.getFontMetrics().getStringBounds(text, g2d);

    tmp0 = new BufferedImage((int)b.getWidth(), (int)b.getHeight(), BufferedImage.TYPE_INT_ARGB);

    g2d = (Graphics2D)tmp0.getGraphics();
    g2d.setFont(drawFont);
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

    int textX = 0;
    int textY = g2d.getFontMetrics().getMaxAscent() - kernelSize / 2;

    if (drawShadow) {
      g2d.setColor(background);
      g2d.drawString(text, textX + shadowOffsetX, textY + shadowOffsetY);
    } // if

    BufferedImage ret = blur.filter(tmp0, null);
    g2d = (Graphics2D)ret.getGraphics();

    g2d.setFont(drawFont);
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

    g2d.setColor(foreground);
    g2d.drawString(text, textX, textY);

    return ret;
  }


  public TextureState getTextureState(String text, boolean drawShadow, int imageWidth, int imageHeight,
      float fontResolution, Color color, Color shadowColor) {

    this.text = text;
    this.drawShadow = drawShadow;
    this.imageWidth = imageWidth;
    this.imageHeight = imageHeight;
    this.fontResolution = fontResolution;
    updateKernel();
    setFont(Font.decode("Arial BOLD 512"));

    BufferedImage img = getImage();

    TextureState ts = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
    Texture tex = TextureManager.loadTexture(img, MinificationFilter.Trilinear, MagnificationFilter.Bilinear, true);
    ts.setTexture(tex);
    ts.setEnabled(true);

    cache.put(text, ts);
    return ts;
  }



That way the text will always use the full width of a rectangular texture and it  WON'T scale the height of the text