Picking With Color

Can someone please show me how to determine which object being selected using “picking with color”. Please use GLUT.

Let say I have two rectangles, red and green which is rendered in orthographic projection. When the user click on the red rect, exit program and cout<<“Red is selected”;

Please avoid using pointer if you can because I’m not good in that.

In your mouse function.

unsigned char col[3];
glReadPixels(x, windowHeight - y - 1, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, col);
if(col[0] == 255 && col[1] == 0 && col[2] == 0)
cout << “Red is selected” << endl;

Tweak the color values in the if-statement to whatever colors you want. They are ordered as red, green and blue. windowHeight is the height of your window. This is needed becuase mouse coordinates is counted from the top, while OpenGL’s origin is in the bottom.

Thanks Bob

If I use double buffering, I have to add this code before glReadPixels(…) command right?


glSelectBuffer takes two parameters, a pointer to a buffer and the size of the buffer. Dunno where you got GL_FRONT from. glSelectBuffer is used when rendering in selection mode.

All you have to do is make sure you’re reading from the buffer you’re drawing into. By deafault, they are the same, so no other commands are needed.

Hai, I’ve got new problem.

void mouseClick (…)
glColor3f(0.5, 0, 0);
glRectf(-10, 10, -5, -10);
GLfloat col[3];
glReadPixels(x, windowHeight-y-1, 1, 1, GL_RGB, GL_FLOAT, col);
cout<< "Red value = " << col[0] << "

OUTPUT : Each time I change GLfloat to float or float to GLfloat,
First time I run, I got “Red value = 0.483871”
Second time and so on, I got “Red value = 0.516129”

QUESTION : Why it is not “Red value = 0.5” ? Why this happended ? How to solve it?


Well, I think was slightly wrong in my second post. I said you should read form the same buffer you draw to. This is not entirely correct. You should always read from the front buffer (because that’s the buffer you see on the screen). If you are using double buffers, the color information you want is in the front buffer. Put a glReadBuffer(GL_FRONT) before glReadPixels or in the initialization phase of your program.

Also remember that you may have precision problems. If you have a 16-bit frame buffer, you usually have 5 bits for the red component. This means you have a precision of 1/32 = approx 0.03. If you expect a value of X, the actual value you get can be anywhere between X - 0.03 and X + 0.03.

Another thing is to make sure you disable everything that affects the color of a fragment, so you can be absolutely sure what color goes into the frame buffer. This includes stuff like texturing, lighting, fogging, and so on.