Picking in Opengl

I am trying to learn opengl’s picking mechanism. I read the instructions in the Red Book and wrote a small demonstration code. But it doesn’t work the way I expected it to. Please help me find the fault.
The problem is that, no matter how small I make the picking area (by reduing ‘width’ and ‘height’ arguments of gluPickMatrix), when I click anywhere on the scene all the objects get picked.
I have drawn two small cubes reasonably separated from each other. I want the cube on which I click to
be selected, but no matter where I click on the scene, both the cubes are being selected. I’ve written the entire code below, kindly help me find the mistake. If going through the entire code is not feasible, kindly suggest areas where one is prone to make mistakes.


#include<GL/glut.h>
#include<GL/gl.h>

float xrot=0,yrot=0;
void paintGL();
void drawScene(GLenum mode);
void drawCube(float size, float color1, float color2, float color3);
void arrows(int key, int x, int y);
void mousePress( int button, int state, int x, int y );
void proces****s(GLint hits, GLuint buffer[]);

void paintGL(void)
{

GLfloat x,y,z,angle,size=0;
int indi;

glClearColor(0.0,0.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);
drawScene(GL_RENDER);
glFlush();
}
void drawScene(GLenum mode)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

glOrtho(-20.0,20.0,-20.0,20.0,-20.0,20.0);

glMatrixMode(GL_MODELVIEW);

// the scene is drawn here
glPushMatrix();
glTranslatef(5.0,0.0,0.0);
if(mode == GL_SELECT)
glPushName(8);
drawCube(1.0,1.0,0.0,0.0);
if(mode == GL_SELECT)
glPopName();
glPopMatrix();
glPushMatrix();
glTranslatef(-5.0,-5.0,0.0);
if(mode == GL_SELECT)
glPushName(5);
drawCube(1.0,0.0,1.0,0.0);
if(mode == GL_SELECT)
glPopName();
glPopMatrix();
}

void drawCube(float size, float color1, float color2, float color3)
{
glColor3f(color1,color2,color3);
glBegin(GL_QUAD_STRIP);
glVertex3f(0.0,0.0,0.0);
glVertex3f(0.0,size,0.0);
glVertex3f(size,0.0,0.0);
glVertex3f(size,size,0.0);
glVertex3f(size,0.0,-size);
glVertex3f(size,size,-size);
glVertex3f(0.0,0.0,-size);
glVertex3f(0.0,size,-size);
glVertex3f(0.0,0.0,0.0);
glVertex3f(0.0,size,0.0);
glEnd();
glBegin(GL_QUADS);
glVertex3f(0.0,size,0.0);
glVertex3f(0.0,size,-size);
glVertex3f(size,size,-size);
glVertex3f(size,size,0.0);
glEnd();
glBegin(GL_QUADS);
glVertex3f(0.0,0.0,0.0);
glVertex3f(0.0,0.0,-size);
glVertex3f(size,0.0,-size);
glVertex3f(size,0.0,0.0);
glEnd();
}
void arrows(int key, int x, int y)
{
switch(key){
case GLUT_KEY_DOWN:
xrot -= 10;
break;
case GLUT_KEY_UP:
xrot += 10;break;
case GLUT_KEY_RIGHT:
yrot -= 10;
break;
case GLUT_KEY_LEFT:
yrot += 10;
break;
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(xrot,1.0,0.0,0.0);
glRotatef(yrot,0.0,1.0,0.0);
paintGL();
}

void mousePress( int button, int state, int x, int y )
{
#define BUFSIZE 1024
GLuint selectBuf[BUFSIZE];
GLint hits;
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT,viewport);
glSelectBuffer(BUFSIZE,selectBuf);
(void) glRenderMode(GL_SELECT);
glInitNames();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPickMatrix((GLdouble) x,(GLdouble) y, 0.1, 0.1, viewport);
gluOrtho2D(0.0, 1.0,0.0,1.0);
drawScene(GL_SELECT);
glPopMatrix();
glFlush();

hits = glRenderMode(GL_RENDER);
process (hits, selectBuf);
}
void proces
s(GLint hits, GLuint buffer[])
{
unsigned int i, j;
GLuint ii,jj,names,*ptr;

printf("hits = %d
", hits);
ptr = (GLuint*) buffer;
for(i=0; i<hits; i++)
{
names = *ptr;
printf("number of names for this hit = %d
“, names);
ptr++;
printf(“z1 is %u;”, *ptr); ptr++;
printf(” z2 is %u
",*ptr); ptr++;
printf("names are “);
for(j=0; j<names; j++)
{
printf(”%d
", *ptr);
ptr++;
}
}
}
main(int argc,char
argv[])
{
glutInit(&argc , argv);
glutInitWindowPosition(30,30);
glutInitWindowSize(300,300);
glutInitDisplayMode(GLUT_SINGLE| GLUT_RGBA| GLUT_DEPTH);
glutCreateWindow(“polygon”);
glutDisplayFunc(paintGL);
glutSpecialFunc(arrows);
glutMouseFunc(mousePress);
glEnable(GL_DEPTH_TEST);
glClearColor(0.0,0.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glutMainLoop();
}


The file is complete, and can be cut-copy-pasted into a file and run. Kindly help me find the problem.
Thanks for any help.

Hi !

gluPickMatrix modifies the projection matrix, but in your drawScene() function you reset the projection matrix again after gluPickMatrix is called, you have to move out the code that changes the projection matrix from drawScene, at least when you do selection.

Mikael

It worked!!! Thanks a lot for going through the code. I would never have been able to notice that error. Thanks a ton.