Tariq Tariq - 1 month ago 24
C++ Question

OpenGL- inaccurate depth values from z buffer

I am drawing a quad in OpenGL and then using glReadPixels to access the depth buffer. But, the problem is I'm always getting 1 from all the position of the OpenGL window. For example, for zbuffer[0][0] (please see the code below), the value should be 0, because that part of the window has no object. Again, for zbuffer[639][470], the value should also be 0, but I am receiving 1 for both the case.

Could you please point me what I am doing wrong here?

#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <iostream>
#include <fstream>

using namespace std;



void display ( ) // Create The Display Function
{

glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

gluLookAt(0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,-1.0 ,0.0 ,1.0 ,0.0);


glBegin(GL_QUADS);

glColor3f(0.813205,0.813205,0.813205);
glVertex3f(-0.389662380802125,0.249152038469432, -1.12528215173346); // top left corner

glColor3f(0.309385,0.309385,0.309385);
glVertex3f(0.433401472883409,0.272288002674917, -0.923754348668237); // top right corner

glColor3f(0.288292,0.288292,0.288292);
glVertex3f(0.441173907261717,-0.296124431126115, -0.915317251508196);// bottom right corner

glColor3f(0.74028,0.74028,0.74028);
glVertex3f(-0.388657135983495,-0.317680965994535, -1.09611219327051); // bottom left corner


glEnd();

GLfloat zbuffer[640][480];

glReadPixels(0,0,640,480,GL_DEPTH_COMPONENT,GL_FLOAT, zbuffer);

cout<<"Depth1:"<<zbuffer[0][0]<<endl;
cout<<"Depth2:"<<zbuffer[639][470]<<endl;

glFlush();

glutSwapBuffers ( );
}

void reshape ( int w, int h ) // Create The Reshape Function (the viewport)
{
glViewport(0 ,0 ,(GLsizei)w,( GLsizei)h);
glMatrixMode (GL_PROJECTION );
glLoadIdentity ( );
gluPerspective(48.6f, (GLfloat) 640 / 480, 0.01f, 1000.0f);
glMatrixMode (GL_MODELVIEW) ;
}

void keyboard ( unsigned char key, int x, int y ) // Create Keyboard Function
{
switch ( key ) {
case 27: // When Escape Is Pressed...
exit ( 0 ); // Exit The Program
break; // Ready For Next Case
default: // Now Wrap It Up
break;
}
}

void mouse(int button, int state, int x, int y) {

float mx = x ;
float my = y ;
// ox = (mx/320-1.0);
// oy = -(my/240 -1.0);
switch(button){
case GLUT_LEFT_BUTTON:
if(state==GLUT_DOWN){
printf("%f,",mx);
printf("%f\n",my);
}
break;
}
}

int main ( int argc, char** argv )
{
glutInit ( &argc, argv );
glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (640, 480);
glutInitWindowPosition(0, 0);
glutCreateWindow ( "My Window" ); directory as title)
glutReshapeFunc ( reshape ) ;
glutDisplayFunc ( display ); // Matching Earlier Functions To Their Counterparts
glutKeyboardFunc ( keyboard );
glutMouseFunc(mouse);
glutMainLoop ( ); // Initialize The Main Loop


return 0;
}


And here is the object drawn in OpenGL:

enter image description here

Answer

For example, for zbuffer[0][0] (please see the code below), the value should be 0, because that part of the window has no object.

No, it shouldn't. THe default glClearDepth value is 1.0, so glClear( GL_DEPTH_BUFFER_BIT) sets every pixel in the depth buffer to 1.0. This also makes sense because using the dfeault conventions, the near plane is mapped to z=0 in window space, and the far plane to z=1, and the depth test is set to GL_LESS, so that fragments will pass which are nearer that what is currently drawn at that position.