I use OpenGL to draw objects, lines, points, etc. in 3D space. Ofcourse, this gets displayed on a 2D screen. Now I want to be able to select the nearest 3D point by clicking the mouse near a 3D point. Any idea how to do this? I programming in QtCreator and i use QPoint to get (x,y) the coordinates of the mouse in th windows. How to get z position? I tryed used glReadPixels() for obtain z cooridnate. but, always returns 0. This is my function:

An OpenGL context needs to be bound when calling any OpenGL functions. This is done automatically for the paintGL() method of a QOpenGLWidget, but if youâ€™re making OpenGL calls from other functions, you may need to call makeCurrent() explicitly.

An OpenGL context needs to be bound when calling any OpenGL functions. This is done automatically for the paintGL() method of a QOpenGLWidget, but if youâ€™re making OpenGL calls from other functions, you may need to call makeCurrent() explicitly.[/QUOTE]

Okay thanks, works perfectly. Depth return other values, but i have a question. I am use x and y as the mouse position in the window and glReadPixels it is activated when i click. How can i verify that the value returned by the variable depth corresponds to position Z?

Fill the screen with a quad (or triangle pair), with vertices at (-1,-1,-1), (1,-1,0), (-1,1,0), (1,1,1) in NDC (i.e. with both model-view and projection matrices set to an identity matrix). Then itâ€™s trivial to compute what the depth should be for a given (x,y) position: depth=((x+0.5)/width+(y+0.5)/height)/2.

Thanks! I did what you told me and I get the Z value with the method glReadPixels(); but with ur equation the values â€‹â€‹differ a bit.
Example, with glReadPixels when I click in the windows to get Z coordinate i get for example z=0.495, and with ur equation depth=((x+0.5)/width+(y+0.5)/height) i get z=0.51 or or something similar. It is right? Can I assume that small margin of error as correct?

Now, in my program i have this in the method

/* Detremining the window z from glReadPixels() */
GLfloat z = 0.0f;
glReadPixels(lastPos.x(), height() - 1 - lastPos.y(),1, 1,
GL_DEPTH_COMPONENT, GL_FLOAT, &z);
qDebug() << "readpixel: " <<z;
/*Get x, y, z coordinates of points in the window*/
GLdouble modelView[16];
glGetDoublev(GL_MODELVIEW_MATRIX, modelView);
GLdouble projection[16];
glGetDoublev(GL_PROJECTION_MATRIX, projection);
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
GLdouble wx,wy,wz;
/*lastpos it's a QPoint variable. lastpost.x() get X position of the mouse in the window. and y the same.*/
gluUnProject(lastPos.x(),viewport[3] - 1 - lastPos.y(),z,modelView,projection,viewport,
&wx,&wy,&wz);
qDebug() << wx << wy << wz

[QUOTE=pelaoqlo;1292376]Thanks! I did what you told me and I get the Z value with the method glReadPixels(); but with ur equation the values â€‹â€‹differ a bit.
Example, with glReadPixels when I click in the windows to get Z coordinate i get for example z=0.495, and with ur equation depth=((x+0.5)/width+(y+0.5)/height) i get z=0.51 or or something similar. It is right? Can I assume that small margin of error as correct?
[/QUOTE]
Errors shouldnâ€™t be more than a small multiple of 1/2n, where n is the number of bits in the depth buffer (typically either 16 or 24).

First, you should be adding 0.5 to the x and y coordinates, as the depth value is calculated for the centre of the pixel, not its lower-left corner. Window coordinates which are integers correspond to pixel corners; window coordinates with a fractional part of 0.5 correspond to pixel centres. I.e.:

Second, if youâ€™re using a perspective projection, the accuracy of depth values can vary wildly depending upon the distance from the near plane. Roughly half of the available depth values are used for -Z values between the near distance and twice the near distance. More generally, 1/N of the available depth values are used for -Z values beyond N times the near plane. If the ratio of far distance to near distance is large, most of the available depth values are used for a relatively small portion of the scene.

To check the accuracy, un-project the window-space x,y coordinates with both z=0 and z=1 to get two points on a line in object space. Find the intersection of that line with the plane x+y-2*z=0, project the intersection point back to window space, and compare the window-space Z to the value in the depth buffer.

x, y, z, they are the maximum and minimum values of the coordinates that I am visualizing in my program, for example if I have a list of coordinates: (-1,2,-1) , (-2,5,0), (2,1,1).

Am I performing the procedure correctly to obtain the value of Z?
So, I think Iâ€™m correctly obtaining the position of the coordinates in the window (?)

You could avoid using glReadPixels() altogether, why not just cast a ray into the scene and check which triangle it hits? In the simplest case, you intersect all objects in the scene with the ray and take the one with the smallest distance. As your scene gets larger, this linear search will get inefficient, and you will have to construct a bounding volume hierarchy for your objects (e.g. a binary AABB tree). Once the hierarchy is created, you can perform kind of a binary search to find the closest intersection whenever you cast a ray. Iâ€™m aware that this solution requires some effort to implement, but itâ€™s robust and scalable.

Here is some code to construct a ray in world space:

auto ndc = mouse_pos_uv * 2.f - 1.f; // mouse_pos_uv are mouse coordinates between 0 and 1
auto near_h = inverse(view_projection_matrix) * Vec4f(ndc, -1.f, 1.f);
auto far_h = inverse(view_projection_matrix) * Vec4f(ndc, 1.f, 1.f);
auto near = near_h.xyz() / near_h.w();
auto far = far_h.xyz() / far_h.w();
auto ray_origin = near;
auto ray_dir = normalize(far - near);