Jump to content
  • Advertisement
Sign in to follow this  
XDigital

Serious Picking Problem

This topic is 4242 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi Coders, I have a serious picking problem. This is my function that evaluate mouse clicks after lots of trials and errors combinig the modelview matrix and the projection matrix. The code comes from the red book, from the super bible, from NeHe and others...
//------------------------------------------------------------------------
static int EvalMouseClick(int x, int y){
//------------------------------------------------------------------------
   GLint nHit;

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

   glInitNames();
   glPushName(0);

   glMatrixMode(GL_PROJECTION);
   glPushMatrix();
      glLoadIdentity();
      gluPickMatrix(double(x),double(viewport[3]-y),2.0,2.0,viewport);

      glLoadIdentity();
      gluPerspective(45.0, (float)windowW/(float)windowH, 1.0, 5000.0f);
      glPushMatrix();
         RenderIcon(GL_SELECT);
      glPopMatrix();

      glMatrixMode(GL_PROJECTION);
   glPopMatrix();
   glMatrixMode(GL_MODELVIEW);

   nHit = glRenderMode(GL_RENDER);

   if (nHit <= 0) return -1;
   return selectBuf[(nHit - 1) * 4 + 3];
}

The following function is the RenderIcon function, which is called from the main render funtion with a glLoadIdentity in front of it and from this function:
//------------------------------------------------------------------------
void RenderIcon(GLenum mode){
//------------------------------------------------------------------------
   GLdouble modelMatrix[16];
   GLdouble projMatrix[16];
   GLdouble xyz[3];

   glGetDoublev(GL_MODELVIEW_MATRIX,modelMatrix);
   glGetDoublev(GL_PROJECTION_MATRIX,projMatrix);

   glDisable(GL_DEPTH_TEST);
   glDisable(GL_LIGHTING);

   glEnable(GL_BLEND);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE);

   glEnable(GL_TEXTURE_2D);
   glColor3f(1.0,1.0,1.0);

   //Character Icon
   glBindTexture(GL_TEXTURE_2D,icon.character.texID);
   glPushMatrix();
      gluUnProject(0.08*viewport[2],0.1*viewport[3],0.0,
         modelMatrix,projMatrix,viewport,&xyz[0],&xyz[1],&xyz[2]);
      glTranslatef(xyz[0],xyz[1],xyz[2]);
      glScalef(0.15,0.15,1.0);
      if (mode==GL_SELECT) glLoadName(ICON_CHARACTER);
      glCallList(icon.character.listID);
   glPopMatrix();

   //Inventory Icon
   glBindTexture(GL_TEXTURE_2D,icon.inventory.texID);
   glPushMatrix();
      gluUnProject(0.2*viewport[2],0.1*viewport[3],0.0,
         modelMatrix,projMatrix,viewport,&xyz[0],&xyz[1],&xyz[2]);
      glTranslatef(xyz[0],xyz[1],xyz[2]);
      glScalef(0.15,0.15,1.0);
      if (mode==GL_SELECT) glLoadName(ICON_INVENTORY);
      glCallList(icon.inventory.listID);
   glPopMatrix();

   //Fight Icon
   glBindTexture(GL_TEXTURE_2D,icon.fight.texID);
   glPushMatrix();
      gluUnProject(0.3*viewport[2],0.1*viewport[3],0.0,
         modelMatrix,projMatrix,viewport,&xyz[0],&xyz[1],&xyz[2]);
      glTranslatef(xyz[0],xyz[1],xyz[2]);
      glScalef(0.15,0.15,1.0);
      if (mode==GL_SELECT) glLoadName(ICON_FIGHT);
      glCallList(icon.fight.listID);
   glPopMatrix();

   glEnable(GL_LIGHTING);
   glEnable(GL_DEPTH_TEST);
   glDisable(GL_TEXTURE_2D);
   glDisable(GL_BLEND);
}

The name stack is filled with all names defined in this function. But my understanding is, that only the picked object (and objects lying behind it) will appear on the name stack. I have the feeling that there is something wrong with the area around the mouse cursor, the matrix mode or even with gluUnProject. Does anyone of you see the fatal user error? Best regards XDigital

Share this post


Link to post
Share on other sites
Advertisement
picking is used for findout what objects lie within a region in the 3d scene for a HUD like what u have just stick a bounding rect around each icon and go something like, simple + faster than picking

bool is_point_within_rect( vec2 point, rectangle rect )
{
if ( point.x > rect.x && point.x < rect.x + rect.w &&
point.y > rect.y && point.y < rect.y + rect.h )
return true;
return false;
}

Share this post


Link to post
Share on other sites
Considering you didnt mention exactly what is wrong with the results you are getting, Im not sure what you are asking about.

I've read in some places that phrase, that your selection results depend on the contents of the name stack. Thats only important for some purposes, as far as I can tell.

I did a lab assignment about picking, and doing LoadName() for everythign I drew, in other words, I had a total of one name on the stack at all times, and it still generated the results I needed within the selection buffer: the list of all the named primitives which fell in the pickmatrix projection.

Start polling OpenGL for error codes, see if it is telling you something.

Share this post


Link to post
Share on other sites
You have a call to glLoadIdentity in between gluPickMatrix and gluPerspective

The load identity will replace any previous results on the currently bound matrix with an Identity matrix.

Share this post


Link to post
Share on other sites
Ok, I try this "is_point_in_rect" function... Anyway, I'm not sure, why the namestack is filled with every defined name. My other application works fine with a similar code.
Cheers
XDigital

Share this post


Link to post
Share on other sites


glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPickMatrix(double(x),double(viewport[3]-y),2.0,2.0,viewport);

// YOUR PROBLEM LIES BELOW!!
glLoadIdentity();
// YOUR PROBLEM LIES ABOVE!!
gluPerspective(45.0, (float)windowW/(float)windowH, 1.0, 5000.0f);
glPushMatrix();
RenderIcon(GL_SELECT);
glPopMatrix();
}

gluPickMatrix is being called and immediately followed with glLoadIdentity. This effectively nullifies gluPickMatrix, making everything which is being drawn in the window be pushed onto your pick stack.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!