gluUnproject and Far Plane values

Hi All,

I’m trying to calculate my screen world limits.

So, for that I project each screen corner (0,0) - (screen_width,0)
( screen_width, screen_height) - (0, screen_height)

to get the world limits.

The way I’m doing this, I don’t know if it’s the correct or best way to do it is like this:


GLfloat dxn, dxf, dyn, dyf, dzn, dzf;
GLfloat x, y, z;
GLfloat t;

gluUnProjectf(aXi, aYi,0.0f, model_viewf, projectionf, iViewPort, &dxn, &dyn, &dzn);
gluUnProjectf(aXi, aYi,1.0f, model_viewf, projectionf, iViewPort, &dxf, &dyf, &dzf);

t = dzn / ( dzn - dzf);

pos3D_x = dxn + t * ( dxf - dxn);
pos3D_y = dyn + t * ( dyf - dyn);

So I get the screen point projected in the near plane and in the far plane. Then I try to get the point where we intersect the plane.

However, this work ok for a pitch until 60º when I increase my pitch, the far plane projected point suddenly becomes positive.

So until there my far plane values were increasing, -1000, -1300 …

Does anyone have any idea about what is happening ?

I really appreciate any help.

Thanks in advance,

Victor

Hi All,

I’ve done some debug to help understand the problem this is the output that i get.

Zn is the return from gluUnproject with z = 0.
Zf is the return from gluUnproject with z = 1.

It seems that when my camera pitch increases , my far plane result from gluUnproject becames closer and closer to the near plane.

When Far plane < near plane I have a problem.


wb: glFrustum() [-0.083770,0.083770,-0.050000,0.050000,0.100000,1000.000000] 
,wb:  [0,0] Zn = 99.060051 and Zf = -949.683716 
wb:  [640,0] Zn = 99.060051 and Zf = -949.683716 
wb:  [640,382] Zn = 99.069763 and Zf = -861.525818 
wb:  [0,382] Zn = 99.069763 and Zf = -861.525818 
wb: world box [-5177316,24693097] - [-5166195,24697903] 
wb: glFrustum() [-0.083770,0.083770,-0.050000,0.050000,0.100000,1000.000000] 
,wb:  [0,0] Zn = 98.166443 and Zf = -982.284119 
wb:  [640,0] Zn = 98.166443 and Zf = -982.284119 
wb:  [640,382] Zn = 98.185623 and Zf = -808.177368 
wb:  [0,382] Zn = 98.185623 and Zf = -808.177368 
wb: world box [-5177596,24693243] - [-5165915,24698142] 
wb: glFrustum() [-0.083770,0.083770,-0.050000,0.050000,0.100000,1000.000000] 
,wb:  [0,0] Zn = 96.661652 and Zf = -1007.921143 
wb:  [640,0] Zn = 96.661652 and Zf = -1007.921143 
wb:  [640,382] Zn = 96.690323 and Zf = -747.576843 
wb:  [0,382] Zn = 96.690323 and Zf = -747.576843 
wb: world box [-5177930,24693370] - [-5165581,24698437] 
wb: glFrustum() [-0.083770,0.083770,-0.050000,0.050000,0.100000,1000.000000] 
,wb:  [0,0] Zn = 94.571251 and Zf = -1025.012817 
wb:  [640,0] Zn = 94.571251 and Zf = -1025.012817 
wb:  [640,382] Zn = 94.609184 and Zf = -680.763733 
wb:  [0,382] Zn = 94.609184 and Zf = -680.763733 
wb: world box [-5178330,24693481] - [-5165181,24698801] 
wb: glFrustum() [-0.083770,0.083770,-0.050000,0.050000,0.100000,1000.000000] 
,wb:  [0,0] Zn = 91.907433 and Zf = -1034.652954 
wb:  [640,0] Zn = 91.907433 and Zf = -1034.652954 
wb:  [640,382] Zn = 91.954346 and Zf = -608.952698 
wb:  [0,382] Zn = 91.954346 and Zf = -608.952698 
wb: world box [-5178825,24693575] - [-5164686,24699260] 
wb: glFrustum() [-0.083770,0.083770,-0.050000,0.050000,0.100000,1000.000000] 
,wb:  [0,0] Zn = 88.693230 and Zf = -1036.372314 
wb:  [640,0] Zn = 88.693230 and Zf = -1036.372314 
wb:  [640,382] Zn = 88.748764 and Zf = -532.309875 
wb:  [0,382] Zn = 88.748764 and Zf = -532.309875 
wb: world box [-5179454,24693657] - [-5164057,24699857] 
wb: glFrustum() [-0.083770,0.083770,-0.050000,0.050000,0.100000,1000.000000] 
,wb:  [0,0] Zn = 84.952965 and Zf = -1029.420288 
wb:  [640,0] Zn = 84.952965 and Zf = -1029.420288 
wb:  [640,382] Zn = 85.016701 and Zf = -451.236023 
wb:  [0,382] Zn = 85.016701 and Zf = -451.236023 
wb: world box [-5180292,24693726] - [-5163219,24700663] 
wb: glFrustum() [-0.083770,0.083770,-0.050000,0.050000,0.100000,1000.000000] 
,wb:  [0,0] Zn = 80.792191 and Zf = -1015.212280 
wb:  [640,0] Zn = 80.792191 and Zf = -1015.212280 
wb:  [640,382] Zn = 80.863503 and Zf = -368.314514 
wb:  [0,382] Zn = 80.863503 and Zf = -368.314514 
wb: world box [-5181448,24693782] - [-5162063,24701791] 
wb: glFrustum() [-0.083770,0.083770,-0.050000,0.050000,0.100000,1000.000000] 
,wb:  [0,0] Zn = 76.095657 and Zf = -993.353699 
wb:  [640,0] Zn = 76.095657 and Zf = -993.353699 
wb:  [640,382] Zn = 76.174141 and Zf = -281.139526 
wb:  [0,382] Zn = 76.174141 and Zf = -281.139526 
wb: world box [-5183239,24693828] - [-5160272,24703556] 
wb: glFrustum() [-0.083770,0.083770,-0.050000,0.050000,0.100000,1000.000000] 
,wb:  [0,0] Zn = 70.967705 and Zf = -962.900879 
wb:  [640,0] Zn = 70.967705 and Zf = -962.900879 
wb:  [640,382] Zn = 71.052757 and Zf = -191.329559 
wb:  [0,382] Zn = 71.052757 and Zf = -191.329559 
wb: world box [-5186333,24693863] - [-5157178,24706632] 
wb: glFrustum() [-0.083770,0.083770,-0.050000,0.050000,0.100000,1000.000000] 
,wb:  [0,0] Zn = 65.450836 and Zf = -925.265869 
wb:  [640,0] Zn = 65.450836 and Zf = -925.265869 
wb:  [640,382] Zn = 65.541817 and Zf = -100.066978 
wb:  [0,382] Zn = 65.541817 and Zf = -100.066978 
wb: world box [-5193058,24693885] - [-5150453,24713356] 
wb: glFrustum() [-0.083770,0.083770,-0.050000,0.050000,0.100000,1000.000000] 
,wb:  [0,0] Zn = 59.583836 and Zf = -880.936951 
wb:  [640,0] Zn = 59.583836 and Zf = -880.936951 
wb:  [640,382] Zn = 59.680035 and Zf = -7.915318 
wb:  [0,382] Zn = 59.680035 and Zf = -7.915318 
wb: world box [-5219293,24693894] - [-5124218,24739689] 

It is not clear to me what you attempt to do, but if you’re trying to construct an AABB around the view frustum, the unprojected frustum corner vertices (or any unprojected points on the frustum) will rotate around the eye position as the pitch changes.
The ‘objZ’ argument of gluUnproject is on the world Z axis, not in eye space. I think that’s where you make the mistake.

Also, I’m not sure if it is relevant, but you may want to read this:

http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html

Most important part: the z-buffer distribution is non-linear. gluUnproject will return the z value in linear fashion, so you cannot compare the two directly.

Hi remdul,

Well what I’m trying to do is , given my glFrustum configuration and viewport I need to know what it’s the 2D box in world coordinates that I need to read let’s say from my spatial database.

After this I know I will have to use frustum culling, but before that I must know how much world I need to fill the screen. In ortho projection is quite simple, with gluUnproject with Z = 0 ( near plane) it works ok.

For me the objz is not necessary, because my world is a 2D world, with roads at z = 0, polygons with z = 0.

So maybe yes, I just need a AABB 2D of the visible world.

Currently I’m trying to do it, like this


GLfloat dxn, dxf, dyn, dyf, dzn, dzf;
GLfloat x, y, z;
GLfloat t;

gluUnProjectf(aXi, aYi,0.0f, model_viewf, projectionf, iViewPort, &dxn, &dyn, &dzn);
gluUnProjectf(aXi, aYi,1.0f, model_viewf, projectionf, iViewPort, &dxf, &dyf, &dzf);

t = dzn / ( dzn - dzf);

pos3D_x = dxn + t * ( dxf - dxn); // WorldX
pos3D_y = dyn + t * ( dyf - dyn); // WorldY


Does the “t” variable has the non linear z-buffer problem ?

Is it possible to solve it ?

Many thanks,

Victor

Hi remdul,

I was wondering. Is it possible to extract the frustum culling world points, and then , using the maximum and minimum world coordinates of X,Y values, construct my 2D world box ?

Is this a correct solution ?

Thanks by your help,

Victor