TextureState doesn't get cleared in Node children

I'm using SimpleGame, and adding nodes to the fpsNode. However, it appears that the text texture used by the Fps display is applied to all sub-geometry, even if I apply a texture state with a null texture in between. Here is my hierarchy:



    fpsNode

Text    Node (*)

          Quad



The marked node has a TextureState with null as the texture.



Here is my code. It creates a quad in the middle of the screen. The quad renders, but it has the font texture applied to it. It is my understanding that that shouldn't happen. So I understand wrong. Please teach me!



I'm no longer using 1.0; I'm using the latest and greatest out of CVS, by the way.



import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.Random;
import java.util.prefs.Preferences;

import javax.swing.UIManager;

import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingSphere;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.SceneElement;
import com.jme.scene.TriMesh;
import com.jme.scene.shape.Quad;
import com.jme.scene.state.LightState;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.GameSettings;
import com.jme.system.PreferencesGameSettings;
import com.jme.util.geom.BufferUtils;


public class TestApp extends SimpleGame {

   Node node;

   @Override
   protected void simpleInitGame() {
      node = new Node();
      TextureState ts = display.getRenderer().createTextureState();
      ts.setTexture(null);
      ts.setEnabled(true);
      node.setRenderState(ts);
      node.setCullMode(SceneElement.CULL_NEVER);
      lightState.setEnabled(false);
      display.getRenderer().setBackgroundColor(new ColorRGBA(0.8f, 0.5f, 0.2f, 1));
      fpsNode.attachChild(node);
      fpsNode.setCullMode(SceneElement.CULL_NEVER);
      Quad q = new Quad("a Quad", 4, 3);
      node.attachChild(q);
      q.updateRenderState();
   }

   protected void simpleUpdate() {
   }

   /**
    * @param args
    */
   public static void main(String[] args) {
      try {
         GameSettings gs = new PreferencesGameSettings(Preferences.userRoot());
         gs.setDepth(32);
         gs.setAlphaBits(8);
         gs.setStencilBits(8);
         gs.setDepthBits(8);
         gs.setFullscreen(false);
         gs.setVerticalSync(false);
         gs.setWidth(800);
         gs.setHeight(600);
         for (int i = 0; i < args.length; ++i) {
            int io = args[i].indexOf('=');
            if (io > 0) {
               String arg = args[i].substring(0, io);
               String value = args[i].substring(io+1);
               gs.set(arg, value);
            }
         }

         TestApp app = new TestApp(); // Create Object

         app.start(); // Start the program
      }
      catch (java.lang.Exception x) {
         System.out.println("Exception caught: " + x.getMessage() + "n");
      }
   }

}


Try this:




TextureState ts = display.getRenderer().createTextureState();
ts.setEnabled(false);
node.setRenderState(ts);
node.setTextureCombineMode(TextureState.REPLACE);

That worked. I think it's the textureCombineMode() that did it, although I have no idea why. That makes me quite confused. Here's what the documentation says about RenderState.setEnabled():


  • Sets if this render state is enabled during rendering. Disabled states
  • are ignored.



    Note the "are ignored" part. I read that as saying that a state with the enabled flag set to false does not have any effect. In fact, I can change the flag between true and false, and both work. However, entirely removing the setRenderState(), but keeping the setTextureCombineMode(), doesn't work. This makes no sense to me – what's going on?

"setTextureCombineMode" controls how individual textures are propagated down the scene. By using REPLACE, you tell, that only the last set texturestate is to be used, as is. And if the last texturestate is a disabled one, the textures will be disabled. A disabled texturestate is not ignored, it disables the use of textures. If "setTextureCombineMode" is set to some COMBINE* mode, then are the disabled texturestates ignored.



Look at source code of LWJGLTextureState.extract method.

A disabled texturestate is not ignored, it disables the use of textures.


So the documentation lies. I'll file a bug about that.