Not that I want to say it was an easy problem, but it was a... simple problem

Took me around 10mins to figure it out (even though I did not answered 10mins after you posted the message above

)
In fact, it costs me more time to post the answer than to find it !
Well *hum* jokes apart. You did not make any error drawing the scene or pushing/popping the names.
You have (had?) two *other* mistakes :
First of all, you use wrong mouse coordinates for the cursor.
In picking, mouse coordinates are used as (m.x, viewport[3]-m.y) because of OpenGL''s mathematical representation of coordinates in 3D which uses a y axis up for positive values and down for negative values (in mouse coordinates, up result in _lower_ value, and down result in _higher_ values.
But you don''t use MS Windows'' mouse cursor : you use your own cursor whose coordinates are exploited in the OpenGL transformation matrices (modelview and projection).
So, you also have to "invert" your cursor position.
Instead of calling glTranslatef(m.x, m.y), I''d recommend using glTranslatef(m.x, window_height-m.y);
Without that, for me the mouse up/down axis is reversed, which is quite frustrating.
Secondly, and more important, you don''t use the good projection matrix.
For selection rendering, you use this perspective :
gluPerspective(45.0f, (GLfloat) (viewport[2]-viewport[0])/(GLfloat) (viewport[3]-viewport[1]), 0.1f, 100.0f);
But for your "normal" rendering, you use this perspective :
gluPerspective(45.0f,(GLfloat)xres/(GLfloat)yres,0.1f,2000.0f);
And there''s a problem because with the first of those perspectives, your far plane is at 100.0f which is not enough for your scene : because terrain is drawn "behind" this far plane 100.0f, the polygons are clipped out of the viewing frustum, result in non hitting the selection buffer.
To correct it, the simple solution is to use the same gluPerspective arguments in BOTH cases.
Otherwise, you can ask OpenGL to "synchronize" this matrix for you.
Instead of doing :
glMatrixMode(GL_PROJECTION); // Selects The Projection MatrixglPushMatrix(); // Push The Projection MatrixglLoadIdentity(); // Resets The Matrix// This Creates A Matrix That Will Zoom Up To A Small Portion Of The Screen, Where The Mouse Is.gluPickMatrix((GLdouble) m.x, (GLdouble) (viewport[3]-m.y), 1.0f, 1.0f, viewport);// Apply The Perspective MatrixgluPerspective(...);glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix...
|
you can do :
GLfloat projection[16]; // The Current Projection MatrixglGetFloatv(GL_PROJECTION_MATRIX, projection);glMatrixMode(GL_PROJECTION); // Selects The Projection MatrixglPushMatrix(); // Push The Projection MatrixglLoadIdentity(); // Resets The Matrix// This Creates A Matrix That Will Zoom Up To A Small Portion Of The Screen, Where The Mouse Is.gluPickMatrix((GLdouble) m.x, (GLdouble) (viewport[3]-m.y), 1.0f, 1.0f, viewport);// Apply The Perspective MatrixglMultMatrixf(projection);glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix...
|
athough I''d not recommend that method since it''s a bit slower. Just keep this in mind if you can''t control the exact projection matrix yourself.
Also, one last thing I''d like to say : do not use a picking region of (1.0f, 1.0f). Sometimes, objects will be difficult to select on a single pixel exactitude. I''d rather recommend using a greater region (but still small of course) like (5.0f, 5.0f), eg :
gluPickMatrix((GLdouble) m.x, (GLdouble) (viewport[3]-m.y),
5.0f,
5.0f, viewport);