Changing the Image ByteBuffer of a Texture

Hi,

i wanted to draw a field of Values (a 2D Flow Field). Therefore i tried to change the ByteBuffer of the image of a Texture. I tried to test that, by changing one (of course everytime a different) byte of the Buffer in simpleUpdate(). The problem is now, that after the first time simpleUpdate() is executed (which does affect the texture), there is no change in the rendered Texture anymore.

I figured out, that as soon as the Method "TextureState.load()" is being called, there is completely no change in the Texture anymore ( for example if i execute this Method before simpleUpdate() has run for the first time). So i think this doesen't work because the ByteBuffer is copied into the graphics Card Memory. But can't it be updated somehow? (Speed is not so important in my case)



Here is the code:




public class Test extends SimpleGame {

   Image textureImage;

   ByteBuffer textureData;

   int textureHeight;

   int n;

   Texture flowScreenT;

   TextureState flowScreenTS;

   public static void main(String[] args) {
      Test app = new Test();
      app.setDialogBehaviour(AbstractGame.ALWAYS_SHOW_PROPS_DIALOG);
      app.start();
   }




   protected void simpleInitGame() {

      TriMesh flowScreen = new TriMesh("Flow Screen");

      // Vertex positions for the mesh
      Vector3f[] vertexes = { new Vector3f(-12, -12, 0),
            new Vector3f(12, -12, 0), new Vector3f(-12, 12, 0),
            new Vector3f(12, 12, 0) };

      // Normal directions for each vertex position
      Vector3f[] normals = { new Vector3f(0, 0, 1), new Vector3f(0, 0, 1),
            new Vector3f(0, 0, 1), new Vector3f(0, 0, 1) };

      // Texture Coordinates for each position
      Vector2f[] texCoords = { new Vector2f(0, 0), new Vector2f(1, 0),
            new Vector2f(0, 1), new Vector2f(1, 1) };

      // The indexes of Vertex/Normal/Color/TexCoord sets.  Every 3 makes a triangle.
      int[] indexes = { 0, 1, 2, 1, 2, 3 };

      // Feed the information to the TriMesh
      flowScreen.reconstruct(BufferUtils.createFloatBuffer(vertexes),
            BufferUtils.createFloatBuffer(normals), null, BufferUtils
                  .createFloatBuffer(texCoords), BufferUtils
                  .createIntBuffer(indexes));

      // Create a bounds
      flowScreen.setModelBound(new BoundingBox());
      flowScreen.updateModelBound();

      flowScreenTS = display.getRenderer().createTextureState();
      flowScreenT = TextureManager.loadTexture(TestKeyInput.class
            .getClassLoader().getResource(
                  "Data//textures//32x32simplegray.bmp"),
            Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR);

      textureImage = flowScreenT.getImage();
      textureHeight = textureImage.getHeight();
      textureData = textureImage.getData();

      flowScreenTS.setTexture(flowScreenT, 0);
      flowScreenTS.setEnabled(true);
      flowScreen.setRenderState(flowScreenTS);

      // Attach the mesh to my scene graph
      rootNode.attachChild(flowScreen);

      lightState.setEnabled(false);
   }





   protected void simpleUpdate() {

      if (n < textureData.limit()) {

         textureData.put(n, (byte) 50);
         
         n++;
      }

   }

}



thanks for any help

I modified my jME copy to have a "reload" method on a texture state, but it broke after a jME CVS update… There's a class called ImageGraphics in jME which allows you to use all AWT Graphics2D drawing methods and such on a jME image object, it automatically updates and is very optimized, I suggest you use that instead of directly modifying the ByteBuffer.

That class also shows you the OpenGL methods needed to update the texture with your changes. You can also see them in code of this project (VideoTexture if I remember correctly);



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



Of course one day this will be in jME itself

Thanks for the fast answers. It took me a bit, but with ImageGraphics it works absolutely fine now  :slight_smile: