Hi Abdallah,
Thanks a lot for your persistence. And indeed, I owe you one, I’m very close to the solution. Just in case someone in the future have similar issue I will try to post the solution.
Before that, here is a link that made my mind clear about openGL transform (mainly w.r.t. the clip plane to viewport c.s. part)
openGL Transform pipeline
For the sake of comprehension, I will make my notations more explicit.
V_dcs=V_dcs.xyz is the window coordinate of the projected point
V_vcs=V_vcs.xyzw are the camera coordinate of the 3D point.
Then given an openGL projection matrix P (possibly created with glFrustum), openGl takes care of the transformation in the way exposed in the above link.
First, V_vcs is turned into V_ccs = P*V_vcs
Then, V_ccs is turned into V_ndcs = V_ccs.xyz/V_ccs.w
and finally, V_ndcs is turned into V_dcs as follows
(in the case the view port is glViewport(0,0,w,h)) :
V_dcs.x = w*(V_ndcs.x+1)/2 and similar for y coordinate
Then the problem is that I want to impose a given global transformation from V_vcs to V_dcs. This transformation is specified as follow.
V_vcs is turned into V_tmp.xyz= Q*V_vcs.xyz/V_vcs.w
V_dcs.xy=V_tmp.xy/V_tmp.z
and
Q=
[fx 0 cx
0 fy cy
0 0 1 ]
Finally, we get the following formula (assuming that V_vcs.w=1):
V_dcs.x = cx+ fx*V_vcs.x/V_vcs.z
So the problem is that I know Q (ie fx, cx,…), but as I want to use openGL power, I need to specify P that would do the same job. And using Abdallah’s hints here is what I get:
Setting P=glFrustum(-zNearcx/fx,zNear(w-cx)/fx,-zNearcy/fy,zNear(h-cy)/fy,zNear,Zfar), we get:
P=
[2*fx/w 0 (w-2*cx)/w 0
0 2*fy/h (h-2*cy)/h 0
0 0 C D
0 0 -1 0]
Hence,
V_ccs.x=2*fx/w*V_vcs.x+(w-2*cx)/w*V_vcs.z
V_ccs.w=-V_vcs.z
Then
V_ndcs.x=-(2*fx*V_vcs.x/V_vcs.z + (w-2*cx))/w
And finally,
V_dcs.x=(1-(2*fx*V_vcs.x/V_vcs.z + (w-2*cx))/w)*w/2
= -2*fx*V_vcs.x/V_vcs.z + cx
which differs from what I want by the minus in front of 2fxV_vcs.x/V_vcs.z
The modification, to make it works as I want seems obvious :
P=glFrustum( zNearcx/fx,-zNear(w-cx)/fx, zNearcy/fy, -zNear(h-cy)/fy,zNear,Zfar).
Unfortunately, cx,fx,cy and fy are positive parameters. This would mean that the right corner of the frustum is on the left and vice versa. I don’t know how bad it is, but I think It’s rather likely that I am missing something obvious which leads to this situation.
I’ll keep you informed if I find the answer.