I am trying to get picking to work, but despite reading about it in the OpenGL Super Bible and studying the NeHe examples for C++Builder 6, I can’t get it to work properly.
I am able to pick some objects but not all, and only in certain views (typically perspective and isometric, not cross-section, elevation, or plan). Some objects are picked when I click near them (noy on them)!
Can anyone see what is wong wih my code please? I would be happy to supply ALL the code (written for C++Builder 6) if that helps.
Many thanks in anticipation
Andrew
Here are (what I think are) the most significant functions:
void OnResize(int width, int height)
{
glViewport(0, 0, width, height);
}
void OnPaint()
{
glLoadIdentity();
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(projection == Perspective) {
double aspect(double(width) / height);
double near_plane(size * width / 10);
double far_plane(near_plane * 1000);
gluPerspective(45, aspect, near_plane, far_plane);
}
else {
double h(size * height); // in cm
double w(size * width); // in cm
glOrtho(-w, w, -h, h, -w, w);
}
glMatrixMode(GL_MODELVIEW);
LocateCamera(); // see below
RenderScene(); // see below
SwapBuffers();
::ValidateRect(hwnd, NULL);
}
void LocateCamera()
{
switch(projection) {
case CrossSection:
gluLookAt(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0);
break;
case Plan:
gluLookAt(0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
break;
case Elevation:
gluLookAt(0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0);
break;
case Isometric:
gluLookAt(-1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0);
break;
case Perspective:
gluLookAt(-20.0, -20.0, -20.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0);
break;
default:
throw std::invalid_argument(FUNC);
}
}
void RenderScene()
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glInitNames();
glPushName(0);
glScaled(scale, scale, scale);
glScaled(100, 100, 100); // we are working in cm per pixel
assert(Draw);
Draw(); // draws the obejcts and pushes names onto the name stack
glPopMatrix();
}
bool HitTest(int x, int y)
{
glSelectBuffer(name_stack.size(), &name_stack[0]);
int viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
glRenderMode(GL_SELECT);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPickMatrix((double)x, viewport[3] - (double)y, 20, 20, viewport);
double aspect(double(width) / height);
double near_plane(size * width / 10.0);
double far_plane(near_plane * 100);
gluPerspective(45, aspect, near_plane, far_plane);
glMatrixMode(GL_MODELVIEW);
RenderScene();
glMatrixMode(GL_PROJECTION);
unsigned int hits = glRenderMode(GL_RENDER);
// pop the projection matrix
glPopMatrix();
return hits;
}
// end of code