package.src.gl.vertex_buffer.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mapbox-gl Show documentation
Show all versions of mapbox-gl Show documentation
A WebGL interactive maps library
The newest version!
// @flow
import assert from 'assert';
import type {
StructArray,
StructArrayMember
} from '../util/struct_array';
import type Program from '../render/program';
import type Context from '../gl/context';
/**
* @enum {string} AttributeType
* @private
* @readonly
*/
const AttributeType = {
Int8: 'BYTE',
Uint8: 'UNSIGNED_BYTE',
Int16: 'SHORT',
Uint16: 'UNSIGNED_SHORT',
Int32: 'INT',
Uint32: 'UNSIGNED_INT',
Float32: 'FLOAT'
};
/**
* The `VertexBuffer` class turns a `StructArray` into a WebGL buffer. Each member of the StructArray's
* Struct type is converted to a WebGL atribute.
* @private
*/
class VertexBuffer {
length: number;
attributes: $ReadOnlyArray;
itemSize: number;
dynamicDraw: ?boolean;
context: Context;
buffer: WebGLBuffer;
/**
* @param dynamicDraw Whether this buffer will be repeatedly updated.
* @private
*/
constructor(context: Context, array: StructArray, attributes: $ReadOnlyArray, dynamicDraw?: boolean) {
this.length = array.length;
this.attributes = attributes;
this.itemSize = array.bytesPerElement;
this.dynamicDraw = dynamicDraw;
this.context = context;
const gl = context.gl;
this.buffer = gl.createBuffer();
context.bindVertexBuffer.set(this.buffer);
gl.bufferData(gl.ARRAY_BUFFER, array.arrayBuffer, this.dynamicDraw ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW);
if (!this.dynamicDraw) {
delete array.arrayBuffer;
}
}
bind() {
this.context.bindVertexBuffer.set(this.buffer);
}
updateData(array: StructArray) {
assert(array.length === this.length);
const gl = this.context.gl;
this.bind();
gl.bufferSubData(gl.ARRAY_BUFFER, 0, array.arrayBuffer);
}
enableAttributes(gl: WebGLRenderingContext, program: Program<*>) {
for (let j = 0; j < this.attributes.length; j++) {
const member = this.attributes[j];
const attribIndex: number | void = program.attributes[member.name];
if (attribIndex !== undefined) {
gl.enableVertexAttribArray(attribIndex);
}
}
}
/**
* Set the attribute pointers in a WebGL context
* @param gl The WebGL context
* @param program The active WebGL program
* @param vertexOffset Index of the starting vertex of the segment
*/
setVertexAttribPointers(gl: WebGLRenderingContext, program: Program<*>, vertexOffset: ?number) {
for (let j = 0; j < this.attributes.length; j++) {
const member = this.attributes[j];
const attribIndex: number | void = program.attributes[member.name];
if (attribIndex !== undefined) {
gl.vertexAttribPointer(
attribIndex,
member.components,
(gl: any)[AttributeType[member.type]],
false,
this.itemSize,
member.offset + (this.itemSize * (vertexOffset || 0))
);
}
}
}
/**
* Destroy the GL buffer bound to the given WebGL context
*/
destroy() {
const gl = this.context.gl;
if (this.buffer) {
gl.deleteBuffer(this.buffer);
delete this.buffer;
}
}
}
export default VertexBuffer;