PDA

View Full Version : About glUnProject!



davie
04-16-2010, 05:12 AM
Hi there,

I want to draw a rect occupied all the client area. so i do the following, but it cannt work.

GLdouble projection[16], modelview[16];
GLint viewport[4];
GLdouble x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4;

glGetDoublev(GL_PROJECTION_MATRIX, projection);
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetIntegerv(GL_VIEWPORT, viewport);

GLfloat wndX,wndY, wndZ;

wndX = g_iWindowWidth;
wndY= viewport[3] - 0;
glReadBuffer(GL_BACK);
glReadPixels(wndX,wndY,1,1,GL_DEPTH_COMPONENT ,GL_INT, &wndZ);
gluUnProject(wndX, wndY, wndZ, modelview, projection, viewport, &x1, &y1, &z1);


wndX = 0;
wndY = viewport[3] - g_iWindowHeight;
glReadBuffer(GL_BACK);
glReadPixels(wndX,wndY,1,1,GL_DEPTH_COMPONENT ,GL_INT, &wndZ);
gluUnProject(wndX, wndY, wndZ, modelview, projection, viewport, &x2, &y2, &z2);

wndX = 0;
wndY = viewport[3] - g_iWindowHeight;
glReadBuffer(GL_BACK);
glReadPixels(wndX,wndY,1,1,GL_DEPTH_COMPONENT ,GL_INT, &wndZ);
gluUnProject(wndX, wndY, wndZ, modelview, projection, viewport, &x3, &y3, &z3);

wndX = g_iWindowWidth;
wndY = viewport[3] - 0;
glReadBuffer(GL_BACK);
glReadPixels(wndX,wndY,1,1,GL_DEPTH_COMPONENT ,GL_INT, &wndZ);
gluUnProject(wndX, wndY, wndZ, modelview, projection, viewport, &x4, &y4, &z4);

glBindTexture(GL_TEXTURE_2D, g_texture[0]);
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x1, y1, z1);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x2, y2, z2);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x3, y3, z3);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x4, y4, z4);
glEnd();

i use glUnProject to convert the four corner pixel to the object coordinate, but i
dont know if this is right, can anybody help me? Thanks a lot!

davie
04-16-2010, 05:24 AM
Hi,

now i set wndZ for 0.01, it works, but i dont know why?

Exoide
04-16-2010, 06:33 AM
Hi Davie,

If you are not getting the expected result it must be because you're using a perspective projection.

When you use gluUnproject() the winZ argument is clamped to 0..1. It means that 0 is the near plane and 1 the far plane which is the opposite to the depth buffer.

Also by reading the winZ value from the depth buffer you can get the vertex position in the wrong plane.

So for your case you should use a constant value for winZ (I think it must be zero (the nearest plane)), in that way you get the four vertices coordinates in the same plane (I assume you're trying to get the rectangle's coordinates that relies in the same plane).

These two lines can be removed


glReadBuffer(GL_BACK);
glReadPixels(wndX,wndY,1,1,GL_DEPTH_COMPONENT ,GL_INT, &wndZ);

davie
04-16-2010, 08:43 AM
Hi Exoide,

Thanks very much!

"in that way you get the four vertices coordinates in the same plane "

if i only need get a vertex coordinate, i should get winZ as the follow or set a constant for it? or both are ok. I find
many people get winZ as the follow, why they dont just set a constant value fot it? Thanks!

glReadBuffer(GL_BACK);
glReadPixels(wndX,wndY,1,1,GL_DEPTH_COMPONENT ,GL_INT, &wndZ);

Exoide
04-16-2010, 09:47 AM
Hi Davie,


if i only need get a vertex coordinate, i should get winZ as the follow or set a constant for it? or both are ok

I think you're mixing different ideas.

When you use glReadPixels() it brings to you the values (in the range you specify) contained in the frame buffer.

If you use GL_DEPTH_COMPONENT effectively it will return to you the pixel's position in the Z buffer.

However what (I'm supposing) you're trying to get is the location (in eye coordinates) of the frustum's corners.

If so these four vertices are "always" in the same plane (I'm supposing that you're thinking in the nearest plane "0"), that's why you have to use the constant. However if you use the depth buffer's values from these pixels you can't assure they're in the plane 0.

That's why your previous version didn't work and the last one did (using 0.01). But if what you wanna do is what I thought then you have to use "0" instead "0.01".


I find many people get winZ as the follow, why they dont just set a constant value fot it? Thanks!

glReadBuffer(GL_BACK);
glReadPixels(wndX,wndY,1,1,GL_DEPTH_COMPONENT ,GL_INT, &wndZ);

That's because they need the Z values of all these pixels for some reason (that's not your case). Remember that glReadPixels() return an array of values and you only need 4 values not the values of all the pixels in the rectangle formed by the four vertices of the corners.

davie
04-17-2010, 07:12 AM
Hi Exoide,

Thanks a lot! i get now.