[Patch]Readable stats against a light background

The stats display in JME3 is very useful - but it’s also unreadable against a light background.



This patch optionally places a 50% opacity black panel behind each text element, making them much more readable.



StatsAppState.java

[patch]

This patch file was generated by NetBeans IDE

It uses platform neutral UTF-8 encoding and n newlines.

— Base (BASE)

+++ Locally Modified (Based On LOCAL)

@@ -35,8 +35,13 @@

import com.jme3.app.state.AppStateManager;

import com.jme3.font.BitmapFont;

import com.jme3.font.BitmapText;

+import com.jme3.material.Material;

+import com.jme3.material.RenderState.BlendMode;

+import com.jme3.math.ColorRGBA;

+import com.jme3.scene.Geometry;

import com.jme3.scene.Node;

import com.jme3.scene.Spatial.CullHint;

+import com.jme3.scene.shape.Quad;





/**

@@ -50,14 +55,17 @@

private Application app;

protected StatsView statsView;

protected boolean showSettings = true;

  • private boolean showFps = true;
  • private boolean showStats = true;
  • private boolean showFps = true;
  • private boolean showStats = true;
  • private boolean darkenBehind = true;



    protected Node guiNode;

    protected float secondCounter = 0.0f;

    protected int frameCounter = 0;

    protected BitmapText fpsText;

    protected BitmapFont guiFont;
  • protected Geometry darkenFps;
  • protected Geometry darkenStats;



    public StatsAppState() {

    }

    @@ -110,6 +118,15 @@

    }

    }


  • public void setDarkenBehind(boolean darkenBehind) {
  •    this.darkenBehind = darkenBehind;<br />
    
  •    setEnabled(isEnabled());<br />
    
  • }

    +
  • public boolean isDarkenBehind() {
  •    return darkenBehind;<br />
    
  • }

    +

    @Override

    public void initialize(AppStateManager stateManager, Application app) {

    super.initialize(stateManager, app);

    @@ -133,6 +150,7 @@



    loadFpsText();

    loadStatsView();
  •    loadDarken();<br />
    

}



/

@@ -148,6 +166,7 @@

fpsText.setText("Frames per second");

fpsText.setCullHint(showFps ? CullHint.Never : CullHint.Always);

guiNode.attachChild(fpsText);

+

}



/


@@ -166,18 +185,40 @@

guiNode.attachChild(statsView);

}


  • public void loadDarken() {
  •    Material mat = new Material(app.assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;);<br />
    
  •    mat.setColor(&quot;Color&quot;, new ColorRGBA(0,0,0,0.5f));<br />
    
  •    mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);<br />
    

+

  •    darkenFps = new Geometry(&quot;StatsDarken&quot;, new Quad(200, fpsText.getLineHeight()));<br />
    
  •    darkenFps.setMaterial(mat);<br />
    
  •    darkenFps.setLocalTranslation(0, 0, -1);<br />
    
  •    darkenFps.setCullHint(showFps &amp;&amp; darkenBehind ? CullHint.Never : CullHint.Always);<br />
    
  •    guiNode.attachChild(darkenFps);<br />
    

+

  •    darkenStats = new Geometry(&quot;StatsDarken&quot;, new Quad(200, statsView.getHeight()));<br />
    
  •    darkenStats.setMaterial(mat);<br />
    
  •    darkenStats.setLocalTranslation(0, fpsText.getHeight(), -1);<br />
    
  •    darkenStats.setCullHint(showStats &amp;&amp; darkenBehind ? CullHint.Never : CullHint.Always);<br />
    
  •    guiNode.attachChild(darkenStats);<br />
    
  • }

    +

    @Override

    public void setEnabled(boolean enabled) {

    super.setEnabled(enabled);



    if (enabled) {

    fpsText.setCullHint(showFps ? CullHint.Never : CullHint.Always);
  •        darkenFps.setCullHint(showFps &amp;&amp; darkenBehind ? CullHint.Never : CullHint.Always);<br />
    

statsView.setEnabled(showStats);

statsView.setCullHint(showStats ? CullHint.Never : CullHint.Always);

  •        darkenStats.setCullHint(showStats &amp;&amp; darkenBehind ? CullHint.Never : CullHint.Always);<br />
    

} else {

fpsText.setCullHint(CullHint.Always);

  •        darkenFps.setCullHint(CullHint.Always);<br />
    

statsView.setEnabled(false);

statsView.setCullHint(CullHint.Always);

  •        darkenStats.setCullHint(CullHint.Always);<br />
    

}

}



@@ -201,6 +242,8 @@



guiNode.detachChild(statsView);

guiNode.detachChild(fpsText);

  •    guiNode.detachChild(darkenFps);<br />
    
  •    guiNode.detachChild(darkenStats);<br />
    

}

[/patch]



StatsView.java

[patch]

This patch file was generated by NetBeans IDE

It uses platform neutral UTF-8 encoding and n newlines.

— Base (BASE)

+++ Locally Modified (Based On LOCAL)

@@ -93,6 +93,10 @@

addControl(this);

}


  • public float getHeight() {
  •    return labels[0].getLineHeight() * statLabels.length;<br />
    
  • }

    +

    public void update(float tpf) {



    if (!isEnabled())

    [/patch]
1 Like

Is it deliberate that topics here don’t appear in the forums->latest topics list btw?

Odd, it appeared but only after I posted the reply asking about the topic not appearing!

Great idea, another way to accomplish the same thing would be to outline the text with a dark color by preprocessing the png font file.

A quick photoshop tryout:


  1. Gaussblur font.png*
  2. Invert the colors.*
  3. Add original file on top*



    *Would be a breeze to implement with ImagePainter :wink:

Yes, I did consider that but

  1. This was simple to do
  2. Modifying the font files might potentially effect other uses of those font files and/or meaning that I need to duplicate the font. As you say ImagePainter would allow it to be done dynamically but ImagePainter isn’t available so…
  3. It could even be done with a custom shader that replaces an alpha 0 pixel with a black alpha 1 pixel if any surrounding pixel is not alpha 0.



    But really: simple problem, simple solution :slight_smile:



    If someone else wants to do something more advanced feel free :smiley:

Actually it is possible to invert the color of the background where the text is, we could add another BlendMode:

2 Likes

That would certainly help too, although I don’t always find those that easy to read either. (In particular IIRC grey goes to grey - you end with grey on grey and can’t see anything)…



Having more blend modes in the tool kit is always nice though :slight_smile:

@zarch said:
...I don't always fine those...


I am disappoint. :P ;)

u r ez 2 dspnt

I’ve applied this patch.

1 Like

I tested it. It’s simple enough and does the job thanks