Jme crashes when changing uvs at runtime

I try to change the uv coordinates in runtime from simpleUpdate(tpf), however it throws this exception:



SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]

java.lang.UnsupportedOperationException: Data has already been sent. Cannot setupData again.

at com.jme3.scene.VertexBuffer.setupData(VertexBuffer.java:465)

at com.jme3.scene.Mesh.setBuffer(Mesh.java:873)

at com.jme3.scene.Mesh.setBuffer(Mesh.java:879)

at max.TestUVCrash.moveU(TestUVCrash.java:41)

at max.TestUVCrash.simpleUpdate(TestUVCrash.java:59)

at com.jme3.app.SimpleApplication.update(SimpleApplication.java:248)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:144)

at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:173)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:218)

at java.lang.Thread.run(Thread.java:662)

I made a test case that proves it. When you press Z or X it will throw that exception.



[java]

import com.jme3.app.SimpleApplication;

import com.jme3.input.KeyInput;

import com.jme3.input.controls.AnalogListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.material.Material;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;

import com.jme3.scene.Mesh;

import com.jme3.scene.VertexBuffer;

import com.jme3.scene.VertexBuffer.Type;

import com.jme3.scene.shape.Box;

import com.jme3.util.BufferUtils;

import java.nio.FloatBuffer;

/**

  • Simple test case to show that u cant change u-v coordinates during runtime from simpleUpdate.
  • press Z or X to crash.

    */

    public class TestUVCrash extends SimpleApplication

    {

    float moveUOffset = 0;

    Geometry cube;

    public static void main(String[] args)

    {

    TestUVCrash app = new TestUVCrash();

    app.start();

    }

    public void moveU(Mesh meshload, float moveUOffset)

    {

    VertexBuffer uv = meshload.getBuffer(Type.TexCoord);

    float[] uvArray = BufferUtils.getFloatArray((FloatBuffer) uv.getData());

    for (int i = 0; i < uvArray.length; i += 2)

    {

    uvArray += moveUOffset; //moves u.

    }

    meshload.setBuffer(Type.TexCoord, 2, uvArray);

    }

    @Override

    public void simpleInitApp()

    {

    Box boxshape1 = new Box(new Vector3f(-3f, 1.1f, 0f), 1f, 1f, 1f);

    cube = new Geometry("My Textured Box", boxshape1);

    Material mat_stl = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");

    mat_stl.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));

    cube.setMaterial(mat_stl);

    rootNode.attachChild(cube);

    initKeys();

    }

    @Override

    public void simpleUpdate(float tpf)

    {

    if (moveUOffset != 0) moveU(cube.getMesh(),moveUOffset);

    moveUOffset=0;

    }

    private void initKeys()

    {

    inputManager.addMapping("IncreaseU", new KeyTrigger(KeyInput.KEY_Z));

    inputManager.addMapping("DecreaseU", new KeyTrigger(KeyInput.KEY_X));

    AnalogListener analogListener = new AnalogListener()

    {

    public void onAnalog(String name, float value, float tpf)

    {

    if (name.equals("IncreaseU"))

    {

    moveUOffset += value;

    }

    if (name.equals("DecreaseU"))

    {

    moveUOffset -= value;

    }

    }

    };

    inputManager.addListener(analogListener, new String[]

    {

    "IncreaseU", "DecreaseU"

    });

    }

    }

    [/java]

Use updateData() instead

1 Like

wow thats so cool. It works now !!!



[java]public void moveU(Mesh meshload, float moveUOffset)

{

VertexBuffer uv = meshload.getBuffer(Type.TexCoord);

float[] uvArray = BufferUtils.getFloatArray((FloatBuffer) uv.getData());

for (int i = 0; i < uvArray.length; i += 2)

{

uvArray += moveUOffset; //moves u.

}

uv.updateData(BufferUtils.createFloatBuffer(uvArray));

}[/java]