• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    ARB_clip_control
4
5Name Strings
6
7    GL_ARB_clip_control
8
9Contact
10
11    Mark J. Kilgard, NVIDIA Corporation (mjk 'at' nvidia.com)
12
13Contributors
14
15    Timo Suoranta, Broadcom
16    Piers Daniell, NVIDIA
17    Stefan Dösinger, CodeWeavers
18    Jeff Bolz, NVIDIA
19    John McDonald, NVIDIA
20    Brian Paul, VMware, Mesa3D
21    Jason Mitchell, Valve
22    Alex Corscadden, VMware
23    Simon Bennett, VMware
24    Mark Callow, HI Corporation
25    Patrick Doane, Blizzard
26    Pat Brown, NVIDIA
27    Brano Kemen
28
29Notice
30
31    Copyright (c) 2014 The Khronos Group Inc. Copyright terms at
32        http://www.khronos.org/registry/speccopyright.html
33
34Specification Update Policy
35
36    Khronos-approved extension specifications are updated in response to
37    issues and bugs prioritized by the Khronos OpenGL Working Group. For
38    extensions which have been promoted to a core Specification, fixes will
39    first appear in the latest version of that core Specification, and will
40    eventually be backported to the extension document. This policy is
41    described in more detail at
42        https://www.khronos.org/registry/OpenGL/docs/update_policy.php
43
44Status
45
46    Complete.
47    Approved by the ARB on June 26, 2014.
48    Ratified by the Khronos Board of Promoters on August 7, 2014.
49
50Version
51
52    Last Modified Date:  2018/04/06
53    NVIDIA Revision:     19
54
55Number
56
57    ARB Extension #160
58
59Dependencies
60
61    Written based on the wording of the OpenGL 4.4 (Compatibility Profile)
62    specification.
63
64Overview
65
66    This extension provides additional clip control modes to configure how
67    clip space is mapped to window space.  This extension's goal is to 1)
68    allow OpenGL to effectively match Direct3D's coordinate system
69    conventions, and 2) potentially improve the numerical precision of the Z
70    coordinate mapping.
71
72    Developers interested in this functionality may be porting content
73    from Direct3D to OpenGL and/or interested in improving the numerical
74    accuracy of depth testing, particularly with floating-point depth
75    buffers.
76
77    OpenGL's initial and conventional clip control state is configured by:
78
79        glClipControl(GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE);
80
81    where geometry with (x,y) normalized device coordinates of (-1,-1)
82    correspond to the lower-left corner of the viewport and the near and far
83    planes correspond to z normalized device coordinates of -1 and +1,
84    respectively.
85
86    This extension can be used to render content used in a Direct3D
87    application in OpenGL in a straightforward way without modifying vertex or
88    matrix data.  When rendering into a window, the command
89
90        glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
91
92    configures the near clip plane to correspond to a z normalized device
93    coordinate of 0 as in Direct3D.  Geometry with (x,y) normalized device
94    coordinates of (-1,-1) correspond to the lower-left corner of the viewport
95    in Direct3D, so no change relative to OpenGL conventions is needed there.
96    Other state related to screen-space coordinates may need to be modified
97    for the application to map from Direct3D to OpenGL window coordinate
98    conventions.  For example, the viewport rectangle in Direct3D needs to be
99    inverted within the window to work properly in OpenGL windowed rendering:
100
101       glViewport(d3d_viewport_x,
102                  window_height - (d3d_viewport_y + d3d_viewport_height),
103                  d3d_viewport_width, d3d_viewport_height);
104
105    When rendering Direct3D content into a framebuffer object in OpenGL, there
106    is one complication -- how to get a correct image *out* of the related
107    textures.  Direct3D applications would expect a texture coordinate of
108    (0,0) to correspond to the upper-left corner of a rendered image, while
109    OpenGL FBO conventions would map (0,0) to the lower-left corner of the
110    rendered image.  For applications wishing to use Direct3D content with
111    unmodified texture coordinates, the command
112
113        glClipControl(GL_UPPER_LEFT, GL_ZERO_TO_ONE);
114
115    configures the OpenGL to invert geometry vertically inside the viewport.
116    Content at the top of the viewport for Direct3D will be rendered to the
117    bottom of the viewport from the point of view of OpenGL, but will have a
118    <t> texture coordinate of zero in both cases.  When operating in this
119    mode, applications need not invert the programmed viewport rectangle as
120    recommended for windowed rendering above.
121
122    Applications happy with OpenGL's origin conventions but seeking
123    potentially improved depth precision can configure clip controls using:
124
125        glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
126
127    to avoid the loss of precision from the DepthRange transformation
128    (which by default is z_window = z_ndc * 0.5 + 0.5).
129
130New Procedures and Functions
131
132    void ClipControl(enum origin, enum depth);
133
134New Tokens
135
136    Accepted by the <origin> parameter of ClipControl:
137
138        LOWER_LEFT                                  0x8CA1
139        UPPER_LEFT                                  0x8CA2
140
141    Accepted by the <depth> parameter of ClipControl:
142
143        NEGATIVE_ONE_TO_ONE                         0x935E
144        ZERO_TO_ONE                                 0x935F
145
146    Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,
147    GetFloatv, and GetDoublev:
148
149        CLIP_ORIGIN                                 0x935C
150        CLIP_DEPTH_MODE                             0x935D
151
152Additions to Chapter 13 of the OpenGL 4.4 (Compatibility Profile)
153Specification (Fixed-Function Vertex Post-Processing)
154
155 -- Modify section 13.5 "Primitive Clipping"
156
157    Insert before the 1st paragraph...
158
159    "The command
160
161        ClipControl(enum origin, enum depth);
162
163    controls the clipping volume behavior.  /origin/ must be either
164    LOWER_LEFT or UPPER_LEFT, otherwise the error INVALID_ENUM is
165    generated.  /depth/ must be either NEGATIVE_ONE_TO_ONE or
166    ZERO_TO_ONE, otherwise the error INVALID_ENUM is generated.
167
168      These parameters update the clip control origin and
169    depth mode respectively.  The state required for clip control is one
170    bit for clip control origin and one bit for clip control depth mode.
171    The initial value of the clip control origin is LOWER_LEFT and the
172    initial value of the depth mode is NEGATIVE_ONE_TO_ONE.
173
174      The error INVALID_OPERATION is generated if ClipControl is
175    executed between the execution of Begin and the corresponding
176    execution of End."
177
178    Replace the first paragraph with...
179
180    "Primitives are clipped to the clip volume. In clip coordinates,
181    the view volume is defined by
182
183        -w_c <= x_c <= w_c
184        -w_c <= y_c <= w_c
185          zm <= z_c <= w_c
186
187     where zm is -w_c when the clip control depth mode is
188     NEGATIVE_ONE_TO_ONE or zero when the mode is ZERO_TO_ONE."
189
190     Change the last sentence of the 7th paragraph to read...
191
192     "If depth clamping is enabled, the
193
194        zm <= z_c <= w_c
195
196      plane equation (see the clip volume definition) is ignored by
197      view volume clipping (effectively, there is no near or far plane
198      clipping)."
199
200 -- Modify section 13.6 "Coordinate Transformations"
201
202    Replace the 3rd paragraph with (where ^T means transpose):
203
204    "If a vertex in clip coordinates is given by (x_c y_c z_c w_c)^T
205    then the vertex's normalized device coordinates are (x_d y_d z_d)^T =
206    (x_c/w_c f*y_c/w_c z_c/w_c)^T where /f/ is +1 when the clip control
207    origin is LOWER_LEFT and -1 when the origin is UPPER_LEFT."
208
209 -- Modify section 13.6.1 "Controlling the Viewport"
210
211    Replace the 2nd sentence of the 1st paragraph with (where ^T means
212    transpose):
213
214    "The vertex's window coordinates, (x_w y_w z_w)^T are given by:
215
216        ( x_w )     ( p_x/2 x_d + o_x )
217        ( y_w )  =  ( p_y/2 y_d + o_y )
218        ( z_w )     (     s z_d + b   )
219
220    where s is (f-n)/2 and b is (n+f)/2 when the clip control depth mode
221    is NEGATIVE_ONE_TO_ONE; or s is (f-n) and b is n when the mode
222    is ZERO_TO_ONE."
223
224Additions to Chapter 14 of the OpenGL 4.4 (Compatibility Profile)
225Specification (Fixed-Function Primitive Assembly and Rasterization)
226
227 -- Modify section 14.6.1 "Basic Polygon Rasterization"
228
229    Replace the 3rd sentence of the 1st paragraph with:
230
231    "One way to compute this area is
232
233               n-1
234               ___
235               \
236      a = 1/2 f \  x^i_w * y^i(+)1_w - x^i(+)1_w * y^i_w
237                /
238               /__
239
240    where f is +1 when the clip control origin is LOWER_LEFT and -1 when
241    the origin is UPPER_LEFT, x^i_w and y^i_w are the x and y window
242    coordinates of the ith vertex of the n-vertex polygon (vertices
243    are numbered starting at zero for purposes of this computation),
244    and i(+)1 is (i+1) mod n."
245
246Additions to the AGL/GLX/WGL Specifications
247
248    None
249
250GLX Protocol
251
252    A new GL rendering command is added. The following command is sent to the
253    server as part of a glXRender request:
254
255        ClipControl
256            2           12              rendering command length
257            2           1340            rendering command opcode
258            4           ENUM            origin
259            4           ENUM            depth
260
261Errors
262
263    The error INVALID_ENUM is generated by ClipControl if origin is not
264    LOWER_LEFT or UPPER_LEFT.
265
266    The error INVALID_ENUM is generated by ClipControl if depth is not
267    NEGATIVE_ONE_TO_ONE or ZERO_TO_ONE.
268
269    The error INVALID_OPERATION is generated if ClipControl is executed
270    between the execution of Begin and the corresponding execution of
271    End.
272
273New State
274
275    Get Value         Type  Get Command  Initial Value        Description      Sec   Attribute
276    ----------------  ----  -----------  -------------------  ---------------  ----  ---------
277    CLIP_ORIGIN       Z2    GetIntegerv  LOWER_LEFT           Clip origin      13.5  xform
278    CLIP_DEPTH_MODE   Z2    GetIntegerv  NEGATIVE_ONE_TO_ONE  Clip depth mode  13.5  xform
279
280New Implementation Dependent State
281
282    None
283
284Issues
285
286    1)  What should this extension be called?
287
288        RESOLVED:  ARB_clip_control
289
290        We frame this extension in terms of how the fixed-function
291        transformation from clip coordinates to window coordinates
292        is specified.  The crucial modifications to OpenGL's existing
293        behavior involve controlling how clip space is interpreted.
294
295        An upper-left origin is really simply negating (flipping) the
296        clip space Y coordinate.  Subsequently the sense of counter-clockwise
297        and clockwise for face culling must be adjusted (flipped).
298
299        A zero-to-one Z mode involves adjusting the clipping equation
300        for the clip space Z coordinate.  Subsequently the depth range
301        transform equation must be adjusted (scaled and biased).
302
303        Hence clip control is a sensible name.
304
305    2)  Should this functionality be exposed with glEnable/glDisable or
306        with a new command.
307
308        RESOLVED:  With a new command, glClipControl.
309
310        We note that this extension does not actually enable or disable
311        functionality, but rather modifies an existing transformation.
312
313        We note that Direct3D is different in two ways: clip Y inversion
314        and zero-to-one clip Z.
315
316        We note the difficulty of a clear enable name.
317        GL_NEGATIVE_ONE_TO_ONE and GL_ZERO_TO_ONE
318        are very explicit about how the Z clip coordinate is treated by
319        the clip equations.  Likewise, GL_LOWER_LEFT and GL_UPPER_LEFT
320        are explicit (and match the token names and meaning for the
321        point sprite functionality).
322
323        We also note the possibility for other possible conventions.
324        For example, an origin at the center of the window.  Hence an
325        enumeration of clip modes is a better choice.  Likewise, a future
326        Z mode could expose W-buffering.
327
328    3)  Why does unextended OpenGL have symmetric clip equations?
329
330        RESOLVED:  This is a legacy of implementation worthy of some
331        explanation...
332
333        Handling the X, Y, and Z directions the same way better
334        facilitates vector operation for hardware efficiency.
335
336        When transformations are done with 32-bit IEEE-754 floating-point
337        values, after transformation to clip space for clipping, the
338        Z values are typically converted to fixed-point for use by a
339        conventional 24-bit fixed-point depth buffer.
340
341        The process of scaling by 0.5 and adding 0.5 to a 32-bit
342        floating-point number in the range [-1,+1] has the effect of
343        appropriately rounding the value so it can be efficiently
344        bit-shifted into a 24-bit fixed-point value in the [0,1]
345        range suitable for depth buffering via linear fixed-point
346        interpolation.
347
348    4)  Should the face culling behavior be modified in GL_UPPER_LEFT
349        clip origin mode?
350
351        RESOLVED:  Yes.
352
353        See how the modifications to section 14.6.1 "Basic Polygon
354        Rasterization" negate the sign of the polygon area when the clip
355        control origin is GL_UPPER_LEFT.
356
357        Since culling behavior is specified as CW (clockwise) or CCW
358        (counter-clockwise) different triangle faces would be culled
359        when the clip origin is changed, which would be an unacceptable
360        side effect.
361
362    5)  Are the projective matrices generated by glFrustum and glOrtho
363        appropriate when the clip Z mode is GL_ZERO_TO_ONE?
364
365        RESOLVED:  No.
366
367    6)  Should the behavior of glFrustum and glOrtho change?
368
369        RESOLVED:  No.
370
371        It's not worth encumbering these routines with adjustments,
372        plus it is easy to make the proper adjustments...
373
374        Taking advantage of how matrix changes concatenate...
375
376        If your clip control origin is GL_UPPER_LEFT, prior to your
377        glFrustum or glOrtho command by:
378
379            glScalef(1,-1,1);
380
381        If your clip control depth mode is GL_ZERO_TO_ONE, precede
382        your glFrustum or glOrtho command by:
383
384            glTranslatef(0,0,0.5);
385            glScalef(1,1,0.5);
386
387        For example, if your code to configure the projection matrix
388        reads:
389
390            glMatrixMode(GL_PROJECTION);
391            glLoadIdentity();
392            glFrustum(-0.5, 0.5, -0.5, 0.5, 1, 3);
393
394        And you wanted to call:
395
396            glClipControl(GL_UPPER_LEFT, GL_ZERO_TO_ONE);
397
398        Then configure your projection matrix as
399
400            glMatrixMode(GL_PROJECTION);
401            glLoadIdentity();
402            // adjust for GL_UPPER_LEFT
403            glScalef(1,-1,1);
404            // adjust for GL_ZERO_TO_ONE
405            glTranslatef(0,0,0.5);
406            glScalef(1,1,0.5);
407            glFrustum(-0.5, 0.5, -0.5, 0.5, 1, 3);
408
409        Technically, the two glScalef could be combined as
410        glScalef(1,-1,0.5);
411
412    7)  Has this topic been discussed elsewhere?
413
414        RESOLVED:  Yes, see:
415
416        "Maximizing Depth Buffer Range and Precision"
417        Brano Kemen
418        http://outerra.blogspot.co.uk/2012/11/maximizing-depth-buffer-range-and.html
419        November 28, 2012
420
421        "Minimum Triangle Separation for Correct Z-Buffer"
422        Kurt Akeley and Jonathan Su
423        http://research.microsoft.com/apps/pubs/default.aspx?id=79213
424        August 2006
425
426        "Tightening the Precision of Perspective Rendering"
427        Paul Upchurch and Mathieu Desbrun
428        http://www.geometry.caltech.edu/pubs/UD12.pdf
429        Journal of Graphics Tools, Volume 16, Issue 1, 2012.
430
431    8)  How does this extension interact with the unclamped depth range
432        parameters of NV_depth_buffer_float's glDepthRangedNV and OpenGL
433        4.3?
434
435        RESOLVED:  Simply apply the equations as specified.
436
437        The implications of this are explored...
438
439        An unclamped depth range applies to floating-point depth buffers.
440
441        (For a conventional [0,1] fixed-point depth buffer, the depth
442        range is clamped to "the range appropriate to the depth buffer's
443        representation."  In practice, this means that unclamped depth
444        values are clamped to the [0,1] range when used with a
445        conventional depth buffer so are effectively still clamped.)
446
447        If an application were to mix the two like this:
448
449          glDepthRangedNV(-1,1);
450          glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
451
452        this would lead to generating interpolated depth values in a
453        [-1,+1] range.  Because floating-point has more precision in the
454        neighborhood of zero, the depth buffer precision is concentrated
455        at zero in window-space Z.  This corresponds to 0.5 in normalized
456        device coordinates.
457
458        Consider if our projection matrix mapped eye-space 2 to
459        clip-space 0.0 and eye-space 1000 to 1.0 with the Z matrix row:
460
461           [  0   0   (n+f)/(n-f)   f*n/(n-f)  ]
462
463        so that
464
465            Zc = -0.5 = 0*x_e + 0*y_e + ((2+1000)/(2-1000))*z_e + (2*1000/(2-1000))*w_e
466
467        solving for z_e when w_e is one, means z_e equals -1.498
468
469        OpenGL 4.3 made a slightly incompatible change in the parameter
470        types for glDepthRange (and related commands) from clamped
471        floating-point types (GLclampd) to unclamped floating-point
472        types (GLdouble).  Hence the functionality of glDepthRangedNV
473        also applies to OpenGL 4.3 in the case of floating-point depth
474        buffers.
475
476    9)  Can an application be guaranteed the exact same pixels being
477        rasterized when the clip control origin is GL_UPPER_LEFT versus
478        GL_LOWER_LEFT, except having the scanlines reversed?
479
480        RESOLVED:  No such rasterization invariance is reasonable to
481        guarantee.  Slight pixel variances are possible.
482
483        The polygon rasterization rules for OpenGL (section 14.6.1,
484        "Polygon Rasterization") states: In such a case [fragment's center
485        lies on a polygon boundary edge] we require that if two polygons
486        lie on either side of a common edge (with identical endpoints)
487        on which a fragment center lies, then exactly one of the polygons
488        results in the production of the fragment during rasterization."
489
490        The specification leaves it to implementations to define the
491        exact edge rule in this case.  If the sense of Y in clip space
492        is flipped, this rule may be decided differently.
493
494        This is further complicated by multisampling where the sample pattern
495        is unlikely to be mirrored in the Y direction.
496
497        These issues are razor's edge cases and should not be an issue
498        for real applications.
499
500    10) Are all the possible combinations of glClipControl useful?
501
502        RESOLVED: Yes, the initial state (GL_LOWER_LEFT/
503        GL_NEGATIVE_ONE_TO_ONE) corresponds to OpenGL's traditional
504        behavior.
505
506        The state GL_LOWER_LEFT/GL_ZERO_TO_ONE corresponds to OpenGL's
507        traditional origin and Direct3D's depth mode.
508
509        The state GL_UPPER_LEFT/GL_ZERO_TO_ONE corresponds to Direct3D's
510        clip volume definition.
511
512        The state GL_UPPER_LEFT/GL_NEGATIVE_ONE_TO_ONE is consistent with
513        the upper-left origin of the window coordinate system of Microsoft
514        Windows and the X Window System.
515
516    11) Should all the possible combinations of glClipControl
517        parameters supported be supported?
518
519        RESOLVED:  Yes, all the combinations should be supported.  The cost
520        is low and this provides orthogonality.
521
522        So it is legal to call:
523
524            glClipControl(GL_UPPER_LEFT, GL_NEGATIVE_ONE_TO_ONE);
525
526    12) Does setting the clip control origin to GL_UPPER_LEFT change the
527        origin of the window coordinate system use for commands such as
528        glViewport, glScissor, glWindowPos2i, and glReadPixels?
529
530        RESOLVED:  No.
531
532        The (x,y) window space location passed to these commands have the
533        (0,0) origin at the lower left corner of the window, independent
534        of the state of the clip control origin.
535
536        So, for example, an application wanting a Direct3D upper-left orign
537        specifying the scissor with upper-left (x,y) coordinates would call:
538
539            glScissor(upper_left_x,
540                      window_height - upper_left_y,
541                      window_width, window_height);
542
543        The rationale for this choice is to avoid confusion for how
544        window space coordinates are passed to commands.  When rendering
545        to resizable windows, the window width and height can change
546        asychronously.  This would mean the scissor command would need
547        to specify a "gravity" for the window origin.  There would also
548        need to be a way to "query" this state relative to difference
549        origin conventions and subject asynchronous window resizes.
550
551        Moreover, this extension is not changing how window space is
552        specified but rather how clip space is specified.
553
554    13) Does the polygon stipple orientation change when the clip control
555        origin is set to GL_UPPER_LEFT?
556
557        RESOLVED:  No.
558
559    14) Will using the GL_ZERO_TO_ONE clip control depth mode improve
560        my depth precision?
561
562        RESOLVED:  Yes, if you use a floating-point depth buffer and
563        place the near and far values at 1.0 and 0.0 (reversed from the
564        normal convention).
565
566        But not much if you use a conventional fixed-point depth buffer.
567
568        This really depends on whether the particular hardware
569        implementation can numerically improve its depth interpolation
570        result.  This depends on a lot of things including the quality
571        of the depth plane equation setup, the number of bits of
572        sub-pixel precision available, and how the depth interpolation
573        is performed.
574
575        With a conventional 24-bit fixed-point depth buffer, applications
576        may be able to achieve half a least significant bit (LSB) of
577        improved depth buffer precision.
578
579        There are typically far better strategies for improving depth
580        precision such as W-buffering, avoiding concatenation of the
581        modelview and projection matrices, and (probably the easiest)
582        better managing your scene's near and far planes.
583
584        With a floating-point depth buffer, it is more likely the
585        GL_ZERO_TO_ONE depth mode will improve depth precision.
586        Unfortunately in the conventional depth range [0,1], the
587        improvement is primarily close to the near plane where there
588        is already excessive precision.  Reversing the depth range with
589        the command
590
591            glDepthRange(1.0, 0.0);
592
593        effectively reverses the near and far values in the depth
594        buffer.  Also remember to reverse the depth function; so
595        glDepthFunc(GL_LESS) should become glDepthFunc(GL_GREATER).
596        However, this involves computing 1-Z which effectively truncates
597        far values (for much the same reason adding +0.5 does).
598
599        Alternatively, the reversal of near and far can happen as part
600        of the projection transformation so the depth range specified
601        with glDepthRange can be the conventional range [0,1].  Arguably
602        folding the near and far reversal into the projection matrix is
603        slightly better than reversing the depth range.  However the
604        problem remains that a very large value is added with a small
605        value close to the far plane so effective depth precision is
606        not substantially improved with a fixed-point depth buffer but
607        has a substantial advantage for a floating-point depth buffer.
608
609    15) How does this extension interact with geometry shaders?
610
611        RESOLVED:  If there is a geometry shader active, it is the
612        geometry shader which is actually writing the clip space position
613        (not the vertex shader).
614
615        One way to implement this extension (ignoring geometry shaders
616        for now) would be to add an epilogue to the application's vertex
617        shader to invert the clip space Y output when the clip control
618        origin is GL_UPPER_LEFT and perform a scale by 2 and bias by negative
619        clip space W to the clip space Z (biasing by negative clip space
620        W is like subtracting 1 in normalized device coordinates).
621
622        However, this epilogue would need to be moved to the geometry
623        shader if a geometry shader was active.
624
625    16) How does this extension interact with tessellation evaluation
626        shaders (without a geometry shader)?
627
628        RESOLVED:  Then the epilogue discussed in issue #15 would need to
629        be added to the tessellation evaluation shader (and not the vertex
630        shader since it is really transforming patch control points).
631
632        If there was a geometry shader active, the geometry shader is
633        where the epilogue would be done.
634
635    17) Does the discussion of the use an epilogue in the last two issues
636        mean using the GL_UPPER_LEFT or GL_ZERO_TO_ONE modes is
637        necessarily slower?
638
639        RESOLVED:  Generally no.
640
641        GPUs that support Direct3D are expected to have a mode to support
642        GL_UPPER_LEFT and GL_ZERO_TO_ONE at full speed and OpenGL
643        implementations for such GPUs should operate at full speed.
644
645    18) Should the clip control state be changed frequently?
646
647        RESOLVED:  Most applications are expected to set the clip control
648        conventions once; for example, to match the Direct3D conventions.
649
650        Some implementations may introduce a flush when changing the
651        clip control state.  Hence frequent clip control changes are
652        not recommended.
653
654        No flush is explicitly required when the clip control changes
655        and some implementations (NVIDIA) will have no significant
656        performance penalty for changing the clip control state.
657
658    19) Issue #6 addresses fixed-function vertex processing adjustments
659        under different clip control modes.  How would a GLSL vertex
660        shader be adjusted, assuming how the shader computes its
661        clip-space position does not change, for different clip control
662        conventions?
663
664        RESOLVED:  The following GLSL epilogues could be added...
665
666        If the clip control origin is GL_UPPER_LEFT, you could add a final
667        operation to negate the clip-space Y component.  So:
668
669           gl_Position.y *= -1;
670
671        If the clip control depth mode is GL_ZERO_TO_ONE, you
672        could scale and bias the conventional [-1,+1] range of
673        normalized-device-coordinate-space Z to the [0,1] range like
674        this:
675
676           gl_Position.z = 0.5*gl_Positon.z + 0.5*gl_Position.w;
677
678        Because
679
680           z_ndc = z_c / w_c
681
682        so the epilogue above computes an adjusted z_ndc':
683
684           z_ndc' = (0.5*z_c + 0.5+w_c)/w_c
685
686        which is the same as:
687
688           z_ndc' = 0.5*z_c/w_c + 0.5
689                  = 0.5*z_ndc + 0.5
690
691        and scaling a [-1,+1] range by 0.5 and biasing by 0.5 computes
692        a linear mapping to the range [0,1].
693
694        Alternatively, rather than adding an epilogue as described,
695        the adjustments above could be folded into the transform matrix
696        typically used to transform object-space to clip-space.  This is
697        a faster approach since it avoids extra math operations in the
698        vertex shaders.
699
700    20) Explain the numerical advantage for potential increased depth
701        precision for the GL_ZERO_TO_ONE clip control depth mode.
702
703        RESOLVED:  If the normal depth range sets near to 0.0 and far
704        to 1.0, this means the effective viewport transform for Z (see
705        section 13.6.1 "Controlling the Viewport") becomes an identity
706        mapping.  So the mapping in GL_ZERO_TO_ONE depth mode is:
707
708            z_w = (f-n)  * z_d + n
709
710        and when near (n) is 0.0 and far (f) is 1.0, this becomes simply:
711
712           z_w = z_d;
713
714        This identity mapping results in no lose or change in the
715        per-vertex window space position.
716
717        Contrast this with the same situation with the
718        GL_NEGATIVE_ONE_TO_ONE depth mode with the mapping:
719
720           z_w =  (f-n)/2 * z_d + (n+f)/2
721
722        and when near (n) is 0.0 and far (f) is 1.0, this becomes simply:
723
724           z_w = 0.5 * z_d + 0.5
725
726        While multiplying z_d by 0.5 has no precision loss (ignoring
727        denorms, this scale simply decrements the exponent by 1 without
728        disturbing the mantissa).  However a bias by 0.5 does distrurb
729        the floating-point precision (also see Issue #3), losing one
730        least-significant-bit (LSB) of precision.
731
732    21) What should the state to control the GL_NEGATIVE_ONE_TO_ONE
733        and GL_ZERO_TO_ONE convention be called?
734
735        RESOLVED:  GL_CLIP_DEPTH_MODE.
736
737        An alternative would be GL_CLIP_Z_MODE but the convention
738        is well-established in the OpenGL API that Z values that are
739        interpreted as depth values are described as DEPTH.
740
741    22) Direct3D 8 and 9 have a window-space coordinate system where
742        pixel centers are centered on integer coordinates.  OpenGL
743        (and Direct3D 10 and 11) position pixel centers at half-pixel
744        locations.  Should ARB_clip_control account for the older Direct3D
745        integer pixel center convention?
746
747        RESOLVED:  No, because existing functionality covers this...
748
749        The EXT_viewport_array extension (made a core part of OpenGL
750        with version 4.1) extends the viewport state to be specified as
751        floating-point (technically fixed-point) values.  Prior to this
752        extension, the viewport parameters were integral.
753
754        With the EXT_viewport_array functionality, you can add a bias of
755        (0.5,0.5) to the viewport (x,y) to shift integer Direct3D 8/9
756        style window space locations to OpenGL's half-pixel convention.
757
758        If you had a Direct3D upper-left viewport (x,y), you'd match
759        the Direct3D clip-space AND window-space conventions like this:
760
761            glClipControl(GL_UPPER_LEFT, GL_ZERO_TO_ONE);
762            const GLuint viewport_index = 0;  // Prior to DirectX 10, there's only a single viewport
763            glViewportIndexedf(viewport_index,
764                x + 0.5f, window_height - (y + view_height) + 0.5f,
765                view_width, view_height);
766
767        where window_height is the height of the window/surface in pixels.
768
769        Also note the EXT_fragment_coord_conventions (made a core part
770        of OpenGL with version 3.2) allows the window position varying
771        input to fragment shaders to reflect the Direct3D 9 window-space
772        convention.  See that extension for details.
773
774    23) Does this extension's state affect user clip planes?
775
776        RESOLVED:  No, user clip planes operate on eye-space coordinates
777        which are not affected by this extension's state.
778
779    24) Does this extension's state affect fixed-function fog?
780
781        RESOLVED:  No, fixed-function fog operates on eye-space distance
782        which is not affected by this extension's state.
783
784    25) Does this extension's state affect the point sprite origin?
785
786        RESOLVED:  No.
787
788        When the EXT_point_sprite functionality was promoted to a core
789        feature in OpenGL 2.0, the GL_POINT_SPRITE_ORIGIN state was added
790        to specify whether the 2D texture coordinate has a lower-left
791        (OpenGL's convention in EXT_point_sprite and NV_point_sprite)
792        or upper-left (Direct3D convention).
793
794        An application wanting to emulate Direct3D's upper-left point
795        sprite texture coordinate origin should change the origin state
796        with an explicit point parameter command.  Specifically:
797
798            glPointParameteri(GL_POINT_SPRITE_ORIGIN, GL_UPPER_LEFT);
799
800        This command is in addition to calling glClipControl and
801        specifying a GL_UPPER_LEFT origin.
802
803    26) Issue #12 says the origin for glWindowPos2i and other glWindowPos*
804        commands is lower-left independent of the clip control state.
805        What about glRasterPos2i and other glRasterPos* commands?
806
807        RESOLVED:  Yes, the raster position specified by glRasterPos2i,
808        etc.  is affected by the clip control state because the
809        object-space position is transformed and clipped just as a point
810        vertex position would be to arrive at the clip-space raster
811        position that is further transformed to window space.
812
813    27) Is the depth value specified for glClearDepth affected by this
814        extension's clip control state?
815
816        RESOLVED:  No, glClearDepth takes a window-space depth value.
817
818        This extension only affects how clip space clipping and the
819        transformation from clip space to window space operates.
820
821        Likewise depth values read (glReadPixels), drawn (glDrawPixels),
822        or copied (glCopyPixels, glBlitFramebuffer) are unaffected by
823        this extension's clip control state.
824
825    28) Does this extension's state affect the operation of polygon
826        offset?
827
828        RESOLVED:  No, polygon offset operates on window-space depth
829        values.  This extension's clip control state operates prior
830        to polygon offset.
831
832    29) Can glClipControl be display listed?
833
834        RESOLVED:  Yes.
835
836    30) Should the command be glClipParameteri to anticipate more
837        control of clipping state?
838
839        RESOLVED:  No.  Given over 20 years with basically zero extensions
840        in the area of clipping state, we realistically don't anticipate
841        more clipping parameters.  Even in the case of this extension, the
842        rationale for this extension is quite limited and not about adding
843        any "features" to clipping.  Instead the purpose is simply to
844        match the conventions of Direct3D (not a functional change).
845        While Direct3D's convention is different from OpenGL, there
846        simply aren't any futher 3D APIs or standards which clip
847        differently.
848
849        Also glClipControl maintains consistency with the existing
850        glClipPlane command pattern for the clipping API.
851
852        Historically "Parameter" has been used for commands that affect
853        managed "object" state and/or have a speciailized "Get" query
854        command (glGetColorTableParameter*) rather than fixed-function
855        pipeline state.  This isn't completely uniform (exceptions:
856        point parameters, patch parameters) but the vast majority of
857        fixed-function rendering state isn't set with gl*Parameter
858        style commands.  When "Parameter" commands are used there
859        is typically a plurality of state settings with different
860        integer/float/double/boolean types.  None of the situations
861        that justify gl*Parameter style commands are present in this
862        extension.
863
864    31) This extension is only useful if it is widely available.  So how
865        easy would this extension be to implement?
866
867        RESOLVED:  No special hardware is required due to the careful
868        way this extension is specified.  The clip control functionality
869        could all be done by inexpensive epilogue math appended to the
870        last shader in the graphics pipeline.  The Y inversion could be
871        performed as part of the viewport transform.
872
873        Given the prevalance of Direct3D-capable hardware, we expect
874        some hardware vendors will implement this extension with
875        special existing modes in their hardware to handle the Direct3D
876        conventions.  However we emphasize no special hardware is required
877        and the performance benefit attributable to such hardware is
878        likely to be extremely meager.
879
880        With respect to Mesa3D and Gallium, Brian Paul observes:  "This
881        extension should be pretty easy to implement in Mesa/gallium.
882        In Gallium we already have a state variable for Z 0/1 vs. -1/+1
883        clipping.  And I think we could implement the Y origin via our
884        viewport state (which is specified in floats)."
885
886    32) Is support for the GL_UPPER_LEFT convention just to match
887        Direct3D/Windows?
888
889        RESOLVED:  No.  Along with Windows/Direct3D/Direct2D, X11 and
890        Java also have upper-left graphics device coordinate systems.
891
892        OpenGL, PostScript, PHIGS, GKS, and Apple's Core Graphics
893        (Quartz 2D) have lower-left graphics device coordinate systems.
894
895    33) When rendering to off-screen framebuffer objects (FBOs) that
896        will subsequently be textured from, how do I make sure the texture
897        coordinate origin and the window space origin are consistent?
898
899        RESOLVED:  Use GL_LOWER_LEFT for the origin parameter of
900        glClipControl in this case.  Use the GL_UPPER_LEFT for the
901        origin parameter when matching Direct3D's origin *and* drawing
902        into a window framebuffer to be directly presented.
903
904    34) Can you provide an example illustrating how applications using the
905        coordinate system conventions of Direct3D map onto this extension?
906
907        RESOLVED:  Consider a Direct3D application rendering a triangle ABC
908        (with counter-clockwise orientation) to a viewport in the upper-left
909        quadrant of the destination surface.  The surface (with Direct3D
910        window coordinates) is illustrated here.
911
912            (0,0)         (960,0)          (1920,0)
913            +------(A)-------+----------------+
914            |^ Y_c == +W_c ^ |                |
915            |                |                |
916            |                |                |
917            |                |                |
918            |v Y_c == -W_c v |                |
919            +-(B)--------(C)-+----------------+
920            |                |                |
921            |                |                |
922            |                |                |
923            |                |                |
924            |                |                |
925            +----------------+----------------+
926            (0,1080)                      (1920,1080)
927
928        In this example, assume vertices A, B, and C have clip coordinates of:
929
930          A = (+0.0, +1.0, +0.5, +1.0)
931          B = (-0.8, -1.0, +0.5, +1.0)
932          C = (+0.8, -1.0, +0.5, +1.0)
933
934        Direct3D's coordinate transformations are functionally similar to
935        OpenGL's, except that (a) the Y coordinate is inverted as part of the
936        viewport transformation mapping normalized device coordinates (NDCs)
937        to window coordinates and (b) the depth range transformation maps Z==0
938        to the near value instead of halfway between near and far as in
939        OpenGL:
940
941          http://msdn.microsoft.com/en-us/library/windows/desktop/
942          bb206341%28v=vs.85%29.aspx
943
944        Because of the Y inversion from (a), vertices in Direct3D with a Y NDC
945        of -1.0 map to the bottom of the viewport (larger Y window coordinates
946        in the Direct3D coordinate system).  This is exactly like OpenGL
947        windowed rendering, where a Y NDC of -1 maps to smaller Y window
948        coordinates (bottom) in the OpenGL coordinate system.  Thanks to this
949        inversion in the Direct3D viewport transformation, rendering a
950        Direct3D scene with the same coordinates and matrices in OpenGL will
951        produce an image with identical vertical orientation and winding
952        (CW/CCW).  However, since the viewport rectangle itself is programmed
953        in window coordinates, a Direct3D-centric viewport of (0,0,960,540)
954        needs to be flipped to (0,540,960,540) to work in OpenGL.
955        Additionally, to get identical near/far clipping and Z values, it's
956        necessary to use the ZERO_TO_ONE mode in this extension to have OpenGL
957        process Z coordinates identically to Direct3D.
958
959        When rendering to off-screen surfaces later used as textures, the
960        issue is a little bit more complex.  A Direct3D application will use
961        the texture coordinates (0,0) to refer to the upper left corner of the
962        upper leftmost pixel of the image.  However, in OpenGL, texture
963        coordinates of (0,0) refer to the lower-left corner of the
964        lower-leftmost pixel of the image.  One way to compensate for this is
965        to remap the <t> texture coordinate with:
966
967          t_OpenGL = 1.0 - t_Direct3D
968
969        Unfortunately, that requires a modification to shaders or other input
970        data in the application.  Instead of doing this, the UPPER_LEFT mode
971        in this extension provides a simple way to use Direct3D texture
972        coordinate conventions -- by rendering the entire scene *upside-down*
973        from the point of view of OpenGL.  The image we want to produce using
974        this technique (below) is a vertically inverted version of the
975        previous image, where OpenGL lower-left window coordinates are
976        depicted in the figure.
977
978            (0,1080)                      (1920,1080)
979            +----------------+----------------+
980            |                |                |
981            |                |                |
982            |                |                |
983            |                |                |
984            |                |                |
985            +-(B)--------(C)-+----------------+
986            |v Y_c == -W_c v |                |
987            |                |                |
988            |                |                |
989            |                |                |
990            |^ Y_c == +W_c ^ |                |
991            +------(A)-------+----------------+
992            (0,0)         (960,0)          (1920,0)
993
994        In this example, the UPPER_LEFT mode in this extension inverts the
995        geometry as part of the transformation from clip coordinates to NDCs,
996        so that vertex A has a Y NDC of -1.0 instead of +1.0.  This puts A at
997        the bottom of the viewport, while B and C remain at the top.  One
998        thing to note is that the inversion changes the orientation of
999        triangle ABC, which is now clockwise instead of counter-clockwise.  To
1000        compensate, this extension also inverts the value computed to compute
1001        face direction when in UPPER_LEFT mode.  The one other thing to note
1002        here is that when rendering this way, the Direct3D viewport should be
1003        used as-is in OpenGL.
1004
1005        Note that a similar inversion technique can be used to implement
1006        OpenGL FBO rendering on graphics hardware supporting only Direct3D
1007        coordinate systems.  If this technique is used on an implementation
1008        doing something like this, the two inversions cancel each other out.
1009
1010    35) Does this extension affect the primitive's winding order in tessellation
1011        evaluation shader when origin is changed to GL_UPPER_LEFT?
1012
1013        RESOLVED:  No, the winding order is not affected. If a change in winding
1014        order of the primitive is needed, it must be done from the tessellation
1015        shader explicitly.
1016
1017Revision History
1018
1019    Rev.    Date    Author     Changes
1020    ----  -------- ---------  ----------------------------------------------
1021    3     04/26/13 mjk        Add issues 15 to 21
1022                              Change CLIP_Z_MODE to CLIP_DEPTH_MODE
1023    4     04/30/13 mjk        Add issue 22
1024    5     05/01/13 mjk        Add issues 22 to 28, fix typos
1025    6     05/09/13 mjk        Add issue 29 to 31
1026    7     05/13/13 pdaniell   Internal revisions
1027    8     05/13/13 mjk        Valve feedback; change to KHR in issues
1028    9     05/13/13 mjk        Change to KHR in issues
1029    10    05/28/13 pdaniell   Fold in feedback from Mark Callow in bug 10245
1030    11    05/30/13 pdaniell   Internal revisions
1031    12    06/06/13 pdaniell   Internal revisions
1032    13    06/17/13 pdaniell   Fix the enum token values
1033    14    07/03/13 mjk        D3D off-screen discussion; issue 32 and 33
1034    15    04/16/14 pdaniell   Prepare spec for OpenGL 4.5
1035    16    04/17/14 pdaniell   Fixes "UPPER_RIGHT" typos to UPPER_LEFT
1036    17    07/30/14 pbrown     Fix incorrect language in the overview
1037                              describing when to use UPPER_LEFT and LOWER_LEFT
1038                              modes; add detailed examples in issue 34.
1039    18    09/17/15 Jon Leech  Correct typo in issue 7 and add contributor
1040                              Brano Kemen from that issue.
1041    19    04/06/18 Vikram     Add issue 35
1042