setZOrder() again

i either have no idea on how to use the zorder or the stuff doesn't work. as far as i understood objects with higher zorder will be rendered in front of objects with lower zorder, but from what i tested, that's not quite true. if i'm right, then quad a should be rendered in front of b (which doesn't happen with ZBufferState.CF_LEQUAL). i suppose it shouldn't matter if the zbuffer is set to ZBufferState.CF_LEQUAL or ZBufferState.CF_LESS because of the big difference in z order. still with ZBufferState.CF_LESS set, the behaviour is the one i expected from ZBufferState.CF_LEQUAL. could someone explain what the actual behaviour should be, and if the current behaviour is correct tell me where i'm wrong? (and then add it to the wiki :stuck_out_tongue: )


import com.jme.app.SimpleGame;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.SceneElement;
import com.jme.scene.shape.Quad;
import com.jme.scene.state.LightState;
import com.jme.scene.state.ZBufferState;

public class TestZOrder extends SimpleGame {

  @Override
  protected void simpleInitGame() {
    ZBufferState zState = display.getRenderer().createZBufferState();
    zState.setEnabled( true );
    zState.setFunction( ZBufferState.CF_LEQUAL);
    rootNode.setRenderState( zState );
   
    Quad a = new Quad("a", 100, 100);
    Quad b = new Quad("b", 200, 200);
   
    a.setLightCombineMode(LightState.OFF);
    b.setLightCombineMode(LightState.OFF);
   
    a.setDefaultColor(ColorRGBA.red);
    b.setDefaultColor(ColorRGBA.blue);
   
    a.setCullMode(SceneElement.CULL_NEVER);
    b.setCullMode(SceneElement.CULL_NEVER);
   
    a.setRenderQueueMode(Renderer.QUEUE_ORTHO);
    b.setRenderQueueMode(Renderer.QUEUE_ORTHO);

    Vector3f center = new Vector3f(display.getWidth() / 2, display.getHeight() / 2, 0);
    a.setLocalTranslation(center);
    b.setLocalTranslation(center);
   
    a.setZOrder(Integer.MAX_VALUE);
    b.setZOrder(Integer.MIN_VALUE);
   
    rootNode.attachChild(a);
    rootNode.attachChild(b);
   
  }
 
  public static void main(String[] args) {
    TestZOrder app = new TestZOrder();
    app.start();
  }

}


The Z values of all your quads are equal, z order is just the order (priority if you like) in which they are rendered.



So with CF_LEQUAL when a new quad is rendered it's drawn on top of the others (the z values are equals so it passes). With CF_LESS it's not, because it's equals, it's not less. This means with LESS the first drawn object is displayed, and with EQUAL the last drawn one.



CF_GEQUAL should be the same as CF_LEQUAL and CF_ALWAYS, and CF_NOTEQUAL the same as CF_LESS.



I uh… think :slight_smile:



CF_ALWAYS has the advantage that there is no Z testing.

thanks. now i finally understand :slight_smile: will you put it in the wiki or should i ? (at least the first sentence) the problem is that i don't find an adequate section for putting it in.



one more question: did anyone find some application for it because as far as i understand it can only be used to alter the effect of the zbuffer functions (then again why alter the function effect and not use the proper function?)

Well, as you see with setZOrder you can control which object in the ORTHO queue is shown on top of the other when they overlap. Useful enough, no?

llama said:

Well, as you see with setZOrder you can control which object in the ORTHO queue is shown on top of the other when they overlap.


not really. that's why i have a problem with z order. i don't want to set another zbuffer mode on my gui because it breaks everything - i would have then to set the z order for every gui element and there are a lot of them, most of them generated -  but if i use z order to make sure the mouse cursor is on top of the gui, it doesn't really work (because of the same reason like in the code above). the workaround is to always add the mouse as the last gui element.

It shouldn't matter if you use ZBufferState.CF_LEQUAL or ZBufferState.CF_LESS, (or CF_GEQUAL/CF_ALWAYS, or CF_NOTEQUAL), as long as you understand that the working of the ZOrder value is reverted (flipped) relative to the other state. So to quote you: "as far as i understood objects with higher zorder will be rendered in front of objects with lower zorder" <-- should depend on the type of ZBufferState (I don't even know which one does what, I admit…)



If you add all your GUI elements to one Node, you'd also have to set only one ZBufferState for all the GUI elements.



Maybe there should be a TestSetZOrder to show this off… (and confirm it's not buggy)/

llama said:

Maybe there should be a TestSetZOrder to show this off.. (and confirm it's not buggy)/


there should be at least a test/demo where the proper use of z order is shown in relation with zbuffer modes (and which should also show that the order in which the nodes are added to a root element does not affect z order if the peoper zbuffer mode is set)