PDA

View Full Version : Picking, glRenderMode



custard
01-27-2009, 12:15 PM
Hi,

I'm using the code below to pick the object under a mouse click. If I use the same gluPerspective parameters that I set during initialization, I get no hits. If I vary them, I get some hits, but the min Z, max Z values for the buffer entries are 0 (or close to 0). On top of that, I've tried with a very simple case, displaying a cube, and clicking on the front face, so that I should get two hits (another one for the back face), and glRenderMode only returns a hit.


void selection(int x, int y)
{
GLuint buffer[512] = {0};
GLint numberOfHits;
GLint viewport[4];

// Use buffer for selection
glSelectBuffer(512, buffer);
// Get viewport info
glGetIntegerv(GL_VIEWPORT, viewport);
// Switch to selection mode
glRenderMode(GL_SELECT);
// Clear the name's stack
glInitNames();
// Push one element onto the stack
glPushName(NULL);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
// Restrict the drawing to an area around the cursor
gluPickMatrix(x, y, 1.0, 1.0, viewport);
// zNear=1000, zFar=10000 during initialization
//gluPerspective(fovy, ((GLdouble) windowWidth) / windowHeight, zNear, zFar);
gluPerspective(fovy, ((GLdouble) windowWidth) / windowHeight, 0.001, 1000);
// Draw the objects onto the screen
glMatrixMode(GL_MODELVIEW);
// Draw only the names in the stack, and fill the array
glutSwapBuffers();
display();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
// Get the number of objects drawn in that area
// Return to render mode
numberOfHits = glRenderMode(GL_RENDER);
list_hits(numberOfHits, buffer);
if (numberOfHits > 0)
{
int objectMinZ = buffer[1];
int objectName = buffer[3];
for (unsigned int i = 1; i < numberOfHits; i++)
{
if (buffer[i*4+1] < GLuint(objectMinZ))
{
objectMinZ = buffer[i*4+1];
objectName = buffer[i*4+3];
}
}
Side::selectSide(objectName);
}
}

Cheers,

scratt
01-27-2009, 11:13 PM
Personally I have had problems with some z values in gluUnProject.
farz = 1.0 for example.

For picking using gluUnProject twice and ray sphere intersection is much better IMO. This removes the need to run through rendering twice, or in a more complicated fashion, on the GPU.

I have not looked at your code in detail btw.

The one hit you are getting is (maybe) because you are looking at the depth buffer so you'll only get the closest hit. That is one drawback with ray / sphere, as you get multiple hits going through z, but that may be what you want then?

custard
01-29-2009, 04:08 PM
I think my problems come from (my not understanding correctly how to use) gluPerspective. If I don't use it at all within the code above, I get some hits. However:

1) for an easy case, such as "I only see the front face", and I click it, I get two hits, the front and the back faces, but the min z corresponds to the back face.

2) sometimes, they are not the hits I expect. For example, if I'm watching three sides of a cube, and I click on the left side, expecting to get left and bottom as hits, I get though left and back. It's as if the picking mechanism would be looking at the cube from a position where it could only see left and front faces.

Does this ring a bell to anyone?

Thanks,

custard
01-29-2009, 04:35 PM
OK, I got it. I was missing the call to gluLookAt after the call to gluPerspective. I had that in my graphics initialization function, and you need to replicate all the settings within the picking code.