Projection Matrix - help!


I’m trying to get a simple 3D app working which will run on software wireframe when opengl is not present. Everything is working except one thing; the projection matrix. I’ve never been able to get a projection matrix working outside of opengl; instead I simply fudged it with something like this:

screen.x = (x / (z / Dist)) + screen.centerX
screen.y = (y / (z / Dist)) + screen.centerY

The mesh vertices are transformed first by the modelling/world matrices (translate, scale etc) and then by the UVN camera matrix. This does the job of a proper projection matrix but it just does’nt cut it. I’ve tried simple z-axis one-point projection matrices such as this:

[ 1 0 0 0 ]
[ 0 1 0 0 ]
[ 0 0 1 dist ]
[ 0 0 0 1 ]

and this

[ 1 0 0 0 ]
[ 0 1 0 0 ]
[ 0 0 1/dist 1/dist ]
[ 0 0 0 1]

when dist is derived from simple trig. It’s usually around 300. Everything I try always seems to produce a orthographic view with no depth foreshortening. The graphics books I have don’t account for this behaviour. What am I missing? Do I have to do something with these point after they are projected before they can be displayed?

Please note; I’m not a graphics newbie. I’ve programmed distributed raytracers, z-buffer renderers, filters and more. But this has always stumped me, and I want to solve it once and for all!

It sounds like you aren’t doing the perspective divide. Googling for that, or looking it up in the Red Book will probably answer your question.

when opengl is not present
When does that happen?

The Red book description of the Projection matrix can be found here . Google is your friend.

What do you mean by ‘perspective divide’?

Sorry, this must seem so simple to you…I’ve got the Red Book, but I still don’t see what I’m doing wrong.

Perspective division is where OpenGL divides the components of each point by the w component. In my edition of the Red Book, it is page 674 that shows exactly what matrix glFrustum creates (It is the last page of Appendix F on homogeneous coordinates & transformation matrices.)

I’m looking at it right now but I still don’t get what you mean, or why it should be necessary

Do you mean:

x /= distz
y /= dist
z /= dist*z


Not quite. x /= w, y /= w, z /= w, w /= w. Remember, you are multiplying a four-dimentional vector by a four-by-four matrix. The last row of the matrix isn’t necessarily 0,0,0,1; it only is if you have an orthographic projection.

Sections 2.11 (“Coordinate Transformations”) and 2.12 (“Clipping”) of the OpenGL spec offer a very thorough explanation of the whole transformation from object coordinates to window coordinates.

– Tom