@thi.ng/webgl 6.6.11 → 6.6.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -1
- package/README.md +1 -1
- package/api/blend.js +36 -32
- package/api/buffers.js +0 -1
- package/api/canvas.js +0 -1
- package/api/ext.js +12 -9
- package/api/glsl.js +0 -1
- package/api/material.js +0 -1
- package/api/model.js +13 -10
- package/api/multipass.js +0 -1
- package/api/shader.js +4 -1
- package/api/stencil.js +26 -22
- package/api/texture.js +589 -252
- package/buffer.js +145 -127
- package/canvas.js +53 -61
- package/checks.js +6 -6
- package/draw.js +84 -69
- package/error.js +7 -3
- package/fbo.js +95 -90
- package/geo/cube.js +28 -26
- package/geo/quad.js +34 -33
- package/logger.js +6 -2
- package/material.js +14 -11
- package/matrices.js +12 -19
- package/multipass.js +155 -146
- package/package.json +22 -19
- package/rbo.js +43 -34
- package/readpixels.js +14 -10
- package/shader.js +342 -335
- package/shaders/lambert.js +79 -48
- package/shaders/phong.js +92 -60
- package/shaders/pipeline.js +35 -27
- package/syntax.js +64 -77
- package/texture.js +277 -230
- package/textures/checkerboard.js +28 -25
- package/textures/stripes.js +19 -18
- package/uniforms.js +70 -67
- package/utils.js +6 -8
package/buffer.js
CHANGED
|
@@ -1,143 +1,161 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
BIT_SHIFTS,
|
|
3
|
+
asGLType,
|
|
4
|
+
typedArrayType
|
|
5
|
+
} from "@thi.ng/api/typedarray";
|
|
6
|
+
import {
|
|
7
|
+
DrawMode
|
|
8
|
+
} from "./api/model.js";
|
|
3
9
|
import { isGL2Context } from "./checks.js";
|
|
4
10
|
import { error } from "./error.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
11
|
+
class WebGLArrayBuffer {
|
|
12
|
+
gl;
|
|
13
|
+
buffer;
|
|
14
|
+
target;
|
|
15
|
+
mode;
|
|
16
|
+
data;
|
|
17
|
+
constructor(gl, data, target = gl.ARRAY_BUFFER, mode = gl.STATIC_DRAW, retain = false) {
|
|
18
|
+
this.gl = gl;
|
|
19
|
+
this.buffer = gl.createBuffer() || error("error creating WebGL buffer");
|
|
20
|
+
this.target = target;
|
|
21
|
+
this.mode = mode;
|
|
22
|
+
if (data) {
|
|
23
|
+
this.set(data);
|
|
24
|
+
if (retain)
|
|
25
|
+
this.data = data;
|
|
21
26
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
}
|
|
28
|
+
bind() {
|
|
29
|
+
this.gl.bindBuffer(this.target, this.buffer);
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
unbind() {
|
|
33
|
+
this.gl.bindBuffer(this.target, null);
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
release() {
|
|
37
|
+
if (this.buffer) {
|
|
38
|
+
this.gl.deleteBuffer(this.buffer);
|
|
39
|
+
delete this.buffer;
|
|
25
40
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
setChunk(data, byteOffset = 0) {
|
|
56
|
-
this.bind();
|
|
57
|
-
this.gl.bufferSubData(this.target, byteOffset, data);
|
|
58
|
-
if (this.data) {
|
|
59
|
-
this.data.set(data, byteOffset >>> BIT_SHIFTS[typedArrayType(data)]);
|
|
60
|
-
}
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Re-applies retained data (from ctor arg) using
|
|
45
|
+
* {@link WebGLArrayBuffer.set}. Presumably the underlying data has been
|
|
46
|
+
* updated elsewhere, but needs to be reflected to WebGL.
|
|
47
|
+
*
|
|
48
|
+
* @remarks
|
|
49
|
+
* If no data is retained, this method is a no-op.
|
|
50
|
+
*/
|
|
51
|
+
update() {
|
|
52
|
+
if (this.data)
|
|
53
|
+
this.set(this.data);
|
|
54
|
+
}
|
|
55
|
+
set(data, mode = this.mode) {
|
|
56
|
+
this.bind();
|
|
57
|
+
this.gl.bufferData(this.target, data, mode);
|
|
58
|
+
if (this.data)
|
|
59
|
+
this.data = data;
|
|
60
|
+
}
|
|
61
|
+
setChunk(data, byteOffset = 0) {
|
|
62
|
+
this.bind();
|
|
63
|
+
this.gl.bufferSubData(this.target, byteOffset, data);
|
|
64
|
+
if (this.data) {
|
|
65
|
+
this.data.set(
|
|
66
|
+
data,
|
|
67
|
+
byteOffset >>> BIT_SHIFTS[typedArrayType(data)]
|
|
68
|
+
);
|
|
61
69
|
}
|
|
70
|
+
}
|
|
62
71
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
const defBuffer = (gl, data, target = gl.ARRAY_BUFFER, mode = gl.STATIC_DRAW, retain = false) => new WebGLArrayBuffer(gl, data, target, mode, retain);
|
|
73
|
+
const compileModel = (gl, spec, mode = gl.STATIC_DRAW) => {
|
|
74
|
+
if (spec.attribPool) {
|
|
75
|
+
spec.attribs = compileAttribPool(
|
|
76
|
+
gl,
|
|
77
|
+
spec.attribPool,
|
|
78
|
+
void 0,
|
|
79
|
+
gl.ARRAY_BUFFER,
|
|
80
|
+
mode
|
|
81
|
+
);
|
|
82
|
+
} else {
|
|
83
|
+
compileAttribs(gl, spec.attribs, mode);
|
|
84
|
+
}
|
|
85
|
+
spec.instances && compileAttribs(gl, spec.instances.attribs, mode);
|
|
86
|
+
compileIndices(gl, spec.indices, mode);
|
|
87
|
+
spec.mode == null && (spec.mode = DrawMode.TRIANGLES);
|
|
88
|
+
return spec;
|
|
76
89
|
};
|
|
77
90
|
const initBuffer = (gl, src, type, mode) => {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
91
|
+
if (src.buffer) {
|
|
92
|
+
src.data && src.buffer.set(src.data);
|
|
93
|
+
} else {
|
|
94
|
+
src.buffer = new WebGLArrayBuffer(gl, src.data, type, mode, src.retain);
|
|
95
|
+
}
|
|
84
96
|
};
|
|
85
97
|
const compileAttribs = (gl, attribs, mode) => {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
98
|
+
if (attribs) {
|
|
99
|
+
for (let id in attribs) {
|
|
100
|
+
initBuffer(gl, attribs[id], gl.ARRAY_BUFFER, mode);
|
|
90
101
|
}
|
|
91
|
-
|
|
102
|
+
}
|
|
103
|
+
return attribs;
|
|
92
104
|
};
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
105
|
+
const compileIndices = (gl, index, mode = gl.STATIC_DRAW) => {
|
|
106
|
+
if (index) {
|
|
107
|
+
initBuffer(gl, index, gl.ELEMENT_ARRAY_BUFFER, mode);
|
|
108
|
+
}
|
|
109
|
+
return index;
|
|
98
110
|
};
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
return vao;
|
|
126
|
-
}
|
|
111
|
+
const compileVAO = (gl, spec) => {
|
|
112
|
+
if (spec.shader) {
|
|
113
|
+
const isGL2 = isGL2Context(gl);
|
|
114
|
+
const ext = !isGL2 ? gl.getExtension("OES_vertex_array_object") : null;
|
|
115
|
+
if (isGL2 || ext) {
|
|
116
|
+
let vao;
|
|
117
|
+
if (isGL2) {
|
|
118
|
+
vao = gl.createVertexArray();
|
|
119
|
+
gl.bindVertexArray(vao);
|
|
120
|
+
} else {
|
|
121
|
+
vao = ext.createVertexArrayOES();
|
|
122
|
+
ext.bindVertexArrayOES(vao);
|
|
123
|
+
}
|
|
124
|
+
!!vao && error("error creating VAO");
|
|
125
|
+
spec.shader.bindAttribs(spec.attribs);
|
|
126
|
+
if (spec.indices) {
|
|
127
|
+
spec.indices.buffer.bind();
|
|
128
|
+
}
|
|
129
|
+
spec.shader.unbind(null);
|
|
130
|
+
if (isGL2) {
|
|
131
|
+
gl.bindVertexArray(null);
|
|
132
|
+
} else {
|
|
133
|
+
ext.bindVertexArrayOES(null);
|
|
134
|
+
}
|
|
135
|
+
return vao;
|
|
127
136
|
}
|
|
137
|
+
}
|
|
128
138
|
};
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
139
|
+
const compileAttribPool = (gl, pool, ids, target = gl.ARRAY_BUFFER, mode = gl.STATIC_DRAW) => {
|
|
140
|
+
const buf = defBuffer(gl, pool.bytes(), target, mode);
|
|
141
|
+
const spec = {};
|
|
142
|
+
for (let id of ids || Object.keys(pool.specs)) {
|
|
143
|
+
const attr = pool.specs[id];
|
|
144
|
+
spec[id] = {
|
|
145
|
+
buffer: buf,
|
|
146
|
+
size: attr.size,
|
|
147
|
+
type: asGLType(attr.type),
|
|
148
|
+
stride: pool.byteStride,
|
|
149
|
+
offset: attr.byteOffset
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
return spec;
|
|
153
|
+
};
|
|
154
|
+
export {
|
|
155
|
+
WebGLArrayBuffer,
|
|
156
|
+
compileAttribPool,
|
|
157
|
+
compileIndices,
|
|
158
|
+
compileModel,
|
|
159
|
+
compileVAO,
|
|
160
|
+
defBuffer
|
|
143
161
|
};
|
package/canvas.js
CHANGED
|
@@ -2,71 +2,63 @@ import { adaptDPI } from "@thi.ng/adapt-dpi";
|
|
|
2
2
|
import { isString } from "@thi.ng/checks/is-string";
|
|
3
3
|
import { error } from "./error.js";
|
|
4
4
|
const defaultOpts = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
alpha: true,
|
|
6
|
+
antialias: true,
|
|
7
|
+
depth: true,
|
|
8
|
+
premultipliedAlpha: true,
|
|
9
|
+
preserveDrawingBuffer: false,
|
|
10
|
+
stencil: false
|
|
11
11
|
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
opts.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
...defaultOpts,
|
|
24
|
-
...opts.opts,
|
|
25
|
-
});
|
|
26
|
-
if (!gl) {
|
|
27
|
-
error("WebGL unavailable");
|
|
12
|
+
const glCanvas = (opts = {}) => {
|
|
13
|
+
const canvas = opts.canvas ? isString(opts.canvas) ? document.getElementById(opts.canvas) : opts.canvas : document.createElement("canvas");
|
|
14
|
+
opts.width && (canvas.width = opts.width);
|
|
15
|
+
opts.height && (canvas.height = opts.height);
|
|
16
|
+
opts.autoScale !== false && adaptDPI(canvas, canvas.width, canvas.height);
|
|
17
|
+
opts.parent && opts.parent.appendChild(canvas);
|
|
18
|
+
const gl = canvas.getContext(
|
|
19
|
+
opts.version === 2 ? "webgl2" : "webgl",
|
|
20
|
+
{
|
|
21
|
+
...defaultOpts,
|
|
22
|
+
...opts.opts
|
|
28
23
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
);
|
|
25
|
+
if (!gl) {
|
|
26
|
+
error("WebGL unavailable");
|
|
27
|
+
}
|
|
28
|
+
opts.onContextLost && canvas.addEventListener("webglcontextlost", opts.onContextLost);
|
|
29
|
+
return {
|
|
30
|
+
canvas,
|
|
31
|
+
gl,
|
|
32
|
+
ext: getExtensions(gl, opts.ext),
|
|
33
|
+
resize: (width, height) => {
|
|
34
|
+
adaptDPI(
|
|
32
35
|
canvas,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
width,
|
|
37
|
+
height,
|
|
38
|
+
opts.autoScale !== false ? window.devicePixelRatio : 1
|
|
39
|
+
);
|
|
40
|
+
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
40
43
|
};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
44
|
+
const getExtensions = (gl, ids, required = true) => {
|
|
45
|
+
const ext = {};
|
|
46
|
+
if (ids) {
|
|
47
|
+
for (let id of ids) {
|
|
48
|
+
ext[id] = gl.getExtension(id);
|
|
49
|
+
required && !ext[id] && error(`extension ${id} not available`);
|
|
48
50
|
}
|
|
49
|
-
|
|
51
|
+
}
|
|
52
|
+
return ext;
|
|
53
|
+
};
|
|
54
|
+
const clearCanvas = (gl, [r, g, b, a], depth = true) => {
|
|
55
|
+
gl.clearColor(r, g, b, a != null ? a : 1);
|
|
56
|
+
gl.clear(gl.COLOR_BUFFER_BIT | (depth ? gl.DEPTH_BUFFER_BIT : 0));
|
|
50
57
|
};
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
* 1.0.
|
|
58
|
-
*
|
|
59
|
-
* @param gl
|
|
60
|
-
* @param color
|
|
61
|
-
* @param depth
|
|
62
|
-
*/
|
|
63
|
-
export const clearCanvas = (gl, [r, g, b, a], depth = true) => {
|
|
64
|
-
gl.clearColor(r, g, b, a != null ? a : 1);
|
|
65
|
-
gl.clear(gl.COLOR_BUFFER_BIT | (depth ? gl.DEPTH_BUFFER_BIT : 0));
|
|
58
|
+
const defaultViewport = (gl) => gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
|
|
59
|
+
export {
|
|
60
|
+
clearCanvas,
|
|
61
|
+
defaultViewport,
|
|
62
|
+
getExtensions,
|
|
63
|
+
glCanvas
|
|
66
64
|
};
|
|
67
|
-
/**
|
|
68
|
-
* Resets viewport to full drawing buffer size.
|
|
69
|
-
*
|
|
70
|
-
* @param gl
|
|
71
|
-
*/
|
|
72
|
-
export const defaultViewport = (gl) => gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
|
package/checks.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TextureType } from "./api/texture.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
const isGL2Context = (gl) => typeof WebGL2RenderingContext !== "undefined" && gl instanceof WebGL2RenderingContext;
|
|
3
|
+
const isFloatTexture = (tex) => tex.type === TextureType.FLOAT || tex.type === TextureType.HALF_FLOAT || tex.type === TextureType.HALF_FLOAT_OES || tex.type === TextureType.FLOAT_32_UNSIGNED_INT_24_8_REV;
|
|
4
|
+
export {
|
|
5
|
+
isFloatTexture,
|
|
6
|
+
isGL2Context
|
|
7
|
+
};
|
package/draw.js
CHANGED
|
@@ -2,77 +2,92 @@ import { isArray } from "@thi.ng/checks/is-array";
|
|
|
2
2
|
import { isGL2Context } from "./checks.js";
|
|
3
3
|
import { error } from "./error.js";
|
|
4
4
|
import { bindTextures, unbindTextures } from "./texture.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
opts.unbindShader !== false && spec.shader.unbind(null);
|
|
34
|
-
opts.unbindTex && unbindTextures(spec.textures);
|
|
5
|
+
const draw = (specs, opts = {}) => {
|
|
6
|
+
const _specs = isArray(specs) ? specs : [specs];
|
|
7
|
+
for (let i = 0, n = _specs.length; i < n; i++) {
|
|
8
|
+
const spec = _specs[i];
|
|
9
|
+
const indices = spec.indices;
|
|
10
|
+
const gl = spec.shader.gl;
|
|
11
|
+
opts.bindTex !== false && bindTextures(spec.textures);
|
|
12
|
+
opts.shaderState !== false && spec.shader.prepareState();
|
|
13
|
+
opts.bindShader !== false && spec.shader.bind(spec);
|
|
14
|
+
if (indices && indices.buffer) {
|
|
15
|
+
indices.buffer.bind();
|
|
16
|
+
if (spec.instances) {
|
|
17
|
+
drawInstanced(gl, spec);
|
|
18
|
+
} else {
|
|
19
|
+
gl.drawElements(
|
|
20
|
+
spec.mode,
|
|
21
|
+
spec.num,
|
|
22
|
+
indices.data instanceof Uint32Array ? gl.UNSIGNED_INT : gl.UNSIGNED_SHORT,
|
|
23
|
+
0
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
} else {
|
|
27
|
+
if (spec.instances) {
|
|
28
|
+
drawInstanced(gl, spec);
|
|
29
|
+
} else {
|
|
30
|
+
gl.drawArrays(spec.mode, 0, spec.num);
|
|
31
|
+
}
|
|
35
32
|
}
|
|
33
|
+
opts.unbindShader !== false && spec.shader.unbind(null);
|
|
34
|
+
opts.unbindTex && unbindTextures(spec.textures);
|
|
35
|
+
}
|
|
36
36
|
};
|
|
37
37
|
const drawInstanced = (gl, spec) => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
const isGL2 = isGL2Context(gl);
|
|
39
|
+
const ext = !isGL2 ? gl.getExtension("ANGLE_instanced_arrays") : void 0;
|
|
40
|
+
if (!(isGL2 || ext)) {
|
|
41
|
+
error("instancing not supported");
|
|
42
|
+
}
|
|
43
|
+
const sattribs = spec.shader.attribs;
|
|
44
|
+
const iattribs = spec.instances.attribs;
|
|
45
|
+
spec.shader.bindAttribs(iattribs);
|
|
46
|
+
for (let id in iattribs) {
|
|
47
|
+
const attr = sattribs[id];
|
|
48
|
+
if (attr) {
|
|
49
|
+
let div = iattribs[id].divisor;
|
|
50
|
+
div = div !== void 0 ? div : 1;
|
|
51
|
+
isGL2 ? gl.vertexAttribDivisor(
|
|
52
|
+
attr.loc,
|
|
53
|
+
div
|
|
54
|
+
) : ext.vertexAttribDivisorANGLE(attr.loc, div);
|
|
42
55
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
spec.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
56
|
+
}
|
|
57
|
+
if (spec.indices) {
|
|
58
|
+
const type = spec.indices.data instanceof Uint32Array ? gl.UNSIGNED_INT : gl.UNSIGNED_SHORT;
|
|
59
|
+
isGL2 ? gl.drawElementsInstanced(
|
|
60
|
+
spec.mode,
|
|
61
|
+
spec.num,
|
|
62
|
+
type,
|
|
63
|
+
0,
|
|
64
|
+
spec.instances.num
|
|
65
|
+
) : ext.drawElementsInstancedANGLE(
|
|
66
|
+
spec.mode,
|
|
67
|
+
spec.num,
|
|
68
|
+
type,
|
|
69
|
+
0,
|
|
70
|
+
spec.instances.num
|
|
71
|
+
);
|
|
72
|
+
} else {
|
|
73
|
+
isGL2 ? gl.drawArraysInstanced(
|
|
74
|
+
spec.mode,
|
|
75
|
+
0,
|
|
76
|
+
spec.num,
|
|
77
|
+
spec.instances.num
|
|
78
|
+
) : ext.drawArraysInstancedANGLE(
|
|
79
|
+
spec.mode,
|
|
80
|
+
0,
|
|
81
|
+
spec.num,
|
|
82
|
+
spec.instances.num
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
for (let id in iattribs) {
|
|
86
|
+
const attr = sattribs[id];
|
|
87
|
+
attr && (isGL2 ? gl.vertexAttribDivisor(attr.loc, 0) : ext.vertexAttribDivisorANGLE(attr.loc, 0));
|
|
88
|
+
}
|
|
89
|
+
spec.shader.unbind(null);
|
|
90
|
+
};
|
|
91
|
+
export {
|
|
92
|
+
draw
|
|
78
93
|
};
|
package/error.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { defError } from "@thi.ng/errors/deferror";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
const WebGLError = defError(() => "WebGL");
|
|
3
|
+
const error = (msg) => {
|
|
4
|
+
throw new WebGLError(msg);
|
|
5
|
+
};
|
|
6
|
+
export {
|
|
7
|
+
WebGLError,
|
|
8
|
+
error
|
|
5
9
|
};
|