I am not very good with python so I will not give some code here, but I will try to cover the theoretical/mathematical part of the question:
These are standard 3D graphics manipulations.
Some more information: Vectors in 3D graphics are 4 dimensional entities. The 3 first coordinates correspond to the euclidean space x,y,z coordinates, usually in local or model space and the last coordinate is the w
or homogenous coordinate, which is used for perspective effects, translation in 3d space and for clipping.
Likewise, 3D space matrices are 4x4 matrices, so that they can handle the 4 dimensional vertices. Usually when a vertex is transformed to screen space, the initial value of w
is 1.0
. There are other values to use but they are for more advanced use.
Transforming to screen space is simply a matter of transforming the vertex by the Model matrix M
, to transform the vertex to world space (where the model resides on the 3D world), by the camera matrix C
, to transform it to the reference frame of the camera, or camera space, by the projection matrix P
to account for projection effects (called projection space), do perspective division and clipping and finally turn the resulting coordinates to pixel space.
So if the vertex is v
, you have to do P*C*M*v
(remember matrix multiplications are non-commutative! Order of multiplication is important!). This has transformed the vector to projection space
After that, you need to clip the vector. If any of the vector's 3 first components is greater in absolute value than the fourth component, then it is outside the field of view of the camera and should be clipped. If the vector is not clipped, then you need to divide each of the 3 components of the vector by the w
coordinate. So if the projection space vector is (x,y,z,w)
, after clipping you get the screen space coordinates (x/w, y/w, z/w, 1)
This will yield normalized coordinates with range {-1.0, 1.0}
. To convert to pixel space, you need to know the width and height of the screen in pixels.
"Screen" here, may not refer to an actual screen, but can be the rendered image. What changes in the description is that instead of an actual screen width/height, you have the x/y resolution of the rendered image.
If (sx, sy)
are the screen space vector x and y coordinates and w, h are the height and width of the screen, or image, then
x = w/2 * (1.0 + sx)
will give the x position in screen space.
For the y component it may be a little more complicated because usually pixel space is counted from the bottom of the screen up, while operating systems count it on reverse. So, depending on the occasion it may be either
y = h/2 * (1.0 + sy)
or
y = h/2 * (1.0 - sy)
A warning though, the names of the spaces can be different in some textbooks. I hope that I have managed to relay the general idea though.
For more information I recommend reading
http://www.glprogramming.com/red/appendixf.html