Code sample for tabbed pane?

    this.adapter = Display.getAdapter();
    this.driverVersion = Display.getVersion();

From org.lwjgl.opengl.Display

OK. Unfortunately, Display defaults to the first video adapter, which may or may not be what we want (this is LWJGL’s fault)

I’ve also added:

System.getProperty("os.name")+" "+System.getProperty("os.arch")+" "+System.getProperty("os.version")

The last missing piece is jMonkeyEngine version :smile:

Then I’ll post the code. It should be made available as an AppState for easy inclusion on all applications, or at least put on a wiki… really, how could you live without it? Every jme project need it! :smiley:

EDIT: Also java.version will be added

Yep. But it’s the one JME will be using and so it’s still useful. For me, it wasn’t about which one the user wanted to use… it was about which one the user was going to be using regardless of what they wanted. :slight_smile: Fixes a lot of failure modes for my players if they know which one they are actually using.

One of the ways of avoiding this is by exporting a special symbol in the executable (Windows OS only):

extern "C" {
    _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
}

This forces the NVIDIA driver to run the application using the NVIDIA card and not the Intel card.
Of course, you have to built your own Java launcher to make this work, I am pretty sure Oracle’s launcher (which the SDK uses) does not export this symbol.

FYI, I was actually getting a virtual video adapter (not a real issue, but still annoying) instead of the real one.

It looks like the problem isn’t even on LWJGL, but instead lies on OpenGL itself: :sob:

Here is the code.
Shows: renderer, opengl, OS and Java info. Still missing the jMonkey version…

As I said, every monkey needs it for debugging information :wink:

    String lemurStyle="glass";
    label = new Label("Renderer: ", settings.getElementId().child("float.label"), lemurStyle);
    label.setTextHAlignment(HAlignment.Right);
    settings.getContainer().addChild(label);
    label = new Label(GL11.glGetString(GL11.GL_RENDERER), settings.getElementId().child("float.label"), lemurStyle);
    label.setTextHAlignment(HAlignment.Right);
    settings.getContainer().addChild(label, 1);
    label = new Label("Vendor:", settings.getElementId().child("float.label"), lemurStyle);
    label.setTextHAlignment(HAlignment.Right);
    settings.getContainer().addChild(label);
    label = new Label(GL11.glGetString(GL11.GL_VENDOR), settings.getElementId().child("float.label"), lemurStyle);
    label.setTextHAlignment(HAlignment.Right);
    settings.getContainer().addChild(label, 1);
    label = new Label("OpenGL:", settings.getElementId().child("float.label"), lemurStyle);
    label.setTextHAlignment(HAlignment.Right);
    settings.getContainer().addChild(label);
    String oglVersion = GL11.glGetString(GL11.GL_VERSION);

    int split = oglVersion.indexOf(' ');
    if (split >= 0) {
        oglVersion = oglVersion.substring(0, split);
    }
    String glslVersion = GL11.glGetString(GL20.GL_SHADING_LANGUAGE_VERSION);

    split = glslVersion.indexOf(' ');
    if (split >= 0) {
        glslVersion = glslVersion.substring(0, split);
    }
    label = new Label(oglVersion + " GLSL " + glslVersion, settings.getElementId().child("float.label"), lemurStyle);
    label.setTextHAlignment(HAlignment.Right);
    settings.getContainer().addChild(label, 1);
    label = new Label("GPU: ", settings.getElementId().child("float.label"), lemurStyle);
    label.setTextHAlignment(HAlignment.Right);
    settings.getContainer().addChild(label);
    label = new Label(Display.getAdapter() + " ver " + Display.getVersion(), settings.getElementId().child("float.label"), lemurStyle);
    label.setTextHAlignment(HAlignment.Right);
    settings.getContainer().addChild(label, 1);
    label = new Label("OS: ", settings.getElementId().child("float.label"), lemurStyle);
    label.setTextHAlignment(HAlignment.Right);
    settings.getContainer().addChild(label);
    label = new Label(System.getProperty("os.name") + " ver." + System.getProperty("os.version"), settings.getElementId().child("float.label"), lemurStyle);
    label.setTextHAlignment(HAlignment.Right);
    settings.getContainer().addChild(label, 1);
    label = new Label("Java: ", settings.getElementId().child("float.label"), lemurStyle);
    label.setTextHAlignment(HAlignment.Right);
    settings.getContainer().addChild(label);
    label = new Label(System.getProperty("java.version") + " " + System.getProperty("os.arch"), settings.getElementId().child("float.label"), lemurStyle);
    label.setTextHAlignment(HAlignment.Right);
    settings.getContainer().addChild(label, 1);

In theory, you should be able to collapse a lot of that code by customizing the style a little.

I haven’t tested this code but something like (for the first block):

    String lemurStyle="glass";
    
    // Setup a right aligned style for glass (could also have
    // been done for all styles
    ElementId id = settings.getElementId().child("justified.float.label");
    Styles styles = GuiGlobals.getInstance().getStyles();
    Attributes attrs = styles.getSelector(id, lemurStyle);
    attrs.set("HAlignment", HAlignment.Right); 
 
    // Then add labels using that style
    Container container = settings.getContainer();
    container.addChild(new Label("Renderer: ", id, lemurStyle));
    container.addChild(new Label(GL11.glGetString(GL11.GL_RENDERER), id, lemurStyle);
    container.addChild(new Label("Vendor:", id, lemurStyle);
    container.addChild(new Label(GL11.glGetString(GL11.GL_VENDOR), id, lemurStyle);
    container.addChild(new Label("OpenGL:", id, lemurStyle);

I’d like to change the style: font and so on.
Where should I start?

Do you want to set the style up in code or in a style file? Do you want to do it like the glass style does?

Well, I have no idea on how the glass style does (apart from the fact that it uses/mimiks CSS), so I guess I want to do it in code.

Sorry, I thought I’d already pointed to it before but I think that was a different conversation and may have been offline.

This is what the glass style definition looks like:
https://code.google.com/p/jmonkeyplatform-contributions/source/browse/trunk/Lemur/src/com/simsilica/lemur/style/base/glass-styles.groovy

Style resources like that are setup to auto merge the files if it finds multiple ones… this is why Lemur-Proto was able to easily extend the glass style for its new components just by having a properly named file in the right place:
https://code.google.com/p/jmonkeyplatform-contributions/source/browse/trunk/Lemur/extensions/LemurProto/src/main/resources/com/simsilica/lemur/style/base/glass-styles.groovy

In each of those cases, selector(“foo”, “bar”) is similar to (in Java) calling Styles.getSelector(“foo”, “bar”) and then setting values on the Attributes object. Any of the stylable properties are annotated on the particular class… so Label lets you set font, font size, text, alignment, etc. through styles.

The groovy-based style definitions are less verbose and feel more like CSS but the functionality is the same.

Here is a longer article on styling in case you haven’t seen it.

I’ve tried to apply a bitmap font. The font is correctly applied, but I also get a black square behind every character… any tip?

Also: I’ve used Panel as a container. Is there a way to set bounds?

For the font, it sounds like it’s at the same Z as whatever it is behind it and being drawn first. But maybe a picture and some code would help make sure. Actually, I think Lemur has a utility method that fixes BitmapFont materials to have their alpha discard threshold set properly which reduces this issue but really in a 2D UI it’s important to have Z setup properly in the first place for Z-ordering. I assume this is a UI in the guiNode? (I forget about the utility method because the style loader stuff runs all fonts through it automatically.)

Regarding the other, I’m not sure what you mean. Also, is there a reason you’re using a Panel as a container instead of a Container?

This is the offending code:

    Attributes attrs = styles.getSelector(Label.ELEMENT_ID, "prism");
    attrs.set("font", assetManager.loadFont("Interface/Fonts/Fontin.fnt"));
    attrs.set("fontSize", 24);

And this the result:

Without the code above, I get this result:

No it’s not! :wink: I’ve attached the Panel to a Node for moving it around.

See the pictures above? I’d like the text to remain within the border. Or at least have it cropped if too long.

Copy&paste from Lemur gems of course! :smiley:

Which Lemur gem? I think all of them that add children will do it on a Container.

The guINode sorts by Z and the regular root node sorts by whatever magic it uses to determine near/far… Lemur adds the ability to set layers to things to cause them to render later and avoid some of these issues. Even the second text you have above has borders around it because it’s being rendered before what’s behind it.

If you are ok with that look then you simply need to fix the font that you are setting using GuiGlobals’ fixFont() method.
https://code.google.com/p/jmonkeyplatform-contributions/source/browse/trunk/Lemur/src/com/simsilica/lemur/GuiGlobals.java#212

If you want to force your text to be drawn after the box then you can set a higher layer to the text to force it to sort later. You can even set that at the container level.
myContainer.setUserData(“layer”, 5)
…and see if that improves it.

Alternately, if calling setUserData() directly gives you the oogies, you can use the LayerComparator’s utility method:
LayerComparator.setLayer(myContainer, 5);

…which is probably better anyway.

1 Like

Oh well, maybe it’s the simsilica stuff :stuck_out_tongue:

Tried with:

LayerComparator.setLayer(label, 5);

also

LayerComparator.setLayer(videoSettings.getContainer(), 5);

and

LayerComparator.setLayer(videoSettings, 5);

No improvement at all.

However, this did the trick:

GuiGlobals.getInstance().fixFont(bf);

Actually, it occurs to me that the only way you will have the issue you see is if the text is in the same bucket as the background… but it looks like your background would be in the Opaque bucket since it contains no transparency.

GUI stuff should definitely be in the Transparent bucket, though. (Edit: when not in the guiNode)

1 Like

Yeah, videoSettings.setQueueBucket(Bucket.Transparent) works also.

Now I’d like to put a light near the text to make it cast a shadow. But the shadow is square :frowning:

Is the ShadowProcessor/Renderer supposed to manage the transparency, in this case of Bitmap Text?

You have to set an alpha discard threshold on the material. mat.setFloat(“AlphaDiscardThreshold”,0.1f);

2 Likes