@pirireis/webglobeplugins 0.8.5 → 0.8.7

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.
Files changed (61) hide show
  1. package/bearing-line/plugin.js +51 -43
  2. package/circle-line-chain/plugin.js +52 -44
  3. package/compass-rose/compass-rose-padding-flat.js +3 -0
  4. package/compassrose/compassrose.js +1 -8
  5. package/heatwave/isobar/plugin.js +4 -1
  6. package/heatwave/isobar/quadtreecontours.js +0 -2
  7. package/heatwave/plugins/heatwaveglobeshell.js +2 -0
  8. package/package.json +1 -1
  9. package/partialrings/goals.md +2 -0
  10. package/partialrings/plugin.js +2 -1
  11. package/point-glow-line-to-earth/draw-subset-obj.js +27 -0
  12. package/point-glow-line-to-earth/keymethod.js +0 -0
  13. package/point-glow-line-to-earth/plugin.js +439 -0
  14. package/point-glow-line-to-earth/types.js +26 -0
  15. package/point-heat-map/index.js +0 -3
  16. package/point-heat-map/plugin-webworker.js +4 -9
  17. package/point-heat-map/point-to-heat-map-flow.js +0 -6
  18. package/point-tracks/plugin.js +42 -17
  19. package/programs/arrowfield/logic.js +6 -4
  20. package/programs/arrowfield/object.js +1 -1
  21. package/programs/float2legendwithratio/object.js +5 -4
  22. package/programs/globe-util/is-globe-moved.js +27 -0
  23. package/programs/globeshell/wiggle/logic.js +3 -7
  24. package/programs/globeshell/wiggle/object.js +1 -2
  25. package/programs/line-on-globe/circle-accurate-3d.js +16 -23
  26. package/programs/line-on-globe/circle-accurate-flat.js +21 -21
  27. package/programs/line-on-globe/lines-color-instanced-flat.js +6 -7
  28. package/programs/line-on-globe/naive-accurate-flexible.js +239 -0
  29. package/programs/line-on-globe/to-the-surface.js +129 -0
  30. package/programs/picking/pickable-renderer.js +216 -0
  31. package/programs/point-on-globe/element-globe-surface-glow.js +168 -0
  32. package/programs/point-on-globe/element-point-glow.js +184 -0
  33. package/programs/point-on-globe/square-pixel-point.js +8 -7
  34. package/programs/programcache.js +9 -0
  35. package/programs/rings/partial-ring/piece-of-pie.js +1 -1
  36. package/programs/totems/camerauniformblock.js +23 -2
  37. package/rangerings/plugin.js +9 -6
  38. package/shaders/fragment-toy/firework.js +55 -0
  39. package/shaders/fragment-toy/singularity.js +59 -0
  40. package/types.js +16 -0
  41. package/util/account/single-attribute-buffer-management/buffer-manager.js +2 -6
  42. package/util/account/util.js +17 -7
  43. package/util/check/typecheck.js +11 -0
  44. package/util/gl-util/buffer/integrate-buffer.js +74 -0
  45. package/util/gl-util/draw-options/client.js +59 -0
  46. package/util/gl-util/draw-options/methods.js +46 -0
  47. package/util/gl-util/draw-options/types.js +18 -0
  48. package/util/gl-util/uniform-block/manager.js +176 -0
  49. package/util/gl-util/uniform-block/roadmap.md +70 -0
  50. package/util/gl-util/uniform-block/shader.js +0 -0
  51. package/util/gl-util/uniform-block/types.js +7 -0
  52. package/util/jshelpers/equality.js +17 -0
  53. package/util/picking/picker-displayer.js +1 -1
  54. package/util/programs/shapesonglobe.js +17 -19
  55. package/util/shaderfunctions/geometrytransformations.js +27 -63
  56. package/bearing-line/roadmap.md +0 -15
  57. package/point-heat-map/plugin.js +0 -132
  58. package/programs/line-on-globe/naive-accurate.js +0 -221
  59. package/programs/line-on-globe/to-the-origin.js +0 -164
  60. package/util/jshelpers/timemethods.js +0 -19
  61. /package/{programs/point-on-globe/element-draw-glow.js → point-glow-line-to-earth/adaptors.js} +0 -0
@@ -79,6 +79,7 @@ class PointOnGlobeProgram {
79
79
  pointSize: gl.getUniformLocation(program, "pointSize"),
80
80
  }
81
81
 
82
+ // eslint-disable-next-line
82
83
  { // assign opacity
83
84
  this._lastOpacity = 1.0;
84
85
  this._lastPointSize = 2.0;
@@ -92,13 +93,13 @@ class PointOnGlobeProgram {
92
93
  gl.uniform1i(this.uniforms.hovered_vertexID, this._lastHoveredID);
93
94
  gl.useProgram(currentProgram);
94
95
  }
95
-
96
+ // eslint-disable-next-line
96
97
  { // assign attribute locations
97
98
  gl.bindAttribLocation(program, 0, "pos3D");
98
99
  gl.bindAttribLocation(program, 1, "pos2D");
99
100
  gl.bindAttribLocation(program, 2, "rgba");
100
101
  }
101
-
102
+ // eslint-disable-next-line
102
103
  { // arrange camera uniform block
103
104
  this.cameraBlockBingingPoint = 0;
104
105
  this.cameraBlockTotem = CameraUniformBlockTotemCache.get(globe);
@@ -112,17 +113,19 @@ class PointOnGlobeProgram {
112
113
  const { gl } = this;
113
114
  const vao = gl.createVertexArray();
114
115
  gl.bindVertexArray(vao);
115
-
116
+ // eslint-disable-next-line
116
117
  {
117
118
  gl.bindBuffer(gl.ARRAY_BUFFER, pos3DBuffer);
118
119
  gl.enableVertexAttribArray(0);
119
120
  gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
120
121
  }
122
+ // eslint-disable-next-line
121
123
  {
122
124
  gl.bindBuffer(gl.ARRAY_BUFFER, pos2DBuffer);
123
125
  gl.enableVertexAttribArray(1);
124
126
  gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
125
127
  }
128
+ // eslint-disable-next-line
126
129
  {
127
130
  gl.bindBuffer(gl.ARRAY_BUFFER, rgbaBuffer);
128
131
  gl.enableVertexAttribArray(2);
@@ -168,8 +171,6 @@ class PointOnGlobeProgram {
168
171
  gl.bindVertexArray(null);
169
172
  }
170
173
 
171
-
172
-
173
174
  free() {
174
175
  if (this._isFreed) return;
175
176
  const { gl, globe } = this;
@@ -180,9 +181,9 @@ class PointOnGlobeProgram {
180
181
  }
181
182
 
182
183
 
183
- const pointOnGlobeProgramCache = Object.freeze({
184
+ const PointOnGlobeProgramCache = Object.freeze({
184
185
  get: (globe) => noRegisterGlobeProgramCache.getProgram(globe, PointOnGlobeProgram),
185
186
  release: (globe) => noRegisterGlobeProgramCache.releaseProgram(globe, PointOnGlobeProgram)
186
187
  });
187
188
 
188
- export { pointOnGlobeProgramCache };
189
+ export { PointOnGlobeProgramCache };
@@ -33,6 +33,9 @@ const globeProgramCache = (function () {
33
33
 
34
34
  function releaseProgram(globe, ProgramClass) {
35
35
  if (cache.has(globe) && cache.get(globe).has(ProgramClass)) {
36
+ if (cache.get(globe).get(ProgramClass).count === 0) {
37
+ throw new Error("The program counter is already 0, cannot release program");
38
+ }
36
39
  cache.get(globe).get(ProgramClass).count--;
37
40
  if (cache.get(globe).get(ProgramClass).count === 0) {
38
41
  globe.api_UnRegisterPlugin(cache.get(globe).get(ProgramClass).program.id); // it calls program.free()
@@ -68,6 +71,9 @@ const glProgramCache = (function () {
68
71
 
69
72
  function releaseProgram(gl, ProgramClass) {
70
73
  if (cache.has(gl) && cache.get(gl).has(ProgramClass)) {
74
+ if (cache.get(gl).get(ProgramClass).count === 0) {
75
+ throw new Error("The program counter is already 0, cannot release program");
76
+ }
71
77
  cache.get(gl).get(ProgramClass).count--;
72
78
  if (cache.get(gl).get(ProgramClass).count === 0) {
73
79
  cache.get(gl).get(ProgramClass).program.free();
@@ -103,6 +109,9 @@ const noRegisterGlobeProgramCache = (function () {
103
109
 
104
110
  function releaseProgram(globe, ProgramClass) {
105
111
  if (cache.has(globe) && cache.get(globe).has(ProgramClass)) {
112
+ if (cache.get(globe).get(ProgramClass).count === 0) {
113
+ throw new Error("The program counter is already 0, cannot release program");
114
+ }
106
115
  cache.get(globe).get(ProgramClass).count--;
107
116
  if (cache.get(globe).get(ProgramClass).count === 0) {
108
117
  cache.get(globe).get(ProgramClass).program.free();
@@ -309,7 +309,7 @@ export class Logic {
309
309
 
310
310
  }
311
311
 
312
- export const pieceOfPieProgramCache = Object.freeze({
312
+ export const PieceOfPieProgramCache = Object.freeze({
313
313
  get: (globe) => noRegisterGlobeProgramCache.getProgram(globe, Logic),
314
314
  release: (globe) => noRegisterGlobeProgramCache.releaseProgram(globe, Logic)
315
315
  });
@@ -30,6 +30,10 @@ export default class
30
30
  this.gl = null;
31
31
  this.globe = null;
32
32
  this.ubo = null;
33
+ this._isMovedParams = {
34
+ lastLod: null,
35
+ isMoved: false,
36
+ }
33
37
  }
34
38
 
35
39
 
@@ -75,7 +79,7 @@ export default class
75
79
 
76
80
  const { gl, traslateFloat32, ubo, mapWHFloat32, globe } = this;
77
81
  gl.bindBuffer(gl.UNIFORM_BUFFER, ubo);
78
- { // view, projection, translate
82
+ { // view, projection, translat
79
83
  gl.bufferSubData(gl.UNIFORM_BUFFER, 0, modelView);
80
84
  gl.bufferSubData(gl.UNIFORM_BUFFER, 64, projection);
81
85
  traslateFloat32.set([translate.x, translate.y, translate.z], 0);
@@ -101,12 +105,24 @@ export default class
101
105
  gl.bufferSubData(gl.UNIFORM_BUFFER, 164, new Float32Array([
102
106
  Distance, Radian * Tilt, Radian * NorthAng, Radian * CenterLong, Radian * CenterLat
103
107
  ]));
104
-
105
108
  }
109
+
106
110
  gl.bindBuffer(gl.UNIFORM_BUFFER, null);
107
111
 
112
+ { // isMoved
113
+ const currentLOD = globe.api_GetCurrentLODWithDecimal()
114
+ this._isMovedParams.isMoved = this._isMovedParams.lastLod !== currentLOD || globe.api_IsScreenMoving();
115
+ this._isMovedParams.lastLod = currentLOD;
116
+ }
108
117
  }
109
118
 
119
+ assignBindingPoint(program, bindingPoint) {
120
+ const { gl } = this;
121
+ const cameraBlockIndex = gl.getUniformBlockIndex(program, "CameraUniformBlock");
122
+ gl.uniformBlockBinding(program, cameraBlockIndex, bindingPoint);
123
+ }
124
+
125
+
110
126
  getUBO() {
111
127
  return this.ubo;
112
128
  }
@@ -124,6 +140,11 @@ export default class
124
140
  }
125
141
 
126
142
 
143
+ isMoved() {
144
+ return this._isMovedParams.isMoved;
145
+ }
146
+
147
+
127
148
  free() {
128
149
  const { gl, ubo } = this;
129
150
  gl.deleteBuffer(ubo);
@@ -52,11 +52,11 @@ import { mapGetOrThrow } from "../util/check/get";
52
52
  import { populateFloat32Array } from "../util/jshelpers/data-filler";
53
53
  import { RingAccount, ringBigPaddingKeyMethod, ringKeyMethod } from "./ring-account";
54
54
  import { CirclePadding3DCache } from "../programs/line-on-globe/degree-padding-around-circle-3d";
55
- import { LineOnGlobeCache } from '../programs/line-on-globe/naive-accurate';
55
+ import { LineOnGlobeCache } from '../programs/line-on-globe/naive-accurate-flexible';
56
56
  import RangeRingAngleText from "./rangeringangletext";
57
57
  import { Z_ALPHA_MODE } from "../programs/line-on-globe/util";
58
58
  import { ENUM_HIDE } from "./enum";
59
-
59
+ import { opacityCheck, constraintFloat } from "../util/check/typecheck";
60
60
  const CIRCLE_FLAT_EDGE_COUNT = 362; // 360 + 2 for closing the circle and a cutting point
61
61
 
62
62
 
@@ -274,7 +274,7 @@ class RangeRings {
274
274
  * @method setOpacity @param { number } opacity
275
275
  */
276
276
  setOpacity(opacity) {
277
- if (typeof opacity !== "number" || opacity < 0 || opacity > 1) throw new Error("Invalid value for opacity");
277
+ opacityCheck(opacity);
278
278
  this._opacity = opacity;
279
279
  this.paddingTextPlugin?.setOpacity(opacity);
280
280
  this._textWritersMap.forEach((writer) => writer.setOpacity(opacity));
@@ -378,6 +378,7 @@ class RangeRings {
378
378
  );
379
379
 
380
380
  const obj = function (bufferManagerComp, divisor = 1) {
381
+ if (bufferManagerComp === null) return null;
381
382
  return { 'buffer': bufferManagerComp.bufferManager.buffer, 'stride': 0, 'offset': 0, divisor }
382
383
 
383
384
  };
@@ -431,8 +432,9 @@ class RangeRings {
431
432
  ]
432
433
  );
433
434
 
434
- this._bigPadding3dFlatVAO = this._bigPadding3dFlatProgram.createVAO(
435
- ...["circlePoint", "circlePoint3d", "paddingPoint", "paddingPoint3d", "dashRatio", "dashOpacity", "rgba",].map(key => obj(this.bufferManagersCompMapPadding.get(key)))
435
+ this._bigPadding3dFlatVAO = this._bigPadding3dFlatProgram.createVAO(//"dashRatio", "dashOpacity"
436
+ ...["circlePoint", "circlePoint3d", "paddingPoint", "paddingPoint3d", null, null, "rgba",].map(key =>
437
+ (key === null) ? null : obj(this.bufferManagersCompMapPadding.get(key)))
436
438
  );
437
439
 
438
440
  this._padding3dOneDegreeVao = this._padding3dProgram.createVAO(
@@ -575,7 +577,8 @@ class RangeRings {
575
577
  // _padding2dProgram.draw(bigPaddingVAO, paddingBufferOrchestrator.length, _opacity);
576
578
  if (_oneDegreePadding) _padding2dProgram.draw(_oneDegree2DPaddingVao, bufferOrchestrator.length * CIRCLE_FLAT_EDGE_COUNT, _opacity, _zAlphaOnDegreePadding);
577
579
  }
578
- _bigPadding3dFlatProgram.draw(_bigPadding3dFlatVAO, paddingBufferOrchestrator.length, _opacity);
580
+ const drawOptions = { drawRange: { first: 0, count: bufferOrchestrator.length } };
581
+ _bigPadding3dFlatProgram.draw(_bigPadding3dFlatVAO, drawOptions, _opacity);
579
582
  this._textWritersMap.forEach((textWriter) => textWriter.draw());
580
583
  gl.enable(gl.DEPTH_TEST);
581
584
  }
@@ -0,0 +1,55 @@
1
+ export const firework = `
2
+ float firework(vec2 point_coord, float phase) {
3
+ float t = phase + 5.0;
4
+ float z = 6.0;
5
+ const int n = 53; // particle count
6
+
7
+ vec3 startColor = vec3(0.0, 0.64, 0.2);
8
+ vec3 endColor = vec3(0.06, 0.35, 0.85);
9
+
10
+ float startRadius = 0.84;
11
+ float endRadius = 1.6;
12
+
13
+ float power = 0.51;
14
+ float duration = 4.0;
15
+
16
+ vec2 v = z * (2.0 * point_coord - vec2(1.0) );
17
+
18
+ vec3 col = vec3(0.0);
19
+ vec2 pm = v.yx * 2.8;
20
+
21
+ float dMax = duration;
22
+ float evo = (sin(phase * 0.01 + 400.0) * 0.5 + 0.5) * 99.0 + 1.0;
23
+
24
+ float mb = 0.0;
25
+ float mbRadius = 0.0;
26
+ float sum = 0.0;
27
+
28
+ for(int i = 0; i < n; i++) {
29
+ float d = fract(t * power + 48934.4238 * sin(float(i / int(evo)) * 692.7398));
30
+
31
+ float a = 6.28 * float(i) / float(n);
32
+ float x = d * cos(a) * duration;
33
+ float y = d * sin(a) * duration;
34
+
35
+ float distRatio = d / dMax;
36
+ mbRadius = mix(startRadius, endRadius, distRatio);
37
+
38
+ vec2 p = v - vec2(x, y);
39
+ mb = mbRadius / dot(p, p);
40
+
41
+ sum += mb;
42
+ col = mix(col, mix(startColor, endColor, distRatio), mb / sum);
43
+ }
44
+
45
+ sum /= float(n);
46
+ col = normalize(col) * sum;
47
+ sum = clamp(sum, 0.0, 0.4);
48
+
49
+ vec3 tex = vec3(1.0);
50
+ col *= smoothstep(tex, vec3(0.0), vec3(sum));
51
+
52
+ float alpha = sum * 2.5;
53
+ return clamp(alpha, 0.0, 1.0);
54
+ }
55
+ `
@@ -0,0 +1,59 @@
1
+
2
+
3
+ const singularity = `
4
+
5
+ vec3 palette(float d){
6
+ return mix(vec3(0.2, 0.7, 0.9), vec3(1.0, 0.0, 1.0), d);
7
+ }
8
+
9
+ vec2 rotate(vec2 p, float a){
10
+ float c = cos(a);
11
+ float s = sin(a);
12
+ return p * mat2(c, s, -s, c);
13
+ }
14
+
15
+ float map(vec3 p){
16
+ for (int i = 0; i < 4; ++i){
17
+ float t = u_phase * 0.2;
18
+ p.xz = rotate(p.xz, t);
19
+ p.xy = rotate(p.xy, t * 1.89);
20
+ p.xz = abs(p.xz);
21
+ p.xz -= 0.85;
22
+ }
23
+ return dot(sign(p), p) / 5.0;
24
+ }
25
+
26
+ vec4 rm(vec3 ro, vec3 rd){
27
+ float t = 0.0;
28
+ vec3 col = vec3(0.0);
29
+ float d;
30
+ for (float i = 0.0; i < 56.0; i++){
31
+ vec3 p = ro + rd * t;
32
+ d = map(p) * 0.5;
33
+ if (d < 0.02){
34
+ break;
35
+ }
36
+ if (d > 100.0){
37
+ break;
38
+ }
39
+ col += palette(length(p) * 0.1) / (400.0 * d);
40
+ t += d;
41
+ }
42
+ return vec4(col, 1.0 / d * 2.0 );
43
+ }
44
+
45
+ vec4 singularity(vec2 pointCoord, float u_phase) {
46
+ vec2 uv = (pointCoord - 0.5); // Normalized coordinates from gl_PointCoord
47
+ vec3 ro = vec3(0.0, 0.0, -50.0);
48
+ ro.xz = rotate(ro.xz, u_phase);
49
+ vec3 cf = normalize(-ro);
50
+ vec3 cs = normalize(cross(cf, vec3(0.0, 1.0, 0.0)));
51
+ vec3 cu = normalize(cross(cf, cs));
52
+
53
+ vec3 uuv = ro + cf * 3.0 + uv.x * cs + uv.y * cu;
54
+ vec3 rd = normalize(uuv - ro);
55
+
56
+ return rm(ro, rd);
57
+ }`;
58
+
59
+ export { singularity };
package/types.js ADDED
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @typedef DrawRange
3
+ * @type {Object}
4
+ * @property {int} first
5
+ * @property {int} count
6
+ *
7
+ * @typedef DrawRangeIndexParamsClient
8
+ * @type {Object}
9
+ * @property {null|DrawRange} drawRange
10
+ * @property {null|Int32List} indexes
11
+ */
12
+
13
+
14
+ /**
15
+ * * @typedef {Array<number>} Color rgba color 0-1 values
16
+ */
@@ -35,12 +35,11 @@ export class BufferManager {
35
35
 
36
36
  deleteBulk(offsets) {
37
37
  const { gl, buffer, itemSize } = this;
38
- const emptyBlock = new Float32Array(this.itemSize).fill(0)
38
+ const emptyBlock = new Float32Array(this.itemSize).fill(NaN)
39
39
  const offsetMultiplier = itemSize * 4;
40
40
  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
41
41
  for (let offset of offsets) {
42
42
  if (offset !== undefined) {
43
-
44
43
  gl.bufferSubData(gl.ARRAY_BUFFER, offset * offsetMultiplier, emptyBlock);
45
44
  }
46
45
  }
@@ -108,7 +107,4 @@ export class BufferManager {
108
107
  this.gl = null;
109
108
  this.isFreed = true;
110
109
  }
111
- }
112
-
113
-
114
-
110
+ }
@@ -1,12 +1,22 @@
1
- export const vaoAttributeLoader = (gl, buffer, position, length, stride, offset, divisor = null, type = null) => {
2
- if (type === null) {
3
- type = gl.FLOAT;
1
+ export const vaoAttributeLoader = (gl, buffer, index, size, stride, offset, divisor = null, type = null) => {
2
+ if (!gl || !buffer) {
3
+ throw new Error("Invalid WebGL context or buffer");
4
4
  }
5
+ if (index < 0) {
6
+ throw new Error("Attribute index must be non-negative");
7
+ }
8
+ if (stride < 0 || offset < 0) {
9
+ throw new Error("Stride and offset must be non-negative");
10
+ }
11
+
12
+ const attribType = type === null ? gl.FLOAT : type;
5
13
  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
6
- gl.enableVertexAttribArray(position);
7
- gl.vertexAttribPointer(position, length, type, false, stride, offset);
14
+ gl.enableVertexAttribArray(index);
15
+ gl.vertexAttribPointer(index, size, attribType, false, stride, offset);
8
16
  if (divisor !== null) {
9
- gl.vertexAttribDivisor(position, divisor);
17
+ gl.vertexAttribDivisor(index, divisor);
10
18
  }
11
19
 
12
- }
20
+ }
21
+
22
+
@@ -26,3 +26,14 @@ export const isTextFont = (textFont) => {
26
26
 
27
27
  }
28
28
 
29
+ export const constraintFloat = (x, lowerBound = null, upperBound = null) => {
30
+ if (typeof x !== "number") throw new Error("type must be numberic");
31
+ if (lowerBound === null && upperBound === null) return;
32
+ if (lowerBound !== null && lowerBound > x) throw new Error(`input must be greater than ${lowerBound}`);
33
+ if (upperBound !== null && x > upperBound) throw new Error(`input must be less than ${upperBound}`);
34
+ }
35
+
36
+
37
+ export const isBoolean = (x) => {
38
+ if (typeof x !== "boolean") throw new TypeError("type must be boolean");
39
+ }
@@ -0,0 +1,74 @@
1
+
2
+ /**
3
+ * @typedef BufferAndReadInfo Buffers can be intertwined or interleaved.
4
+ * This object forces user to adapt generic convention of buffer and read information.
5
+ * @type {Object}
6
+ * @property {WebGLBuffer} buffer
7
+ * @property {number} stride
8
+ * @property {number} offset
9
+ */
10
+
11
+ /**
12
+ *
13
+ * @param {WebGLBuffer} gl
14
+ * @param {BufferAndReadInfo} bufferAndReadInfo
15
+ * @param {number} index
16
+ * @param {number} size
17
+ * @param {Object} options
18
+ * @param {*} options.type | default gl.FLOAT, gl.UNSIGNED_BYTE, gl.SHORT, gl.UNSIGNED_SHORT, gl.INT, gl.UNSIGNED_INT
19
+ * @param {number} options.divisor
20
+ * @param {Array<number>} options.escapeValues
21
+ * @returns
22
+ */
23
+
24
+ const attributeLoader = (gl, bufferAndReadInfo, index, size, { divisor = null, type = null, escapeValues = null, normalized = false } = {}) => {
25
+ if (size < 1 || size > 4) throw new Error("Size must be between 1 and 4");
26
+ if (bufferAndReadInfo == null) {
27
+ if (escapeValues !== null) constantFunction(gl, index, size, escapeValues);
28
+ return;
29
+ }
30
+
31
+ const { buffer, stride, offset } = bufferAndReadInfo;
32
+ if (!gl || !buffer) {
33
+ throw new Error("Invalid WebGL context or buffer");
34
+ }
35
+ if (index < 0) {
36
+ throw new Error("Attribute index must be non-negative");
37
+ }
38
+ if (stride < 0 || offset < 0) {
39
+ throw new Error("Stride and offset must be non-negative");
40
+ }
41
+ console.log("stride", stride, "offset", offset);
42
+ const attribType = type === null ? gl.FLOAT : type;
43
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
44
+ gl.enableVertexAttribArray(index);
45
+ gl.vertexAttribPointer(index, size, attribType, normalized, stride, offset);
46
+ if (divisor !== null) {
47
+ gl.vertexAttribDivisor(index, divisor);
48
+ }
49
+
50
+ }
51
+
52
+ /**
53
+ *
54
+ * @param {WebGLBuffer} buffer
55
+ * @param {number} stride
56
+ * @param {number} offset
57
+ * @returns {BufferAndReadInfo}
58
+ */
59
+ const createBufferAndReadInfo = (buffer, stride = 0, offset = 0) => {
60
+ if (buffer == null) return null;
61
+ console.log("createBufferAndReadInfo", buffer, stride, offset);
62
+ return { buffer, stride, offset };
63
+ }
64
+
65
+
66
+
67
+ const constantFunction = (gl, index, size, escapeValues) => {
68
+ const func = `vertexAttrib${size}f`;
69
+ console.log(`Using constant function ${func}`, gl[func], escapeValues);
70
+ gl[func](index, ...escapeValues);
71
+ }
72
+
73
+
74
+ export { attributeLoader, createBufferAndReadInfo };
@@ -0,0 +1,59 @@
1
+
2
+
3
+ class DrawOptionsClient {
4
+
5
+ /**
6
+ * @typedef DrawOptionsClientAdaptor
7
+ * @type {Object}
8
+ * @property {function} setElements
9
+ * @property {function} setDrawRange
10
+ * @property {function} free
11
+ *
12
+ * @param {*} gl
13
+ * @param {*} adaptorsMap
14
+ */
15
+ constructor(gl, adaptorsMap) {
16
+ this.gl = gl;
17
+ this.adaptorsMap = adaptorsMap;
18
+ this.elementBuffers = new Map();
19
+ }
20
+
21
+ __init() {
22
+ const { gl, adaptorsMap } = this;
23
+ // create element buffer for each element buffer type
24
+ for (const [key, value] of Object.entries(adaptorsMap)) {
25
+ const elementBuffer = gl.createBuffer();
26
+ this.elementBuffers.set(key, elementBuffer);
27
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer);
28
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, value, gl.DYNAMIC_DRAW);
29
+ }
30
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
31
+
32
+
33
+ }
34
+
35
+
36
+ setDrawRange() {
37
+
38
+ }
39
+
40
+
41
+ /**
42
+ *
43
+ * @param {null|Int32List|Int32Array} elementIndexes
44
+ */
45
+ setElements(elementIndexes = null) {
46
+
47
+ }
48
+
49
+ getDrawOptions() {
50
+
51
+ }
52
+
53
+
54
+
55
+
56
+ free() {
57
+
58
+ }
59
+ }
@@ -0,0 +1,46 @@
1
+ import './types'
2
+
3
+ /**
4
+ *
5
+ * @param {WebGL2RenderingContext} gl
6
+ * @param {WebGL2RenderingContext.DrawMode} mode
7
+ * @param {DrawRangeIndexParams} drawOptions
8
+ */
9
+
10
+
11
+ // first and element effects the vertexID, which is unfortunately not effected
12
+ const drawInstanced = (gl, mode, drawOptions, vertexCount) => {
13
+ const { drawRange, indexType = gl.UNSIGNED_INT } = drawOptions;
14
+ const { first = 0, count: instanceCount = 1 } = drawRange;
15
+ if (first > 0 || drawOptions.elementBuffer) {
16
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, drawOptions.elementBuffer);
17
+ gl.drawElementsInstanced(mode, vertexCount, indexType, first, instanceCount);
18
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
19
+ } else {
20
+
21
+ gl.drawArraysInstanced(mode, first, vertexCount, instanceCount);
22
+ }
23
+ }
24
+
25
+
26
+ /**
27
+ *
28
+ * @param {WebGL2RenderingContext} gl
29
+ * @param {WebGL2RenderingContext.DrawMode} defaultMode
30
+ * @param {DrawRangeIndexParams} drawOptions
31
+ */
32
+
33
+ const drawArrays = (gl, defaultMode, drawOptions) => {
34
+ const { drawRange, elementBuffer, indexType = gl.UNSIGNED_INT, drawMode = null } = drawOptions;
35
+ const { first, count } = drawRange;
36
+ const mode = drawMode ?? defaultMode;
37
+ if (elementBuffer) {
38
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer);
39
+ gl.drawElements(mode, count, indexType, first);
40
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
41
+ } else {
42
+ gl.drawArrays(mode, first, count);
43
+ }
44
+ }
45
+
46
+ export { drawArrays, drawInstanced }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @typedef DrawRange
3
+ * @type {Object}
4
+ * @property {int} first
5
+ * @property {int} count
6
+ *
7
+ * @typedef DrawRangeIndexParams
8
+ * @type {Object}
9
+ * @property {null|DrawRange} drawRange
10
+ * @property {null|ElementBuffer} elementBuffer
11
+ * @property {null|indexType} indexType
12
+ * @property {null|int} drawMode
13
+ *
14
+ */
15
+
16
+
17
+
18
+