1Name 2 3 EXT_instanced_arrays 4 5Name Strings 6 7 GL_EXT_instanced_arrays 8 9Contributors 10 11 Contributors to ARB_instanced_arrays desktop OpenGL extension 12 from which this extension borrows heavily 13 Abhijit Bhelande, Apple 14 Benj Lipchak, Apple 15 16Contact 17 18 Benj Lipchak, Apple (lipchak 'at' apple.com) 19 20Status 21 22 Complete 23 24Version 25 26 Last Modified Date: June 26, 2013 27 Revision: 2 28 29Number 30 31 OpenGL ES Extension #156 32 33Dependencies 34 35 OpenGL ES 2.0 is required. 36 37 This extension is written against the OpenGL ES 2.0 Specification. 38 39 OES_element_index_uint affects the definition of this extension. 40 41Overview 42 43 A common use case in GL for some applications is to be able to 44 draw the same object, or groups of similar objects that share 45 vertex data, primitive count and type, multiple times. This 46 extension provides a means of accelerating such use cases while 47 reducing the number of API calls, and keeping the amount of 48 duplicate data to a minimum. 49 50 This extension introduces an array "divisor" for generic 51 vertex array attributes, which when non-zero specifies that the 52 attribute is "instanced." An instanced attribute does not 53 advance per-vertex as usual, but rather after every <divisor> 54 conceptual draw calls. 55 56 (Attributes which aren't instanced are repeated in their entirety 57 for every conceptual draw call.) 58 59 By specifying transform data in an instanced attribute or series 60 of instanced attributes, vertex shaders can, in concert with the 61 instancing draw calls, draw multiple instances of an object with 62 one draw call. 63 64IP Status 65 66 No known IP claims. 67 68New Tokens 69 70 Accepted by the <pname> parameters of GetVertexAttribfv and 71 GetVertexAttribiv: 72 73 VERTEX_ATTRIB_ARRAY_DIVISOR_EXT 0x88FE 74 75New Procedures and Functions 76 77 void VertexAttribDivisorEXT(uint index, uint divisor); 78 void DrawArraysInstancedEXT(enum mode, int first, sizei count, 79 sizei instanceCount); 80 void DrawElementsInstancedEXT(enum mode, sizei count, enum type, 81 const void *indices, sizei instanceCount); 82 83Additions to Chapter 2 of the OpenGL ES 2.0 Specification 84 85 Modify section 2.8 (Vertex Arrays), p. 21 86 87 (insert before section Transferring Array Elements, p. 21) 88 89 "The command 90 91 void VertexAttribDivisorEXT(uint index, uint divisor); 92 93 modifies the rate at which generic vertex attributes advance, which is 94 useful when rendering multiple instances of primitives in a single draw call 95 (see DrawArraysInstancedEXT and DrawElementsInstancedEXT below). If 96 <divisor> is zero, the attribute at slot <index> advances once per vertex. 97 If <divisor> is non-zero, the attribute advances once per <divisor> 98 instances of the primitives being rendered. An attribute is referred to as 99 instanced if its <divisor> value is non-zero. 100 101 An INVALID_VALUE error is generated if <index> is greater than or equal to 102 the value of MAX_VERTEX_ATTRIBS." 103 104 (replace all occurrences of "DrawArrays or DrawElements" with "DrawArrays, 105 DrawElements, or the other Draw* commands", for example the first sentence 106 of Transferring Array Elements, p. 21) 107 108 "When an array element i is transferred to the GL by DrawArrays, 109 DrawElements, or the other Draw* commands described below, each generic 110 attribute is expanded to four components." 111 112 (replace second through fourth paragraphs of Transferring Array Elements) 113 114 "The command 115 116 void DrawArraysOneInstance(enum mode, int first, sizei count, 117 int instance); 118 119 does not exist in the GL, but is used to describe functionality in the rest 120 of this section. This command constructs a sequence of geometric primitives 121 by successively transferring elements for <count> vertices. Elements <first> 122 through <first> + <count> − 1 of each enabled non-instanced array are 123 transferred to the GL. <mode> specifies what kind of primitives are 124 constructed, as defined in section 2.6.1. 125 126 If an enabled vertex attribute array is instanced (it has a non-zero 127 <divisor> as specified by VertexAttribDivisorEXT), the element that is 128 transferred to the GL, for all vertices, is given by: 129 130 floor(instance / divisor) 131 132 If an array corresponding to a generic attribute is not enabled, then the 133 corresponding element is taken from the current generic attribute state (see 134 section 2.7). Otherwise, if an array is enabled, the corresponding current 135 generic attribute value is unaffected by the execution of 136 DrawArraysOneInstance. 137 138 Specifying <first> < 0 results in undefined behavior. Generating the error 139 INVALID_VALUE is recommended in this case. 140 141 The command 142 143 void DrawArrays(enum mode, int first, sizei count); 144 145 is equivalent to the command sequence 146 147 DrawArraysOneInstance(mode, first, count, 0); 148 149 The command 150 151 void DrawArraysInstancedEXT(enum mode, int first, sizei count, 152 sizei instanceCount); 153 154 behaves identically to DrawArrays except that <instanceCount> instances of 155 the range of elements are executed and the value of <instance> advances 156 for each iteration. Those attributes that have non-zero values for 157 <divisor>, as specified by VertexAttribDivisorEXT, advance once every 158 <divisor> instances. It has the same effect as: 159 160 if (mode, count, or instanceCount is invalid) 161 generate appropriate error 162 else { 163 for (i = 0; i < instanceCount; i++) { 164 DrawArraysOneInstance(mode, first, count, i); 165 } 166 } 167 168 The command 169 170 void DrawElementsOneInstance(enum mode, sizei count, enum type, 171 const void *indices, int instance); 172 173 does not exist in the GL, but is used to describe functionality in the rest 174 of this section. This command constructs a sequence of geometric primitives 175 by successively transferring elements for <count> vertices. The ith element 176 transferred by DrawElementsOneInstance will be taken from element 177 <indices>[i] of each enabled non-instanced array, where <indices> specifies 178 the location in memory of the first index of the element array being 179 specified. <type> must be one of UNSIGNED_BYTE, UNSIGNED_SHORT, or 180 UNSIGNED_INT indicating that the index values are of GL type ubyte, ushort, 181 or uint respectively. <mode> specifies what kind of primitives are 182 constructed, as defined in section 2.6.1. 183 184 If an enabled vertex attribute array is instanced (it has a non-zero 185 <divisor> as specified by VertexAttribDivisorEXT), the element that is 186 transferred to the GL, for all vertices, is given by: 187 188 floor(instance / divisor) 189 190 If an array corresponding to a generic attribute is not enabled, then the 191 corresponding element is taken from the current generic attribute state (see 192 section 2.7). Otherwise, if an array is enabled, the corresponding current 193 generic attribute value is unaffected by the execution of 194 DrawElementsOneInstance. 195 196 The command 197 198 void DrawElements(enum mode, sizei count, enum type, 199 const void *indices); 200 201 behaves identically to DrawElementsOneInstance with the <instance> 202 parameter set to zero; the effect of calling 203 204 DrawElements(mode, count, type, indices); 205 206 is equivalent to the command sequence: 207 208 if (mode, count or type is invalid) 209 generate appropriate error 210 else 211 DrawElementsOneInstance(mode, count, type, indices, 0); 212 213 The command 214 215 void DrawElementsInstancedEXT(enum mode, sizei count, enum type, 216 const void *indices, sizei instanceCount); 217 218 behaves identically to DrawElements except that <instanceCount> instances of 219 the set of elements are executed and the value of <instance> advances 220 between each set. Instanced attributes are advanced as they do during 221 execution of DrawArraysInstancedEXT. It has the same effect as: 222 223 if (mode, count, instanceCount, or type is invalid) 224 generate appropriate error 225 else { 226 for (int i = 0; i < instanceCount; i++) { 227 DrawElementsOneInstance(mode, count, type, indices, i); 228 } 229 } 230 231 (append to first sentence of last paragraph of Transferring Array Elements) 232 233 "..., and n integers representing vertex attribute divisors." 234 235 (append to last sentence of last paragraph of Transferring Array Elements) 236 237 "..., the divisors are each zero." 238 239Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State 240Requests) 241 242 In section 6.1.8, add to the list of pnames accepted by GetVertexAttrib*v: 243 VERTEX_ATTRIB_ARRAY_DIVISOR_EXT 244 245Dependencies on OES_element_index_uint 246 247 If OES_element_index_uint is not supported, remove references to 248 UNSIGNED_INT as a valid <type> for DrawElements*. 249 250Errors 251 252 INVALID_VALUE is generated by VertexAttribDivisorEXT if <index> 253 is greater than or equal to MAX_VERTEX_ATTRIBS. 254 255 INVALID_ENUM is generated by DrawElementsInstancedEXT if <type> is 256 not one of UNSIGNED_BYTE, UNSIGNED_SHORT or UNSIGNED_INT. 257 258 INVALID_VALUE is generated by DrawArraysInstancedEXT if <first>, 259 <count>, or <instanceCount> is less than zero. 260 261 INVALID_VALUE is generated by DrawElementsInstancedEXT if <count> or 262 <instanceCount> is less than zero. 263 264 INVALID_ENUM is generated by DrawArraysInstancedEXT or 265 DrawElementsInstancedEXT if <mode> is not one of the kinds of primitives 266 accepted by DrawArrays and DrawElements. 267 268 269New State 270 271 Changes to table 6.2, p. 136 (Vertex Array Data) 272 Initial 273 Get Value Type Get Command Value Description Sec. 274 --------- ---- ----------- ------- ----------- ---- 275 VERTEX_ATTRIB_ARRAY_DIVISOR_EXT 16* x Z+ GetVertexAttribiv 0 Vertex attrib array 2.8 276 instance divisor 277Issues 278 279 None 280 281Revision History 282 283 #1 November 11 2012, Abhijit Bhelande and Benj Lipchak 284 - initial conversion from ARB to APPLE for ES2 285 #2 June 26 2013, Benj Lipchak 286 - promotion from APPLE to EXT 287