The viewport
So far, all vertices where defined in such a way, that they are directly put onto the screen with pixel coordinates, either directly in coordinates or with transforms.
This isn't the nicest way generally, even in the 2D case. For example, if our screen changes resolution, we have to redefine all the vertices or transforms. With the definition of the perspective matrix and the visible volume we have a sensible way to specify points. We use an abstract drawing surface which is specified in the range . We then additionally specify a viewport, a region of our actual drawing surface (window, canvas, ...) and transform all vertices from to . That way, we can easily change resolutions and even draw subimages onto our drawing surface by specifying the viewport origin () and the size (). It isn't really necessary, but in like in OpenGL, we will transform the depth () values as well, but just from to .
Now these transformations aren't that complicated. Here is how to get the coordinate transform as a sequence of transformations: .
The full transformations from normalized device coordinates (NDC) to window coordinates (W) are thus given by:
You can put that transform in a matrix or just write out the equations. And with that we have defined our viewport!