Nifty-GUI – Batch renderer

This is mainly aimed at @void256

I have just tried the Nifty Batch renderer, to see the effects, and i’m impressed, congrats; it does what it says on the tin. But i’m observing a lot more vertices generated, which isn’t really a problem on the desktop, but on android the advantage of batching seems to be countered by the net generated vertices. It goes from 2000 to 100,000! I also use 2 fonts, and 1 of them doesn’t seem to be displayed correctly after batching. All I have done between the 2, is add 2048, 2048 to the NiftyJmeDisplay constructor (also tried 4096 for the hell of it, but same result :)).

Before batching:

After batching (Notice the top font, and the jME stats in the bottom corner):

Notes (if it matters):

  • The screen is built using java builders
  • Each of the rows is made of 3 panels each, so it’s not really a super complex screen.

If you can’t reproduce it, then I can try and make a slimmed down test case.

Cheers

I looked liked this: :-o

Then, I commited that: http://code.google.com/p/jmonkeyengine/source/detail?r=10886 :slight_smile: Please try again with a nightly jME build. The StatsView should display correct values now!

Explanation:

Nifty internally allocates a VertexBuffer for each (Nifty-) batch. It allocates memory to store 2000 quads for each batch. Later these batches are filled with as many quads as required and the content of the VertexBuffer is updated. Unfortunately Nifty did not respect the following JavaDoc of VertexBuffer.updateData():

[java]
/* …

  • It is allowed to specify a buffer with different capacity than the
  • originally set buffer, HOWEVER, if you do so, you must
  • call Mesh.updateCounts() otherwise bizarre errors can occur.
    */…
    public void updateData(Buffer data) …
    [/java]

So, Nifty has to call mesh.updateCounts() after modifying the VertexBuffer to make the StatsView display correct values.

Thanks for reporting, Wesley! :smiley:

1 Like

nice one :), the stats are fixed, thanks!

Although I still have the issue with the text. I have 2 fonts, the .png is 512x512px for both, named Arial32 and ArialBlack (the one with the drop shadow). Where ArialBlack should be used, it looks like Arial32 is used, and the spacing is very big (see screenshot).

(I actually use 3 fonts, but 1 of them is only used when “in game”, and that screen hasn’t loaded yet, and fyi that one works fine)

Sorry, I forgot about that other Problem :wink:

Can you check the .fnt files? The first line in the .fnt starts with conten like: “info face=“Tahoma,Bold” …”. Do both of your font files contain the same value for the “face” attribute eventually? If that is the case can you modify one entry to contain a different value?

The value for “face” is used internally as the key for a Map. So when you use the same source font (“Arial”) for both fonts I suspect that the value of face is the same which would make the fonts overwrite each other when they are loaded by Nifty.

It would probably be better to use the filename for the Map key or something.

Can you confirm that the face Attribute is the issue? In that case I could fix that… if not can you provide both font files please?

1 Like

Ah nice one, they actually both had null! (these were made using the jME font creator), and my other font did have a value (got it from somewhere else).

Here’s one of the culprits:
info face=null size=42 bold=0 italic=0 charset=ASCII unicode=0 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1

I gave them both a different name and it worked like a charm! :), thanks

While you are here :P, I tried 2048 x 2048 on android and get Out of Memory errors, so I’m probably going to be forced to use 1024 x 1024 (that may even be too big as well! :s). Is there a way to use “multiple” texture atlases, or disable some screens being batched? (some of my menus have a lot of images and i’m not too bothered about the performance of those, mainly just “in-game” ones). I can understand there being many issues with a “hybrid”, so I can try work around it.

Cheers

Nice that you could fix the font issue yourself :wink: I’ve added an issue to not depend on the face attribute in the future to Niftys issue tracker at github anyway: https://github.com/void256/nifty-gui/issues/166 later.

About multiple texture atlases:

Currently the atlas texture should be cleared when a screen ends. So if you switch from one screen to another the new screen should start with a clean texture atlas so that only the resources needed for that screen are uploaded into the texture.

However, running out of texture space in the single texture atlas is currently an issue. Having multiple texture atlases (for a single screen) would not help much since switching between several texture atlases would break the purpose of batching. What could help of course would use an array texture for this but I’ve not checked if that’s available in OpenGL ES.

What could help but what is not yet available is to make the use of texture atlases explicit. So that you could decide render these elements with that texture atlas and use a different texture atlas for those other elements. Since you can probably get away with a couple of switches anyway. But if you have several texture atlases and the resources of your screen are randomly placed in these atlases you’ll end up with a lot of switching in the worst case. Not nifty :wink:

I’ve discussed some options with @3xp0n3nt before but we don’t yet have a clear plan how to improve that yet.

And there is no way to disable batching right now for a single screen too.

1 Like

ah ok, thanks for the info, help and commit (fix) :slight_smile:

I should be able to work around this now then, there’s definitely an optimization I can make, my font files take up a lot of space just by themselves! 1024 x 512px, so I will try using just 1 and even reduce the size more, as well as all my other images. Thanks again