Picking not working...

I’m trying to create a program that draws 2d polygons and then uses picking to select and edit them, however I can’t manage to get any hits and I don’t know why.

Mouse function: left click draws objects and right click selects them.

 
void mouse(int btn, int state, int x, int y)
{
	//glutMotionFunc(mouse(btn, state, x, y));
	static int count;
	int where;
	static int xp[2],yp[2];

	GLuint selectBuf[SIZE];
	GLint hits;
	GLint viewport[4];

	//Left Button
	if(btn==GLUT_LEFT_BUTTON && state==GLUT_DOWN)  //LEFT BUTTON
	{
		glPushAttrib(GL_ALL_ATTRIB_BITS);
		where = pick(x,y);
		glColor3f(r, g, b);
		if(where != 0)
		{
			count = 0;
			draw_mode = where;
		}
		else switch(draw_mode)
		{
			case(LINE):
				if(count==0)
				{
					count++;
					xp[0] = x;
					yp[0] = y;
				}
				else 
				{
					line newLine = line (x, wh-y, xp[0], wh-yp[0]);
					shapelist.add(newLine);
					numS++;
					std::cout<<"numS = "<<numS;
					glBegin(GL_LINES);
						glVertex2i(x, wh-y);
						glVertex2i(xp[0], wh-yp[0]);
					glEnd();
					draw_mode=0;
					count=0;
				}
				break;
			case(RECTANGLE):
				if(count == 0)
				{
					count++;
					xp[0] = x;
					yp[0] = y;
				}
				else 
				{
					rectangle newRect = rectangle(x, wh-y, xp[0], wh-yp[0], fill);
					shapelist.add(newRect);
					numS++;
					if(fill) glBegin(GL_POLYGON);
					else glBegin(GL_LINE_LOOP);
						glVertex2i(x,wh-y);
						glVertex2i(x,wh-yp[0]);
						glVertex2i(xp[0],wh-yp[0]);
						glVertex2i(xp[0],wh-y);
					glEnd();
					//newRect.draw();
					draw_mode=0;
					count=0;
				}
				break;

			case (TRIANGLE):
				switch(count)
				{
					case(0):
						count++;
						xp[0] = x;
						yp[0] = y;
						break;
					case(1):
						count++;
						xp[1] = x;
						yp[1] = y;
						break;
					case(2): 
						triangle newTri = triangle (xp[0], xp[1], x, wh-yp[0], wh-yp[1], wh-y, fill);
						shapelist.add(newTri);
						numS++;
						if(fill) glBegin(GL_POLYGON);
						else glBegin(GL_LINE_LOOP);
							glVertex2i(xp[0],wh-yp[0]);
							glVertex2i(xp[1],wh-yp[1]);
							glVertex2i(x,wh-y);
						glEnd();
						draw_mode=0;
						count=0;
				}
				break;
			case(POINTS):
			{
				drawSquare(x,y);
				count++;
			}
		}

		glPopAttrib();
		glFlush();
	}
	else if (btn==GLUT_RIGHT_BUTTON && state==GLUT_DOWN) //RIGHT BUTTON
	{

		glPushAttrib(GL_ALL_ATTRIB_BITS);
		if (rightActive)
		{
			//---------
			//Selecting objects
			glGetIntegerv (GL_VIEWPORT, viewport);

			glSelectBuffer (SIZE, selectBuf);
			glRenderMode(GL_SELECT);

			glInitNames();
			glPushName(0);

			glMatrixMode(GL_PROJECTION);
			glPushMatrix();
				glLoadIdentity();
				/* create 3x3 pixel picking region near cursor location */
				gluPickMatrix ((GLdouble) x, (GLdouble) (viewport[3] - y), 3.0, 3.0, viewport);
				gluOrtho2D(wh, ww, wh, 0);
				drawObjects(GL_SELECT);
				glMatrixMode(GL_PROJECTION);
			glPopMatrix ();

			hits = glRenderMode (GL_RENDER);
			processHits (hits, selectBuf);

			//glutPostRedisplay();
			//-----------

			if (rightMFunc == 1)
				shapelist.deleteANode(top);
			else if (rightMFunc == 2)
				selected.move(x, y);
			else if (rightMFunc == 3);
				selected.reshape(x, y);
		}
		glPopAttrib();
		glFlush();
	}
}



Process Hits:

 
void processHits (GLint hits, GLuint buffer[])
{
   unsigned int i, j;
   GLuint names, *ptr;
   std::cout<< "HITS = "<<hits;

   ptr = (GLuint *) buffer;
   for (i = 0; i < hits; i++)
   { /*  for each hit  */
      names = *ptr;
	  std::cout<<"NAMES = "<<names;
      ptr+=3;
      for (j = 0; j < names; j++)
      { /*  for each name */
		 top = (int) ptr;
		 std::cout<<"PTR = "<<ptr;
		 ptr++;
      }
   }
   //top--;  do i need this?
   std::cout<<"TOP = "<<top;
   selected = shapelist.getXObject(top);
}

drawObjects:

 
void drawObjects(GLenum mode)
{
	GLuint i, j;
	glRenderMode(mode);
	for (i=0; i<numS; i++)
	{
		glLoadName(i);
		shapelist.getHead().draw();
	}
	/*for (i=0; i<3; i++)
	{
		if(mode == GL_SELECT)
			glLoadName(i);
		glColor3f(1.0, 0.0, 0.0);
		for(j=0; j<3; j++) 
		{
			glRectf(-0.5, -0.5, 1.0, 1.0);
			if(mode == GL_SELECT) 
				glLoadName(i);
			glColor3f(0.0, 0.0, 1.0);
			glRectf(-1.0, -1.0, 0.5, 0.5);
		}
	}*/
} 

I apologize, I know its a lot of code to look through, but any help would be greatly appreciated

Are you working in 2D?

If so then why not just do this on the CPU side using an algorithm similar to the ones discussed here:

http://www.exaflop.org/docs/naifgfx/naifpip.html

I am not a fan of GL picking (although apparently there are differing views here in the forums now) as it is deprecated AFAIK, and also for simple “collision detection” / selection it’s far easier to just do this on the CPU side IMO.

I have always personally found this page to offer some better alternatives:

http://www.opengl.org/resources/faq/technical/selection.htm

If you are editing geometry then you are going to have geometry on the CPU side, so CPU side methods are probably better for you, and will be more efficient.

well, the first link is much better to use… Thanks scratt… :slight_smile:

The biggest problem is software is very slow!!

-Kurt