Picking SelectBuffer

Started by
4 comments, last by TomasH 19 years, 8 months ago
I have implemented picked with the gluPickMatrix command, and it registers the number of objects that are under the mouse cursor at any given time, but it does not supply correct numbers in the selectbuffer. I get 0, huge number, huge number, 0, then all 0's no matter what the objectcount is. I am sure that all ID's are set from 0 to m_quadcount/m_linecount respectively. The relavent code is posted below. int OpenGL::check_collision(int x, int y) { int objectcount=0; int viewportcoords[4]= {0}; unsigned int selectbuffer[32] = {0}; // set the select buffer glSelectBuffer(32, selectbuffer); // get the coordinates for the viewport glGetIntegerv(GL_VIEWPORT, viewportcoords); // switch to project matrix mode glMatrixMode(GL_PROJECTION); // push on a new matrix so I don't effect the back buffer glPushMatrix(); // set the render mode so that what we render isn't actually drawn to screen glRenderMode(GL_SELECT); // reset the projection matrix glLoadIdentity(); // get the projection matrix for the pick region gluPickMatrix(x, viewportcoords[3]-y, 2, 2, viewportcoords); // reset the aspect ratio gluPerspective(45.0f, (GLfloat)(viewportcoords[2]-viewportcoords[0])/(GLfloat)(viewportcoords[3]-viewportcoords[1]), 0.00001f, 100.0f); // change to modelview mode glMatrixMode(GL_MODELVIEW); // render drawscene(); // get the number of objects in the clicked region objectcount = glRenderMode(GL_RENDER); // change back to projection matrix glMatrixMode(GL_PROJECTION); // pop the projection matrix glPopMatrix(); glMatrixMode(GL_MODELVIEW); return objectcount; } int OpenGL::drawscene(GLvoid) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt(m_x, m_y, m_zoom, m_x, m_y,0, 0,1,0); glInitNames(); if (m_quadcount) { for (int i=0; i<m_quadcount+1;i++) { if (quads.visible==1) { glLoadName(quads.ID); glBegin(GL_QUADS); glColor3fv(quads.color); glVertex3d(quads.box.left, quads.box.top,0); glVertex3d(quads.box.right, quads.box.top,0); glVertex3d(quads.box.right, quads.box.bottom,0); glVertex3d(quads.box.left, quads.box.bottom,0); glEnd(); } } } if (m_linecount) { for (int i=0; i<m_linecount;i++) { glLoadName(lines.ID); glBegin(GL_LINES); if (!lines.color && m_clear_c==0) glColor3f(1.0f,1.0f,1.0f); else if (!lines.color && m_clear_c==1) glColor3f(0.0f,0.0f,0.0f); else glColor3f(lines.r, lines.g, lines.b); if (lines.x1 < 0 || lines.x2 <0) MessageBox(NULL, "x less than 0", "alert", MB_OK); glVertex2d(lines.x1, lines.y1); glVertex2d(lines.x2, lines.y2); glEnd(); } } return 1; }
Advertisement
Quote:Original post by Adawyn
I get 0, huge number, huge number, 0, then all 0's no matter what the objectcount is.

First zero - number of names on the stack
First huge number - minimum window-coordinate z of all primitives that have intersected since last hit. Multiplied by 2^32-1
Second huge number - same but maximum z
Rest of zeros - would be the name stack, if there was actually anything on it.

There is nothing on the name stack since you haven't pushed anything on it. Add a glPushName(0) after glInitNames().

Had you been checking glGetError, you would have gotten a GL_INVALID_OPERATION for trying to change the topmost element of an empty stack. The lesson is, of course, to use glGetError [grin]
Adding that I now get a 1 in the first position and a 3rd huge number for the 4th value in the array. Should I not be using loadname? should I only push the names onto the name stack and then not pop them until I finish the call to check_collision?
Quote:Original post by Adawyn
Adding that I now get a 1 in the first position and a 3rd huge number for the 4th value in the array. Should I not be using loadname?

glLoadName should work fine. The 4th value - the huge number - is what was on the name stack when the hit occured..
Check the IDs again, make sure that they are correct (your huge number should be equal to one of the IDs.)
the number is always the same... 3452816845... and the second and third entries in the array are both 4294961663
4294961663/(2^31-1) is approximately 1, i.e. close to the far plane.. I really can't say why the name is that huge number...

I don't know if it has anything to do with the problem, but I find this strange:
gluPerspective(45.0f, (GLfloat)(viewportcoords[2]-viewportcoords[0])/(GLfloat)(viewportcoords[3]-viewportcoords[1]), 0.00001f, 100.0f);

The second parameter, ratio, is supposed to be width/height. Why do you (width-x)/(height-y)? Doesn't make sense to me..
Also, putting the near plane that close might not be a good idea. Try putting it at 1.0 instead. link

This topic is closed to new replies.

Advertisement