UNPKG

@awayjs/stage

Version:
126 lines (97 loc) 3.15 kB
import { IVao } from '../base/IVao'; import { ContextWebGL } from './ContextWebGL'; import { IndexBufferWebGL } from './IndexBufferWebGL'; type TWebGLVao = WebGLVertexArrayObjectOES | WebGLVertexArrayObject; export class VaoContextWebGL { public static isSupported(gl: WebGLRenderingContext | WebGL2RenderingContext) { if (window.WebGL2RenderingContext && gl instanceof window.WebGL2RenderingContext) { return true; } if (gl.getSupportedExtensions().indexOf('OES_vertex_array_object') > -1) { return true; } return false; } private readonly _createVertexArray: () => TWebGLVao; private readonly _deleteVertexArray: (e: TWebGLVao) => void; private readonly _bindVertexArray: (e: TWebGLVao) => void; /* internal */ _lastBoundedVao: VaoWebGL; /* internal */ _isRequireUnbound: boolean = false; constructor (private _context: ContextWebGL) { const gl = _context._gl; if (!VaoContextWebGL.isSupported(gl)) { throw '[VaoContextWebGL] VAO not supported!'; } if (window.WebGL2RenderingContext && gl instanceof window.WebGL2RenderingContext) { this._createVertexArray = gl.createVertexArray.bind(gl); this._deleteVertexArray = gl.deleteVertexArray.bind(gl); this._bindVertexArray = gl.bindVertexArray.bind(gl); } else { const ext = gl.getExtension('OES_vertex_array_object'); this._createVertexArray = ext.createVertexArrayOES.bind(ext); this._deleteVertexArray = ext.deleteVertexArrayOES.bind(ext); this._bindVertexArray = ext.bindVertexArrayOES.bind(ext); } } createVertexArray(): TWebGLVao { this._context.stats.counter.vao++; return this._createVertexArray(); } unbindVertexArrays() { this._bindVertexArray(null); this._lastBoundedVao = null; this._isRequireUnbound = false; } bindVertexArray (v: VaoWebGL) { this._context.stateChangeCallback && this._context.stateChangeCallback('bindVertexArray'); // not unbound vao, to reduce bound flips if (v === this._lastBoundedVao) { return; } if (!v) { // mark that we require a unbound VAO as fast as possible this._isRequireUnbound = true; return; } this._isRequireUnbound = false; this._lastBoundedVao = v; this._bindVertexArray(v._vao); } deleteVertexArray (v: VaoWebGL) { if (this._lastBoundedVao === v) { this._bindVertexArray(null); } this._deleteVertexArray(v._vao); this._lastBoundedVao = null; this._context.stats.counter.vao--; } } export class VaoWebGL implements IVao { /* internal */ _vao: TWebGLVao; /* internal */ _indexBuffer: IndexBufferWebGL; constructor (private _context: ContextWebGL) { this._vao = _context._vaoContext.createVertexArray(); } attachIndexBuffer(buffer: IndexBufferWebGL) { if (this._indexBuffer) { return; } this.bind(); this._context.bindIndexBuffer(buffer); this._indexBuffer = buffer; } bind() { this._context._vaoContext.bindVertexArray(this); } unbind(force = false) { if (force) { this._context._vaoContext.unbindVertexArrays(); return; } this._context._vaoContext.bindVertexArray(null); } dispose() { this._context._vaoContext.deleteVertexArray(this); this._vao = null; } }