I know there’s a lot of confusion about the W coordinate in OpenGL land. Typically you start out with Euclidean geometry (i.e., just an X, Y and Z coordinate for each vertex). In such cases, OpenGL assigns a W coordinate with a value of 1.0 to each such point when it is first loaded into the GL pipeline. This converts your vertices to homogeneous form, though they’re still Euclidean since all the W are 1.0 .
For the typical perspective transform, the projection matrix just causes each vertex’s Z coordinate to be copied to its W coordinate. For an orthographic projection, each vertex’s W coordinate is left alone by the projection matrix. (There are other projections possible than just these two types. But whatever it is, it involves defining the W coordinate in some way.)
When the OpenGL pipeline does its perspective divide for each vertex before the rasterization step, it divides the X, Y, and Z by W. This is true even in the programmable shaders pipeline.
Dividing X, Y, and Z by W is actually the standard mathematical way of transforming homogeneous coordinates to Euclidean coordinates, which is why OpenGL uses this seemingly screwy way of doing the perspective divide.
Anyway, nothing says you have to use Euclidean geometry with OpenGL. You don’t have to implicitly or explicitly define the vertices of your geometry with W coordinates that equal one. In fact, if you ever work with rational geometry, you will need to define your vertices with W coordinates that are not all equal to one. If you do this, then you can’t do things in OpenGL the way they are typically done, though. At some point, you will have to convert your geometry from your homogeneous coordinate system to Euclidean by dividing your X, Y, and Z by your W, then assign 1.0 to W and then you can go about all the stuff the way people usually do in OpenGL for the projection transformation.
You might wonder, fine, but does anybody ever actually use rational geometry with W coordinates that don’t all equal one? The answer is: Yes! Rational Bezier curves and surfaces (and by extension NURBS curves and surfaces) all use the W coordinate to do their thing. They need to do this in order to represent any conic sections exactly, the most important of which are circles and circular arcs, but also ellipses and hyperbola (parabolas can be represented exactly without resorting to rational representations). This all gets really interesting with programmable shaders.