# VertexArray :::info Unless you are writing framework level code, it is usually not necessary to create `VertexArray` instances in luma.gl applications. It is often simpler to just provides attributes directly to the [`Model`](/docs/api-reference/engine/model) class. Still, it can be useful to review this documentation to understand how attributes are handled by luma.gl under the hood. ::: A `VertexArray` object lets the application map a set of GPU buffers to shader locations and the index buffer. By providing a vertexArray to a draw call, the buffers will be made available as input data to shaders, Using multiple `VertexArray` makes it easy for applications to reuse the same shaders. Remarks: - WebGPU - WebGPU does not provide a native VertexArray type resource. This is just a convenience class that groups all attribute and index buffer bindings for a draw call. - WebGL - - WebGL2 - see the [OpenGL Wiki](https://www.khronos.org/opengl/wiki/Vertex_Specification#Vertex_Array_Object). - WebGL1 - If the [OES_vertex_array_object](https://registry.khronos.org/OpenGL/extensions/OES/OES_vertex_array_object.txt) extension is not available, `VertexArrayObject` is polyfilled (binding all buffers before each draw call). (This is the only WebGL extension that can be polyfilled on the client side). ## Usage Import the `VertexArray` class so that your app can use it: ```typescript import {VertexArray} from '@luma.gl/core'; ``` Create a new VertexArray ```typescript const vertexArray = device.createVertexArray(); } ``` Adding attributes to a VertexArray ```typescript const vertexArray = device.createVertexArray(); vertexArray.setBuffer(location, buffer); ``` Deleting a VertexArray ```typescript vertexArrayObject.destroy(); ``` Setting a constant vertex attribute ```typescript import {VertexArray} from '@luma.gl/core'; const vertexArray = device.createVertexArray(); vertexArray.setConstant(0, [0, 0, 0]); ``` To discover how many attribute locations are available on the current system ```typescript const maxVertesAttributes = device.limits.maxVertexAttributes; ``` ## Methods `VertexArray` inherits from `Resource`. ### constructor ```typescript device.createVertexArray(gl : WebGLRenderingContext, props : Object) ``` Creates a new VertexArray - `props` (Object) - passed through to `Resource` superclass constructor and to `initialize` ### VertexArray.getDefaultArray() : VertexArray Returns the "global" `VertexArray`. Note: The global `VertexArray` object is always available. Binds the `null` VertexArray. ### initialize(props : Object) : VertexArray Reinitializes a `VertexArray`. - `attributes`=`{}` (`Object`) - map of attributes, can be keyed by index or names, can be constants (small arrays), `Buffer`, arrays or typed arrays of numbers, or attribute descriptors. - `elements`=`null` (`Buffer`) - optional buffer representing elements array (i.e. indices) - `program` - Transfers information on vertex attribute locations and types to this vertex array. ### setConstant Sets a constant value for a vertex attribute. When this `VertexArray` is used in a `Program.draw()` call, all Vertex Shader invocations will get the same value. ```typescript vertexArray.setConstant(location: number, constant: NumberArray) : VertexArray ``` - `location` - index of the attribute - `array` - the constant value Remarks: - WebGL APIs: [`vertexAttrib4[u]{f,i}v`](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttrib) ### setBuffer(location: number, buffer : Buffer [, accessor : Object]) : VertexArray ```typescript setBuffer(location: number, buffer : Buffer [, accessor : Object]) : VertexArray ``` Binds the specified attribute in this vertex array to the supplied buffer - Set a location in vertex attributes array to a buffer, specifying - its data layout and integer to float conversion and normalization flags - `location` (_GLuint_ | _String_) - index/ordinal number of the attribute - `buffer` (_WebGLBuffer_|_Buffer_) - WebGL buffer to set as value Remarks: - WebGL APIs `gl.vertexAttrib{I}Pointer`, [gl.vertexAttribDivisor](https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/vertexAttribDivisor) ## Types, Constants, Enumarations ## Attribute Accessors When setting `Buffer` attributes, additional data can be provided to specify how the buffer should be accessed. This data can be stored directly on the `Buffer` accessor or supplied to `.setBuffer`. - `target`=`buffer.target` (_GLuint_, ) - which target to bind to - `size` (_GLuint_) - number of values (components) per element (1-4) - `type` (_GLuint_) - type of values (e.g. gl.FLOAT) - `normalized` (_boolean_, false) - normalize integers to [-1,1] or [0,1] - `integer` (_boolean_, false) - `WebGL 2` disable int-to-float conversion - `stride` (_GLuint_, 0) - supports strided arrays - `offset` (_GLuint_, 0) - supports strided arrays - `layout.normalized`=`false` (GLbool) - normalize integers to [-1,1], [0,1] - `layout.integer`=`false` (GLuint) - WebGL 2 only, disable int-to-float conv. - `divisor` - Sets the frequency divisor used for instanced rendering (instances that pass between updates of attribute). Usually simply set to 1 or 0 to enable/disable instanced rendering. 0 disables instancing, >=1 enables it. Notes: - The application can enable normalization by setting the `normalized` flag to `true` in the `setBuffer` call. - **WebGL 2** The application can disable integer to float conversion when running under WebGL 2, by setting the `integer` flag to `true`. - [`glVertexAttribIPointer`](https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/vertexAttribIPointer) specifies _integer_ data formats and locations of vertex attributes. Values are always left as integer values. Only accepts the integer types gl.BYTE, gl.UNSIGNED_BYTE, gl.SHORT, gl.UNSIGNED_SHORT, gl.INT, gl.UNSIGNED_INT Notes about Instanced Rendering - About setting `divisor` in attributes: Instanced attributes requires WebGL 2 or a (widely supported) WebGL 1 extension. Apps can use the luma.gl feature detection system to determine if instanced rendering is available, though the extension is so ubiquitously supported that many apps just make the assumption: [instanced_arrays](https://webglstats.com/webgl/extension/ANGLE_instanced_arrays). - An attribute is referred to as **instanced** if its divisor value is non-zero. - The divisor modifies the rate at which vertex attributes advance when rendering multiple instances of primitives in a single draw call. - If divisor is zero, the attribute at slot index advances once per vertex. - If divisor is non-zero, the attribute advances once per divisor instances of the set(s) of vertices being rendered.