Drawing for Picking

Hello,

when I draw my objects with glRecti() picking with gluPickMatrix() works fine. But when I draw them with glBegin(GL_TRIANGLES)glVertex()…glEnd(), it seems like all the objects that are drawn are selected independently from where I click on the screen (slightly modified example 13-3 red book).

Why cant I pick the things drawn with glBegin()… correctly?
What does glRecti do that the the other drawing routine does not?

thanks in advance
peter

Example:

class Triangle{
public:
Triangle( GLuint name, int pos ):m_name(name),m_pos(pos){}
void draw()const{
glColor3f(1,0,0);
glLoadName (m_name);
glRecti (m_pos, m_pos, m_pos + 10, m_pos + 10); //works

/* glBegin(GL_POLYGON); //does not work
glVertex3f(9 + m_pos, 10,4);
glVertex3f(14 + m_pos,10,4);
glVertex3f(11 + m_pos,5,4);
glEnd();
//glFlush();
*/
}
private:
GLuint m_name;
int m_pos;
};

I don’t see anything out of the ordinary. Care to be more specific, and post your picking code?

The following picking program works. If you uncomment the drawing of the triangle it stops working (wherever I press the cursor all triangles are reported as a hit).
The picking code is in function selectObject(), and the code for processing the hits in proces****s().

thank you very much for your interest and any suggestion.
peter

#include <gl\glut.h>
#include <vector>
#include <iostream>

class Triangle{
public:
Triangle( GLuint name, int pos ):m_name(name),m_pos(pos){}
void draw()const{
glLoadName(m_name);
glColor3f(1,0,0);
glRecti (m_pos, m_pos, m_pos + 10, m_pos + 10); //works
/*
glBegin(GL_TRIANGLES);
glVertex3f(9 + m_pos, 10,4);
glVertex3f(14 + m_pos,10,4);
glVertex3f(11 + m_pos,5,4);
glEnd();
//glFlush();
*/
}
private:
GLuint m_name;
int m_pos;
};

std::vector <Triangle> triangles;
const int HITBUFSIZE = 512;

void proces****s( GLint hits, GLuint buffer[] ){
std::cerr << "hits: " << hits << "
";
GLuint ptr = (GLuint)buffer;
for (GLint i = 0; i < hits; i++) {
GLuint names = *ptr;
std::cerr << "number of names for this hit = " << names << "
";
ptr++;
std::cerr << "z1: " << (*ptr/0x7fffffff);
ptr++;
std::cerr << " z2: " << (*ptr/0x7fffffff);
ptr++;
std::cerr << "
names: ";
for( GLuint j = 0; j < names; j++){
std::cerr << (*ptr) << " ";
ptr++;
}
std::cerr << "
";
}
std::cerr << "

";
}

void drawObjects(){
for( std::vector<Triangle>::const_iterator ti = triangles.begin(); ti != triangles.end(); ++ti){
(*ti).draw();
}
}

void selectObjects(int button, int state, int x, int y){
if (button != GLUT_LEFT_BUTTON | | state != GLUT_DOWN){
return;
}
GLint viewport[4];
glGetIntegerv (GL_VIEWPORT, viewport);
GLuint selectBuf[HITBUFSIZE];
glSelectBuffer (HITBUFSIZE, selectBuf);

glRenderMode (GL_SELECT);
glInitNames();
glPushName(0);

glMatrixMode (GL_PROJECTION);
glPushMatrix ();
glLoadIdentity ();
gluPickMatrix ((GLdouble) x, (GLdouble)(viewport[3]-y),5, 5, viewport);
glOrtho (-50.0, 50.0, -50.0, 50.0, 20.0, -20.0);
glMatrixMode(GL_MODELVIEW);
drawObjects();
glMatrixMode (GL_PROJECTION);
glPopMatrix ();
glFlush ();
GLint hits = glRenderMode (GL_RENDER);
proces****s (hits, selectBuf);
glutPostRedisplay();

}

void display(){
glClear (GL_COLOR_BUFFER_BIT);
drawObjects();
glFlush ();
}

void reshape (int w, int h){
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho (-50.0, 50.0, -50.0, 50.0, 20.0, -20.0);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
}

void init(void){
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
}

int main(int argc, char** argv){
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
triangles.push_back(Triangle(1,10));
triangles.push_back(Triangle(2,20));
triangles.push_back(Triangle(3,30));
triangles.push_back(Triangle(4,40));
init ();
glutMouseFunc (selectObjects);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}

Hi, sorry for interrupting.

===========================================
This is what I take from Peter’s code

gluPickMatrix ((GLdouble) x, (GLdouble)(viewport[3]-y),5, 5, viewport);
glOrtho (-50.0, 50.0, -50.0, 50.0, 20.0, -20.0);

===========================================
I want to ask something here

How can I set the 2nd line; glOrtho(…) automatically? What I mean is, how to detect the current projection setting so that I don’t have to hard code it.

I’m creating picking class which I hope there’ll be a way to detect the user projection setting so that I can pass it into the 2nd line (after gluPickMatrix).

What I mean by projection setting is glOrtho/gluPerspective including all its parameters (left,right,near,far,aspec ratio, etc).

===========================================
Another question (OT)

How to BOLD my words in this discussion forum? I see many of you HIGHLIGHT your question.

peter_1:
I checked the documentation for glRecti() and it says z = 0 for the rectangle drawn. You’re glVertex*() calls set z to 4. I don’t know if this is significant, but you can try setting z to 0 in your vertex calls and see if it makes a difference. Otherwise I can’t say what is the problem. I’m not very experienced at sifting through code but everything looks fine as far as I can tell. Worse, I don’t use GLUT and I don’t use Template classes (which I assume this std::vector <Triangle> triangles) thing is, so I can’t test it either. Maybe someone else can find what’s wrong.

Binqay:
I know about getting the projection matrix, with glGetDoublev(), but I don’t know how to use that to set the viewing volume, which is what glOrtho()/gluPerspective() does. Perhaps someone else knows the answer.

Bold is UBB code . There’s a link below the submit button that explains everything.

Thanks Furrage, but setting the z value to 0 did not help.

If somebody knows the answer please post . I am still stuck with this problem and I can’t continue my project.