Picking in opengl

Hey guys,

I was trying out the picking methods in opengl and I am currently working on the method of coloring each objects uniquely in the back buffer and selecting the object based on these colors. Well actually, it aint working all well. When I use the glReadPixels() and see for the pixel that I selected I am not getting the correct color values in the pixels that the function returns. I cant find out whats wrong.

For example heres my processfunction for the picking:

void processPick ()
{
GLint viewport[4];
GLubyte pixel[3];

glGetIntegerv(GL_VIEWPORT,viewport);

glReadPixels(cursorX,viewport[3]-cursorY,1,1,GL_RGB,GL_UNSIGNED_BYTE,(void *)pixel);

printf("%d %d %d

“,pixel[0],pixel[1],pixel[2]);
if (pixel[0] == 255)
printf (“You picked the 1st octa”);
else if (pixel[1] == 255)
printf (“You picked the 2nd octa”);
else if (pixel[2] == 255)
printf (“You picked the 3rd octa”);
else if (pixel[0] == 250)
printf (“You picked the 2nd snowman on the 2nd row”);
else
printf(“You didn’t click a snowman!”);
printf (”
");

}

Now when I click on the black portion of the viewport i shoudl be getting 0,0,0 but no instead it shows me some other color values. And when I click on the object that is of unique color, I get a 0,0,0… I cant understand this situation.

Also I am wondering , whether it doesnt work because i am using an ortho projection. Does picking need to be perspective projection?

Plz reply if anyone knows.

Yours

Siddharth

picking is independent of the projection type.
but of course, you have to set up the same
projection/modelview matrices that you use when
you draw the model. it could help if you post some
more code, especially the part in which you call
the picking routine.

It may be because you’re using an unsigned byte that’s giving the wrong value?? I’m using exactly the same code in my program, and it works fine - but I’m just using a normal byte.

This is my code (in Java):

int viewport[] = new int[4];
byte pixel[] = new byte[3];
gl.glGetIntegerv(GL_VIEWPORT,viewport);
gl.glReadPixels(mouse_x,viewport[3]-mouse_y,1,1,GL_RGB,GL_BYTE,pixel);

And yes, I’m using perspective projection. See if that makes any difference. :slight_smile:

Dan.

Right, I’ll try to explain my code as much as possible and avoid confusion. Here goes:

//For picking
void processPick ()
{
GLint viewport[4];
GLubyte pixel[3];

glGetIntegerv(GL_VIEWPORT,viewport);

glReadPixels(cursorX,viewport[3]-cursorY,1,1,GL_RGB,GL_UNSIGNED_BYTE,(void *)pixel);

printf("%d %d %d

“,pixel[0],pixel[1],pixel[2]);
if (pixel[0] == 255)
printf (“You picked the 1st octa”);
else if (pixel[1] == 255)
printf (“You picked the 2nd octa”);
else if (pixel[2] == 255)
printf (“You picked the 3rd octa”);
else if (pixel[0] == 250)
printf (“You picked the 2nd snowman on the 2nd row”);
else
printf(“You didn’t click a snowman!”);
printf (”
");

}

void display(void)
{
//glutSetWindow(mainWindow);

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

/* view transform */
if (trackballMove) 
{
    glRotatef(angle, axis[0], axis[1], axis[2]);

}

{
	//Draw the x , y , z Axis and the grid initially.
	DrawAxis() ;
	Draw3DGrid() ;

	glPushMatrix() ;

	glTranslatef(MoveX , 0.0f , MoveZ) ;

	

	//To tilt the cube along with T1 octahedron and make one of the face 
//of T1 on the XZ plane.

	glRotatef(-36.0f , 0.0f , 0.0f , 1.0f) ;
	glRotatef(45.0f , 1.0f , 0.0f , 0.0f) ;
	glTranslatef(0.0f , 1.0f , 0.0f) ;
	
	if(mode == RENDER)
		DrawSetOne(RENDER) ;
	else
	{
		if(mode == SELECT)
		{
			DrawSetOne(SELECT) ;
		}
	}

	glPopMatrix() ;
	

	//To draw the second Octahedron T2 along with the cube on the T1 
	//Octahedron along the edge
	//opposite to the Z axis.

	glPushMatrix();
	
	glTranslatef(MoveX , 0.0f , MoveZ) ;
	glTranslatef(0.81f , 1.15f , 0.0f) ;
	glRotatef(ang,0,0,1);
	glRotatef(-36.0f , 0.0f , 0.0f , 1.0f) ;
	glRotatef(45.0f , 1.0f , 0.0f , 0.0f) ;
	glTranslatef(0.0f , 1.0f , 0.0f) ;	
	
	if(mode == RENDER)
		DrawSetTwo(RENDER) ;
	else
		if(mode == SELECT)
			DrawSetTwo(SELECT) ;

	glPopMatrix() ;

	//To draw the third Octahedron T3 along with the cube on the T2 
	//Octahedron along the edge
	//opposite to the Z axis.
	
	glPushMatrix() ;

	glTranslatef(MoveX , 0.0f , MoveZ) ;
	glTranslatef(0.81f , 1.15f , 0.0f) ;
	glRotatef(ang,0,0,1);
	glTranslatef(0.81f , 1.15f , 0.0f) ;
	glRotatef(ang1,0,0,1);
	glRotatef(-36.0f , 0.0f , 0.0f , 1.0f) ;
	glRotatef(45.0f , 1.0f , 0.0f , 0.0f) ;
	glTranslatef(0.0f , 1.0f , 0.0f) ;

	if(mode == RENDER)
		DrawSetThree(RENDER) ;
	else
		if(mode == SELECT)
			DrawSetThree(SELECT) ;

	glPopMatrix() ;
	

	glFlush() ;
}

if (mode == SELECT) 
{
	processPick();
	mode = RENDER;
}
else
	if(mode == RENDER)
		glutSwapBuffers();

}

void mouseButton(int button, int state, int x, int y)
{
if(button != GLUT_LEFT_BUTTON || state != GLUT_DOWN)
return ;

if(button==GLUT_LEFT_BUTTON) switch(state) 
{
	case GLUT_DOWN:
		y=winHeight-y;
		startMotion( x,y);
		
		//For picking.
		cursorX = x;
		cursorY = y;
		mode = SELECT;
		break;

	case GLUT_UP:
		stopMotion( x,y);
		break;
} 

}

void main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutCreateWindow(“colorcube”);
glutReshapeFunc(myReshape);
glutDisplayFunc(display);
glutMouseFunc(mouseButton);
glutMotionFunc(mouseMotion);
glutKeyboardFunc(Keyboard) ;
glutSpecialFunc(ArrowKeys) ;

glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-5.0, 5.0, -5.0, 5.0, -200.0, 200.0);
glMatrixMode(GL_MODELVIEW);

glutMainLoop();

}

So these are my essentials parts of code that i think are relavant to picking. I have no Init() in my code as i do all of them in my main() itself. Basically in the display() i have to draw a model that is arranged in a way that is on top of each each other so taht the next object touches the edge of the object below and hence i have done the transformations. But the point here is , i have kept a mode variable which is set when the mouse is clicked and depending on this, the object is drawn in the back buffer or its drawn with buffers swapping. I have used only glOrtho and that too at the main(). So guys could u tell wats wrong with this code???

thanx