color coded picking

I’m not clear on what you’ve got there, I think maybe a typo as your first example of what I’ve got isn’t what I’ve got. I only increment the colors per triangle, as I understand it, incrementing colors per vertex would change the colors for every vertex position and they all need to be the same color.

Also, when I do a readPixel, the triangle that gets highlighted jumps all over the place as if it were getting 3 random vertices from my model. That part might be too complicated to post so I’ll just keep at it, but the colors I don’t understand why they’re not right.

I try to clarify how my colors are done here. I did change indices as you suggest and now see more colors. Before I thought all the empty triangles were just shades of black I couldn’t see and my drawNormally after drawColorCoded fooled me into thinking they were being drawn. I think my next important step is getting the tri’s all solid colors.

I do quesiton this line, am I understanding this correctly.
// 3 colors and we store 32 bit ints for each color w/ putInt?
ByteBuffer cBuffer = BufferUtils.newByteBuffer(3 * 4);


for (each triangle) { 
    int idx = 0;

    for (int i = 0; i < 3; i++) { // loop vertices of a single triangle 
        // ...
        cBuffer.putInt(idx, getRed());
        triBuffer.put(idx++, (float) node.getX());

        cBuffer.putInt(idx, getGreen());
        triBuffer.put(idx++, (float) node.getY());

        cBuffer.putInt(idx, getBlue());
        triBuffer.put(idx++, (float) node.getZ());

        // by not incrementing colors inside this loop, R, G, and B stay same color.

        indicesBuffer[i].put(index++); 
        indicesBuffer[i].put(index++); 
        indicesBuffer[i].put(index++); 
    }

colorBuffer[i].put(cBuffer); // add 9 colors per 9 vertices of this triangle
elementBuffer[i].put(triBuffer); // add 9 vertices of this triangle to array

incrementColor();
}

first you’re specifying the data you upload as GL_UNSIGNED_BYTE

gl.glColorPointer(3, GL.GL_UNSIGNED_BYTE, 0, colorBuffer[index]);

And then you pass an IntBuffer?

You have to encode your index (int) into RGB values (3 bytes, not 3 ints), then read them back as RGB (3 bytes) and decode them into your index.

So put your colors in a ByteBuffer

I am putting my colors in a ByteBuffer and my colors get incremented with the code below, they’re just int value that I put there. I’m sure something here I’ve not got corrrect and not understanding how to code the RGB values into an index since I already have an index that goes into the indicesBuffer (an IntBuffer). I think I’m thinking that the index into the index buffer pairs up w/ the same index into the color buffer since that color was added the same time that index was add (as in our triangle loops above).


	private int red = 0;
	private int green = 0;
	private int blue = 0;
        //...

	public void incrementColor() {
		if (blue < 255) {
			blue++;
		}
		else if (green < 255) {
			green++;
			blue = 0;
		}
		else {
			red++;
			green = 0;
			blue = 0;
		}

		return;
	}

This code is where the RGB gets decoded into an index. Does this index not come out to the same as the index’s I’m assigning in the indicesBuffer? Maybe I’m just getting lucky hits.


	public void readElementColor(GLAutoDrawable drawable) {
		GL gl = drawable.getGL();
		
		mouseBuffer.clear();
		
		gl.glReadPixels(renderer.getMouseX(), renderer.getMouseY(), 
			1, 1, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, mouseBuffer);

		mouseBuffer.rewind();
		
		/*
		 *  This turns the byte into an unsigned byte (using the sign-bit as the
		 *  ordinary 8th bit of an int, 32bit).
		 */
		int r = mouseBuffer.get() & 0xFF;
		int g = mouseBuffer.get() & 0xFF;
		int b = mouseBuffer.get() & 0xFF;

		// Decode the RGB to an index.
		activeTriangleIndex = (r << 16) | (g << 8) | (b << 0);
						
		return;
	}

How exactly are you coding these colors into an index? I think if I can get past this, then I can assign my indicesBuffer the index from the RGB encoding and not use my method of just incrementing a counter for the index.

You say to OpenGL that the format of your colorbuffer is GL_UNSIGNED_BYTE and has 3 elements (3 bytes)

Now, let’s see what yuo are actually sending to the GPU, per elements:

ByteBuffer.putInt®;
ByteBuffer.putInt(g);
ByteBuffer.putInt(b);

Now count the bytes… an int is 32 bit, a byte is 8 bit. so if you write an int to a buffer, it takes up 4 bytes. So with the above code, you push 12 bytes per element to the GPU, while it expects 3, the result is, well, to be short: it just won’t work, because the interpretation of the data is wrong (GPU-side).

With the following code, you will fill your color-buffer with bytes:

ByteBuffer.put((byte)r);
ByteBuffer.put((byte)g);
ByteBuffer.put((byte)b);

HTH

Ugh, that worked well and now I have solid colors. I didn’t think I could do that because I thought some colors (millions range, not that I would probably get that high) would get truncated by casting like that.

Now to fix the highlighting of the correct triangle. :slight_smile: Thanks for all your help.

Thanks guys, this turned out incredibly nice. I’ve loaded models w/ several hundred thousand elements and the highlighting actually keeps up w/ the mouse pointer, translation, speedy quick!

:slight_smile: Great you got it to work!

Yes, that’s great! Well done!

[quote]Basically you don’t use select mode anymore.
[/quote]
Interesting! Would someone enlighten me as to why?

I do use select on scenes with lots of tris and have been wondering about it’s performance. Most of my crashes seem to occur in glDrawElements in select mode as well… I would’ve expected select mode to be efficient as you don’t need to do real painting. It’s also useful to get the name stack out (Object ID, Subobject ID) and occasionally to see items behind the front tri…

Selction-mode is quite slow by itself (maybe 30% of plain rendering).

The amount of triangles doesn’t really matter, it’s about the name-count. When doing 1 name per triangle, you’re almost back to immediate-mode (as in: gl-call count).

So selection-mode is quite useful, but not a general solution, infact, it’s quite limited in use when you care about performance.

Thanks Riven! I don’t have many names - typically only one or two per object (and that might be 3-5000 tris) with a scene with maybe 100 objects max (I’d read that lots of names could be a problem). But if the selection rendering itself is slow that would explain much. I’ll have to try redoing the selection code to use colour picking.

Just pick only once per second, if you can get away with it.