| Name |
| |
| OES_viewport_array |
| |
| Name Strings |
| |
| GL_OES_viewport_array |
| |
| Contributors |
| |
| Contributors to NV_viewport_array |
| Daniel Koch, NVIDIA |
| Jeff Leger, Qualcomm |
| |
| Contact |
| |
| Tobias Hector, Imagination Technologies (tobias.hector 'at' imgtec.com) |
| |
| Notice |
| |
| Copyright (c) 2010-2016 The Khronos Group Inc. Copyright terms at |
| http://www.khronos.org/registry/speccopyright.html |
| |
| Specification Update Policy |
| |
| Khronos-approved extension specifications are updated in response to |
| issues and bugs prioritized by the Khronos OpenGL ES Working Group. For |
| extensions which have been promoted to a core Specification, fixes will |
| first appear in the latest version of that core Specification, and will |
| eventually be backported to the extension document. This policy is |
| described in more detail at |
| https://www.khronos.org/registry/OpenGL/docs/update_policy.php |
| |
| Status |
| |
| Approved by the OpenGL ES Working Group on April 20, 2016 |
| Ratified by the Khronos Board of Promoters on July 22, 2016 |
| |
| Version |
| |
| Last Modified Date: 2016/04/19 |
| Author Revision: 5 |
| |
| Number |
| |
| Open GL ES Extension #267 |
| |
| Dependencies |
| |
| OpenGL ES 3.2, EXT_geometry_shader or OES_geometry_shader is required. |
| |
| This extension is written against the OpenGL ES 3.2 Specification (August |
| 10, 2015) |
| |
| This extension is written against the OpenGL ES Shading Language 3.20.2 |
| Specification (August 6, 2015) |
| |
| This extension has interactions with EXT_draw_buffers_indexed, OES_draw_buffers_indexed and ES3.2 |
| |
| Overview |
| |
| OpenGL ES is modeled on a pipeline of operations. The final stage in this |
| pipeline before rasterization is the viewport transformation. This stage |
| transforms vertices from view space into window coordinates and allows the |
| application to specify a rectangular region of screen space into which |
| OpenGL ES should draw primitives. Unextended OpenGL ES implementations provide a |
| single viewport per context. In order to draw primitives into multiple |
| viewports, the OpenGL ES viewport may be changed between several draw calls. |
| With the advent of Geometry Shaders, it has become possible for an |
| application to amplify geometry and produce multiple output primitives |
| for each primitive input to the Geometry Shader. It is possible to direct |
| these primitives to render into a selected render target. However, all |
| render targets share the same, global OpenGL ES viewport. |
| |
| This extension enhances OpenGL ES by providing a mechanism to expose multiple |
| viewports. Each viewport is specified as a rectangle. The destination |
| viewport may be selected per-primitive by the geometry shader. This allows |
| the Geometry Shader to produce different versions of primitives destined |
| for separate viewport rectangles on the same surface. Additionally, when |
| combined with multiple framebuffer attachments, it allows a different |
| viewport rectangle to be selected for each. This extension also exposes a |
| separate scissor rectangle for each viewport. Finally, the viewport bounds |
| are now floating point quantities allowing fractional pixel offsets to be |
| applied during the viewport transform. |
| |
| IP Status |
| |
| No known IP claims. |
| |
| New Procedures and Functions |
| |
| void ViewportArrayvOES(uint first, sizei count, const float * v); |
| void ViewportIndexedfOES(uint index, float x, float y, float w, float h); |
| void ViewportIndexedfvOES(uint index, const float * v); |
| void ScissorArrayvOES(uint first, sizei count, const int * v); |
| void ScissorIndexedOES(uint index, int left, int bottom, sizei width, sizei height); |
| void ScissorIndexedvOES(uint index, const int * v); |
| void DepthRangeArrayfvOES(uint first, sizei count, const float * v); |
| void DepthRangeIndexedfOES(uint index, float n, float f); |
| void GetFloati_vOES(enum target, uint index, float *data); |
| |
| [[If none of OpenGL ES 3.2, EXT_draw_buffers_indexed or OES_draw_buffers_indexed are supported]] |
| void EnableiOES(enum target, uint index); |
| void DisableiOES(enum target, uint index); |
| boolean IsEnablediOES(enum target, uint index); |
| |
| New Tokens |
| |
| Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv, |
| and GetInteger64v: |
| |
| MAX_VIEWPORTS_OES 0x825B |
| VIEWPORT_SUBPIXEL_BITS_OES 0x825C |
| VIEWPORT_BOUNDS_RANGE_OES 0x825D |
| VIEWPORT_INDEX_PROVOKING_VERTEX_OES 0x825F |
| |
| Accepted by the <pname> parameter of GetIntegeri_v: |
| |
| SCISSOR_BOX 0x0C10 |
| |
| Accepted by the <pname> parameter of GetFloati_vOES: |
| |
| VIEWPORT 0x0BA2 |
| DEPTH_RANGE 0x0B70 |
| |
| Accepted by the <pname> parameter of Enablei, Disablei, and IsEnabledi: |
| |
| SCISSOR_TEST 0x0C11 |
| |
| Additions to Chapter 11 of the OpenGL ES 3.2 Specification (Programmable Vertex |
| Post-Processing) |
| |
| Modifications to Section 11.3.4.5, Layer Selection |
| |
| Rename the section to "Layer and Viewport Selection". |
| |
| Add the following paragraph after the first paragraph: |
| |
| Geometry shaders may also select the destination viewport for each |
| output primitive. The destination viewport for a primitive may be |
| selected in the geometry shader by writing to the built-in output |
| variable gl_ViewportIndex. This functionality allows a geometry |
| shader to direct its output to a different viewport for each |
| primitive, or to draw multiple versions of a primitive into several |
| different viewports. |
| |
| Replace the first two sentences of the last paragraph with: |
| |
| The specific vertex of a primitive that is used to select the |
| rendering layer or viewport index is implementation-dependent and |
| thus portable applications will assign the same layer and viewport |
| index for all vertices in a primitive. The vertex conventions |
| followed for gl_Layer and gl_ViewportIndex may be determined by |
| calling GetIntegerv with the symbolic constants |
| LAYER_PROVOKING_VERTEX and VIEWPORT_INDEX_PROVOKING_VERTEX_OES, |
| respectively. |
| |
| Additions to Chapter 12 of the OpenGL ES 3.2 Specification (Fixed-Function |
| Vertex Post-Processing) |
| |
| Modifications to section 12.5.1 "Controlling the Viewport" |
| |
| Replace the entire section to read: |
| |
| The viewport transformation is determined by the selected viewport's |
| width and height in pixels, p_x and p_y, respectively, and its |
| center (o_x,o_y) (also in pixels) ... |
| |
| { leave equations intact } |
| |
| Multiple viewports are available and are numbered zero through the |
| value of MAX_VIEWPORTS_OES minus one. If a geometry shader is active |
| and writes to gl_ViewportIndex, the viewport transformation uses the |
| viewport corresponding to the value assigned to gl_ViewportIndex |
| taken from an implementation-dependent primitive vertex. If the |
| value of the viewport index is outside the range zero to the value |
| of MAX_VIEWPORTS_OES minus one, the results of the viewport |
| transformation are undefined. If no geometry shader is active, or if |
| the active geometry shader does not write to gl_ViewportIndex, the |
| viewport numbered zero is used by the viewport transformation. |
| |
| A single vertex may be used in more than one individual primitive, in |
| primitives such as TRIANGLE_STRIP. In this case, the viewport |
| transformation is applied separately for each primitive. |
| |
| The factor and offset applied to Z_d for each viewport encoded by n |
| and f are set using |
| |
| void DepthRangeArrayfvOES(uint first, sizei count, const float * v); |
| void DepthRangeIndexedfOES(uint index, float n, float f); |
| void DepthRangef(float n, float f); |
| |
| DepthRangeArrayfvOES is used to specify the depth range for multiple |
| viewports simultaneously. <first> specifies the index of the first |
| viewport to modify and <count> specifies the number of viewports. |
| Viewports whose indices lie outside the range [<first>, <first> + <count>) |
| are not modified. The <v> parameter contains the address of an array of |
| float types specifying near (n) and far (f) for each viewport in that |
| order. Values in <v> and the parameters <n> and <f> are clamped to |
| the range [0, 1] when specified. |
| |
| DepthRangeIndexedfOES specifies the depth range for a single viewport |
| and is equivalent (assuming no errors are generated) to: |
| |
| float v[] = { n, f }; |
| DepthRangeArrayfvOES(index, 1, v); |
| |
| DepthRangef sets the depth range for all viewports to the same values |
| and is equivalent (assuming no errors are generated) to: |
| |
| for (uint i = 0; i < MAX_VIEWPORTS_OES; i++) |
| DepthRangeIndexedfOES(i, n, f); |
| |
| Z_w is represented as either ... |
| |
| Errors |
| |
| An INVALID_VALUE error is generated if the sum of <first> and <count> is |
| greater than the value of MAX_VIEWPORTS_OES. |
| |
| An INVALID_VALUE error is generated if <count> is negative. |
| |
| An INVALID_VALUE error is generated if <index> is greater than or equal to |
| the value of MAX_VIEWPORTS_OES. |
| |
| Viewport transformation parameters are specified using |
| |
| void ViewportArrayvOES(uint first, sizei count, const float * v); |
| void Viewport(int x, int y, sizei w, sizei h); |
| void ViewportIndexedfOES(uint index, float x, float y, float w, float h); |
| void ViewportIndexedfvOES(uint index, const float * v); |
| |
| ViewportArrayvOES specifies parameters for multiple viewports |
| simultaneously. <first> specifies the index of the first viewport to |
| modify and <count> specifies the number of viewports. Viewports whose |
| indices lie outside the range [<first>, <first> + <count>) are not modified. |
| <v> contains the address of an array of floating point values |
| specifying the left (x), bottom (y), width (w) and height (h) of |
| each viewport, in that order. <x> and <y> give the location of the |
| viewport's lower left corner and <w> and <h> give the viewport's |
| width and height, respectively. |
| |
| ViewportIndexedfOES and ViewportIndexedfvOES specify parameters for a |
| single viewport and are equivalent (assuming no errors are |
| generated) to: |
| |
| float v[4] = { x, y, w, h }; |
| ViewportArrayvOES(index, 1, v); |
| |
| and |
| |
| ViewportArrayvOES(index, 1, v); |
| |
| respectively. |
| |
| Viewport sets the parameters for all viewports to the same values |
| and is equivalent (assuming no errors are generated) to: |
| |
| for (uint i = 0; i < MAX_VIEWPORTS_OES; i++) |
| ViewportIndexedfOES(i, (float)x, (float)y, (float)w, (float)h); |
| |
| The viewport parameters shown in the above equations are found from these |
| values as |
| |
| o_x = x + w /2, |
| o_y = y + h / 2, |
| p_x = w, |
| p_y = h. |
| |
| The location of the viewport's bottom-left corner, given by (x,y), are |
| clamped to be within the implementation-dependent viewport bounds range. |
| The viewport bounds range [min, max] tuple may be determined by |
| calling GetFloatv with the symbolic constant VIEWPORT_BOUNDS_RANGE_OES |
| (see chapter 20). |
| |
| Viewport width and height are clamped to implementation-dependent maximums |
| when specified. The maximum width and height may be found by calling |
| GetFloatv with the symbolic constant MAX_VIEWPORT_DIMS. The maximum |
| viewport dimensions must be greater than or equal to the larger of |
| the visible dimensions of the display being rendered to (if a |
| display exists), and the largest renderbuffer image which can be |
| successfully created and attached to a framebuffer object (see |
| chapter 9). |
| |
| Errors |
| |
| An INVALID_VALUE error is generated if the sum of <first> and <count> is |
| greater than the value of MAX_VIEWPORTS_OES. |
| |
| An INVALID_VALUE error is generated if <count> is negative>. |
| |
| An INVALID_VALUE error is generated if <index> is greater than or equal to |
| the value of MAX_VIEWPORTS_OES. |
| |
| An INVALID_VALUE error is generated if any <w> or <h> value is negative. |
| |
| The state required to implement the viewport transformations is four |
| floating-point values and two clamped floating-point values for each |
| viewport. In the initial state, w and h for each viewport are set to |
| the width and height, respectively, of the window into which the GL |
| is to do its rendering. If the default framebuffer is bound but no |
| default framebuffer is associated with the GL context (see chapter |
| 9), then w and h are initially set to zero. o_x and o_y are set to |
| w/2 and h/2, respectively. n and f are set to 0.0 and 1.0, |
| respectively. |
| |
| The precision with which the GL interprets the floating point viewport |
| bounds is implementation-dependent and may be determined by querying the |
| implementation-defined constant VIEWPORT_SUBPIXEL_BITS_OES. |
| |
| Additions to Chapter 13 of the OpenGL ES 3.2 Specification (Fixed-Function |
| Primitive Assembly and Rasterization) |
| |
| Replace section 13.8.2 "Scissor Test" with the following: |
| |
| The scissor test determines if (x_w, y_w) lies within the scissor rectangle |
| defined by four values for each viewport. These values are set with |
| |
| void ScissorArrayvOES(uint first, sizei count, const int * v); |
| void ScissorIndexedOES(uint index, int left, int bottom, sizei width, sizei height); |
| void ScissorIndexedvOES(uint index, int * v); |
| void Scissor(int left, int bottom, sizei width, sizei height); |
| |
| ScissorArrayvOES defines a set of scissor rectangles that are each |
| applied to the corresponding viewport (see section 12.5.1 |
| "Controlling the Viewport"). <first> specifies the index of the |
| first scissor rectangle to modify, and <count> specifies the number |
| of scissor rectangles. <v> contains the address of an array of |
| integers containing the left, bottom, width and height of the |
| scissor rectangles, in that order. |
| |
| If left <= x_w < left + width and bottom <= y_w < bottom + height |
| for the selected scissor rectangle, then the scissor test passes. |
| Otherwise, the test fails and the fragment is discarded. For points, |
| lines, and polygons, the scissor rectangle for a primitive is |
| selected in the same manner as the viewport (see section 12.5.1). |
| |
| The scissor test is enabled or disabled for all viewports using |
| Enable or Disable with the symbolic constant SCISSOR_TEST. The test |
| is enabled or disabled for a specific viewport using Enablei or |
| Disablei with the constant SCISSOR_TEST and the index of the |
| selected viewport. When disabled, it is as if the scissor test |
| always passes. The value of the scissor test enable for viewport <i> |
| can be queried by calling IsEnabledi with <target> SCISSOR_TEST and |
| <index> <i>. The value of the scissor test enable for viewport zero |
| may also be queried by calling IsEnabled with the same <target>, |
| but no <index> parameter. |
| |
| ScissorIndexedOES and ScissorIndexedvOES specify the scissor rectangle for |
| a single viewport and are equivalent (assuming no errors are |
| generated) to: |
| |
| int v[] = { left, bottom, width, height }; |
| ScissorArrayvOES(index, 1, v); |
| |
| and |
| |
| ScissorArrayvOES(index, 1, v); |
| |
| respectively. |
| |
| Scissor sets the scissor rectangle for all viewports to the same |
| values and is equivalent (assuming no errors are generated) to: |
| |
| for (uint i = 0; i < MAX_VIEWPORTS_OES; i++) { |
| ScissorIndexedOES(i, left, bottom, width, height); |
| } |
| |
| Calling Enable or Disable with <target> SCISSOR_TEST is |
| equivalent, assuming no errors, to: |
| |
| for (uint i = 0; i < MAX_VIEWPORTS_OES; i++) { |
| Enablei(SCISSOR_TEST, i); |
| /* or */ |
| Disablei(SCISSOR_TEST, i); |
| } |
| |
| Errors |
| |
| An INVALID_VALUE error is generated if the sum of <first> and <count> is |
| greater than the value of MAX_VIEWPORTS_OES. |
| |
| An INVALID_VALUE error is generated if <index> is greater than or equal to |
| the value of MAX_VIEWPORTS_OES. |
| |
| An INVALID_VALUE error is generated if any <width> or <height> value is |
| negative. |
| |
| The state required consists of four integer values per viewport, and |
| a bit indicating whether the test is enabled or disabled for each |
| viewport. In the initial state, left = bottom = 0, and width and |
| height are determined by the size of the window into which the GL is |
| to do its rendering for all viewports. If the default framebuffer is |
| bound but no default framebuffer is associated with the GL context |
| (see chapter 9), then with and height are initially set to zero. |
| Initially, the scissor test is disabled for all viewports. |
| |
| Additions to Chapter 20 of the OpenGL ES 3.2 Specification (Context State |
| Queries) |
| |
| Modifications to Section 20.1 Simple Queries |
| |
| Add to the list of indexed query functions: |
| |
| void GetFloati_vOES(enum target, uint index, float *data); |
| |
| Additions to Chapter 3 of the OpenGL ES Shading Language Specification |
| |
| Add a new Section 3.4.x, GL_OES_viewport_array Extension |
| |
| 3.4.x GL_OES_viewport_array Extension |
| |
| To use the GL_OES_viewport_array extension in a shader it must be |
| enabled using the #extension directive. |
| |
| The shading language preprocessor #define GL_OES_viewport_array will |
| be defined to 1 if the GL_OES_viewport_array extension is supported. |
| |
| Additions to Chapter 7 of the OpenGL ES Shading Language Specification |
| |
| Add the following built-in to section 7.1.4, Geometry Shader Special |
| Variables: |
| |
| out highp int gl_ViewportIndex; |
| |
| Add the following paragraph to the end of Section 7.1.4.2, Geometry Shader |
| Output Variables: |
| |
| gl_ViewportIndex provides the index of the viewport to which the next |
| primitive emitted from the geometry shader should be drawn. Primitives |
| generated by the geometry shader will undergo viewport transformation and |
| scissor scissor testing using the viewport transformation and scissor |
| rectangle selected by the value of gl_ViewportIndex. |
| The viewport index used will come from one of the |
| vertices in the primitive being shaded. Which vertex the viewport index |
| comes from is determined as discussed in section 11.3.4.5 of the OpenGL ES |
| Specification, but may be undefined, so it is best to write the same |
| viewport index for all vertices of the primitive. If a geometry shader does |
| not assign a value to gl_ViewportIndex, viewport transform and scissor |
| rectangle zero will be used. If a geometry shader statically assigns a value to |
| gl_ViewportIndex and there is a path through the shader that does not set |
| gl_ViewportIndex, then the value of gl_ViewportIndex is undefined for |
| executions of the shader that take that path. See section 11.3.4.5 "Layer |
| and Viewport Selection" of the OpenGL ES Specification for more information. |
| |
| Add the following build-in to section 7.1.5 "Fragment Shader Special |
| Variables: |
| |
| in highp int gl_ViewportIndex; |
| |
| Add the following paragraph to the end of section 7.1.5 "Fragment Shader |
| Special Variables: |
| |
| The input variable gl_ViewportIndex will have the same value that was |
| written to the output variable gl_ViewportIndex in the geometry stage. If |
| the geometry stage does not dynamically assign to gl_ViewportIndex, the |
| value of gl_ViewportIndex in the fragment shader will be undefined. If the |
| geometry stage makes no static assignment to gl_ViewportIndex, the value |
| in the fragment stage is undefined. Otherwise, the fragment stage will read |
| the same value written by the geometry stage, even if that value is out of |
| range. If a fragment shader contains a static access to gl_ViewportIndex, |
| it will count against the implementation defined limit for the maximum |
| number of inputs to the fragment stage. |
| |
| Add the following built-in to section 7.2 "Built-In Constants": |
| |
| const highp int gl_MaxViewports = 16; |
| |
| Errors |
| |
| INVALID_VALUE is generated by ViewportArrayvOES if <first> + <count> is |
| greater than or equal to the value of MAX_VIEWPORTS_OES, or if any |
| viewport's width or height is less than 0. |
| |
| INVALID_VALUE is generated by ScissorArrayvOES if <first> + <count> is |
| greater than or equal to the value of MAX_VIEWPORTS_OES, or if any |
| scissor rectangle's width or height is less than zero. |
| |
| INVALID_VALUE is generated by DepthRangeArrayfvOES if <first> + <count> is |
| greater than or equal to the vaue of MAX_VIEWPORTS_OES. |
| |
| An INVALID_VALUE error is generated by Enablei, Disablei and IsEnabledi if |
| <target> is SCISSOR_TEST and <index> is greater than or equal to the value |
| of MAX_VIEWPORTS_OES |
| |
| New State |
| |
| Table 21.6: |
| |
| Get Value Type Get Command Initial Value Description Sec |
| ------------------------ ---------------- -------------- ------------- ------------------------ ----- |
| VIEWPORT 16* x 4 x R GetFloati_vOES See 12.5.1 Viewport origin & extent 12.5.1 |
| DEPTH_RANGE 16* x 2 x R[0,1] GetFloati_vOES See 12.5.1 Depth range near & far 12.5.1 |
| |
| NOTE: The changes are that VIEWPORT and DEPTH_RANGE are extended to |
| accommodate 16* copies. Viewport now consists of floating-point values. |
| |
| Table 21.13: |
| |
| Get Value Type Get Command Initial Value Description Sec |
| ------------------------ ---------- ------------- ------------- ------------------- ------ |
| SCISSOR_TEST 16* x B IsEnabledi FALSE Scissoring enabled 13.8.2 |
| SCISSOR_BOX 16* x 4 x Z GetIntegeri_v See 13.8.2 Scissor box 13.8.2 |
| |
| NOTE: The only change is that SCISSOR_TEST and SCISSOR_BOX are extended |
| to accommodate 16* copies. |
| |
| New Implementation Dependent State |
| |
| Get Value Type Get Command Minimum Value Description Sec. |
| --------- ---- ----------- ------------- ------------------- ----- |
| MAX_VIEWPORT_DIMS (NOTE 1) 2 x Z+ GetFloatv See 12.5.1 Maximum viewport dimensions 12.5.1 |
| MAX_VIEWPORTS_OES Z+ GetIntegerv 16 Maximum number of 12.5.1 |
| active viewports |
| VIEWPORT_SUBPIXEL_BITS_OES Z+ GetIntegerv 0 Number of bits of sub-pixel 12.5.1 |
| precision for viewport bounds |
| VIEWPORT_BOUNDS_RANGE_OES 2 x R GetFloatv [-32768, 32767] Viewport bounds range [min,max] 12.5.1 |
| VIEWPORT_INDEX_PROVOKING_VERTEX_OES Z_4 GetIntegerv -- (NOTE 2) vertex convention followed by 12.5.1 |
| the gl_ViewportIndex GLSL |
| variable |
| |
| NOTE 1: The recommended get command is changed from GetIntegerv to GetFloatv. |
| NOTE 2: Valid values are: FIRST_VERTEX_CONVENTION, |
| LAST_VERTEX_CONVENTION, PROVOKING_VERTEX, UNDEFINED_VERTEX. |
| |
| Interactions with EXT_draw_buffers_indexed, OES_draw_buffers_indexed and OpenGL ES 3.2 |
| |
| If EXT_draw_buffers_indexed is supported, EnableiEXT, DisableiEXT and |
| IsEnablediEXT can be used in place of their core counterparts. |
| |
| If only EXT_draw_buffers_indexed is supported, replace all mentions |
| of Enablei, Disablei and IsEnabledi with their EXT suffixed counterparts. |
| |
| If OES_draw_buffers_indexed is supported, EnableiOES, DisableiOES and |
| IsEnablediOES can be used in place of their core counterparts. |
| |
| If only OES_draw_buffers_indexed is supported, replace all mentions |
| of Enablei, Disablei and IsEnabledi with their OES suffixed counterparts. |
| |
| If none of these are supported, then the EnableiOES, DisableiOES and |
| IsEnablediOES functions are added, with exactly the same specification as |
| the equivalently named core functions in OpenGL ES 3.2. Replace all mentions |
| of Enablei, Disablei and IsEnabledi with their OES suffixed counterparts. |
| |
| Issues |
| |
| See issues section in ARB_viewport_array. |
| |
| #1 What are the differences from ARB_viewport_array? |
| |
| - OpenGL ES does not support the double datatype. The changed interfaces of |
| glDepthRangeArrayfvOES and DepthRangeIndexedfOES reflect that. 'float' is |
| being used instead of 'clampf', with additional constraints in the text |
| that the values will get clamped. |
| - The ability to access gl_ViewportIndex from the fragment shader was added |
| from ARB_fragment_layer_viewport. |
| - Unlike ARB_fragment_layer_viewport, the value of gl_ViewportIndex is undefined |
| if it wasn't written by the geometry shader. |
| |
| |
| Revision History |
| |
| Rev. Date Author Changes |
| ---- -------- -------- ----------------------------------------- |
| 1 10/12/2015 thector Initial draft |
| 2 23/03/2016 thector Changed to EXT |
| 3 06/04/2016 thector Made gl_ViewportIndex undefined in a fragment shader if not previously written |
| 4 13/04/2016 thector Changed to OES |
| Added interactions with OES_draw_buffers_indexed |
| Allowed dependency on OES_geometry_shader as well as EXT_geometry_shader |
| 5 19/04/2016 dkoch Typographical fixes. |
| Sync some additional language with GL 4.5 and GLSL 4.50. |