Picking related question

First of all i should explain the exemple-program that i’m trying to do, or what i have so far.
I’m trying to make a User Interface, so i can choose variables (as a player picking speels or using buttons).
So far i made a scroll bar(already working fine, although not using picking) and 3 simple buttons, as you can see:

But the buttons i wanted to use picking, I had no idea how to do this so i went searching and i found this picking metod: Game Programming Wiki - GPWiki
Although i dont know if it is the most correct for what i want… anyway, when picking 3D objects the code works wonderfull, although when it comes to pick what im drowing directly in my projection matrix it just says that ive clicked in all objects.
i.e. if i name botton’s 1, 2 and 3, it says that i picked all of the 3. In other words, he thinks that i clicked everything in my projection matrix.

as you can see in the image, all buttons were clicked :c and as you can see in the first image, the 3 buttons are quite separated(the red, yellow and blue squares). The other numbers that appear are for other objects in the way, like the floor and the mouse.

I’d apressiate any help.

The problem is in the source of information. :slight_smile:
Instead of reading tutorial, you should read chapter 13 of the Red book (OpenGL Programming guide).

This answer is not a replacement for reading the book, just a cue what is going on.
Well, OpenGL is doing exactly what you have said to do. Picking is just a special case of selecting. By selecting OpenGL assumes retrieving primitives that intersect viewing frustum. All “buttons” in your scene are visible, so all of them are retrieved. In order to make picking useful, you have to narrow viewing frustum used for picking. If you are using glOrtho() it can be done quite easily, but is a bit tricky for perspective projection. That’s why OpenGL Utility Library (GLU) has a very useful function for “narrowing” projection matrix – gluPickMatrix(). Call it before setting your projection matrix, with setting picking area to several pixels.

Be aware that all this works only on “fixed pipeline” legacy OpenGL.

Thank you Aleksandar for the replie.
“you have to narrow viewing frustum used for picking” yes he does that with:

gluPickMatrix(k, l, 1.0, 1.0, view);
gluPerspective(60, 1.0, 0.0001, 1000.0);

Thats all very well explained in the tutorial, or i might have read it somewhere else. Puting the viewing agle at ‘1’ around the cursor etc.

I think the problem is after, when i call the drawing function after setting this prestective. Because of the way i pass from ‘3D’ drawing to ‘2D’ drawing inside the drawing function in order to make the UI.


 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

 /* draw the floor */
 	glLoadName(0);
 glBegin(GL_QUADS);
     glColor3f(0.2f, 0.2f, 0.2f);
     glVertex3f(-100.0, 0.0, -100.0);
     glColor3f(0.4f, 0.4f, 0.4f);
     glVertex3f(-100.0, 0.0, 100.0);
     glColor3f(0.6f, 0.6f, 0.6f);
     glVertex3f(100.0, 0.0, 100.0);
     glColor3f(0.8f, 0.8f, 0.8f);
     glVertex3f(100.0, 0.0, -100.0);
 glEnd();

...other 3D objects...

                    glPushMatrix();
                    setOrthographicProjection();
                    glLoadIdentity();

                    drawUI();

                    resetPerspectiveProjection();
                    glPopMatrix();

 glLoadIdentity();
 gluLookAt( x, y, z,
           x+lx,y+ly,z+lz,
           0.0,1.0,0.0);
 glutSwapBuffers();

And so the UI draws itself adapting the the current ‘window’ or prespective, it has its own push and pop of the matrix mode, and so, if we could see it, even if the the viewing angle is ‘1’ the UI will still appear correctly to us, and so it does too to the Picking equations, wich means the computer will ‘see’ or pick all the UI cause im adapting it to the new prespective(i think or so thats the way i understood it).

And so I was thinking that instead of ‘feeding’ the picking function with the drawing funtion i should feed it with the UI drawing(drawUI) funtion independent from the rest of the drawing function, and from all the other projection ‘mutations’, but that way it isnt detecting any hits that way.

I dont know if i misunderstood your replie, hope i didnt.

Something is terrible wrong with your code. gluLookAt() should be the first function call right after glClear(). Also, you definitely need to read some better article. There is no such thing as “angle 1 around the cursor”. “The picking window” is define in screen coordinates (i.e. pixels)! And it should not be 1 pixel wide. gluPickmatrix() doesn’t work correctly if you are changing projection matrix at will. Avoid drawing anything that is not pickable in the selection mode. Since you are drawing interface in 2D mode, in selection mode just draw the interface and adjust ortho-matrix.

imagine that when you are in GL_SELECT mode, everytime you draw something that is visible, a counter is incremented. Then, when you call glRenderMode(GL_RENDER) to actually draw something on the framebuffer, the counter is returned to you. This counter is the number of objects drawn when in GL_SELECT mode. If you restrict the drawing area to half screen, the counter is incremented only for the object in the visible area. I think you got the trick :slight_smile: If you restrict the area to a single pixel, which is where the mouse is, glRenderMode will return a counter that is the number of objects under the mouse. In this way you can determine which objects are under the mouse.

thats the explanation i got of picking from that tutorial… and he’s example works very good.

Im just messing too much with the MatrixMode -.-" mixing too many unrelated exemples in one single program…(drawing 2D objects over 3D, or UI in other words, and picking at the same time)

And yes, the gluLookAt works very fine like that, in all programs i made so far.
Heres an exemple of a 3D pacman i made:

I understand a bit more of what you said here after reading a bit of chapter 12, and comparing the code in the tutorial with the code in the book. Ill do a new function just to draw what i need(only the buttons would be enough i think) with the correct matrix mode, specialy for the selecting porpouse, and give it a try.