Problems with fonts

Hi!

I tried to show a negative number in the HUD with the default tonegodgui font. But the minus sign did not show up. I thought that maybe it was the font that didn’t have the minus sign. What’s up with the minus sign?

Also, I tried setting the font in the style to the default jME font, Interface/Fonts/Default.fnt, but then I got the following error, why?

java.lang.IllegalArgumentException: Material parameter is not defined: Clipping
at com.jme3.material.Material.checkSetParam(Material.java:446)
at com.jme3.material.Material.setParam(Material.java:462)
at com.jme3.material.Material.setVector4(Material.java:653)
at tonegod.gui.core.Element.setFontPages(Element.java:2306)
at tonegod.gui.core.Element.updateLocalClipping(Element.java:2281)
at tonegod.gui.core.Element.updateClipping(Element.java:2250)
at tonegod.gui.core.Element.updateNodeLocation(Element.java:957)
at tonegod.gui.core.Element.setY(Element.java:952)
at tonegod.gui.core.Element.addChild(Element.java:412)
at game.client.hud.proxy$tonegod.gui.controls.extras.ChatBox$0.addChild(Unknown Source)
at tonegod.gui.controls.extras.ChatBox.<init>(ChatBox.java:155)
at tonegod.gui.controls.extras.ChatBox.<init>(ChatBox.java:107)
at game.client.hud.proxy$tonegod.gui.controls.extras.ChatBox$0.<init>(Unknown Source)
at game.client.hud$init_hud_system.invoke(hud.clj:51)
at game.client.core$create_client_jme3_app$simple_init_fn__7162.invoke(core.clj:167)
at game.common.core_functions$create_jme3_app$fn__6070.invoke(core_functions.clj:33)
at game.common.core_functions.proxy$com.jme3.app.SimpleApplication$0.simpleInitApp(Unknown Source)
at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:226)
at game.common.core_functions.proxy$com.jme3.app.SimpleApplication$0.initialize(Unknown Source)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:130)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:207)
at java.lang.Thread.run(Thread.java:722)

the GUI library replaces the font loader from JME.

All you need to do is load the font again and all should be fine (the JME font that is).

EDIT: The reason is:

JME loads the ui font prior to the new Loader being registered. It is not using the libraries shader. Reloading the font will point it to the libraries shader for rendering.

EDIT 2: Likey, the default font sampling from the font texture in a way that is missing the single line of pixels (or blurring to the point of being non-visible). I’ve noticed this with lower case I and L as well.

@t0neg0d I’m not sure I understand what you mean. Load it again? When?

@tuffe said: @t0neg0d I'm not sure I understand what you mean. Load it again? When?

When JME initializes SimpleApplication, it loads the font used to display statistics. This happens prior to you initializing the screen class. Suring the initialization of your screen, I unload JME’s standard font loader and replace it with a custom one so I can apply clipping to text. Basically there is a material associated with the font so the GPU knows what shader to render it with.

The way you load a font is:

[java]
assetManager.loadFont(“path/To/Bitmap/Font”);
[/java]

Since the BitmapFontLoader is changed out, you’ll have to load the font JME uses, using this method, so it is pointing at the proper shader prior to using it as a tonegodGUI font.

@t0neg0d

So if I understand you correctly, I’m just gonna use assetManager.loadFont to load the standard font, because if I just use it via the style xml file, it will not get loaded properly?

Is this just with that particular font, because it is cached or something? Because otherwise, what good is the font in the style?

And then I’m gonna use Element.setFont(), or what? Is there a way to set it globally?

When you say that you unload JME’s standard font loader, that sounds bad. Can you not load a font without swapping loaders? Modifying state like that behind the scenes is never good.

@tuffe said: @t0neg0d

So if I understand you correctly, I’m just gonna use assetManager.loadFont to load the standard font, because if I just use it via the style xml file, it will not get loaded properly?

Is this just with that particular font, because it is cached or something? Because otherwise, what good is the font in the style?

And then I’m gonna use Element.setFont(), or what? Is there a way to set it globally?

When you say that you unload JME’s standard font loader, that sounds bad. Can you not load a font without swapping loaders? Modifying state like that behind the scenes is never good.

It should load fine through the xml def file.

How are you referencing the font once you’ve loaded it? Or is it being reference by the library controls themselves after this?

If you can throw together a minimal test app showing the issue and just paste the code here so I can accurately repro the issue, I’ll get this fixed right away.

@t0neg0d

I set the line:

<property name=“defaultFont” type=“String” value=“gamedef/Fonts/tonegodGUI.fnt” />

in Fonts.xml to:

<property name=“defaultFont” type=“String” value=“Interface/Fonts/Default.fnt” />

Then I tried making a very simple HUD (in Clojure, but I think you will understand):

[java]
(defn init-hud-system [app]
(let [gui-node (.getGuiNode app)
screen (Screen. app “gamedef/style_map.xml”)
pw consts/portrait-width
ph consts/portrait-height
ry consts/resolution-y
ch consts/chat-height
cw consts/chat-width
gap 2
psize (Vector2f. pw ph)
self-label (Label. screen “self” (Vector2f. gap gap) psize)
target-label (Label. screen “target” (Vector2f. (+ pw (* 2 gap)) gap)
psize)
chat-box (proxy [ChatBox]
[screen “chat”
(Vector2f. gap (- ry ch gap))
(Vector2f. cw ch)]
(onSendMsg [msg]
(.receiveMsg this msg)))]
(.setTextVAlign self-label BitmapFont$VAlign/Top)
(.setTextVAlign target-label BitmapFont$VAlign/Top)
(.addElement screen self-label)
(.addElement screen target-label)
(.addElement screen chat-box)
(.setGlobalAlpha screen 1)
(->HudSystem gui-node screen chat-box self-label target-label)))[/java]

I’m only using a ChatBox and two Labels and adding them to a screen (and later adding screen to guiNode). (Sceen. args) = new Screen(args). (.method obj args) = obj.method(args).

And I don’t know about “referencing”, I thought it would just work once I set the font in the style.

EDIT: I don’ mean to be lazy by not making a test app. But really I just changed the font in the XML file. Try it yourself, that will probably do it.

Sounds simple enough. I’ll run the test here and see if can repro the issue.

The only thing that sounds out-of-place is the last note you added to the post above.

Initializing the screen class adds a node to the guiNode that all elements are attached to via screen.addElement(el). This is for limiting what picking is selecting against.

In the mean time, just try initializing the single screen class and then build/attach your components.

If you are looking for a Nifty-like implementation of multiple “screens”, this is accomplished using AppStates in tonegodGUI.

@t0neg0d

Sorry, what last note? That I’m attaching the screen to the guiNode? I tried not doing that but it made no difference.

EDIT: I don’t know what you are talking about with the sceen node thing. If the screen is not added to the guiNode, nothing shows up.

When you say adding to the guiNode, are you adding the screen as a control? i.e. guiNode.addControl(screen);?

Ok…

I tested this with the following and all seems to work fine.

FontTest.java
[java]
package test;

import com.jme3.app.SimpleApplication;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.math.Vector2f;
import com.jme3.renderer.RenderManager;
import tonegod.gui.controls.buttons.ButtonAdapter;
import tonegod.gui.core.Screen;

/**

  • test

  • @author normenhansen
    */
    public class FontTest extends SimpleApplication implements ActionListener {
    Screen screen;
    ButtonAdapter b1;

    public static void main(String[] args) {
    FontTest app = new FontTest();
    app.start();
    }

    @Override
    public void simpleInitApp() {
    flyCam.setDragToRotate(true);
    flyCam.setMoveSpeed(15f);
    inputManager.setCursorVisible(true);

     screen = new Screen(this, "Interface/style_map.xml");
     guiNode.addControl(screen);
     
     b1 = new ButtonAdapter(screen, Vector2f.ZERO) {
     	@Override
     	public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
     		System.out.println("Hi");
     	}
     };
     b1.setText("JME Font");
     b1.setFontSize(16);
     screen.addElement(b1);
    

    }

    private void setupKeys() {

    }

    @Override
    public void simpleUpdate(float tpf) {

    }

    @Override
    public void simpleRender(RenderManager rm) {
    //TODO: add render code
    }

    public void onAction(String name, boolean isPressed, float tpf) {

    }
    }

[/java]

And the modified xml files:

[java]
// style_map.xml
<?xml version=“1.0” encoding=“UTF-8”?>
<root>
<cursors path=“tonegod/gui/style/def/Common/Cursors/Cursors.xml” />
<audio path=“tonegod/gui/style/def/Common/Audio/Audio.xml” />
<style control=“Font” path=“Interface/Fonts.xml” /> // <<<<< pointing to local copy
<style control=“Common” path=“tonegod/gui/style/def/Common/Common.xml” />
<style control=“Scrolling” path=“tonegod/gui/style/def/Scrolling/Scrolling.xml” />
<style control=“Window” path=“tonegod/gui/style/def/Window/Window.xml” />
<style control=“Button” path=“tonegod/gui/style/def/Button/Button.xml” />
<style control=“Dial” path=“tonegod/gui/style/def/Dial/Dial.xml” />
<style control=“Menu” path=“tonegod/gui/style/def/Menu/Menu.xml” />
<style control=“Label” path=“tonegod/gui/style/def/Label/Label.xml” />
<style control=“Slider” path=“tonegod/gui/style/def/Slider/Slider.xml” />
<style control=“Spinner” path=“tonegod/gui/style/def/Spinner/Spinner.xml” />
<style control=“TextField” path=“tonegod/gui/style/def/TextField/TextField.xml” />
<style control=“TabControl” path=“tonegod/gui/style/def/Tabs/Tabs.xml” />
<style control=“ChatBox” path=“tonegod/gui/style/def/ChatBox/ChatBox.xml” />
<style control=“Indicator” path=“tonegod/gui/style/def/Common/Extras/Indicator.xml” />
<style control=“ColorWheel” path=“tonegod/gui/style/def/Common/Extras/ColorWheel.xml” />
</root>

// Fonts.xml
<?xml version=“1.0” encoding=“UTF-8”?>
<root>
<element name=“Font”>
<font>
<property name=“defaultFont” type=“String” value=“Interface/Fonts/Console.fnt” /> // <<<< JME’s console font
</font>
<attributes></attributes>
<images></images>
<effects></effects>
</element>
</root>
[/java]

@t0neg0d

Yeah I just tried that too, and it works with Console.fnt but not Default.fnt.

You can copy the .fnt and .png files to a local asset directory and change this in the first line of the .fnt file and all will work fine:

charset=“ASCII”

to

charset=""

I’ll see about updating the FontLoader to make sure this doesn’t happen. Thanks for the catch.

Actually… not sure what the issue is with this particular font, I just went through the loader looking for the issue and couldn’t find anything that looked odd, so I opened back up the .fnt file, set charset=“ASCII” again, and the font loaded fine.

So, it is possible that the file is corrupt in some odd manner? Just open the local copy, set chatset="" save… then retype ASCII and save again and it will run fine. /boggle

Hm, yeah. Very strange.