lilian
March 21, 2010, 1:53am
1
I dont get it. The javadoc clearly says Line represent a collection of lines, and if mode=SEGMENT, they can be disconnected.
I have a bunch of points, but i want to draw line between some of them, not ALL.
So why does the following fragment cause a crash with IllegalArgumentException (in LWJGRenderer.draw()) ??
By experimenting, i found that unless length(index buf) = length(vertex buf), the Line will not work (crash).
Any ideas how to make this work?
Vector3f[] verts = new Vector3f[4];
verts[0] = new Vector3f(0f, 10f, 0f);
verts[1] = new Vector3f(0f, -10f, 0f);
verts[2] = new Vector3f(10f, 0f, 0f);
verts[3] = new Vector3f(-10f, 0f, 0f);
int[] pts = {0, 1}; // referencing only 1 line (2 verts)
com.jme.scene.Line cross = new com.jme.scene.Line("cross", BufferUtils.createFloatBuffer(verts), null,
null, null);
cross.setMode(com.jme.scene.Line.SEGMENTS);
cross.setIndexBuffer(BufferUtils.createIntBuffer(pts));
My OpenGL knowledge is almost not existent, so i cant explain it really. But this is what happens:
Your Line has 2 indices and 4 vertices
In the Draw Line Method:
IntBuffer indices = lines.getIndexBuffer();
indices.rewind();
indices.limit(lines.getVertexCount()); // <<- Exception
GL11.glDrawElements(mode, indices);
Because your index Buffer is smaller than the VertexCount the exception happens.
public final Buffer limit(int newLimit) {
if ((newLimit > capacity) || (newLimit < 0))
throw new IllegalArgumentException();
So i guess the Index und Vertex buffer have to be always the same size?
Just don't call setIndexBuffer() at all, the constructor will create the Index buffer automatically for you.
And the result is a Cross.
p.s. It seems you use jME1 (com.jme.scene.Line.SEGMENTS is a jME 1 constant) are you aware of that ? :)
lilian
March 24, 2010, 12:56am
3
thanks CoreDump.
But I do not want to connect all vertices in the vertexarray! Only some, thats why in example with 4 points, i connect only 2. Seems like a JME bug! Ugh…
We cant switch to JME 2 as its API is not compatible with JME 1.0, which means big parts of the project have to be redone…no time !
Alric
March 24, 2010, 1:18am
4
I'm not saying you should do it for the sake of a problem like this, but just want to point out that the switch from JME1 to 2 isn't that much work. Much of it is little more than search and replace - you shouldn't need to rewrite any code from scratch.
@lilian what is the result you see in jme1 if you dont call setIndexBuffer()?
lilian
March 26, 2010, 11:07pm
6
if indexbuf is not set, then the points are connected out of order, because they are listed in the vertex array out-of-order.
Oh and same bug exists in JME2, i tried with a small program. JME doesnt support arbitrary index arrays.
Line.Mode Segments
Every two vertices referenced by the indexbuffer will be considered a stand-alone line segment.
Seems to work for me.
If you dont set the index buffer, the order how the verts are creates is relevant.
public class TestLine extends SimpleGame {
@Override
protected void simpleInitGame() {
Vector3f[] verts = new Vector3f[4];
verts[0] = new Vector3f(0f, 10f, 0f);
verts[1] = new Vector3f(10f, 0f, 0f);
verts[2] = new Vector3f(0f, -10f, 0f);
verts[3] = new Vector3f(-10f, 0f, 0f);
int[] pts = {0, 2,1,3}; // Lines between point 0 <-> 2 and 1<-> 3
com.jme.scene.Line cross = new com.jme.scene.Line("cross", BufferUtils.createFloatBuffer(verts), null,
null, null);
cross.setIndexBuffer(BufferUtils.createIntBuffer(pts));
cross.setMode(Mode.Segments);
rootNode.attachChild(cross);
}
public static void main(String[] args) {
TestLine game = new TestLine();
game.setConfigShowMode(ConfigShowMode.AlwaysShow);
game.start();
}
}