I am new to open gl, and have been putting together a viewer for a bunch of 2d objects (points, lines, circles, and arcs) that represent a part. I have my viewer working, and it allows me to zoom in and out, pan the part, and rotate it. But what I need to do is allow the user to select one of the individual features (point, line, …) so that I can display some information about that feature.
When the initial view comes up, and I am looking right at 0, 0, 0, the picking stuff does work kinda OK. I can pan around the object and I still get the same OK results. But as soon as I zoom or rotate the drawing, the picking stuff falls apart and sometimes returns the wrong answer. I think it is something in the drawing code while in picking mode. I am either missing a necessary step, or have 1 step too many. I have tried many things, with only worse results. Below is the best code so far that works with panning anyway.
void C3DRender::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
/* how big to make the pick buffer: */
#define PICK_BUFFER_SIZE 256
GLuint PickBuffer[PICK_BUFFER_SIZE]; /* picking buffer */
// setup the picking buffer
glSelectBuffer( PICK_BUFFER_SIZE, PickBuffer );
// the the current viewport
int viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
// select render mode
glRenderMode( GL_SELECT );
// initialize the name stack
glInitNames();
// give the stack a default value
glPushName(0);
// select the projection matrix
glMatrixMode(GL_PROJECTION);
// load it on to the stack
glPushMatrix();
// reset the matrix
glLoadIdentity();
// create a matrix that will zoom up to a very small portion around the mouse
gluPickMatrix(point.x,viewport[3]-point.y,10,10,viewport);
gluPerspective(45.0f, (GLfloat) (viewport[2]-viewport[0])/(GLfloat) (viewport[3]-viewport[1]), 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
//on draw code
//glLoadIdentity();
glTranslatef(0.0f, 0.0f, -m_fZoom);
glTranslatef(m_fPosX, m_fPosY, 0.0f);
glRotatef(m_fRotX, 1.0f, 0.0f, 0.0f);
glRotatef(m_fRotY, 0.0f, 1.0f, 0.0f);
// Clear color and depth buffer bits
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw OpenGL scene
oglDrawFeatures();
// Swap buffers
//SwapBuffers(hdc);
// restoring the original projection matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
//glFlush();
int Nhits = 0;
Nhits = glRenderMode( GL_RENDER );
if( Nhits != 0 ) {
int i, j;
unsigned int number;
unsigned int minz;
unsigned int maxz;
unsigned int name;
int ptr = 0;
for( i=0; i<Nhits; i++) {
number = PickBuffer[ptr++];
minz = PickBuffer[ptr++];
maxz = PickBuffer[ptr++];
for(j=0; j<number; j++) {
name = PickBuffer[ptr++];
}
}
}
CView::OnLButtonDown(nFlags, point);
}
I basically have a breakpoint set at the name = line to see if it’s working. Once I have it working I plan to tie it in with the rest of the code. The oglDrawFeatures is correctly naming the features because when it does work I do get the correct answer.
Thanks for your help.
- Brian