I know I have asked this before, but I seem to be getting nowhere so I hope some kind person out there has had this same problem and can help.

I have an image being rendered in OpenGL that is composed of Points and Lines (built using Display Lists) and would like the user to be able to select a particular point with the mouse.

I read a little on Picking with OpenGL but I can find nothing on selecting vertices, only a singular object. Is there ANY way to select an individual (or series) of vertices in OpenGL with a mouse click? Using the GL_SELECT mode would be great except I need finer granularity (at the vertex point (X, Y, Z), not the polygon/object level). I have even tried using the feedback mode, but just generally get errors.

I am new to OpenGL (with still a lot to learn), so if anyone could provide some simple example code that would be great. However, at this point ANY help would be wonderful.

P.S. The images being rendered could be quite large (e.g.,

for point selection i usually use gluProject, like this:

``````typedef struct Point { double x, y, z; };
Point   P[123];
int     num_points = 123;

int PickPoint(int mouse_x, int mouse_y) {
double         d, dx, dy, dmin = 1.e20;
GLdouble       mm[16], pm[16];
GLint          vp[4];
double         wx, wy, wz;
int            picked_point = -1;

glGetDoublev(GL_PROJECTION_MATRIX, pm);
glGetDoublev(GL_MODELVIEW_MATRIX, mm);
glGetIntegerv(GL_VIEWPORT, vp);

for(int i = 0; i < num_points; i ++) {
gluProject(P[i].x, P[i].y, P[i].z, mm, pm, vp, &wx, &wy, &wz);
dx = (double)mouse_x - wx;
dy = (double)(vp[3]-mouse_y) - wy;
d  = dx*dx + dy*dy;

if(d < dmin) {
dmin = d;
picked_point = i; } }

return(picked_point); }
``````

input parameters are the mouse pointer x/y-coordinates. the algorithm returns the point, whose position on the screen is closest to the mouse pointer. note the line in which dy is calculated: i don’t know what it is like in windows, but in linux the reference screen value y=0 is different between opengl and the window system, which creates the mouse event (and thus the values for mouse_x/mouse_y).

(i hope it works, i just hacked it into the keyboard from scratch )

All I can say is THANK YOU RigidBody. A newbie like myself can use all the help I can get. I will give the idea you posted a try.

Once again, thanks for the help.

I copied the code above into the format I am using (Java JOGL) and it has some strange behavior. Sometimes the correct Node ID is displayed and sometimes it is not. Maybe the calculation for my z values are off?

Anyway, posted below is a snippet of the code:

Integer retVal = new Integer(-1);
int viewport[] = new int[4];
double mvmatrix[] = new double[16];
double projmatrix[] = new double[16];
int realy = 0;
double wcoord[] = new double[4];
double d, dx, dy, dmin = 1.e20;

Enumeration enum = nodes.keys();

while(enum.hasMoreElements()) {

Integer nodeID = (Integer)enum.nextElement();
Node node = (Node)nodes.get(nodeID);

glu.gluProject((double)node.getX(), (double)node.getY(), (double)node.getZ(), mvmatrix, 0, projmatrix, 0, viewport, 0, wcoord, 0);

dx = (double)x - wcoord[0];
dy = (double)(viewport[3] - realy) - wcoord[1];
d = dxdx + dydy;
if (d < dmin) {
dmin = d;
retVal = nodeID;
}
}// End of WHILE-LOOP
return retVal;

The nodes object is a Hastable with KEYS being the ID of the node and value a class with x, y, and z coordinate values and retVal is the Integer that should be returned from the method.

Can anyone please tell me what I am doing wrong?

Thanks to anyone with any ideas.

i have to admit my java knowledge is limited. nothing against java, but i don’t think there are so many people here who have a java development environment installed. if you want to reach people, you better use glut.

anyway, at first sight i don’t see you using glGet*** to read the matrices. second, wcoord[] should have a size of 3 doubles, not 4.

Thank you for responding, RigidBody.

I agree that Java is not the best language for real graphics programming (I am however suprised at the speed attained via the JNI bindings to OpenGL). The reason I am using it is I need platform neutrality for the program I am working on.

I left out the glGet*** to read the matrices for the purposes of brevity. Below is what they look like:

gl.glGetIntegerv(GL.GL_VIEWPORT, viewport, 0);
gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX, mvmatrix, 0);
gl.glGetDoublev(GL.GL_PROJECTION_MATRIX, projmatrix, 0);

Other than the wcoord[] being a size of 3 doubles and not 4, can you see anything else that could be responsible for the strange behavior?

Thank you for your kind help.

well, i’m not saying that java is better or worse than anything else, it’s just that you will find more people in this forum who have experience with c/c++. if you were using glut, you could easily try the code i posted, or i could try the code that you posted. if you don’t use glut (or xlib/glx), i can make only wild guesses what the problem could be.