Side effects of VertexBuffer's setUsage method?

What exactly does setUsage do in VertexBuffer? I would have guessed that it merely sets the VertexBuffer into the given mode, and so calling setUsage(x) when the VertexBuffer is already set to usage x would have no effect. Even so, my experiments show otherwise.

In the following example I make the vertices of a box wiggle randomly. In my experience it is perfectly normal to modify the position buffer of mesh and see no corresponding change in how the mesh is rendered, even if the position buffer has its usage set to Dynamic. Even so, by repeatedly calling setUsage(Usage.Dynamic) I can get the intended effect. I don’t understand why setUsage should have any effect upon an already Dynamic VertexBuffer, but if I remove that line from the below application the vertices will not move. More precisely, they will move slightly and then freeze, as though calling setUsage only applies to the next frame of animation.

What is the real cause of this effect?

public final class UsageTest extends SimpleApplication {
	public static void main(String... args) {
		new UsageTest().start();
	}
	private Mesh mesh;
	private static final float DRIFT = 0.01f;
	@Override
	public void simpleUpdate(float tpf) {
		final VertexBuffer vbuf = mesh.getBuffer(Type.Position);
		System.out.println(vbuf.getUsage()); // Outputs: "Dynamic"
		vbuf.setUsage(Usage.Dynamic); // Usage is already dynamic, but this is needed
		final FloatBuffer posBuf = (FloatBuffer)vbuf.getData();
		for(int i = 0; i < posBuf.limit(); i++)
		{
			float value = posBuf.get(i);
			float w = (float)Math.random();
			value += -DRIFT * (1f - w) + DRIFT * w;
			posBuf.put(i, value);
		}
	}
	@Override
	public void simpleInitApp() {
		mesh = new Box(2f, 2f, 2f);
		mesh.getBuffer(Type.Position).setUsage(Usage.Dynamic);
		Geometry box = new Geometry("Box", mesh);
		Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
		mat.setColor("Color", ColorRGBA.Blue);	
		box.setMaterial(mat);
		rootNode.attachChild(box);
	}
}

You never update the buffer. Take a look at the other Mesh implementations that allow changes at runtime.

1 Like

Thank you. I see now that updateData(Buffer data) is not just yet another way to change the content of the VertexBuffer. Taking a buffer as an argument is quite misleading, especially since its one-line summary comment says just: “Called to update the data in the buffer with new data.”

That’s a really critical point that ought to be in the main VertexBuffer javadoc comment since updating the GPU is an essential part of using a VertexBuffer. The javadoc comment for updateData could also be better.

I’ve often wanted to make some pull requests to improve the javadoc. Even a novice like me ought to be able to make some improvements just by looking at the source, seeing what each method does, and then writing it down in the comment. Maybe this is the time to finally try it and stop hoping that a jMonkey expert will do it for me.

1 Like