PDA

View Full Version : OpenGL and MFC: picking object



ChrisT
05-05-2001, 04:04 AM
Hi,

My problem is that when i want to use picking technics with MFC, it doesn't work. I use the picking technic described in the red book but it doesn't work. I hope someone could help me. It's very important. Thanks.

Tim Stirling
05-05-2001, 05:44 AM
What exactly doesn't work?, what rpoblems are there? what technique are you useing? I have OpenGL's selection working with MFC.

ChrisT
05-05-2001, 07:30 AM
In fact, I have several cubes in the view and I want to select them by picking them with the mouse. So I use the OnLButtonDown function to process the selection. But the result of glRenderMode(GL_RENDER) always return 0. I give you the code:



void CWindowsGLView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CWindowsGLDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);

GLuint selectBuffer[BUFFSIZE];
GLint hits;
GLint viewport[4];

glGetIntegerv(GL_VIEWPORT, viewport);

glSelectBuffer(BUFFSIZE, selectBuffer);
(void)glRenderMode(GL_SELECT);

glInitNames();
glPushName(0);

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();

glEnable(GL_DEPTH_TEST);

double size = 0.0, s;
std::vector<Piece *>::iterator it;
for(it = pDoc->graphics.begin(); it != pDoc->graphics.end(); it++) {
s = (*it)->size();
if(s > size) size = s;
}

gluPickMatrix((GLdouble)point.x, (GLdouble)(viewport[3]-point.y), 10.0, 10.0, viewport);
gluPerspective(30.0, 1.0, 0.01 * size, 30.0 * size);
gluLookAt(0.0, 8.0*size, 6.0*size, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

for(it = pDoc->graphics.begin(); it != pDoc->graphics.end(); it++)
(*it)->internalDraw(1);

glMatrixMode(GL_PROJECTION);
glPopMatrix();
glFlush();

hits = glRenderMode(GL_RENDER);

CView::OnLButtonDown(nFlags, point);
}

//The function internalDraw
void GraphicObject::internalDraw(int mode) {
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glTranslated(translation[0], translation[1], translation[2]);

glRotated(rotation[0], 1.0, 0.0, 0.0);
glRotated(rotation[1], 0.0, 1.0, 0.0);
glRotated(rotation[2], 0.0, 0.0, 1.0);

glScaled(scale[0], scale[1], scale[2]);

if(mode == 0)
redraw();
else
selection();

glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}

//The function selection
void Cube::selection()
{
double s = _size/2.0;
glColor3f(wcolor[0], wcolor[1], wcolor[2]);
glLineWidth(wwidth);
glDisable(GL_LIGHTING);

glLoadName((GLuint)getNumeroGL());
glPushName((GLuint)getNumeroGL());
glBegin(GL_LINES);
glVertex3f(s, s, s);
glVertex3f(-s, s, s);
glVertex3f(-s, s, s);
glVertex3f(-s, -s, s);
glVertex3f(-s, -s, s);
glVertex3f(s, -s, s);
glVertex3f(s, -s, s);
glVertex3f(s, s, s);
glVertex3f(s, s, -s);
glVertex3f(-s, s, -s);
glVertex3f(-s, s, -s);
glVertex3f(-s, -s, -s);
glVertex3f(-s, -s, -s);
glVertex3f(s, -s, -s);
glVertex3f(s, -s, -s);
glVertex3f(s, s, -s);
glVertex3f(s, s, s);
glVertex3f(s, s, -s);
glVertex3f(-s, s, s);
glVertex3f(-s, s, -s);
glVertex3f(s, -s, s);
glVertex3f(s, -s, -s);
glVertex3f(-s, -s, s);
glVertex3f(-s, -s, -s);
glEnd();
}


thanks. http://www.opengl.org/discussion_boards/ubb/wink.gif

ChrisT
05-05-2001, 08:04 AM
Can you give me your code please?
Thank you very much. http://www.opengl.org/discussion_boards/ubb/smile.gif

Tim Stirling
05-05-2001, 11:02 PM
void CTedDoc::FindHit(int x, int y)
{
GLuint selectBuf [512];
GLint hits, i, j, k;
int namez, z1, z2;
GLint viewport [4];
char text [255], temp [255];
glGetIntegerv(GL_VIEWPORT, viewport);
glSelectBuffer(512, selectBuf);

glMatrixMode(GL_PROJECTION);
glPushMatrix ();
glLoadIdentity ();
glRenderMode(GL_SELECT); // switch to selection mode.
gluPickMatrix(x, viewport[3]-y, 0.1, 0.1, viewport);
gluPerspective(45.0f, width/height,0.1f,500.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glRotatef(m_xRotate, 1.0, 0.0, 0.0); // Look About
glRotatef(m_yRotate, 0.0, 1.0, 0.0);
glTranslatef(-m_xPos, -m_yPos, -m_zPos); // Move To Walking Position

DrawLevel(GL_SELECT);
hits = glRenderMode(GL_RENDER);
glMatrixMode(GL_PROJECTION);
glPopMatrix ();
glMatrixMode(GL_MODELVIEW);
sprintf (text, "Total No. of hits (object under mouse): %d\n\n\n", hits);
j = 0;

int minz, num, n;
num = -1;minz = 100;
for (i = 0; i < hits; i++){
namez = selectBuf [j]; j++;
z1 = selectBuf [j]; j++;
z2 = selectBuf [j]; j++;
n = selectBuf[j];
if (z1 < minz){
minz = z1;
num = n;
}
}


This just gets called from OnLButtonDown and it works ok, It is only a quick hack I made with the help of a tutorial but it seems to work ok, however it will probably be inefficient, unstable, poorly written and have some flaws in it but hell, it works.

ChrisT
05-06-2001, 02:30 AM
Thank you for this code, but it doesn't work. I don't understand why. Do you have an idea. please....

ChrisT
05-06-2001, 03:39 AM
OK, i found the problem. In fact the problem was that i used glBegin() with GL_LINES and not with GL_QUADS or GL_TRIANGLES. Thank for your help and your code.