written count is incremented every time a primitive is recorded into a buffer object. If transform feedback is not active, this counter is not incremented. If the primitive does not fit in the buffer object, the counter is not incremented.
These two queries can be used together to determine if all primitives have been written to the bound feedback buffers; if both queries are run simultaneously and the query results are equal, all primitives have been written to the buffer(s). If the number of primitives written is less than the number of primitives generated, the buffer is full.
2.17
Primitive Clipping
Primitives are clipped to theclip volume. In clip coordinates, theview volume
is defined by
−wc≤xc≤wc
−wc≤yc≤wc
−wc≤zc≤wc.
This view volume may be further restricted by as many asnclient-defined half- spaces. (nis an implementation-dependent maximum that must be at least6.) The clip volume is the intersection of all such half-spaces with the view volume (if no client-defined half-spaces are enabled, the clip volume is the view volume).
A vertex shader may write a single clip distance for each supported half-space to elements of thegl ClipDistance[]array. Half-spacenis then given by the set of points satisfying the inequality
cn(P)≥0,
wherecn(P)is the value of clip distancenat pointP. For point primitives,
cn(P) is simply the clip distance for the vertex in question. For line and triangle primitives, per-vertex clip distances are interpolated using a weighted mean, with weights derived according to the algorithms described in sections3.5and3.6.
Client-defined half-spaces are enabled with the genericEnablecommand and disabled with the Disable command. The value of the argument to either com- mand isCLIP DISTANCEiwhereiis an integer between 0 andn−1; specifying a value ofienables or disables the plane equation with indexi. The constants obey
CLIP DISTANCEi=CLIP DISTANCE0+i.
If the primitive under consideration is a point, then clipping passes it un- changed if it lies within the clip volume; otherwise, it is discarded.
If the primitive is a line segment, then clipping does nothing to it if it lies entirely within the clip volume, and discards it if it lies entirely outside the volume.
2.17. PRIMITIVE CLIPPING 83
If part of the line segment lies in the volume and part lies outside, then the line segment is clipped and new vertex coordinates are computed for one or both vertices. A clipped line segment endpoint lies on both the original line segment and the boundary of the clip volume.
This clipping produces a value, 0 ≤ t ≤ 1, for each clipped vertex. If the coordinates of a clipped vertex arePand the original vertices’ coordinates areP1 andP2, thentis given by
P=tP1+ (1−t)P2.
The value oftis used to clip vertex shader varying variables as described in sec- tion2.17.1.
If the primitive is a polygon, then it is passed if every one of its edges lies entirely inside the clip volume and either clipped or discarded otherwise. Polygon clipping may cause polygon edges to be clipped, but because polygon connectivity must be maintained, these clipped edges are connected by new edges that lie along the clip volume’s boundary. Thus, clipping may require the introduction of new vertices into a polygon.
If it happens that a polygon intersects an edge of the clip volume’s boundary, then the clipped polygon must include a point on this boundary edge.
Primitives rendered with user-defined half-spaces must satisfy a complemen- tarity criterion. Suppose a series of primitives is drawn where each vertexihas a single specified clip distancedi(or a number of similarly specified clip distances,
if multiple half-spaces are enabled). Next, suppose that the same series of primi- tives are drawn again with each such clip distance replaced by−di (and the GL
is otherwise in the same state). In this case, primitives must not be missing any pixels, nor may any pixels be drawn twice in regions where those primitives are cut by the clip planes.
The state required for clipping is at least 6 bits indicating which of the client- defined half-spaces are enabled. In the initial state, all half-spaces are disabled.
2.17.1 Clipping Shader Varying Outputs
Next, vertex shader varying variables are clipped. The varying values associ- ated with a vertex that lies within the clip volume are unaffected by clipping. If a primitive is clipped, however, the varying values assigned to vertices produced by clipping are clipped.
Let the varying values assigned to the two verticesP1 andP2 of an unclipped edge bec1 andc2. The value oft(section2.17) for a clipped pointPis used to obtain the varying value associated withPas4
4Since this computation is performed in clip space before division byw
c, clipped varying values
2.17. PRIMITIVE CLIPPING 84
c=tc1+ (1−t)c2.
(Multiplying a varying value by a scalar means multiplying each ofx,y,z, andw
by the scalar.)
Polygon clipping may create a clipped vertex along an edge of the clip volume’s boundary. This situation is handled by noting that polygon clipping proceeds by clipping against one half-space at a time. Varying value clipping is done in the same way, so that clipped points always occur at the intersection of polygon edges (possibly already clipped) with the clip volume’s boundary.
For vertex shader varying variables specified to be interpolated without per- spective correction (using the noperspectivequalifier), the value oft used to obtain the varying value associated withPwill be adjusted to produce results that vary linearly in screen space.
Varying outputs of integer or unsigned integer type must always be declared with theflatqualifier. Since such varyings are constant over the primitive being rasterized (see sections3.5.1and 3.6.1), no interpolation is performed.
Chapter 3
Rasterization
Rasterization is the process by which a primitive is converted to a two-dimensional image. Each point of this image contains such information as color and depth. Thus, rasterizing a primitive consists of two parts. The first is to determine which squares of an integer grid in window coordinates are occupied by the primitive. The second is assigning a depth value and one or more color values to each such square. The results of this process are passed on to the next stage of the GL (per- fragment operations), which uses the information to update the appropriate loca- tions in the framebuffer. Figure3.1 diagrams the rasterization process. The color values assigned to a fragment are initially determined by the rasterization opera- tions (sections3.4through3.7) and modified by a fragment shader as defined in section3.9. The final depth value is initially determined by the rasterization op- erations and may be modified or replaced by a fragment shader. The results from rasterizing a point, line, or polygon can be routed through a fragment shader.
A grid square along with its parameters of assigned colors,z(depth), fog coor- dinate, and texture coordinates is called afragment; the parameters are collectively dubbed the fragment’sassociated data. A fragment is located by its lower left cor- ner, which lies on integer grid coordinates. Rasterization operations also refer to a fragment’scenter, which is offset by(1/2,1/2)from its lower left corner (and so lies on half-integer coordinates).
Grid squares need not actually be square in the GL. Rasterization rules are not affected by the actual aspect ratio of the grid squares. Display of non-square grids, however, will cause rasterized points and line segments to appear fatter in one direction than the other. We assume that fragments are square, since it simplifies antialiasing and texturing.
Several factors affect rasterization. Primitives may be discarded before ras- terization. Points may be given differing diameters and line segments differing
3.1. DISCARDING PRIMITIVES BEFORE RASTERIZATION 86 Point Rasterization Triangle Rasterization Line
Rasterization FragmentProgram From
Primitive
Assembly Fragments
Figure 3.1. Rasterization.
widths. A point, line segment, or polygon may be antialiased.
3.1
Discarding Primitives Before Rasterization
Primitives can be optionally discarded before rasterization by callingEnableand DisablewithRASTERIZER DISCARD. When enabled, primitives are discarded im- mediately before the rasterization stage, but after the optional transform feedback stage (see section2.15). When disabled, primitives are passed through to the ras- terization stage to be processed normally. When enabled,RASTERIZER DISCARD
also causes the Clearand ClearBuffer*commands to be ignored.