Object overlapping by order of creation

Hi !



I thougt I was clear of starters bugs but… 



I have a problem with objects overalapping other objects that are in front of this object.  I use the zbuffer.CF_LEQUAL flag for my zbufferstate and i apply it to my rootnode…  it seems that if I attach an object to the rootnode before an other object, it will always be drawn on top of the other one even if i should see the other object because it is closer to the camera…



here is the general code of the creation :



/** Create a ZBuffer to display pixels closest to the camera above farther ones. */

        ZBufferState buf = getRenderer().createZBufferState();

        buf.setEnabled( true );

        buf.setFunction( ZBufferState.CF_LEQUAL );

        rootNode.setRenderState( buf );



        billeNode = createBille();



        board[0] = createBoard( 1.5f, 3.5f, -0.9f, 0, "board1" );

        boardMaterialState[0] = getRenderer().createMaterialState();

        boardMaterialState[0].setShininess( 100 );

        boardMaterialState[0].setAmbient( new ColorRGBA( 0, 0, 0.5f, 1 ) );

        boardMaterialState[0].setDiffuse( new ColorRGBA( 0, 0, 0.75f, 1 ) );

        boardMaterialState[0].setSpecular( new ColorRGBA( 0.25f, 0.5f, 1, 1 ) );

        board[0].getChild( 0 ).setRenderState( boardMaterialState[0] );

        board[0].getChild( 1 ).setRenderState( boardMaterialState[0] );

        board[0].setRenderState( boardMaterialState[0]);

        board[0].updateRenderState();

        board[0].updateWorldBound();



        board[1] = createBoard( 1.5f, 3.5f, 0.7f, 0, "board2" );

        boardMaterialState[1] = getRenderer().createMaterialState();

        boardMaterialState[1].setShininess( 100 );

        boardMaterialState[1].setAmbient( new ColorRGBA( 0, 0.5f, 0, 1 ) );

        boardMaterialState[1].setDiffuse( new ColorRGBA( 0, 0.75f, 0, 1 ) );

        boardMaterialState[1].setSpecular( new ColorRGBA( 0.25f, 1, 0.5f, 1 ) );

        board[1].getChild( 0 ).setRenderState( boardMaterialState[1] );

        board[1].getChild( 1 ).setRenderState( boardMaterialState[1] );

        board[1].updateRenderState();

        board[1].updateWorldBound();



        pivot = new Node( "Pivot node" );



        board[0].updateRenderState();

        board[1].updateRenderState();

        pivot.attachChild( board[1] );

        pivot.attachChild( board[0] );

        pivot.attachChild( billeNode );

        pivot.updateRenderState();



        rootNode.attachChild(pivot);







In this case, the board[1] node that is attached to the pivot node first is the one that overlapps the other nodes… 

the problem moves if i attach another node to the pivot node first…



please help…  I'm kind of desperate on this… 



thanks…




You need to call rootNode.updateRenderState();

thanks for the quick help but I already call updaterenderstate of the rootnode at the end of all the objects creation… 



Also, sorry for the misleading information but the object that seems to overlap all the others is the last one attached to the node and not the first one…



thanks in advance guys…




Here is all the creation code :



            cam = this.getRenderer().getCamera();



           

            cam.setFrustumPerspective( 60f, ( float ) width / ( float ) height, 0.1f, 500 );

            setBackground( new ColorRGBA( 0f, 0f, 0f, 0.25f ) );



            createLightStates();

            createTextureStates();

            createMaterialStates();

            createAlphaStates();



            headerNode = create2DHeader();

           

            board[0] = createBoard( 1.5f, 3.5f, -0.9f, 0, "board1" );

            boardMaterialState[0] = getRenderer().createMaterialState();

            boardMaterialState[0].setShininess( 100 );

            boardMaterialState[0].setAmbient( new ColorRGBA( 0, 0, 0.5f, 1 ) );

            boardMaterialState[0].setDiffuse( new ColorRGBA( 0, 0, 0.75f, 1 ) );

            boardMaterialState[0].setSpecular( new ColorRGBA( 0.25f, 0.5f, 1, 1 ) );

            board[0].getChild( 0 ).setRenderState( boardMaterialState[0] );

            board[0].getChild( 1 ).setRenderState( boardMaterialState[0] );

            board[0].setRenderState( boardMaterialState[0]);

            board[0].updateRenderState();

            board[0].updateWorldBound();





            board[1] = createBoard( 1.5f, 3.5f, 0.7f, 0, "board2" );

            boardMaterialState[1] = getRenderer().createMaterialState();

            boardMaterialState[1].setShininess( 100 );

            boardMaterialState[1].setAmbient( new ColorRGBA( 0, 0.5f, 0, 1 ) );

            boardMaterialState[1].setDiffuse( new ColorRGBA( 0, 0.75f, 0, 1 ) );

            boardMaterialState[1].setSpecular( new ColorRGBA( 0.25f, 1, 0.5f, 1 ) );

            board[1].getChild( 0 ).setRenderState( boardMaterialState[1] );

            board[1].getChild( 1 ).setRenderState( boardMaterialState[1] );

            board[1].updateRenderState();

            board[1].updateWorldBound();



            board[2] = createBoard( 0.75f, 3.5f, 1.9f, 0, "board3" );



            boardMaterialState[2] = getRenderer().createMaterialState();

            boardMaterialState[2].setShininess( 100 );

            boardMaterialState[2].setAmbient( new ColorRGBA( 0.5f, 0, 0, 1 ) );

            boardMaterialState[2].setDiffuse( new ColorRGBA( 0.75f, 0, 0, 1 ) );

            boardMaterialState[2].setSpecular( new ColorRGBA( 1, 0.5f, 0.25f, 1 ) );

            board[2].getChild( 0 ).setRenderState( boardMaterialState[2] );

            board[2].getChild( 1 ).setRenderState( boardMaterialState[2] );

            board[2].updateWorldBound();

            board[2].updateRenderState();

            cam.setLocation( new Vector3f( 0, 0f, 60 + this.valZoom ) );

         



            pivot = new Node( "Pivot node" );





            pivot.attachChild( board[0] );

            pivot.attachChild( board[2] );

            pivot.attachChild( board[1] );

         

            pivot.updateRenderState();

         

            rootNode.attachChild( headerNode );



            rootNode.attachChild( pivot );



            pivot.setRenderState( ls3 );



            headerNode.setRenderState( ls3 );

            headerNode.updateRenderState();



            pivot.updateWorldBound();



            /** Create a ZBuffer to display pixels closest to the camera above farther ones. */

            ZBufferState buf = getRenderer().createZBufferState();

            buf.setEnabled( true );

            buf.setFunction( ZBufferState.CF_GREATER );

            buf.setWritable( true );

            rootNode.setRenderState( buf );



            cam.update();

            rootNode.updateWorldBound();

            rootNode.updateGeometricState( 0.0f, true );

            rootNode.updateRenderState();



Everything seems correct… 



any ideas?

As a more general note: there's no need to call updateWorldBound anywhere, if you call updateGeometricState(value, true) on the top Node. (The javadoc of updateWorldBound explains this)



What you want to do though, is call updateModelBound() for each geometry you've created.



As for your problem, if I get it right, you say that whatever "board" you add last gets always drawn on top of the rest, no matter what angle etc. you're looking at it? Or something else?



And uhm… why suddenly  buf.setFunction( ZBufferState.CF_GREATER ); instead of  buf.setFunction( ZBufferState.CF_LEQUAL ); you had before?

Sorry Llama,



            I just added this zbuffer.CF_GREATER  call to test different values with my zbuffer to see the differences…  Also, thanks for the tip with the updateworldbound call…  But I still have the same problem… It's like the zbuffer state i set on the rootnode does'nt follow to all children nodes…  I' ve verified with the debugger and the pivot node seems to have the zbufferstate correctly setted but the board[] nodes do not have the zbufferstate in them and the two trimesh that are attached to those boardnodes have a zbufferstate value different than the rootnode… 



I'm jammed with this problem… 

Well… very weird. Maybe I'm missing something obvious but I can't spot it.



You confirm that if you change the order in which you add the the boards, the "problem mesh" that comes out on top changes too? Eg if you add "1" last, it comes out on top?

You are exactly right…  Does'nt matter which node i attach to the pivot node last, it will be displayed on top of everything else I attach to the scene or the pivot node…



I have the same problem with my board node : it contains two trimesh 1 for the exterior of the board and one for the interior with a different texture and material… if I attach the trimesh that displays the interior last, it will display the interior of the board at all times and i am not able to see the exterior of the board… 



very weird indeed here is an example of the code that creates the log that contains all the boards :





private Node createBille()

{



        Node n = new Node( "NodeBilleComplete" );

        TriMesh m = b.CreateGeometryForLog( tShape );

        CloneCreator cc = new CloneCreator( m );

        TriMesh m2 = ( TriMesh ) cc.createCopy();



        m.setRenderState( billeTextureState );

        m.setRenderState( billeMaterialState1 );



        m2.setRenderState( billeMaterialState2 );



        // Make the mouse's background blend with what's already there

        m.setRenderState( billeAlphaState );

        m2.setRenderState( billeAlphaState );//That

Strangely, I tried to attach the interior of the log first and the exterior second and it displays my log correctly…  But, from what i know, the order in which I attach my trimeshs to a node should' nt influence the display.



weird stuff… 


could it be possible my problem comes form the clones i create to have different textures on the interior and exterior of the shape?



How could it display correctly only when i attach them in a specific order?


and the code for the implementor :





import com.jme.math.*;

import com.jme.renderer.Renderer;

import com.jme.scene.Node;

import com.jme.scene.shape.Box;

import com.jme.system.DisplaySystem;

import com.jme.bounding.BoundingBox;

import com.jmex.awt.SimpleCanvasImpl;





public class Comact3DImplementor extends SimpleCanvasImpl

{

    private Node pivot;

    private float posX = 0;

    private float posX2 = 0;

    private float posY = 0;





    private int type = 0;

    private float valZoom = 0.0f;



    private boolean leftButtonDown = false;

    private boolean rightButtonDown = false;

    private int MousePosX = 0;

    private int MousePosY = 0;

    private int OldMousePosX = 0;

    private int OldMousePosY = 0;

    private boolean middleButtonDown;

    private DisplaySystem dispSystem;

    private boolean updated = true;





    public Comact3DImplementor( int width, int height, int type, DisplaySystem disp )

    {



        this( width, height, type );



        dispSystem = disp;

    }



    public Comact3DImplementor( int width, int height, int type )

    {

        super( width, height );

        this.type = type;

    }



    public void simpleSetup()

    {

        cam = getRenderer().getCamera();



        if( dispSystem != null )

        {

            dispSystem.setRenderer( getRenderer() );





        }





        cam.setFrustumPerspective( 50f, ( float ) renderer.getWidth() / ( float ) renderer.getHeight(), 0.1f, 500 );

        cam.setLocation(new Vector3f( 0,0,-50 ));

        cam.setDirection(new Vector3f( 0,0,1 ));



        pivot = new Node("pivot");



        Box b  = new Box("boite",new Vector3f(0,0,20),10,10,10);

        b.setModelBound( new BoundingBox() );

        b.updateModelBound();



        b.setRenderQueueMode( Renderer.QUEUE_OPAQUE );





        Box b2  = new Box("boite2",new Vector3f(0,0,-20),10,10,10);

        b2.setModelBound( new BoundingBox() );

        b2.updateModelBound();



        b2.setRenderQueueMode( Renderer.QUEUE_OPAQUE );







        pivot.attachChild( b );

        pivot.attachChild( b2 );

        b.setRandomColors();

        b2.setRandomColors();



        rootNode.attachChild( pivot );



        rootNode.updateGeometricState( 0.0f, true );

        rootNode.updateRenderState();

        cam.update();

    }



    public void simpleUpdate()

    {

        if( ( leftButtonDown || rightButtonDown ) )

        {



            Quaternion qp = pivot.getLocalRotation();



            if( leftButtonDown )

            {



                posX = FastMath.DEG_TO_RAD * ( ( float ) ( MousePosX - OldMousePosX ) * 360f / renderer.getWidth() );

                Quaternion q = new Quaternion();

                q.fromAngleAxis( posX, new Vector3f( 0, 1, 0 ) );



                qp.multLocal( q );



                posY = FastMath.DEG_TO_RAD * ( ( float ) ( MousePosY - OldMousePosY ) * 360f / renderer.getHeight() );

                Quaternion q2 = new Quaternion();

                q2.fromAngleAxis( posY, new Vector3f( 1, 0, 0 ) );

                qp.multLocal( q2 );



            }



            if( rightButtonDown )

            {



                posX2 = FastMath.DEG_TO_RAD * ( ( float ) ( MousePosX - OldMousePosX ) * 360f / renderer.getWidth() ) * 5;

                Quaternion q3 = new Quaternion();

                q3.fromAngleAxis( posX2, new Vector3f( 0, 0, 1 ) );

                qp.multLocal( q3 );



            }



            pivot.setLocalRotation( qp );



            OldMousePosX = MousePosX;

            OldMousePosY = MousePosY;

            updated = true;

        }



        cam.update();

    }



    public void setZoom( float valZoom )

    {

        this.valZoom += valZoom;



        cam.setLocation( new Vector3f( cam.getLocation().x, cam.getLocation().y, 60 + this.valZoom ) );

        cam.setFrustumPerspective( 60f, ( float ) renderer.getWidth() / ( float ) renderer.getHeight(), 0.1f, 500 );



        cam.setDirection(new Vector3f( 0,0,-1 ));





        cam.update();



        updated = true;



    }



    public void setMousePos( int x, int y )

    {



        MousePosX = x;

        MousePosY = y;

        //To change body of created methods use File | Settings | File Templates.

    }



    public void setOldMousePos( int x, int y )

    {



        OldMousePosX = x;

        OldMousePosY = y;

    }



    public void setButton0Down( boolean down )

    {



        updated = true;

        leftButtonDown = down;

        updated = true;

        //To change body of created methods use File | Settings | File Templates.

    }



    public void setButton1Down( boolean down )

    {



        updated = true;

        middleButtonDown = down;

        updated = true;

        //To change body of created methods use File | Settings | File Templates.

    }



    public void setButton2Down( boolean down )

    {

        updated = true;

        rightButtonDown = down;

        updated = true;

        //To change body of created methods use File | Settings | File Templates.

    }





    public boolean isUpdated()

    {

        return updated;

    }



    public void setUpdated( boolean updated )

    {

        this.updated = updated;

    }



    public void resizeCanvas( int width, int height )

    {

        super.resizeCanvas( width, height );



        cam.setFrustumPerspective( 60f, ( float ) renderer.getWidth() / ( float ) renderer.getHeight(), 0.1f, 500 );

        cam.setLocation(new Vector3f( 0,0,-50 ));

        cam.setDirection(new Vector3f( 0,0,1 ));

        cam.update();

        updated = true;

    }



}





thanks to all for the help with this prob…



Ken


Well, then you might want to try your code in a "SimpleGame" first. If it works normal there, likely some of this is the problem.

Ok, found the problem!  Two problems, first : 



PixelFormat format = new PixelFormat(bitDepth, alphaBits, depthBufferBits, stencilBits, sampleBits);



depthBufferBits was setted to 0.



and second :



cam.setFrustumPerspective( 60f, ( float ) renderer.getWidth() / ( float ) renderer.getHeight(), 0.000001f, 500 );



the 0.0000001 value seems to do strange things to the frustum of the camera



thnks Llama for the help!



klangelier

Ok, it works now?



Next time you have a problem like this, please mention you use such a custom setup right away :slight_smile:

Woah, 0.0000001 is insanely small near plane. A 24 bit depth buffers resolution would only be able to handle precision for objects that are about 0.25 units away from the camera. After only 5 units from the camera, objects have to be almost 4 units difference from each other in order for seperation to be accurate.

he he he,



I have a tendency to test those parameters a little bit too much maybe…