OpenGL Rendering Pipeline
The OpenGL Rendering Pipeline is the sequence of steps that the OpenGL system performs to execute a Drawing Command. In OpenGL, objects are described by sequences of vertices, which will be processed and turned into various images. A drawing command is the state needed to describe these vertices and how they are to be rendered.
The rendering process begins with the user describing how their vertex data is stored and should be interpreted. A vertex is an arbitrary, user-defined conglomeration of information. These vertices are ordered in a sequence; the OpenGL rendering system respects the sequence of vertices provided by the user.
The user then executes a drawing command, which takes those stored vertices and renders them based on various OpenGL state the user has set up. Part of the drawing command is a description of how to interpret a sequence of vertices. This defines whether a vertex sequence is a list of lines, points, triangles, and so forth.
From here, this sequence of vertices goes through a number of processing steps, defined by user-defined shader programs. The first is the Vertex Shader, which takes each input vertex and performs arbitrary processing, returning an output vertex. After this is an optional Tessellation stage, where patch primitives can be subdivided into smaller primitives. The next step is the optional Geometry Shader stage, where incoming points/lines/triangles can be processed as a primitive, resulting in zero or more output primitives.
The vertices then undergo a number of non-shader-based processing steps. At this point, the vertices can be collected into buffers, if the user wishes to save post-transformed vertices for later use. The vertex positions then undergo a series of transformations into the space of the display area, as defined by the display device and user settings.
In the next stage, the sequence of vertices is transformed into a set of primitives, which can then be rasterized. User settings can cause triangle primitives to be culled (not rendered) based on their facing.
When a primitive is rasterized, it is broken down into a series of fragments. Each fragment represents a sample-sized area of the primitive, as well as data output by the Vertex Processing stage that is interpolated across the area of the primitive.
These fragments are then processed by a Fragment Shader. This performs arbitrary processing on the fragment, producing an output fragment that contains the depth of the fragment and a number of output colors. The fragment shader can even discard the fragment, preventing it from being visible and preventing the fragment shader's computations from having any visible effects.
The output fragment, consisting of a depth, stencil, and a number of color values, then undergo a series of processing steps that include a myriad of operations. The fragment depth value can be tested against the current depth value at that sample point. The fragment stencil value can be tested against the current stencil value at that sample point. Each of the fragment output colors can be blended against the sample colors from the image that each output is going to. There are many other processing steps.
The final step is that, if the fragment has not yet been discarded, it is data is written to the various images associated with the current Framebuffer. The writing of this data can be masked, preventing certain channels of colors from being written.