/** * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose */ import { Program } from './program'; import { ElementsBuffer, AttributeBuffers } from './buffer'; import { WebGLExtensions } from './extensions'; import { idFactory } from '../../mol-util/id-factory'; const getNextVertexArrayId = idFactory() function getVertexArray(extensions: WebGLExtensions): WebGLVertexArrayObject { const { vertexArrayObject } = extensions if (!vertexArrayObject) { throw new Error('VertexArrayObject not supported') } const vertexArray = vertexArrayObject.createVertexArray() if (!vertexArray) { throw new Error('Could not create WebGL vertex array') } return vertexArray } function getVertexArrayObject(extensions: WebGLExtensions) { const { vertexArrayObject } = extensions if (vertexArrayObject === null) { throw new Error('VertexArrayObject not supported') } return vertexArrayObject } export interface VertexArray { readonly id: number bind: () => void update: () => void reset: () => void destroy: () => void } export function createVertexArray(extensions: WebGLExtensions, program: Program, attributeBuffers: AttributeBuffers, elementsBuffer?: ElementsBuffer): VertexArray { const id = getNextVertexArrayId() let vertexArray = getVertexArray(extensions) let vertexArrayObject = getVertexArrayObject(extensions) function update() { vertexArrayObject.bindVertexArray(vertexArray) if (elementsBuffer) elementsBuffer.bind() program.bindAttributes(attributeBuffers) vertexArrayObject.bindVertexArray(null) } update() let destroyed = false return { id, bind: () => { vertexArrayObject.bindVertexArray(vertexArray) }, update, reset: () => { vertexArray = getVertexArray(extensions) vertexArrayObject = getVertexArrayObject(extensions) update() }, destroy: () => { if (destroyed) return vertexArrayObject.deleteVertexArray(vertexArray) destroyed = true } } }