Z-Order on Gui Node

Is there a way to set the order of gui-node objects? I want to control the z-order to display the jme statistic on top then the nifty gui and at least my own hud.

What about the y localtranslation value?

Hmm, has nifty a localTranslation?



And i tried to set my hud in y and z translated, y doesnt has an effect and z value over 1/-1 makes my hud dissappear.



So i don't think thats the way, is it?

I think i read in the Nifty doc that layers were drawn from back to front in the order they were declared in the xml file.

you could render every layer in nifty

and here is the link

http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Layout_Introduction



maybe that could help you

Thanks, but it's not only nifty related. For my problem i need only 1 nifty layer but need the nifty rendered in front of a hud rendered orthogonal in the gui bucket of jme. Also the statistic view i want to render in front of the hud.

Heres a picture.

According to the GUIComparator UIElements are sorted by zOrder.



public class GuiComparator implements GeometryComparator {

    public int compare(Geometry o1, Geometry o2) {
        if (o1 instanceof UIElement && o2 instanceof UIElement){
            UIElement e1 = (UIElement) o1;
            UIElement e2 = (UIElement) o2;
            if (e1.getZOrder() > e2.getZOrder())
                return 1;
            else if (e1.getZOrder() < e2.getZOrder())
                return -1;
            else
                return 0;
        }
        return 0;
    }

    public void setCamera(Camera cam) {
    }

}



Maybe your different GUI elements should implement UIElement so that you can set the zOrder value.

I tried it , but is has no effect. Perhaps it isn't implemented yet.

Works for me like a charm:

I have two classes:


   class CursorImage extends Geometry implements UIElement {
      public CursorImage() {
         super("mouseCursor", new Quad(20f, 20f, true));
      }

      @Override
      public int getZOrder() {
         return 3;
      }

      @Override
      public void setZOrder(int order) {

      }
   }

public class MenuItem extends BitmapText implements UIElement {
   @Override
   public int getZOrder() {
      return 2;
   }

   @Override
   public void setZOrder(int order) {
   }
}



And initialize them like:


   private void createCursorImage(int width, int height) {
      cursorImage = new CursorImage();
      cursorImage.setLocalRotation(new Quaternion().fromAngleAxis(
            -FastMath.HALF_PI, Vector3f.UNIT_Z));
      cursorImage.setCullHint(CullHint.Never);
      cursorImage.setQueueBucket(Bucket.Gui);
      cursorImage.updateModelBound();
   }



Initialization of menu node is similar. And until I used UIElement, the cursor was behind the menu, what is definitely wrong.

After carefully reading your post, I see that you are using Nifty and "normal" geometry. In this case I think u need to look at JME sources to see if Nifty has any ZOrder set. And if not u might wanna add it. :)

It seems that problem is bit more complicated. In examples Nifty activated as:


guiViewPort.addProcessor(niftyDisplay);



and I think you are adding your geometry to "guiNode", which is actually attached as Scene in SimpleApplication:


guiViewPort.attachScene(guiNode);


and all scenes are processed after processors. This mean your GUI will always be drawn on top of Nifty GUI.
As solution I could only suggest try, create new viewPort for Nifty:


niftyViewPort = renderManager.createPostView("Nifty view", cam);
niftyViewPort .addProcessor(niftyDisplay);

Unfortunately the scene isn't visible after making a new viewport.

ViewPort niftyViewPort = renderManager.createPostView("Nifty view", cam);
      NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager,
            inputManager, audioRenderer, niftyViewPort);
      niftyViewPort.addProcessor(niftyDisplay);



And concerning the other problem. I implements the UIElement on jme's StatsView:

@Override
   public int getZOrder() {
      return 1;
   }



and on my own Geomtry:

protected class HudGeometry extends Geometry implements UIElement {

      private int zOrder = 0;

      public HudGeometry(String name, Quad q) {
         super(name, q);
      }

      @Override
      public void setZOrder(int zOrder) {
         this.zOrder = zOrder;
      }

      @Override
      public int getZOrder() {
         return zOrder;
      }
   }



But no effect. I tried the zOrder to be 1 on stats and 2 on hud and reverse and both objects are include in the gui-node and in gui render bucket.

A solution would be to implement your own GUI processor and add it to the viewPort after the NiftyProcessor

Processors are executed in the order you add them.

You need to add following line:


niftyViewPort.setClearEnabled(false);


So your geometry will be visible.

Concerning ZOrder problem, I made a simple test and it works, you can play with it yourself:



package jme3test.gui;

import com.jme3.app.SimpleApplication;
import com.jme3.ui.Picture;
import com.jme3.ui.UIElement;

public class TestOrtho extends SimpleApplication {

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

   class MyPic extends Picture implements UIElement {
      int order;

      public MyPic(int order) {
         super("MyPic");
         setZOrder(order);
      }

      public int getZOrder() {
         return order;
      }

      public void setZOrder(int order) {
         this.order = order;
      }
   }

   public void simpleInitApp() {
      Picture p = new MyPic(2);
      p.setPosition(0, 0);
      p.setWidth(100);
      p.setHeight(100);
      p.setImage(assetManager, "Interface/Logo/Monkey.png", false);
      p.setLocalTranslation(200, 200, 0);

      Picture p2 = new MyPic(1);
      p2.setPosition(0, 0);
      p2.setWidth(100);
      p2.setHeight(100);
      p2.setImage(assetManager, "Interface/Logo/Monkey.png", false);
      p2.setLocalTranslation(250, 250, 0);

      // attach geometry to orthoNode
      guiNode.attachChild(p);
      guiNode.attachChild(p2);
   }

}

Yes the scene is now visible again. But nifty is still rendered behind the hud. Hmm :?. The gui viewport seems to be rendered last cause without "niftyViewPort.setClearEnabled(false);" the hud is still visible.



Yap this i found in RenderManager:

 public void render(float tpf){
         for (int i = preViewPorts.size() - 1; i >= 0; i--){
             renderViewPort(preViewPorts.get(i), tpf);
         }
         for (int i = viewPorts.size() - 1; i >= 0; i--){
             renderViewPort(viewPorts.get(i), tpf);
         }
         for (int i = postViewPorts.size() - 1; i >= 0; i--){
             renderViewPort(postViewPorts.get(i), tpf);
         }
     }


And the other problem seems to be that the StatsView is a Node not a Geomtry. So Nodes aren't compared, right?



Thanks a lot to you, i think there are only a few steps to get the problems solved .

Ye, nodes are not compared. It should be implemented by Geometry.



Regarding order issue. With JME hack I managed to get them in proper order, and now I'm trying the get it working in proper way.



Just if you re curious, the hack is to change render method in Render manager to smth like:


      for (int i =0; i < = postViewPorts.size(); i++) {
         renderViewPort(postViewPorts.get(i), tpf);
      }



and disable ZBuffer writes on HUD.

But ATM I can't figure  out way to do it without intrusion into JME sources. Or at least, not with such crucial change.

I tried to revert the render order yet, but then if the HUD is displayed the nifty disappears. How can i disable ZBuffer writes on the HUD?

Something like


p.getMaterial().getAdditionalRenderState().setDepthWrite(false);

So I guess what everyone is looking for is a way to control which gui objects appear on top of another, including niftygui. I guess this can be fixed :slight_smile:

What do you guys think if we got rid of UIElement and instead used the getLocalTranslation().z for example? You would be able to set nifty's z value as well.

z? why not y then it is as you would expect,a s y is in jme the depth…