@thi.ng/webgl
Version:
WebGL & GLSL abstraction layer
94 lines (93 loc) • 2.62 kB
JavaScript
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
};