Extensions

Source: core/Buffer.js

/**
 * Buffer
 * @property {any} data
 */
export class Buffer {
  /**
   * Creates an instance of Buffer.
   * @constructor
   * @param {string} locationName - Attribute/uniform location name
   * @param {TypedArray|number} data - Data or length of data
   * @param {number} rows - Number of rows - default 1
   * @param {number} cols - Number of columns - default 1
   * @param {number} target - Buffer target - default ARRAY_BUFFER
   * @param {number} type - Buffer type - default DYNAMIC_DRAW
   * @param {number} divisor - Attribute divisor - default 1
   * @param {number} dataType - Data type - default FLOAT
   */
  constructor(
    locationName,
    data,
    rows = 1,
    cols = 1,
    target = WebGL2RenderingContext.ARRAY_BUFFER,
    type = WebGL2RenderingContext.DYNAMIC_DRAW,
    divisor = 1,
    dataType = WebGL2RenderingContext.FLOAT,
  ) {
    const elemCount = rows * cols;

    this.data = typeof data === "number" ? new Float32Array(data * elemCount) : data;
    this._locationName = locationName;
    this._rows = rows;
    this._cols = cols;
    this._target = target;
    this._type = type;
    this._stride = elemCount * 4;
    this._offset = cols * 4;
    this._divisor = divisor;
    this._dataType = dataType;
    if (this._type === WebGL2RenderingContext.STATIC_DRAW) {
      this._stride = this._offset = 0;
    }
  }

  /**
   * Create and binf buffer
   * @param {WebGLContext} gl
   * @param {Object} locations
   */
  create(gl, locations) {
    this._location = locations[this._locationName];
    this._buffer = gl.createBuffer();
    this.bind(gl);
  }

  /**
   * binf buffer
   * @param {WebGLContext} gl
   */
  bind(gl) {
    gl.bindBuffer(this._target, this._buffer);
  }

  /**
   * Upload buffer
   * @param {WebGLContext} gl
   */
  upload(gl) {
    this.bind(gl);
    this._enable(gl);
    gl.bufferData(this._target, this.data, this._type);
  }

  /**
   * Destruct class
   */
  destruct(gl) {
    this.bind(gl);
    gl.deleteBuffer(this._buffer);
    this.data = this._buffer = null;
  }

  /**
   * @param {WebGLContext} gl
   * @ignore
   */
  _enable(gl) {
    const { _rows, _location, _cols, _stride, _offset, _divisor, _dataType } = this;
    let i = -1;
    while (++i < _rows) {
      const loc = _location + i;
      gl.enableVertexAttribArray(loc);
      gl.vertexAttribPointer(loc, _cols, _dataType, false, _stride, i * _offset);
      gl.vertexAttribDivisor(loc, _divisor);
    }
  }
}