UNPKG

@thi.ng/webgl

Version:

WebGL & GLSL abstraction layer

94 lines (93 loc) 2.62 kB
import { isArray } from "@thi.ng/checks/is-array"; import { isGL2Context } from "./checks.js"; import { error } from "./error.js"; import { bindTextures, unbindTextures } from "./texture.js"; const draw = (specs, opts = {}) => { const _specs = isArray(specs) ? specs : [specs]; for (let i = 0, n = _specs.length; i < n; i++) { const spec = _specs[i]; const indices = spec.indices; const gl = spec.shader.gl; opts.bindTex !== false && bindTextures(spec.textures); opts.shaderState !== false && spec.shader.prepareState(); opts.bindShader !== false && spec.shader.bind(spec); if (indices?.buffer) { indices.buffer.bind(); if (spec.instances) { __drawInstanced(gl, spec); } else { gl.drawElements( spec.mode, spec.num, indices.data instanceof Uint32Array ? gl.UNSIGNED_INT : gl.UNSIGNED_SHORT, 0 ); } } else { if (spec.instances) { __drawInstanced(gl, spec); } else { gl.drawArrays(spec.mode, 0, spec.num); } } opts.unbindShader !== false && spec.shader.unbind(null); opts.unbindTex && unbindTextures(spec.textures); } }; const __drawInstanced = (gl, spec) => { const isGL2 = isGL2Context(gl); const ext = !isGL2 ? gl.getExtension("ANGLE_instanced_arrays") : void 0; if (!(isGL2 || ext)) { error("instancing not supported"); } const sattribs = spec.shader.attribs; const iattribs = spec.instances.attribs; spec.shader.bindAttribs(iattribs); for (let id in iattribs) { const attr = sattribs[id]; if (attr) { let div = iattribs[id].divisor; div = div !== void 0 ? div : 1; isGL2 ? gl.vertexAttribDivisor( attr.loc, div ) : ext.vertexAttribDivisorANGLE(attr.loc, div); } } if (spec.indices) { const type = spec.indices.data instanceof Uint32Array ? gl.UNSIGNED_INT : gl.UNSIGNED_SHORT; isGL2 ? gl.drawElementsInstanced( spec.mode, spec.num, type, 0, spec.instances.num ) : ext.drawElementsInstancedANGLE( spec.mode, spec.num, type, 0, spec.instances.num ); } else { isGL2 ? gl.drawArraysInstanced( spec.mode, 0, spec.num, spec.instances.num ) : ext.drawArraysInstancedANGLE( spec.mode, 0, spec.num, spec.instances.num ); } for (let id in iattribs) { const attr = sattribs[id]; attr && (isGL2 ? gl.vertexAttribDivisor(attr.loc, 0) : ext.vertexAttribDivisorANGLE(attr.loc, 0)); } spec.shader.unbind(null); }; export { draw };