Hi Petr,
I'm considering writing on vectors and trigonometry - probably in PDF form. However it occurred to me that Sanctum (in Samples) implements this idea without GL. It should follow that in order to get the *same* 3D -> 2D transformation that GL does, there may meed to be some tuning of the magic numbers (for instance field of view distance, abbreviated fovd)
So the chunk that implements the equation is:
...
' Project vectors onto the screen plane.
vec3Ddotnhat = vec(i, 1) * nhat(1) + vec(i, 2) * nhat(2) + vec(i, 3) * nhat(3)
vec2D(i, 1) = (vec(i, 1) * uhat(1) + vec(i, 2) * uhat(2) + vec(i, 3) * uhat(3)) * fovd / vec3Ddotnhat
vec2D(i, 2) = (vec(i, 1) * vhat(1) + vec(i, 2) * vhat(2) + vec(i, 3) * vhat(3)) * fovd / vec3Ddotnhat
...
In the above, vec(i,1), vec(i,2), and vec(i,3) are the x, y, z-components, respectively of a vector that locates a 3D point, such as the corner of a cube, or a spot in a texture, or whatever. In a static world, these vectors never move. In a world where things move, the animations are done in vec(i,j) space. So far so good?
Meanwhile, there are three more vectors at play: uhat, vhat, and nhat. These all end in "hat" to denote that they are unit vectors (of length 1). The vector uhat is locked in the plane of your screen and points left to right. The vector vhat is also locked in the plane of your screen and points down to up. However, do not think of these vectors as *ON* your screen. Instead you must picture a giant plane cutting through your 3D scene, and your screen stays aligned with this plane, but far away. In other words, uhat and vhat track the orientation of the view you're computing. When the player swivels his head, these vectors are what change. Finally nhat is perpendicular to uhat and vhat, and points directly out the screen toward your eye.
In the code, "vec3Ddotnhat" is the projection of the 3D vector along the nhat vector. The answer is just a number, so put it on the shelf for second.
In the next two lines, we calculate the actual position, in 2D cartesian coordinates, of the original 3D point. (Finally we calculate what's ON screen.) How? We take that vector's projection (dot product) along uhat, and then separately along vhat. This will flatten the whole 3D scene onto the big imaginary plane cutting through it. Finally, to achieve the proper illusion of depth, we multiply by the field of view distance and divide by "vec3Ddotnat".
Anyway, hope that helps a little. This is what's going on in the sketch.
....
EDIT: Clipping planes are an advanced lesson - you don't want to render the *entire* level of course all at once - but I think this isn't on target with your question.... yet