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