TextureState.clear() fails - heres a solution

Note: This is a JME1 related issue (may also apply to JME2).







TextureState has a method, clearTextures(), which should remove all the textures in the state.

However, if a TextureState has the same Texture (in the sense that Texture1.equals(Texture2)) at two different units, the current implementation will only remove the first.



The problem is that, despite being passed the actual index of the texture unit to remove, removeTexture(int textureUnit) indexes textureUnit against the array of textures to get the texture to remove, then passes that off to removeTexture(Texture texture) which then searches through the very same array of texture units to find the index

that we started with earlier. However, if the same texture is in the array twice, then this search may return the wrong texture, and then the intended texture isn't removed at all.



Here is a little patch to fix this:


Index: src/com/jme/scene/state/TextureState.java
===================================================================
RCS file: /cvs/jme/src/com/jme/scene/state/TextureState.java,v
retrieving revision 1.43
diff -u -r1.43 TextureState.java
--- src/com/jme/scene/state/TextureState.java   5 Oct 2007 22:39:48 -0000   1.43
+++ src/com/jme/scene/state/TextureState.java   1 Jul 2008 22:55:56 -0000
@@ -279,11 +279,14 @@
                 || textureUnit >= texture.size())
             return false;
 
-        Texture t = getTexture(textureUnit);
+        Texture t = texture.get(textureUnit);
         if (t == null)
             return false;
 
-        return removeTexture(t);
+        texture.set(textureUnit, null);
+        idCache[textureUnit] = 0;
+       
+        return true;
 
     }

I'm not using JME2 right now, but a quick look through the source code suggests that the implementation for clearTextures is the same. Here's the same patch, but against JME2:


Index: C:/Users/Sam/workspace/jme2/src/com/jme/scene/state/TextureState.java
===================================================================
--- C:/Users/Sam/workspace/jme2/src/com/jme/scene/state/TextureState.java   (revision 3888)
+++ C:/Users/Sam/workspace/jme2/src/com/jme/scene/state/TextureState.java   (working copy)
@@ -263,11 +263,13 @@
                 || textureUnit >= texture.size())
             return false;
 
-        Texture t = getTexture(textureUnit);
+        Texture t = texture.get(textureUnit);
         if (t == null)
             return false;
 
-        return removeTexture(t);
+        texture.set(textureUnit, null);
+        idCache[textureUnit] = 0;
+        return true;
 
     }
 

Thanks for these.  Good catch. :)  Updated in 1.0 and 2.0