GUI Performance Suggestions

Ive been reading about gui performance in other engines. It seems a lot of 3d engines have some sort of optimization so that each element is not a draw call. Kind of like batching. In unity, there is a plugin ($95, unfortunately) that creates an atlas of all textures used in a screen as well as the font on the fly, and intuitively uses a single draw call to draw all the elements of the gui using texture coordinates on the atlas.

Thats one of the example screenshots for the unity plugin, also there is some discussion of it on the esenthel engine forum here:
http://www.esenthel.com/community/showthread.php?tid=5031

Thoughts?

Also, general gui performance tips thread

Nifty has a batched renderer, although not tried it yet

Yes NIfty 1.3.3 has batching.
http://nifty-gui.lessvoid.com/archives/562

And nifty’s batching is only for 90$!! Just contact @void256

bargin, i’ll take 2

Nice! Thanks everyone, i never knew that.

Man, I really should charge more for the texture atlas generator that is build into Nifty, like $94.99 or so…

It’d still be cheaper than the Unity-Plugin!!!1111111111111einself :lol:

4 Likes

Hehe my own solutions works also fine and is compatible with any gui framework for jme.

A seperate framebuffer for the gui that is only renderd on changes. Is around as fast as one textures quad can get ^^ (And yes rebatching needs computation as well, as both techniques must touch each element at least once)

Is there anything similar for t0neg0dgui? I saw the texture atlas usage, can atlasing have the same performance increases as batching? Sorry void236, but I avoided nifty for some time because I was learning about t0neg0d’s gui system, and I don’t exactly have much free time to learn nifty now.

@t0neg0d

Don’t know how to tag someone, is that right?

@8Keep123 said: Is there anything similar for t0neg0dgui? I saw the texture atlas usage, can atlasing have the same performance increases as batching? Sorry void236, but I avoided nifty for some time because I was learning about t0neg0d's gui system, and I don't exactly have much free time to learn nifty now.

@t0neg0d

Don’t know how to tag someone, is that right?

There are few options in my gui library. Though, the most exciting is that the 2D framework has opened up a world of possibilities for batching (Though, there is no batching required as you decide what is contained in what mesh and this can be as infinitely large as you like) with ultimate control over every quad or 9-patch contained within an AnimElement.

You can also create parent linkage between QuadData that performs the same as armature skeletons.

You could easily build an entire UI within a single mesh and still be able to manipulate everything within the UI as if it were individual objects. This can be as finite as individuals characters within a text string of the AnimText class. All QuadData within the Mesh allow for TemporalActions to be applied to them for positioning, rotating, scaling along both axis’, pathing and texCoord manipulation either instantly, or over time (interpolated as you choose) around whatever defined origin you choose.

The new BitmapText replacement allows all of these same options on the text as a whole or the individual characters. Because of the way the text is created, there is no issues associated with rotating text either.

As for Altasing:

The support is extensive and allows for multiple atlas images.

I guess it really comes down to what it is you need. tonegodGUI is a lot more than just a GUI library, all of the games I’ve been developing as of late are completely written using nothing but the library components.

1 Like
@t0neg0d said: There are few options in my gui library. Though, the most exciting is that the 2D framework has opened up a world of possibilities for batching (Though, there is no batching required as you decide what is contained in what mesh and this can be as infinitely large as you like) with ultimate control over every quad or 9-patch contained within an AnimElement.

You can also create parent linkage between QuadData that performs the same as armature skeletons.

You could easily build an entire UI within a single mesh and still be able to manipulate everything within the UI as if it were individual objects. This can be as finite as individuals characters within a text string of the AnimText class. All QuadData within the Mesh allow for TemporalActions to be applied to them for positioning, rotating, scaling along both axis’, pathing and texCoord manipulation either instantly, or over time (interpolated as you choose) around whatever defined origin you choose.

The new BitmapText replacement allows all of these same options on the text as a whole or the individual characters. Because of the way the text is created, there is no issues associated with rotating text either.

As for Altasing:

The support is extensive and allows for multiple atlas images.

I guess it really comes down to what it is you need. tonegodGUI is a lot more than just a GUI library, all of the games I’ve been developing as of late are completely written using nothing but the library components.

im not a super coder like you haha… Could you explain what I should keep in mind get the best performance when designing and implementing my gui? I don’t understand most of what you said :frowning:

@8Keep123 said: im not a super coder like you haha... Could you explain what I should keep in mind get the best performance when designing and implementing my gui? I don't understand most of what you said :(
  1. Always use Texture Atlasing!
  2. Very kind of you to refer to me as super coder, but this won’t help improve performance :wink: Oh… and I’m a buffoon!

Side notes:

  • If you are using an Element for functionality only with no visual component, call: Element.setAsContainerOnly();
  • Certain functions have a performance impact:
    – If it effects a buffer, it will fire off an update to the GPU for that buffer.
    – Here is a list of those:
    – ** Resizing
    – ** Vertex color changes
    – ** Actually… that’s about it

Most effects are updates to shader params & do not have any significant impact.

Eventually, I’ll be providing a series of GUI components that are based of the new 2D framework. But for now, the above works fine for me!

1 Like

Thanks, so all your default elements (buttons, window, etc…) are optimized to use a single texture atlas when the texture atlas is switched on? Does using a single texture atlas mean that drawing the entire gui will only use one object and texture switch?

I saw there is documentation on the wiki, but a lot of what ive been reading in the code isnt there, is the documentation very out of date? Is the sdk plugin still updated or should I manually compile it from source?

Thanks again on all of your hard work on your plugin!

@8Keep123 said: Thanks, so all your default elements (buttons, window, etc..) are optimized to use a single texture atlas when the texture atlas is switched on? Does using a single texture atlas mean that drawing the entire gui will only use one object and texture switch?

I saw there is documentation on the wiki, but a lot of what ive been reading in the code isnt there, is the documentation very out of date? Is the sdk plugin still updated or should I manually compile it from source?

Thanks again on all of your hard work on your plugin!

Texture atlasing will use a single shared (indexed) texture for all elements rendered. So multiple elements, single texture when using the traditional GUI components. Lately, I have been clearing all renderables from components and using the 2D framework to do a bit more visually… however, you’ll find little to know performance hits with very complex UI’s.

The docs are semi-out-of-date atm, but there are common constructor for all Element based GUI components. Once you have learned how to use one… you know how to use all of them.

You won’t need to compile the source… just go to the repo linked in the documentation and grab the latest compiled jar from downloads. No clue what the state of the community plugin repo is. I don’t think it is being built anymore (at least for now) @normen could answer this better, as I believe it is on his todo list.

1 Like

Thanks!

@mifth said: Yes NIfty 1.3.3 has batching. http://nifty-gui.lessvoid.com/archives/562

Oh, I’m getting a strange Exception when using TestNiftyGui.java with the new BatchRenderer.
I’m using the latest SDK and when I remove the params 2048, 2048 the old nifty renderer works.

[java]
Nov 14, 2013 5:37:43 PM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NoClassDefFoundError: org/jglfont/spi/BitmapFontRenderer
at com.jme3.niftygui.NiftyJmeDisplay.<init>(NiftyJmeDisplay.java:129)
at mygame.Main.simpleInitApp(Main.java:85)
at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:226)
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)
Caused by: java.lang.ClassNotFoundException: org.jglfont.spi.BitmapFontRenderer
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
… 6 more
[/java]

@Ogli said: Oh, I'm getting a strange Exception when using TestNiftyGui.java with the new BatchRenderer. I'm using the latest SDK and when I remove the params 2048, 2048 the old nifty renderer works.

[java]
Nov 14, 2013 5:37:43 PM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NoClassDefFoundError: org/jglfont/spi/BitmapFontRenderer
at com.jme3.niftygui.NiftyJmeDisplay.<init>(NiftyJmeDisplay.java:129)
at mygame.Main.simpleInitApp(Main.java:85)
at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:226)
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)
Caused by: java.lang.ClassNotFoundException: org.jglfont.spi.BitmapFontRenderer
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
… 6 more
[/java]

@void256 can you check it?

The lib that does the font parsing when using the batch renderer is called jglfont and IS part of the jme repository. The jMonkeyEngine3.jar contains a reference to that lib in its MANIFEST.MF: “lib/jglfont-core.jar” which should make the lib work out of the box.

I don’t know why in your case it is not being found. When I build jme from the source and include jMonkeyEngine3.jar in eclipse it works for me.

PS: The batch renderer will not rely on jme anymore for text rendering. This is all handled inside Nifty now which will make text look the same over all NiftyRenderDevice implementations (lwjgl, jogl, jme, slick2d). And for that to work you’ll need that lib in your classpath.

Okay, since I do also have a SVN checkout of jME, I tried the test example there, and it does work.
Only the SDK version (which should include a 6 weeks old version of jME doesn’t work.

Okay, new info: When I add this lib “lib/jglfont-core.jar” to the SDK test project, it works too.
Seems like someone forgot to pack this new .jar into the SDK?

When I look at the frames-per-second I get 2755 instead of 2760 for the old renderer.
But it only includes a very small Nifty test gui with a simple lable, maybe the overhead is bigger in these rare cases?

Since I may talk with the creator of nifty here:
I see that jME has some more nifty classes called “default controls”. Somehow these weren’t part of my SVN checkout of Nifty. So this is why I couldn’t find the textfield implementation and asked this stupid question in your forum.
Now I wonder why the SVN did not include the “default controls” that jME includes…