Text behind Quad problem

Hi,



I've got a serious problem with the Text class of jme.

When I render a Sphere (lesson2 from flag rush tuts), a white quad and red Text, the quad and the text are rendered in QUEUE_ORTHO mode, the text always appears behind the quad. (no matter what I change, but how can I correct this?)



The following code is contains my problem:



package texttest;

import com.jme.app.BaseGame;
import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.input.InputSystem;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.Text;
import com.jme.scene.shape.Quad;
import com.jme.scene.shape.Sphere;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.system.JmeException;
import com.jme.util.TextureManager;
import com.jme.util.Timer;

public class Main extends BaseGame {

    protected Timer timer;
    private Camera cam;
    private Node scene;
    private TextureState ts;
    private int width, height, depth, freq;
    private boolean fullscreen;
   
    private Quad rect;
    private Text text;
   
    protected void update(float interpolation) {
        timer.update();
       
        interpolation = timer.getTimePerFrame();       
    }

    protected void render(float interpolation) {
        display.getRenderer().clearBuffers();

        display.getRenderer().draw(scene);
    }

    protected void initSystem() {
        width = properties.getWidth();
        height = properties.getHeight();
        depth = properties.getDepth();
        freq = properties.getFreq();
        fullscreen = properties.getFullscreen();

        try {
            display = DisplaySystem.getDisplaySystem(properties.getRenderer());
            display.createWindow(width, height, depth, freq, fullscreen);

            cam = display.getRenderer().createCamera(width, height);
        }
        catch (JmeException e) {
            e.printStackTrace();
           
            System.exit(1);
        }

        display.getRenderer().setBackgroundColor(ColorRGBA.black);

        cam.setFrustumPerspective(45.0f, (float)width / (float)height, 1, 1000);
        Vector3f loc = new Vector3f(0.0f, 0.0f, 25.0f);
        Vector3f left = new Vector3f(-1.0f, 0.0f, 0.0f);
        Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
        Vector3f dir = new Vector3f(0.0f, 0f, -1.0f);
       
        cam.setFrame(loc, left, up, dir);
       
        cam.update();

        timer = Timer.getTimer(properties.getRenderer());

        display.getRenderer().setCamera(cam);
    }

    protected void initGame() {
        scene = new Node("Scene graph node");

        Sphere s = new Sphere("Sphere", 30, 30, 25);
        s.setLocalTranslation(new Vector3f(0, 0, -40));
        s.setModelBound(new BoundingBox());
        s.updateModelBound();
       
        rect = new Quad("rect", 50, 50);
        rect.setDefaultColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 0.0f));
        rect.getLocalRotation().set(0, 0, 0, 1);               
        rect.getLocalTranslation().set(500,
                                       height - 25 - 10,
                                       0);
        rect.getLocalScale().set(1, 1, 1);
        rect.setRenderQueueMode(Renderer.QUEUE_ORTHO);
              
        text = Text.createDefaultTextLabel("testText");               
        text.setTextColor(new ColorRGBA(1.0f, 0.5f, 0.5f, 1.0f));
        text.getLocalRotation().set(0, 0, 0, 1);
        text.getLocalTranslation().set(500,
                                       height - 25 - 10,
                                       0);
        text.getLocalScale().set(1, 1, 1);
        text.setRenderQueueMode(Renderer.QUEUE_ORTHO);
        text.print("texteee");
       
        ts = display.getRenderer().createTextureState();
        ts.setEnabled(true);
        ts.setTexture(TextureManager.loadTexture("images/square.jpg",
                                                 Texture.MM_LINEAR_LINEAR,
                                                 Texture.FM_LINEAR));
        s.setRenderState(ts);
       
        scene.attachChild(rect);       
        scene.attachChild(text);
        scene.attachChild(s);
       
        scene.updateGeometricState(0.0f, true);
        scene.updateRenderState();
    }
   
    protected void reinit() {
        display.recreateWindow(width, height, depth, freq, fullscreen);
    }
 
    protected void cleanup() {
        ts.deleteAll();
    }
   
    public static void main(String[] args) {
        Main app = new Main();

        app.setDialogBehaviour(NEVER_SHOW_PROPS_DIALOG, "");
        app.start();
    }   
}



Has anybody got a solution?

Thanks,

Starik

Anybody?



I'm getting real desperate!



:?

In Ortho mode, the object order is determined by the Z order. Look at getZOrder() and setZOrder() in Spatial.java

you might also want to look at this topic if you have questions about the z value:

http://www.jmonkeyengine.com/jmeforum/index.php?topic=3145

Well, in this case Z order is an int. It's like a simple priority which ORTHO object should be drawn last (and thus on top of the rest).

Thanks for your, replies, I didn't get to it till today but the z-order wasn't the

solution I think.



Because in the following code, I've created a class that should become a custom textfield.

So it has a background (Quad) and text (Text) the class itself extends a Node and gets

added to a window (also a Node). As the last thing I add a window to the scene.

(The scene consists out of a Sphere like in lesson2).



(When I uncomment the line  //quad.setRenderState(ts); the text gets drawn in front of

the Quad as I suspected. Without that renderstate set I cannot get the text drawn in front

of the Quad.



How is that possible? And is the way I'm creating a UI making any sense?



UIComp class:



public class UIComp extends Node implements KeyInputListener {
    private Quad quad;
    private Text text;   
    private String value;
   
    private TextureState ts;
   
    public UIComp(Renderer aRenderer) {
        super("UINode");
       
        KeyInput.get().addListener(this);
       
        value = "hallo";
       
        ts = aRenderer.createTextureState();
        ts.setEnabled(true);
        ts.setTexture(TextureManager.loadTexture("images/grass01.jpg",
                                                 Texture.MM_LINEAR_LINEAR,
                                                 Texture.FM_LINEAR));
       
        quad = new Quad("quad", 50, 50);
        quad.setDefaultColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 0.5f));
        quad.setLocalTranslation(new Vector3f(400.0f, 400, 0.0f));       
        quad.setRenderQueueMode(Renderer.QUEUE_ORTHO);       
        //quad.setRenderState(ts);
       
        text = Text.createDefaultTextLabel(Text.DEFAULT_FONT);       
        text.setLocalTranslation(new Vector3f(350, 415, 0.0f));       
        text.setTextColor(new ColorRGBA(1.0f, 0.0f, 0.0f, 1.0f));
        text.print("hallo");
        text.setZOrder(quad.getZOrder() - 20);
       
        this.attachChild(quad);
        this.attachChild(text);
       
        this.updateGeometricState(0.0f, true);
        this.updateRenderState();
    }

    public void onKey(char c, int i, boolean b) {
        if (c == 8) {
            if (value.length() > 1)
                value = value.substring(0, value.length() - 2);
        }
        else
            value += c;
       
        text.print(value);
    }
}



Initgame method: (Main class)


protected void initGame() {
        MouseInput.get().setCursorVisible(true);       
       
        scene = new Node("Scene graph node");
               
        ts = display.getRenderer().createTextureState();
        ts.setEnabled(true);
        ts.setTexture(TextureManager.loadTexture("images/grass01.jpg",
                                                 Texture.MM_LINEAR_LINEAR,
                                                 Texture.FM_LINEAR));
       
        Sphere s = new Sphere("Sphere", 30, 30, 25);
        s.setLocalTranslation(new Vector3f(0, 0, -40));
        s.setModelBound(new BoundingBox());
        s.updateModelBound();
        s.setRenderState(ts);

        UIComp comp = new UIComp(display.getRenderer());
       
        scene.attachChild(s);       
        scene.attachChild(comp);
       
        scene.updateGeometricState(0.0f, true);
        scene.updateRenderState();
    }


May be off the mark here, but on observation try changing

text.setZOrder(quad.getZOrder() - 20);



to

text.setZOrder(quad.getZOrder() + 20);

Or switch to using the Pass system and have the text drawn last.

@kidneybean

(that doesn't have any effect)



@renanse

Do you have a link regarding the Pass system? Since I'm a noob in JME.


Well, if it doesn't work maybe the Zbuffer is used after all. Try setting a ZBufferState with CF_ALWAYS for your ortho objects.

Check out SimplePassGame and TestBloom, TestSketch.  There isn't any big doc on it yet, but those should get you started.

I'm sorry to say that your answers didn't work :frowning:



But the good news is, it works now. I guess it had something to do with the texture on a quad.

So if you don't apply a texture on a quad, the text stays invisible.



Just thought I let you know…