openGL/GLSL Projection matrix

Hi everyone. I am new on this forum and I have the following question.

I want to use a glsl shader to set the view matrix and the projection matrix of the camera.
Basically, the shader would look like (tell me if I’m wrong).

uniform mat4 projMatrix;
uniform mat4 viewMatrix;
void main()
{

gl_FrontColor = gl_Color;
gl_Position = projMatrix*viewMatrix * gl_Vertex;

}

The problem is that in my case, I want to impose a given mapping from Camera coordinate system to window coordinate system (rather than to the clip plane coordinate system). This mapping is characterized by a 3 by 3 matrix P of this form:

P=
[fx 0 cx
0 fy cy
0 0 1 ]

My main problem is to compute projMatrix (4x4 matrix used in the shader) from P.
Unfortunately, I don’t know well enough the transformations applied by OpenGL to map clip plane coordinate system to window coordinate system.
Thanks to anyone helping on this.
regards
Loic

if M ur modelview matrix, P ur projection matrix and V ur vertex in object space.
so ur vertex in eye space Ve=MV;
now to project it to the camera space u have to do the following :
//normalize
Ve.x=Ve.x/Ve.z;
Ve.y=Ve.y/Ve.z;
Ve.z=1;
now to find ur screen coordinate u ,v:
u=fx
Ve.x+cx;
v=fy*Ve.y+cy;

Hi thanks for the reply.
You’re perfectly right, but I don’t see how it would help me to compute projMatrix. To be clearer, my original problem was not to compute the projection of V in the screen coordinate (what you explained very well), but rather to compute the necessary projection matrix so that the pipeline :
V --> Ve=MV --> Vclip = projMatrixVe --> Vscreen= unknown function of Vclip

is equivalent to the pipeline you described :
V --> Ve=MV --> Ve/=Ve.z --> Vscreen=(u,v,1)=PVe

I insist that, what I can’t figure out is how Vscreen depends on Vclip in openGl pipeline. If I knew this, I think I could determine projMatrix so that both path give the same Vscreen…

Hope, I’m more precise.

glFrustum(-zNearcx/fx,zNear(image_width-cx)/fx,
-zNearcy/fy,zNear(image_height-cy)/fy,zNear,Zfar);
with zNear>0
this will generate a virtual camera perspective identical to ur real camera perspective with fx,fy,cx,cy ( assuming that u have removed the distortions)

now to find the matrix generated by glFrustum go to the sdk doc :
http://www.opengl.org/sdk/docs/man/xhtml/glFrustum.xml
and calculate the matrix paramters then u can send this matrix to ur shader.
hope this will help u !

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.

It seems that having P=glFrustum( zNearcx/fx,-zNear(w-cx)/fx, zNearcy/fy, -zNear(h-cy)/fy,zNear,Zfar) ie putting the right boundary of the frustum on the left and vice versa works.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.