 |
 |
|
 | |
Picking Tutorial
Color Coding
The Red Book describes an interesting approach to picking based on color coding. This is a very simple approach that can be used instead of using the OpenGL API described in the previous sections.
The color coding scheme does not require any perspective changes and therefore it is simpler in theory. Just define a rendering function where the relevant objects (pickable and occluders) are assigned each a different color. When the user clicks the mouse over the scene, render the scene on the back buffer, read back the selected pixel from the back buffer and check its color. The process is completely transparent to the user because the buffers are not swapped, so the color coding rendering is never seen.
For instance, consider the following scene with 4 snowmen. What you're seeing is the result of the normal rendering function.

The next figure shows the result produced in the back buffer by the color coding rendering function. As you can see each snowman has a different color.

The required steps when the mouse is clicked are:
1. Call the color coding rendering function
2. Read the pixel where the mouse was clicked from the back buffer
3. Process the color information to find out which item was clicked
4. Do NOT swap buffers, otherwise the user will see the color coding
Bellow the normal rendering function is presented. It contains the code to render both the ground as well as the snowmen (contained in the display list).
void draw() {
// Draw ground
glColor3f(0.9f, 0.9f, 0.9f);
glBegin(GL_QUADS);
glVertex3f(-100.0f, 0.0f, -100.0f);
glVertex3f(-100.0f, 0.0f, 100.0f);
glVertex3f( 100.0f, 0.0f, 100.0f);
glVertex3f( 100.0f, 0.0f, -100.0f);
glEnd();
// Draw 4 Snowmen
glColor3f(1.0f, 1.0f, 1.0f);
for(int i = 0; i < 2; i++)
for(int j = 0; j < 2; j++) {
glPushMatrix();
glTranslatef(i*3.0,0,-j * 3.0);
glColor3f(1.0f, 1.0f, 1.0f);
glCallList(snowman_display_list);
glPopMatrix();
}
}
The following function is for color coding rendering. As you can see the ground was left out since it is neither a pickable object, nor an occluding one. Also the code for the snowmen was altered
void drawPickingMode() {
// Draw 4 SnowMen
glDisable(GL_DITHER);
for(int i = 0; i < 2; i++)
for(int j = 0; j < 2; j++) {
glPushMatrix();
// A different color for each snowman
switch (i*2+j) {
case 0: glColor3ub(255,0,0);break;
case 1: glColor3ub(0,255,0);break;
case 2: glColor3ub(0,0,255);break;
case 3: glColor3ub(250,0,250);break;
}
glTranslatef(i*3.0,0,-j * 3.0);
glCallList(snowman_display_list);
glPopMatrix();
}
glEnable(GL_DITHER);
}
|