PDA

View Full Version : gluUnProject



David Doria
02-24-2009, 03:38 PM
I am trying to get the depth at of the 3d point that was projected to every pixel. I am reading the depth buffer, then using gluUnProject to get the 3d location at each pixel, then finding the distance from the 3d location to the camera. However, it is producing the following result:

http://rpi.edu/~doriad/cube.jpg
On the left is a cube rendered with perspective projection. The right is the output of my code. As you can see, there are bizarre lines through the whole thing, but the overall shape is right which leads me to believe I am close to doing it right. Does anyone see a problem with this code?




void ReadDepthBuffer()
{
float depths[640*480];
glReadPixels(0, 0, 640, 480, GL_DEPTH_COMPONENT, GL_FLOAT, depths);
WriteDepthFile("buffer.txt", depths);

}

void WriteDepthFile(const string &Filename, float* depths)
{
ofstream fout(Filename.c_str());

double ModelView[16];
glGetDoublev(GL_MODELVIEW_MATRIX, ModelView);

double Projection[16];
glGetDoublev(GL_PROJECTION_MATRIX, Projection);

GLint Viewport[4];
glGetIntegerv(GL_VIEWPORT, Viewport);

double x;
double y;
double z;

vnl_double_3 Eye(EyeX, EyeY, EyeZ);

for(unsigned int im_x = 0; im_x < Width; im_x++)
{
for(unsigned int im_y = 0; im_y < Height; im_y++)
{
double CurrentDepth = depths[Height*im_x + im_y];
bool success = gluUnProject(static_cast<double>(im_x), static_cast<double>(im_y), CurrentDepth, ModelView, Projection, Viewport, &amp;x, &amp;y, &amp;z);
vnl_double_3 ModelCoord(x, y, z);
double Dist = (ModelCoord - Eye).magnitude();
if(!success)
Dist = 0.0;

fout << im_x << " " << im_y << " " << Dist << endl;
}
}

fout.close();

}



Thanks,

Dave

overlay
02-24-2009, 06:56 PM
Maybe unpack settings should be set to 1?

Read section "7. Watch Your Pixel Store Alignment" in the article "Avoiding 16 Common OpenGL Pitfalls":

http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/

Also in the FAQ:

http://opengl.org/resources/faq/technical/rasterization.htm#rast0015

"
For both glDrawPixels() and glReadPixels(), keep in mind:

* The width and height parameters are in pixels.
* If the drawn or read pixel data seems correct, but is slightly off, make sure you've set alignment correctly. Argument values are controlled with the glPixelStore*() functions. The PACK and UNPACK values control sending and receiving pixel data, from and to OpenGL, respectively.
"

overlay
02-24-2009, 07:02 PM
Actually, after looking at your code, you're indexing the depth buffer in the wrong order. Values are contiguous in x not in y.

you should have
depth[y*width+x]
not
depth[x*height+y]

David Doria
02-25-2009, 07:24 AM
Hm I tried it like that, but got a much more "wrong indexing" type result (the cube was in little lines over the whole image).

Unfortunately I didn't really follow what they were saying in those links - was my

float depths[640*480];
not sufficient to store these values?

Also, what does gluUnProject do when there was no point in the scene that mapped to that pixel (in this case, when a pixel did not come from the cube)? It said it returns false if it "fails", but it doesn't seem to be returning false, so I guess not hitting something doesn't count as failing?

I also tried



glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_ALIGNMENT, 1);


but nothing changed.

Dave