View Full Version : A conclusion of how does gluPickMatrix work?

07-21-2003, 04:38 AM
Hi! I'm studying how gluPickMatrix works, and make some conclusion, can you see if it is correct? Or if there is any places unclear?

Thank you!

The books and documentation said that gluPickMatrix used with the projection matrix to restrict drawing.

This means that gluPickMatrix's job is to obtain a restricted part of 3D space. then when drawing is going on, the OpenGL will detect if the drawing is happen in that area and load the name stack if yes.

Let's consider what we need for gluPickMatrix to defind the restricted volumn of space.

1)projection matrix. This is specified by almost all documentations, books about OpenGL. Because the restricted volumn must be a subset of the volumn defined by projection matrix.

2)Viewport and the picked area of viewport. This is explicitly shown by the fact that they are peremeters of gluPickMatrix.

3)ModelView matrix. View matrix is usually by gluLookAt; model matrix is usually by scalef and so on. They are defined when drawing the primitives.

07-21-2003, 06:04 AM
that's true for 1 and 2 but there is no need of the modelview matrix.

if it where needed, you would not be able to place object in your scene using glTranslate and glRotate because gluPickMatrix have been called before.

gluPickMatrix just need the projection matrix and the interest area in the viewport.

07-21-2003, 10:02 AM
Hi! Thank you for reading.

I also never see any book or documentation talking about point 3. But I guess it is true by thinking about an example.
projection matrix is (-1, 1, -1, 1, -3, 3)
viewport never change
user clicks on the same point
when gluLookAt is called with different z eye and center parameter-pairs such as (0,-1), and (-1,0) the obtained result will be completely different even if the user draws the same primitives to exectly same positions. Because different parameters of gluLookAt causes different restricted 3D-space.

Above is not from any books. Can you see if there is any thing wrong with it?

Thank you!

07-21-2003, 11:27 PM
here is the code gluPickMatrix (extracted from Mesa 5.0.1):

gluPickMatrix(GLdouble x, GLdouble y,
GLdouble width, GLdouble height, GLint viewport[4])
GLfloat m[16];
GLfloat sx, sy;
GLfloat tx, ty;

sx = viewport[2] / width;
sy = viewport[3] / height;
tx = (viewport[2] + 2.0 * (viewport[0] - x)) / width;
ty = (viewport[3] + 2.0 * (viewport[1] - y)) / height;

#define M(row,col) m[col*4+row]
M(0, 0) = sx;
M(0, 1) = 0.0;
M(0, 2) = 0.0;
M(0, 3) = tx;
M(1, 0) = 0.0;
M(1, 1) = sy;
M(1, 2) = 0.0;
M(1, 3) = ty;
M(2, 0) = 0.0;
M(2, 1) = 0.0;
M(2, 2) = 1.0;
M(2, 3) = 0.0;
M(3, 0) = 0.0;
M(3, 1) = 0.0;
M(3, 2) = 0.0;
M(3, 3) = 1.0;
#undef M


as you can see, there isn't any access to the modelview matrix (the access to projection matrix is implicit - glMultMatrixf)

the computed matrix restrict the projection area. the opengl pipeline is:

vertex -> modelview -> projection -> clipping

if a vertex transformed by modelview is not in the frustum defined by the projection matrix then it is discarded. the frustum have been modified by gluPickMatrix. this function, called after reset the projection matrix (glLoadIdentity) and before the glFrustum/gluPerspective/glOrtho/gluOrtho2D call modify the default clipping planes.

when you call glLoadIdentity, the projection volume is: x(-1,1) y(-1,1) z(-1,1) (the same volume could be computed using glOrtho(-1,1, -1,1, -1,1) http://www.opengl.org/discussion_boards/ubb/wink.gif
gluPickMatrix moves the xmin, xmax, ymin and ymax values. your projection is applied after gluPickMatrix. since opengl matrix operations are applied in reverse order, a vertex is first projected then restricted to the pick volume and discarded if it's outside.

I don't kwow if I ware very clearly, if not, let me kwow and I'll try to post something most ... clear http://www.opengl.org/discussion_boards/ubb/biggrin.gif

07-22-2003, 12:22 AM
Thank you http://www.opengl.org/discussion_boards/ubb/smile.gif
Can you tell me what does these two lines of code mean?

tx = (viewport[2] + 2.0 * (viewport[0] - x)) / width;
ty = (viewport[3] + 2.0 * (viewport[1] - y)) / height;

07-22-2003, 01:11 AM
you have :

|------------------| viewport
| |
| |-----| pick |
| | | area |
| |-----| |
| |

sx 0 0 tx
0 sy 0 ty
0 0 1 0
0 0 0 1

screen coord -> PICK MATRIX -> "pick" coord

the matrix scale the vertex (sx, sy) and translate it (tx, ty).