I'm trying to get world coordinates from any of my rendered vertices in OpenGL window (I prefer to use GLUT library). The problem is when I'm calling glReadPixels function to get depth value of a vertex, it always returns a 1 value, when I'm clicking my mouse anywhere.
I am stuck on this point, have already read a ton of articles, but didn't get any answer.
Here is my code:
display function
void display(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH | GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glDepthRange(200, 2000);
//here i put some glBegins and glEnds
glutSwapBuffers();}
main function
int main(int argc, char **argv){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(1280, 720);
glutInitWindowPosition(50, 86);
glutCreateWindow("2D correlation function");
glClearColor(1,1,1,1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glFrustum(-150, 150, -150, 150, 200, 2000);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutKeyboardFunc(keyboard);
gluLookAt(200,400,200,0,0.0,0.0,0.0,0.0,1.0);
glScalef(0.4, 0.4, 0.4);
glutDisplayFunc(display);
timer();
glutMainLoop();
return 0;}
mouse clicking function
void mouse(int button, int state, int x, int y){
GLdouble objX, objY, objZ;
GLdouble matModelView[16], matProjection[16];
GLint viewport[4];
glGetDoublev(GL_MODELVIEW_MATRIX, matModelView);
glGetDoublev(GL_PROJECTION_MATRIX, matProjection);
glGetIntegerv(GL_VIEWPORT, viewport);
GLfloat winX = x;
GLfloat winY = viewport[3] - y;
GLfloat winZ = 0;
glReadPixels(winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
cout << winX << " " << winY << " " << winZ << " " <<endl;
gluUnProject(winX, winY, winZ, matModelView, matProjection, viewport, &objX, &objY, &objZ);
cout << objX << " " << objY << " " << objZ << " " <<endl;}
Because of this, my world coordinates are displayed incorrectly:
example of mouse clicking

another example

I think i'm doing something wrong in display procedure
The parameter to glEnable has to be a single enumerator constant. The parameter is not a bit field.
The following is not valid and will generate a GL_INVALID_ENUM error, which can be detected by glGetError or Debug Output:
glEnable(GL_DEPTH | GL_DEPTH_TEST);
It has to be
glEnable(GL_DEPTH_TEST);
Anyway GL_DEPTH is not a valid parameter for glEnable, but it is possibly an parameter to glCopyPixels.
Note, the value of the enumerator constant GL_DEPTH_TEST is 0x0B71 and the value of GL_DEPTH is 0x1801. A binary or (|) operation of the both constants won't make any sense.
Because of this the depth test has never been enabled and nothing was written to the depth buffer.
Further note, that the values which are accepted for the depth range glDepthRange have to be in the range [0, 1]. The values which are passed to the glDepthRange are both clamped to this range before they are accepted.
This means, that
glDepthRange(200, 2000);
is equal to
glDepthRange(1, 1);
so the depth range is [1, 1] and all values returned by glReadPixels are 1, too.
Skip to solve the issue.glDepthRange(200, 2000);
glGetDoublev(GL_MODELVIEW_MATRIX, matModelView) gets the current model view matrix from the GL_MODELVIEW matrix stack.
glGetDoublev(GL_PROJECTION_MATRIX, matProjection) gets the current projection matrix from the GL_PROJECTION matrix stack.
So you should put the projection matrix on the GL_PROJECTION matrix stack and the view matrix on the GL_MODELVIEW matrix stack (see glMatrixMode):
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-150, 150, -150, 150, 200, 2000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(200,400,200,0,0.0,0.0,0.0,0.0,1.0);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With