Wow, this is cool

[video]http://youtu.be/FYcUy5Y0oyI[/video]

Noticed the Wiki was editable again, so I started putting together tutorials for tonegodGUI, to update the documentation. This is the example of embedding GUI components into your game’s scene. Talk about freakin’ sweetness.

Three lines of code to set this up… muhahahaha. However, I want to update a portion of how it works–When I set the width/height of the OSR, the camera seems to not be placed Y-up and starts from the top of the subscreen dimensions down. /boggle. So, I need to update it to place the camera where 0,0 matches up with the 0,0 of the sub-screen so picking works properly when altering the render width/height. This just makes it possible to limit the subscreen dimensions to something that matches the geometry your rendering on to.

7 Likes

For any who want to make use of this in it’s current form… here is the setup code. I was wrong… it take 4 line of code… so I take back 1 or 2 of my ha’s from my muhaha.

[java]
subScreen = new SubScreen(screen, (Geometry)accessPanel.getChild(0));
screen.addSubScreen(subScreen);

rootNode.attachChild(subScreen.getGeometry());
subScreen.setSubScreenBridge((int)screen.getWidth(), (int)screen.getHeight(), guiSubScene);
[/java]

guiSubScene in the last line is an empty node. The OSRViewPort requires a node to use as your off-screen scene. After using the above, you can use the subScreen exactly like the screen class. Create components using the subScreen in place of screen, like so:

[java]
Window window = new Window(subScreen, Vector2f.ZERO);
subScreen.addElement(window);
window.centerToParent();
[/java]

And, ker-blam… the geometry you handed to the subscreen will now have a window on it that you can move, resize, etc, etc.

I committed an update that resolved the the sizing the viewport issue without having to move the camera.

Thats really impressive. Whats the performance hit?

@8Keep123 said: Thats really impressive. Whats the performance hit?

Good question.

It should be the same as using the off-screen rendering example in the JME docs, though I recall @madjack saying he noticed a performance increase when from switching this to OSRViewPort control in the library. Does that mean there is one? God knows.

On the other hand, nothing being rendered off screen uses lighting, etc, etc… it’s basically rendering another GUI node which also applies texture atlasing (if you are using it). So, all in all, it should have limited impact beyond what the library adds anyways.

Amazing. Nifty doesn’t compare to that. That is some awesome work!

1 Like
@squizzle said: Amazing. Nifty doesn't compare to that. That is some awesome work!

Well… you can at least render to texture with nifty, I’m just not sure about the interaction part.

You can definitely do this with Lemur (so sayeth the YouTube) @pspeed This is a correct statement, yes?

I was referring to performance. I know those systems can also do 3d but not as simple and fast as yours. Is Lemur a gui system? I thought it was mostly just a hud system.

You also put in a hell of a lot more effort then any other gui system for jme.

@squizzle said: I was referring to performance. I know those systems can also do 3d but not as simple and fast as yours. Is Lemur a gui system? I thought it was mostly just a hud system.

You also put in a hell of a lot more effort then any other gui system for jme.

Lemur is really cool. It’s coolest feature is actual 3d objects as contextual ui components. Maybe @pspeed can give you a rundown of it.

It’s really awesome work.

EDIT: I also don’t have as many different projects I am working on as Paul… he keeps JME running and growing + Lemur + ZayES (sp?) + His own game + more I am sure.

EDIT 2: I also decided to focus part of my effort in a different direction for UI, the 2D framewwork for JME games. It’s basically a port of most (if not all) functionality from LibGDX

Lemur is a GUI system that works with both 2D and 3D objects. It sees no different really between an object in the guiNode or one in the 3D scene and has been built around this concept.

For example, if you have a model already in your scene then it’s just a few lines of code to make clicking on it do something:
[java]
// Convenience method for creating or reusing the mouse event
// control when adding a listener
MouseEventControl.addListenersToSpatial( myModel, new DefaultMouseListener() {
@Override
protected void click( MouseButtonEvent event, Spatial target, Spatial capture ) {
System.out.println( “Clicked on:” + target );
}
});
[/java]

(Note: the mouse event stuff can even be used separately from the rest of Lemur.)

Lemur includes some normal GUI elements also like buttons, labels, etc… and they can be easily customized through composition. These default GUI elements are just regular JME Node extensions with a special control added. Adding this control to any other spatial will let it participate in layouts.

Also, there are some swing like layouts. Basic equivalents of Swing’s BorderLayout and GridBagLayout (SpringGridLayout) that can also be used with 3D objects.

While I’m on the subject in a thread that isn’t mine, there are some other random goodies like:
-InputMapper: wraps InputManager to provide more robust input management to include key-combos, function groups, and the ability to treat analog and ‘boolean’ inputs the same.
-MBox: like JME’s Box mesh except it can be subdivided and sides can be excluded during construction
-DMesh: wraps a mesh to provide a deformed mesh using a deformation function (this is what I use to warp the pages of my book UI which are really just textured MBoxes.)
-TbtQuad: basically a nine-patch. For stretching bordered textures.
-CSS-like style support using annotation based injection.

Pretty much all parts mentioned can be used by themselves. Together they make a GUI library.

…these reminds me that I keep meaning to post some “Lemur Gems” threads.

Back to the original topic now.

Thanks!

I really like the idea of CSS type layouts/properties/whatever.

@t0neg0d said: Thanks!

I really like the idea of CSS type layouts/properties/whatever.

Yeah, it’s “css-like” at best and based on the element ID (plus overall style)

So in the basic case, where CSS might have:
[java]
p
{
color:red;
text-align:center;
}
[/java]

Lemur might have:
[java]
selector(“label”, “myStyle”)
{
color:color(1,0,0,1)
textHAlignment=HAlignment.CENTER
}
[/java]

…or something. (“selector” being a word I stole from CSS even if it doesn’t use it in its syntax.")

And I support a similar nesting though it’s based on ID instead of hierarchy.

so in CSS:
[java]
.impact p
{
color:white
}
[/java]

…would apply to any paragraph inside of an element with class ‘impact’. Even if it’s way nested.

In Lemur, I can’t really do this because the styles are applied before the element has a hierarchy but I liked the idea and it’s still useful. So Lemur takes apart the ID and does containment that way.

So if I have some Label with a special element ID “impact.option.label” then the similar Lemur style would be:
[java]
selector(“impact”, “label”, “myStyle”)
{
color:color(1,1,1,1)
}
[/java]

…which apply to any label with “impact.label”, “impact.foo.bar.label”, and our original “impact.option.label”.

Anything applied to the style directly would be the default for any gui element of that style. So if I want all of the fonts of “myStyle” to default to some special font:
[java]
selector(“myStyle”)
{
font:font(“Interface/arial.fnt”)
}
[/java]

Any GUI element property with a Style annotation can be set this way. So it just depends on what the GUI element has defined… but layouts, insets, font, font size, etc. are all pretty standard.

Also note: in the above examples I intentionally left the formatting similar to the CSS though I generally use C-style formatting in my own style files.

And because the style file is actually a groovy script, you can do a little coding there too. So here is a snippet of one of my actual style files (for the book UI):
[java]
// Defaults for the style
selector(“book-paper”) {
font = font(“Interface/templar64.fnt”)
color = color(0.1, 0.3, 70f/255, 0.70)

highlightColor = color(0.0, 0.5, 0.6, 0.980)
highlightShadowColor = color(0, 0, 0, 0.5)
shadowColor = color(0, 0, 0, 0);

// For any containers... by default this will be their layout
layout = new SpringGridLayout();

}

// The root container for a page
selector(“page”, “book-paper”) {
insets = new Insets3f(10, 20, 10, 10);
}

selector(“button”, “book-paper”) {
fontSize = 52
insets = new Insets3f(10, 20, 0, 0);
}

selector(“bookmark.button”, “book-paper”) {
background = new QuadBackgroundComponent(texture(“Interface/ribbon.png”))
background.setMargin(48, 7)
background.color = color(0.2, 0.5, 0.6, 1)

color = color(161/255f, 134/255f, 51f/255, 0.7)
highlightColor = color(0.9, 0.9, 0.6, 0.80)

}
[/java]

And a final note: the style stuff is not dependent on any other Lemur classes and can be used independently for any other classes/objects that may want similar “cascading” attribute setting behavior.

Edit: P.S.: at some point I will add a “style” keyword that can be used to wrap a bunch of selectors so that you don’t have to keep repeating the style name every time.

Edit2: got rid of an erroneous comment… gotta clean up this file someday.

1 Like

This is really, really cool.

So, the styles are defined in? For instance:

[java]
.impact p
{
color:white
}
[/java]

is css(ish)… but, I’m assuming it’s java using something like groovy? Or is it parsed from an external file? I’m so unfamiliar with how this would be done. /cry

EDIT: I saw you mention the style files are groovy… but which of the above is the actual style file (I assume the more java(ish) one) and how do you extract info from the css-like files?

It’s a really interesting approach to simplifying something that isn’t so simple.

@t0neg0d said: This is really, really cool.

So, the styles are defined in? For instance:

[java]
.impact p
{
color:white
}
[/java]

is css(ish)… but, I’m assuming it’s java using something like groovy? Or is it parsed from an external file? I’m so unfamiliar with how this would be done. /cry

EDIT: I saw you mention the style files are groovy… but which of the above is the actual style file (I assume the more java(ish) one) and how do you extract info from the css-like files?

It’s a really interesting approach to simplifying something that isn’t so simple.

I was giving actual CSS examples along side the Lemur-style examples. So anything that as ‘p’ in it is just CSS for demonstration purposes and then the following snippet shows Lemur styles doing a similar configuration.

I hope that clarifies.

To answer your other question that I skipped…

The styles files are pretty much straight groovy that I preload a “style” API for… so I provide some convenience functions for loading fonts, textures, colors, etc… I may add more later but I was trying to keep the API as lean as possible… and as dependency-free as possible.

You can also setup styles directly in Java code if preferred.

[java]
Attributes attrs = styles.getAttributes(“label”, “myStyle”);
attrs.set(“color”, new ColorRGBA(1, 0, 0, 1));
attrs.set(“font”, assetManager.loadFont(“Interface/arial.fnt”));
…and so on…
[/java]

@pspeed said: To answer your other question that I skipped...

The styles files are pretty much straight groovy that I preload a “style” API for… so I provide some convenience functions for loading fonts, textures, colors, etc… I may add more later but I was trying to keep the API as lean as possible… and as dependency-free as possible.

You can also setup styles directly in Java code if preferred.

[java]
Attributes attrs = styles.getAttributes(“label”, “myStyle”);
attrs.set(“color”, new ColorRGBA(1, 0, 0, 1));
attrs.set(“font”, assetManager.loadFont(“Interface/arial.fnt”));
…and so on…
[/java]

I like this… atm these are defined through xml on this side, stored in a style manager that you can retrieve values from… but I personally think it becomes semi-cryptic because you have to remember the Style’s key and attribute’s key. I like the idea of self contained attributes that can be handed to any component. Takes the having to remember key names out of the equation.

On the back side, styles work the same for all components, which makes it simple to alter… but I can’t say I’m thrilled with the setup (easy for the user… not for me!)

@t0neg0d said: I like this... atm these are defined through xml on this side, stored in a style manager that you can retrieve values from... but I personally think it becomes semi-cryptic because you have to remember the Style's key and attribute's key. I like the idea of self contained attributes that can be handed to any component. Takes the *having to remember key names* out of the equation.

On the back side, styles work the same for all components, which makes it simple to alter… but I can’t say I’m thrilled with the setup (easy for the user… not for me!)

On the code side, a class sets itself up to receive styles by annotating its setters:
[java]
@StyleAttribute(“color”)
public void setColor( ColorRGBA color ) {
text.setColor(color);
}
[/java]

Then during creation the styles are applied like:
[java]
styles.applyStyles(this, elementId, style);
[/java]
…which assumes the global Styles object was looked up already.

Though the style system doesn’t care when you apply styles. The default Lemur GUI components do it in the constructor.

Also, while I’m here, a class can define a set of default styles for itself:
[java]
@StyleDefaults(ELEMENT_ID)
public static void initializeDefaultStyles( Attributes attrs ) {
attrs.set(“background”, new QuadBackgroundComponent(new ColorRGBA(0,0,0,0)), false);
attrs.set(“highlightColor”, ColorRGBA.Yellow, false);
attrs.set(“shadowColor”, new ColorRGBA(0, 0, 0, 0.5f), false);
}
[/java]

This will be run by the style system the first time this class is encountered. There is an alternate form that takes the Styles object as a parameter in addition to the attributes.

@pspeed said: On the code side, a class sets itself up to receive styles by annotating its setters: [java] @StyleAttribute("color") public void setColor( ColorRGBA color ) { text.setColor(color); } [/java]

Then during creation the styles are applied like:
[java]
styles.applyStyles(this, elementId, style);
[/java]
…which assumes the global Styles object was looked up already.

Though the style system doesn’t care when you apply styles. The default Lemur GUI components do it in the constructor.

Also, while I’m here, a class can define a set of default styles for itself:
[java]
@StyleDefaults(ELEMENT_ID)
public static void initializeDefaultStyles( Attributes attrs ) {
attrs.set(“background”, new QuadBackgroundComponent(new ColorRGBA(0,0,0,0)), false);
attrs.set(“highlightColor”, ColorRGBA.Yellow, false);
attrs.set(“shadowColor”, new ColorRGBA(0, 0, 0, 0.5f), false);
}
[/java]

This will be run by the style system the first time this class is encountered. There is an alternate form that takes the Styles object as a parameter in addition to the attributes.

Aside from the use of annotations, how the end user perceives/implements styles is very similiar

Style are defined by control type and the globals are used during construction.
These can be altered on a global sense via xml, or through the style manage.
And in the end each control con be altered to be whatever you need that instance to do.

Big differences that I see (aside from implementation, obviously) is the multiple options you provided for setting, changing, altering styles. Lots of choices… which is nice, seeing as everyone’s coding style is different.

In ine, you define styles globally via XML… that’s the only option atm.
Past this, you have multiple options for how you define, alter and change.

Though, I think the annotation idea is cool :wink:

On a semi-unrelated note… I’ve made some serious progress with the replacement for BitmapText I’m working on… this still uses BitmapFont as a backing, however, all of the issues I’ve encounter (personally) with BitmapText really seem to revolve around vertical and horizontal alignment.

I’ve added Character and Word line-wrapping and all seems to work really well with dynamic resizing. There is a lot less involved in this implementation, so running tests against BitmapText, I’m already seeing a decent increase in performance with dynamic text-wrapping and a test that I use that constantly changes the string being used (basically the same paragraph is passed to setText() every frame)

The 2D framework is completely separate from the GUI library, but can be easily wrapped into Element based components, this way, people can make use of animation system without having to use any of the core components like Screen.

Long winded story for this… perhaps you can take a look at the AnimElement & AnimText classes after I am finish it up and see if any of the approaches would be useful when someone builds up the nerve to rewrite BitmapText (I wouldn’t want that job… )

My ultimate dreeeaaam for that whole system is to have it leverage geometry instancing and not have to update the buffers on the CPU. But, that can’t happen yet.

I have designed a new BitmapText on paper that also fixes some problems in BitmapFont as well as the overall design and interaction between the two… I’m just wary of doing anything with it because a) it’s a lot of time to make sure it works the same in 100% of cases, and b) it’s a hell from which I fear there is no return. :wink:

The next time I have to fix a bug in BitmapText that requires more than duct tape and bailing wire then I’ll probably throw the whole thing out.

1 Like
@pspeed said: I have designed a new BitmapText on paper that also fixes some problems in BitmapFont as well as the overall design and interaction between the two... I'm just wary of doing anything with it because a) it's a lot of time to make sure it works the same in 100% of cases, and b) it's a hell from which I fear there is no return. ;)

The next time I have to fix a bug in BitmapText that requires more than duct tape and bailing wire then I’ll probably throw the whole thing out.

The BIGGEST issue I’m having at the moment with BitmapFont, is the lack of JavaDoc info for methods. It’s like bobbing for apples without the unsanitary condition.