PDA

View Full Version : custom projection matrix

Florin Bratu
11-28-2005, 06:35 AM
Hello!
From as far as I read, the most widely-used graphic systems do projections by first defining a "canonica volume" in which all the objects will be fitted, and eventually clipped, and then the actual projection will take place in that volume.
Now, from the theory, projection transformations map a 3d object on a 2d plane (the general case is n dimension obj on an n-1 dimension space).
My question is : how can I calculate a projection matrix for a particular projection, in order to comply with this model? i.e. the "canonical volume" model?
Example : I want to define an oblic projection in OpenGL. I have calculated the following projection matrix:
GLdouble g_dOblicProj[]={
1 , 0 , -0.5 , 0 ,
0 , 1 , 3.25 , 0 ,
0 , 0 , 0 , 0,
0 , 0 , 0 , 1
};
But when I load it using glLoadMatrix, I get the same effect as though I was using an orthographic projection
what are the changes required in order to make it work?

memfr0b
11-28-2005, 07:09 AM
The projection matrix in OpenGL generally doesn't remove a dimension, because the z value of the transformed vertex is still needed for depth testing. Instead the vertices are transformed from eye coordinates to normalized device coordinates (where (-1, -1, -1) is the near-lower-left corner and (1, 1, 1) is the far-upper-right corner). The z coordinate is then converted to the depth value, and x and y are transformed by the viewport matrix/equation to pixel values.

The perspective effect of the gluPerspective/glFrustum matrix is caused by the transformed vertice's w component being generated from the original vertice's z value (the fourth row is (0 0 -1 0) not (0 0 0 1) as with most other matrices; see glFrustum (http://pyopengl.sourceforge.net/documentation/manual/glFrustum.3G.html) ). The projected vertex is defined as (x/w y/w z/w), so the w value increasing with z causes the x and y components to shrink with increasing z (distance).

An oblique perspective frustum can easily be generated with glFrustum, no need to build the matrix yourself. Just give non-symmetric values for left/right or bottom/top.

Florin Bratu
11-28-2005, 08:07 AM
I dont think that an oblique projection can be generated by using glOrtho, because an oblique projection requires that the projection direction is not orthogonal to the projection plane, and glOrtho does that. I've tested it , and it doesn't help if you use non-symmetric values; you have to make your own projectiojn matrix.

memfr0b
11-28-2005, 02:57 PM
You're right, you can't create an oblique frustum with glOrtho. I was talking about glFrustum, which can.

For an oblique orthographic projection, you'll indeed have to build you own matrix. Simply start with the normal orthograpic matrix and add the shearing part.

The result should look something like this (untested):

l: left
r: right
b: bottom
t: top
n: near
f: far

tx = (r+l)/(r-l)
ty = (t+b)/(t-b)
tz = (f+n)/(f-n)

sx = 2*dx/(r-l)
sy = 2*dy/(t-b)

/ 2/(r-l) 0 sx/(f-n) tx \
| 0 2/(t-b) sy/(f-n) ty |
| 0 0 -2/(f-n) tz |
\ 0 0 0 1 /