Text missing when changing gamestates

Hello again,



The rest of the code



InGame is kind of mini-physics demo (a tennis ball falling to a table and a box on it).



import com.jme.image.Texture;
import com.jme.input.FirstPersonHandler;
import com.jme.input.InputHandler;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.input.action.InputAction;
import com.jme.input.action.InputActionEvent;
import com.jme.light.PointLight;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.shape.Box;
import com.jme.scene.shape.Sphere;
import com.jme.scene.state.LightState;
import com.jme.scene.state.MaterialState;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.util.BumpMapColorController;
import com.jme.util.TextureManager;
import com.jmex.physics.DynamicPhysicsNode;
import com.jmex.physics.StaticPhysicsNode;
import com.jmex.physics.contact.MutableContactInfo;
import com.jmex.physics.material.Material;

public class InGame extends CameraPhysicsGameState
{
    protected InputHandler input;
    protected InputHandler cameraInputHandler;
   
   
    public InGame(String name)
    {
        super(name);
       
        initSimplePhysicsGame();
       
        buildPhysicDemo();
        buildTennisBall();
       
        rootNode.updateGeometricState(0, true);
        rootNode.updateRenderState();
    }
   
    @Override
    protected void stateUpdate(float tpf)
    {
        input.update( tpf );
    }

    //Could also re-implement render(float)
    @Override
    protected void stateRender(float tpf)
    {
    }

    @Override
    protected void onActivate()
    {
        super.onActivate();
    }

    @Override
    protected void onDeactivate()
    {
        super.onActivate();
    }

    private void initSimplePhysicsGame()
    {
        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 );
        /** Move our camera to a correct place and orientation. */
        cam.setFrame( loc, left, up, dir );
        /** Signal that we've changed our camera's location/frustum. */
        cam.update();
       
        // ---- LIGHTS
        /** Set up a basic, default light. */
        PointLight light = new PointLight();
        light.setDiffuse( new ColorRGBA( 0.75f, 0.75f, 0.75f, 0.75f ) );
        light.setAmbient( new ColorRGBA( 0.5f, 0.5f, 0.5f, 1.0f ) );
        light.setLocation( new Vector3f( 100, 100, 100 ) );
        light.setEnabled( true );

        /** Attach the light to a lightState and the lightState to rootNode. */
        LightState lightState = DisplaySystem.getDisplaySystem().getRenderer().createLightState();
        lightState.setEnabled( true );
        lightState.attach( light );
        rootNode.setRenderState( lightState );
       
        // ---- INPUT
        cameraInputHandler = new FirstPersonHandler( cam, 50, 1 );
        input = new InputHandler();
        input.addToAttachedHandlers( cameraInputHandler );
       
        KeyBindingManager.getKeyBindingManager().set("exit", KeyInput.KEY_ESCAPE);
        input.addAction(
            new InputAction()
            {
                public void performAction( InputActionEvent evt )
                {
                    if ( !evt.getTriggerPressed() )
                    {
                        Main.changeGameState("menu");
                    }
                }
            }
            , "exit", false );
       
    }
   
    private void buildPhysicDemo()
    {
        StaticPhysicsNode staticNode = getPhysicsSpace().createStaticNode();
        rootNode.attachChild( staticNode );
        final Box visualFloorBox = new Box( "floor", new Vector3f(), 5, 0.25f, 5 );
        staticNode.attachChild( visualFloorBox );
        staticNode.generatePhysicsGeometry();

        DynamicPhysicsNode dynamicNode = getPhysicsSpace().createDynamicNode();
        rootNode.attachChild( dynamicNode );
        final Box visualFallingBox = new Box( "falling box", new Vector3f(), 0.5f, 0.5f, 0.5f );
        dynamicNode.attachChild( visualFallingBox );
        dynamicNode.generatePhysicsGeometry();
        dynamicNode.getLocalTranslation().set( 0, 5, 0 );
    }
   
    private void buildTennisBall()
    {
        //The ball itself
        Sphere ball = new Sphere("ball", 32, 32, /*0.065f*/1);
       
        final Material tennisBallMaterial = new Material( "tennis ball" );
        tennisBallMaterial.setDensity( 50.0f );
        MutableContactInfo tennisContactDetails = new MutableContactInfo();
        tennisContactDetails.setBounce( 0.7f );
        tennisContactDetails.setMu( 10000 );
        tennisContactDetails.setDampingCoefficient(1f);
        tennisContactDetails.setSpringConstant(1f);
        tennisBallMaterial.putContactHandlingDetails( Material.DEFAULT, tennisContactDetails );
       
        DynamicPhysicsNode phyBall = getPhysicsSpace().createDynamicNode();
        rootNode.attachChild( phyBall );
        phyBall.attachChild(ball);
        phyBall.generatePhysicsGeometry();
        phyBall.getLocalTranslation().set( 0, 7, 0 );
        phyBall.setMaterial( tennisBallMaterial );
        phyBall.computeMass();
       
        //Ball texture
        BumpMapColorController bumpController = new BumpMapColorController(ball);
        ball.addController(bumpController);

        MaterialState ms = DisplaySystem.getDisplaySystem().getRenderer()
            .createMaterialState();
        ms.setColorMaterial(MaterialState.ColorMaterial.Diffuse);
        ball.setRenderState(ms);
        ball.updateRenderState();

        TextureState ts = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
        ts.setEnabled(true);
        Texture tex = TextureManager.loadTexture(
            InGame.class.getClassLoader().getResource("data/tennisballnormal.jpg"),
            Texture.MinificationFilter.BilinearNearestMipMap,
            Texture.MagnificationFilter.Bilinear);

        tex.setWrap(Texture.WrapMode.Repeat);
        tex.setApply(Texture.ApplyMode.Combine);
        tex.setCombineFuncRGB(Texture.CombinerFunctionRGB.Dot3RGB);
        tex.setCombineSrc0RGB(Texture.CombinerSource.CurrentTexture);
        tex.setCombineSrc1RGB(Texture.CombinerSource.PrimaryColor);
        ts.setTexture(tex, 0);

        Texture tex2 = TextureManager.loadTexture(
            InGame.class.getClassLoader().getResource("data/tennisball.jpg"),
            Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.Bilinear, 0.0f, true);
        tex2.setApply(Texture.ApplyMode.Combine);
        tex2.setWrap(Texture.WrapMode.Repeat);
        tex2.setCombineFuncRGB(Texture.CombinerFunctionRGB.Modulate);
        tex2.setCombineSrc0RGB(Texture.CombinerSource.Previous);
        tex2.setCombineSrc1RGB(Texture.CombinerSource.CurrentTexture);
        ts.setTexture(tex2, 1);

        ball.copyTextureCoordinates(0, 1, 1.0f);

        ball.setRenderState(ts);       
    }
}



Thank you again.

PS: sorry for double post

The Text lost its Texture when switching, so check where you attach / detach the text from the rootNode and add a updateRenderState() after attaching it.



rootNode.updateRenderState() at the end of setMenu() fixes the Problem.



Also if you later attach objects in your InGame state dynamicly, always do a updateRenderstate after you have finished attaching objects to the node.

Thanks for your quick response, it's now working. But I have a doubt, why does it work correctly when I change the menu items using gotoMenuX() without changing gamestates?

i'm not sure, maybe because no other texture has been created or used.