PDA

View Full Version : gluUnproject and Far Plane values

Victor Hugo
05-27-2009, 08:09 AM
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, &amp;dxn, &amp;dyn, &amp;dzn);
gluUnProjectf(aXi, aYi,1.0f, model_viewf, projectionf, iViewPort, &amp;dxf, &amp;dyf, &amp;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.

Victor

Victor Hugo
05-28-2009, 02:46 AM
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]

remdul
05-28-2009, 06:51 AM
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.

Victor Hugo
05-28-2009, 07:31 AM
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, &amp;dxn, &amp;dyn, &amp;dzn);
gluUnProjectf(aXi, aYi,1.0f, model_viewf, projectionf, iViewPort, &amp;dxf, &amp;dyf, &amp;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

Victor Hugo
05-28-2009, 07:49 AM
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