Picking working on Mac Os X, not on XP [solved]

Hi,

I’m working on picking and the following code shows different results on Mac Os X and XP (doesn’t work on XP).
I have no idea why.


// METHOD FOR PICKING SPEAKERS
private void getSpeakerFromMouse()
{
        // INIT PICKING
	int hits = 0;
	int[] vPort = new int[4];
	IntBuffer selectBuf = ByteBuffer.allocateDirect(2048).asIntBuffer();
	gl.glGetIntegerv(GL.GL_VIEWPORT, vPort, 0);
	gl.glSelectBuffer(selectBuf.capacity(), selectBuf);
	gl.glRenderMode(GL.GL_SELECT);
	gl.glInitNames();
	gl.glMatrixMode(GL.GL_PROJECTION);
	gl.glPushName(-1);
	gl.glPushMatrix();
	gl.glLoadIdentity(); // reset the proj. matrix
	// !!! leave gluPickMatrix after glloadidentity
	/* create MOUSE_SELECT_SIZExMOUSE_SELECT_SIZE pixel picking region near cursor location */
	glu.gluPickMatrix(mousex, mousey, MOUSE_SELECT_SIZE, MOUSE_SELECT_SIZE, vPort, 0);
	// !!! leave gluOrtho after glupickmatrix
	glu.gluOrtho2D(minX, maxX, minY, maxY);

        // DRAW SPEAKERS AND LOAD NAMES
	drawSpeakers(false);
	gl.glPopMatrix();
	gl.glFlush();
	hits = gl.glRenderMode(GL.GL_RENDER);

        // TREAT PICKING BUFFER
	if (hits == 0)
	{
		speakerSelected = -1;
		return;
	}

	int offset = 0;
	int names = -1;
	for (int i = 0; i < hits; i++)
	{
		names = selectBuf.get(offset);
		offset++;
		offset++;
		offset++;
		for (int j = 0; j < names; j++)
		{
			if (j == (names - 1))
			{
				speakerSelected = selectBuf.get(offset);
			}
			offset++;
		}
	}
}

The objects I’m trying to pick are named via the standard call to gl.glLoadName(int)
The content of selectBuf is printed when I pick the object Spk 0 (with ID -2147483648)
Here are the results :

On XP, java 1.5.0_06, NVidia Geforce2 MX

Objects drawn and there name :
Spk 0 -2147483648
Spk 1 -2147483647
Spk 2 -2147483646
Spk 3 -2147483645
Spk 4 -2147483644
Spk 5 -2147483643
Spk 6 -2147483642
Spk 7 -2147483641

Content of ‘selectBuf’ (16 first ints on 512)
16777216 -2130968705 -2130968705 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 …

What are those numbers ? Now is trying to get the 16777216nth of the selectBuf which of course doesn’t exist, thus throws an exception.

On Mac OS X, java 1.5.0_06, ATI Mobility Radeon 9700

Objects drawn and there name :
Spk 0 -2147483648
Spk 1 -2147483647
Spk 2 -2147483646
Spk 3 -2147483645
Spk 4 -2147483644
Spk 5 -2147483643
Spk 6 -2147483642
Spk 7 -2147483641

Content of ‘selectBuf’ (16 first ints on 512)
1 2147483647 2147483647 -2147483648 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 …

This is good, the name is the number to pick beginning at index 3, so it’s fine.

Maybe it’s due to the graphic card, it’s an old one but I thought Java was over that.

Any clue anyone ?

Thanks

Léo

Without looking deeper into your test case I am 99% sure the reason is that you didn’t set the native order on your ByteBuffer before turning it into an IntBuffer. I strongly recommend using the BufferUtil class in com.sun.opengl.util for this case. Please also see the demos.misc.Picking demo in the jogl-demos workspace.

[quote]Without looking deeper into your test case I am 99% sure the reason is that you didn’t set the native order on your ByteBuffer before turning it into an IntBuffer. I strongly recommend using the BufferUtil class in com.sun.opengl.util for this case. Please also see the demos.misc.Picking demo in the jogl-demos workspace.
[/quote]
You’re the best !
Sorry for this, I thought my code came from the examples but it doesn’t seem to be the case, so I didn’t check the demos.

So the solution is :

IntBuffer selectBuf = BufferUtil.newIntBuffer(512);

instead of

IntBuffer selectBuf = ByteBuffer.allocateDirect(2048).asIntBuffer();

Thanks Ken

Léo


BufferUtil.newIntBuffer(512);

is the same as:


ByteBuffer.allocateDirect(512 * 4).order(ByteOrder.nativeOrder()).asIntBuffer();

BufferUtils is heaven for the lazy developer ::slight_smile: