@pirireis/webglobeplugins 1.1.23 → 1.2.0

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.
@@ -7,7 +7,7 @@ import { BufferOrchestrator, BufferManager } from "../util/account";
7
7
  import { PickerDisplayer } from '../util/picking/picker-displayer';
8
8
  import { wgs84ToCartesian3d, wgs84ToMercator } from '../Math/methods';
9
9
  import { constraintFloat, opacityCheck } from '../util/check/typecheck';
10
- import { createBufferAndReadInfo } from '../util/gl-util/buffer/attribute-loader';
10
+ import { AttributeLoader } from '../util/gl-util/buffer/attribute-loader';
11
11
  import { CameraUniformBlockTotemCache } from '../programs/totems/camerauniformblock';
12
12
  /**
13
13
  * is used with depth we can create a line from surface to the point.
@@ -76,16 +76,16 @@ class PointGlowLineToEarthPlugin {
76
76
  _glowPointWrapper.program = ElementPointGlowProgramCache.get(globe);
77
77
  _lineProgramWrapper.program = LineOnGlobeCache.get(globe);
78
78
  this._pickerDisplayer = new PickerDisplayer(globe);
79
- const obj = (key) => key === null ? null : createBufferAndReadInfo(this._bufferManagersMap.get(key).bufferManager.buffer);
80
- _pickableWrapper.vao = _pickableWrapper.program.createVAO(createBufferAndReadInfo(this._bufferManagersMap.get('pos3D').bufferManager.buffer, 6 * 4, 0), createBufferAndReadInfo(this._bufferManagersMap.get('pos2D').bufferManager.buffer), createBufferAndReadInfo(this._bufferManagersMap.get('rgba').bufferManager.buffer, 8 * 4, 0), createBufferAndReadInfo(this._bufferManagersMap.get('size').bufferManager.buffer));
81
- _pickableWrapper.vaoLine = _pickableWrapper.program.createVAO(...['pos3D', 'pos2D', 'rgba', null].map(obj));
82
- _pickableWrapper.vaoHoverPoint = _pickableWrapper.program.createVAO(createBufferAndReadInfo(this._bufferManagersMap.get('pos3D').bufferManager.buffer, 6 * 4, 0), createBufferAndReadInfo(this._bufferManagersMap.get('pos2D').bufferManager.buffer), null, createBufferAndReadInfo(this._bufferManagersMap.get('size').bufferManager.buffer));
83
- _pickableWrapper.vaoHoverLine = _pickableWrapper.program.createVAO(...['pos3D', 'pos2D', null, null].map(obj));
84
- _glowPointWrapper.vao = _glowPointWrapper.program.createVAO(createBufferAndReadInfo(this._bufferManagersMap.get('pos3D').bufferManager.buffer, 6 * 4, 0), createBufferAndReadInfo(this._bufferManagersMap.get('pos2D').bufferManager.buffer), null, createBufferAndReadInfo(this._bufferManagersMap.get('size').bufferManager.buffer));
85
- // _lineProgramWrapper.vao = _lineProgramWrapper.program.createVAO(
79
+ const obj = (key) => key === null ? null : AttributeLoader.createBufferAndReadInfo(this._bufferManagersMap.get(key).bufferManager.buffer);
80
+ _pickableWrapper.vao = _pickableWrapper.program.createAttributeLoader(AttributeLoader.createBufferAndReadInfo(this._bufferManagersMap.get('pos3D').bufferManager.buffer, 6 * 4, 0), AttributeLoader.createBufferAndReadInfo(this._bufferManagersMap.get('pos2D').bufferManager.buffer), AttributeLoader.createBufferAndReadInfo(this._bufferManagersMap.get('rgba').bufferManager.buffer, 8 * 4, 0), AttributeLoader.createBufferAndReadInfo(this._bufferManagersMap.get('size').bufferManager.buffer));
81
+ _pickableWrapper.vaoLine = _pickableWrapper.program.createAttributeLoader(...['pos3D', 'pos2D', 'rgba', null].map(obj));
82
+ _pickableWrapper.vaoHoverPoint = _pickableWrapper.program.createAttributeLoader(AttributeLoader.createBufferAndReadInfo(this._bufferManagersMap.get('pos3D').bufferManager.buffer, 6 * 4, 0), AttributeLoader.createBufferAndReadInfo(this._bufferManagersMap.get('pos2D').bufferManager.buffer), null, AttributeLoader.createBufferAndReadInfo(this._bufferManagersMap.get('size').bufferManager.buffer));
83
+ _pickableWrapper.vaoHoverLine = _pickableWrapper.program.createAttributeLoader(...['pos3D', 'pos2D', null, null].map(obj));
84
+ _glowPointWrapper.vao = _glowPointWrapper.program.createAttributeLoader(AttributeLoader.createBufferAndReadInfo(this._bufferManagersMap.get('pos3D').bufferManager.buffer, 6 * 4, 0), AttributeLoader.createBufferAndReadInfo(this._bufferManagersMap.get('pos2D').bufferManager.buffer), null, AttributeLoader.createBufferAndReadInfo(this._bufferManagersMap.get('size').bufferManager.buffer));
85
+ // _lineProgramWrapper.vao = _lineProgramWrapper.program.createAttributeLoader(
86
86
  // ...[null, 'pos3D', null, 'reverse3D', null, null, "rgba"].map(obj)
87
87
  // );
88
- // _pickableWrapper.vaoRev = _pickableWrapper.program.createVAO(
88
+ // _pickableWrapper.vaoRev = _pickableWrapper.program.createAttributeLoader(
89
89
  // ...['reverse3D', 'pos2D', 'rgba', 'size'].map(obj)
90
90
  // );
91
91
  _pickableWrapper.ubo = _pickableWrapper.program.createUBO();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pirireis/webglobeplugins",
3
- "version": "1.1.23",
3
+ "version": "1.2.0",
4
4
  "main": "index.js",
5
5
  "author": "Toprak Nihat Deniz Ozturk",
6
6
  "license": "MIT",
@@ -2,7 +2,7 @@ import { createProgram } from "../../../util/webglobjectbuilders";
2
2
  import { CameraUniformBlockString, CameraUniformBlockTotemCache } from "../../totems/index";
3
3
  import { cartesian3DToGLPosition, mercatorXYToGLPosition, } from "../../../util/shaderfunctions/geometrytransformations";
4
4
  import { noRegisterGlobeProgramCache } from "../../programcache";
5
- import { attributeLoader } from "../../../util/gl-util/buffer/attribute-loader";
5
+ import { AttributeLoader } from "../../../util/gl-util/buffer/attribute-loader";
6
6
  import { UniformBlockManager } from "../../../util/gl-util/uniform-block/manager";
7
7
  import { drawArrays } from "../../../util/gl-util/draw-options/methods";
8
8
  const ESCAPE_VALUE = -1;
@@ -100,17 +100,14 @@ export class LineProgram {
100
100
  this._ubosPublished.push(ubo);
101
101
  return ubo;
102
102
  }
103
- createVAO(position3D, position2D, color) {
104
- const { gl } = this;
105
- const vao = gl.createVertexArray();
106
- gl.bindVertexArray(vao);
107
- attributeLoader(gl, position3D, 0, 3);
108
- attributeLoader(gl, position2D, 1, 2);
109
- attributeLoader(gl, color, 2, 4, { escapeValues: [ESCAPE_VALUE, ESCAPE_VALUE, ESCAPE_VALUE, ESCAPE_VALUE] });
110
- gl.bindVertexArray(null);
111
- return vao;
103
+ createAttributeLoader(position3D, position2D, color) {
104
+ return new AttributeLoader(this.gl, [
105
+ { bufferAndReadInfo: position3D, index: 0, size: 3, options: { escapeValues: [NaN, NaN, NaN] } },
106
+ { bufferAndReadInfo: position2D, index: 1, size: 2, options: { escapeValues: [NaN, NaN] } },
107
+ { bufferAndReadInfo: color, index: 2, size: 4, options: { escapeValues: [ESCAPE_VALUE, ESCAPE_VALUE, ESCAPE_VALUE, ESCAPE_VALUE] } },
108
+ ]);
112
109
  }
113
- draw(vao, drawOptions, opacity = 1, flexibleUBO = null) {
110
+ draw(attributeLoader, drawOptions, opacity = 1, flexibleUBO = null) {
114
111
  const { gl, program, cameraBlockTotem } = this;
115
112
  gl.useProgram(program);
116
113
  if (opacity !== this._opacity.value) {
@@ -120,10 +117,10 @@ export class LineProgram {
120
117
  const ubo = flexibleUBO || this._defaultFlexibleUBO;
121
118
  cameraBlockTotem.bind(uniformBindingPoints.camera);
122
119
  ubo.bind();
123
- gl.bindVertexArray(vao);
120
+ attributeLoader.bind();
124
121
  // drawArrays(gl, gl.POINTS, drawOptions);
125
122
  drawArrays(gl, gl.LINE_STRIP, drawOptions);
126
- gl.bindVertexArray(null);
123
+ attributeLoader.unbind();
127
124
  ubo.unbind();
128
125
  cameraBlockTotem.unbind(uniformBindingPoints.camera);
129
126
  }
@@ -2,7 +2,7 @@ import { CameraUniformBlockString, CameraUniformBlockTotemCache } from "../totem
2
2
  import { slerp, POLE, R_3D, mercatorXYToGLPosition, cartesian3DToGLPosition } from "../../util/shaderfunctions/geometrytransformations";
3
3
  import { createProgram } from "../../util/webglobjectbuilders";
4
4
  import { noRegisterGlobeProgramCache } from "../programcache";
5
- import { attributeLoader } from "../../util/gl-util/buffer/attribute-loader";
5
+ import { AttributeLoader } from "../../util/gl-util/buffer/attribute-loader";
6
6
  import { UniformBlockManager } from "../../util/gl-util/uniform-block/manager";
7
7
  import { drawInstanced } from "../../util/gl-util/draw-options/methods";
8
8
  const GLOBE_MIDPOINT_COUNT = 30;
@@ -93,7 +93,6 @@ void main() {
93
93
  }
94
94
  `;
95
95
  class Logic {
96
- vaosPublished = [];
97
96
  isFreed = false;
98
97
  globe;
99
98
  gl;
@@ -135,11 +134,11 @@ class Logic {
135
134
  * @param opacity - Opacity value (0-1)
136
135
  * @param flexibleUBO - Optional flexible uniform buffer object
137
136
  */
138
- draw(vao, drawOptions, opacity, flexibleUBO = null) {
137
+ draw(attributeLoader, drawOptions, opacity, flexibleUBO = null) {
139
138
  const { gl, program, globe, cameraBlockTotem, _defaultFlexibleUBO } = this;
140
139
  gl.useProgram(program);
141
140
  cameraBlockTotem.bind(uniformBindingPoints.camera);
142
- gl.bindVertexArray(vao);
141
+ attributeLoader.bind();
143
142
  if (opacity !== this._lastOpacity) {
144
143
  gl.uniform1f(this._opacityLocation, opacity);
145
144
  this._lastOpacity = opacity;
@@ -149,7 +148,7 @@ class Logic {
149
148
  ubo.bind();
150
149
  drawInstanced(gl, gl.LINE_STRIP, drawOptions, vertexCount);
151
150
  ubo.unbind();
152
- gl.bindVertexArray(null);
151
+ attributeLoader.unbind();
153
152
  cameraBlockTotem.unbind(uniformBindingPoints.camera);
154
153
  }
155
154
  createUBO(bufferReadType = "STATIC_DRAW") {
@@ -162,32 +161,23 @@ class Logic {
162
161
  ]));
163
162
  return ubo;
164
163
  }
165
- createVAO(startPotision2DBufferObj, startPotision3DBufferObj, endPosition2DBufferObj, endPosition3DBufferObj, dashRatioBufferObj, dashOpacityBufferObj, colorBufferObj) {
166
- const { gl } = this;
167
- const vao = gl.createVertexArray();
168
- if (!vao) {
169
- throw new Error("Failed to create vertex array object");
170
- }
171
- gl.bindVertexArray(vao);
164
+ createAttributeLoader(startPotision2DBufferObj, startPotision3DBufferObj, endPosition2DBufferObj, endPosition3DBufferObj, dashRatioBufferObj, dashOpacityBufferObj, colorBufferObj) {
172
165
  const divisor = 1;
173
- attributeLoader(gl, startPotision2DBufferObj, 0, 2, { divisor });
174
- attributeLoader(gl, startPotision3DBufferObj, 1, 3, { divisor });
175
- attributeLoader(gl, endPosition2DBufferObj, 2, 2, { divisor });
176
- attributeLoader(gl, endPosition3DBufferObj, 3, 3, { divisor });
177
- attributeLoader(gl, dashRatioBufferObj, 4, 1, { divisor, escapeValues: [escapeValue] });
178
- attributeLoader(gl, dashOpacityBufferObj, 5, 1, { divisor, escapeValues: [escapeValue] });
179
- attributeLoader(gl, colorBufferObj, 6, 4, { divisor, escapeValues: [escapeValue, escapeValue, escapeValue, escapeValue] });
180
- gl.bindVertexArray(null);
181
- gl.bindBuffer(gl.ARRAY_BUFFER, null);
182
- this.vaosPublished.push(vao);
183
- return vao;
166
+ return new AttributeLoader(this.gl, [
167
+ { bufferAndReadInfo: startPotision2DBufferObj, index: 0, size: 2, options: { divisor } },
168
+ { bufferAndReadInfo: startPotision3DBufferObj, index: 1, size: 3, options: { divisor } },
169
+ { bufferAndReadInfo: endPosition2DBufferObj, index: 2, size: 2, options: { divisor } },
170
+ { bufferAndReadInfo: endPosition3DBufferObj, index: 3, size: 3, options: { divisor } },
171
+ { bufferAndReadInfo: dashRatioBufferObj, index: 4, size: 1, options: { divisor, escapeValues: [escapeValue] } },
172
+ { bufferAndReadInfo: dashOpacityBufferObj, index: 5, size: 1, options: { divisor, escapeValues: [escapeValue] } },
173
+ { bufferAndReadInfo: colorBufferObj, index: 6, size: 4, options: { divisor, escapeValues: [escapeValue, escapeValue, escapeValue, escapeValue] } }
174
+ ]);
184
175
  }
185
176
  free() {
186
177
  if (this.isFreed)
187
178
  return;
188
179
  CameraUniformBlockTotemCache.release(this.globe);
189
180
  this.gl.deleteProgram(this.program);
190
- this.vaosPublished.forEach((vao) => this.gl.deleteVertexArray(vao));
191
181
  this._ubosPublished.forEach((ubo) => ubo.free());
192
182
  this.isFreed = true;
193
183
  }
@@ -3,7 +3,7 @@ import { CameraUniformBlockTotemCache, CameraUniformBlockString } from "../totem
3
3
  import { mercatorXYToGLPosition, cartesian3DToGLPosition, R_3D, R } from "../../util/shaderfunctions/geometrytransformations";
4
4
  import { noRegisterGlobeProgramCache } from "../programcache";
5
5
  import { drawArrays, DrawRangeIndexParams } from "../../util/gl-util/draw-options/methods";
6
- import { attributeLoader } from "../../util/gl-util/buffer/attribute-loader";
6
+ import { AttributeLoader } from "../../util/gl-util/buffer/attribute-loader";
7
7
  import { UniformBlockManager } from "../../util/gl-util/uniform-block/manager";
8
8
  const uniformBindingPoints = {
9
9
  camera: 0,
@@ -139,17 +139,13 @@ class PointOnGlobeProgram {
139
139
  const ubo = uniformBlockManager.createUBO(this.gl);
140
140
  return ubo;
141
141
  }
142
- createVAO(pos3DBufferObj, pos2DBufferObj, rgbaBufferObj, sizeBufferObj) {
143
- const { gl } = this;
144
- const vao = gl.createVertexArray();
145
- gl.bindVertexArray(vao);
146
- attributeLoader(gl, pos3DBufferObj, 0, 3);
147
- attributeLoader(gl, pos2DBufferObj, 1, 2);
148
- attributeLoader(gl, rgbaBufferObj, 2, 4, { escapeValues: [-1, -1, -1, -1] });
149
- attributeLoader(gl, sizeBufferObj, 3, 1, { escapeValues: [-1] });
150
- gl.bindVertexArray(null);
151
- gl.bindBuffer(gl.ARRAY_BUFFER, null);
152
- return vao;
142
+ createAttributeLoader(pos3DBufferObj, pos2DBufferObj, rgbaBufferObj, sizeBufferObj) {
143
+ return new AttributeLoader(this.gl, [
144
+ { bufferAndReadInfo: pos3DBufferObj, index: 0, size: 3 },
145
+ { bufferAndReadInfo: pos2DBufferObj, index: 1, size: 2 },
146
+ { bufferAndReadInfo: rgbaBufferObj, index: 2, size: 4, options: { escapeValues: [-1, -1, -1, -1] } },
147
+ { bufferAndReadInfo: sizeBufferObj, index: 3, size: 1, options: { escapeValues: [-1] } }
148
+ ]);
153
149
  }
154
150
  /**
155
151
  *
@@ -181,4 +177,4 @@ const PickableRendererProgramCache = Object.freeze({
181
177
  get: (globe) => noRegisterGlobeProgramCache.getProgram(globe, PointOnGlobeProgram),
182
178
  release: (globe) => noRegisterGlobeProgramCache.releaseProgram(globe, PointOnGlobeProgram)
183
179
  });
184
- export { PickableRendererProgramCache };
180
+ // export { PickableRendererProgramCache };
@@ -3,7 +3,7 @@ import { CameraUniformBlockTotemCache, CameraUniformBlockString } from "../totem
3
3
  import { mercatorXYToGLPosition, cartesian3DToGLPosition, R_3D, R } from "../../util/shaderfunctions/geometrytransformations";
4
4
  import { noRegisterGlobeProgramCache } from "../programcache";
5
5
  import { drawArrays } from "../../util/gl-util/draw-options/methods"; //DrawRangeIndexParams
6
- import { attributeLoader } from "../../util/gl-util/buffer/attribute-loader";
6
+ import { AttributeLoader } from "../../util/gl-util/buffer/attribute-loader";
7
7
  import { UniformBlockManager } from "../../util/gl-util/uniform-block/manager";
8
8
  const uniformBindingPoints = {
9
9
  camera: 0,
@@ -139,34 +139,30 @@ class PointOnGlobeProgram {
139
139
  const ubo = uniformBlockManager.createUBO(this.gl);
140
140
  return ubo;
141
141
  }
142
- createVAO(pos3DBufferObj, pos2DBufferObj, rgbaBufferObj, sizeBufferObj) {
143
- const { gl } = this;
144
- const vao = gl.createVertexArray();
145
- gl.bindVertexArray(vao);
146
- attributeLoader(gl, pos3DBufferObj, 0, 3);
147
- attributeLoader(gl, pos2DBufferObj, 1, 2);
148
- attributeLoader(gl, rgbaBufferObj, 2, 4, { escapeValues: [-1, -1, -1, -1] });
149
- attributeLoader(gl, sizeBufferObj, 3, 1, { escapeValues: [-1] });
150
- gl.bindVertexArray(null);
151
- gl.bindBuffer(gl.ARRAY_BUFFER, null);
152
- return vao;
142
+ createAttributeLoader(pos3DBufferObj, pos2DBufferObj, rgbaBufferObj, sizeBufferObj) {
143
+ return new AttributeLoader(this.gl, [
144
+ { bufferAndReadInfo: pos3DBufferObj, index: 0, size: 3 },
145
+ { bufferAndReadInfo: pos2DBufferObj, index: 1, size: 2 },
146
+ { bufferAndReadInfo: rgbaBufferObj, index: 2, size: 4, options: { escapeValues: [-1, -1, -1, -1] } },
147
+ { bufferAndReadInfo: sizeBufferObj, index: 3, size: 1, options: { escapeValues: [-1] } }
148
+ ]);
153
149
  }
154
150
  /**
155
151
  *
156
152
  * @param {vertexArrayObject} vao
157
153
  * @param {DrawRangeIndexParams} drawOptions
158
154
  */
159
- draw(vao, drawOptions, ubo = null) {
155
+ draw(attibuteLoader, drawOptions, ubo = null) {
160
156
  const { gl, program } = this;
161
157
  gl.useProgram(program);
162
- gl.bindVertexArray(vao);
158
+ attibuteLoader.bind();
163
159
  this.cameraBlockTotem.bind(uniformBindingPoints.camera);
164
160
  ubo = ubo || this._defaultUBO;
165
161
  ubo.bind();
166
162
  drawArrays(gl, gl.POINTS, drawOptions);
167
163
  ubo.unbind();
168
164
  this.cameraBlockTotem.unbind(uniformBindingPoints.camera);
169
- gl.bindVertexArray(null);
165
+ attibuteLoader.unbind();
170
166
  }
171
167
  free() {
172
168
  if (this._isFreed)
@@ -9,7 +9,7 @@ import { CameraUniformBlockTotemCache, CameraUniformBlockString } from "../totem
9
9
  import { PI, cartesian3DToGLPosition, circleLimpFromLongLatRadCenterCartesian3D_accurate } from "../../util/shaderfunctions/geometrytransformations";
10
10
  import { createProgram } from "../../util/webglobjectbuilders";
11
11
  import { noRegisterGlobeProgramCache } from "../programcache";
12
- import { attributeLoader } from "../../util/gl-util/buffer/attribute-loader";
12
+ import { AttributeLoader, attributeLoader } from "../../util/gl-util/buffer/attribute-loader";
13
13
  import { drawInstanced } from "../../util/gl-util/draw-options/methods";
14
14
  import { UniformBlockManager } from "../../util/gl-util/uniform-block/manager";
15
15
  const uboBlockManager = new UniformBlockManager("FlexibleBlock", [
@@ -67,7 +67,6 @@ class Logic {
67
67
  constructor(globe) {
68
68
  this.globe = globe;
69
69
  this.gl = globe.gl;
70
- this._vaoCache = [];
71
70
  this.program = createProgram(this.gl, vs, fs);
72
71
  const { gl, program } = this;
73
72
  const currentProgram = gl.getParameter(gl.CURRENT_PROGRAM);
@@ -95,22 +94,18 @@ class Logic {
95
94
  uboBlockManager.assignBindingPoint(this.gl, this.program);
96
95
  this._defaultUBO = uboBlockManager.createUBO(this.gl);
97
96
  }
98
- createVAO(pos3DObj, radiusObj, colorObj) {
99
- const { gl } = this;
100
- const vao = gl.createVertexArray();
97
+ createAttributeLoader(pos3DObj, radiusObj, colorObj) {
101
98
  const divisor = 1;
102
- gl.bindVertexArray(vao);
103
- attributeLoader(gl, pos3DObj, 0, 3, { divisor });
104
- attributeLoader(gl, radiusObj, 1, 1, { divisor, escapeValues: [-1] });
105
- attributeLoader(gl, colorObj, 2, 4, { divisor, escapeValues: [-1, -1, -1, -1] });
106
- gl.bindVertexArray(null);
107
- this._vaoCache.push(vao);
108
- return vao;
99
+ return new AttributeLoader(this.gl, [
100
+ { bufferAndReadInfo: pos3DObj, index: 0, size: 3, options: { divisor } },
101
+ { bufferAndReadInfo: radiusObj, index: 1, size: 1, options: { divisor, escapeValues: [-1] } },
102
+ { bufferAndReadInfo: colorObj, index: 2, size: 4, options: { divisor, escapeValues: [-1, -1, -1, -1] } }
103
+ ]);
109
104
  }
110
- draw(vao, drawOptions, opacity = 1.0, ubo = null) {
105
+ draw(attibuteLoader, drawOptions, opacity = 1.0, ubo = null) {
111
106
  const { gl, program } = this;
112
107
  gl.useProgram(program);
113
- gl.bindVertexArray(vao);
108
+ attibuteLoader.bind();
114
109
  if (opacity !== this._uniforms.opacity) {
115
110
  gl.uniform1f(this._uniforms.opacity_loc, opacity);
116
111
  this._uniforms.opacity = opacity;
@@ -119,15 +114,13 @@ class Logic {
119
114
  ubo.bind();
120
115
  drawInstanced(gl, gl.TRIANGLE_FAN, drawOptions);
121
116
  ubo.unbind();
122
- gl.bindVertexArray(null);
117
+ attibuteLoader.unbind();
123
118
  }
124
119
  free() {
125
120
  if (this._isFreed)
126
121
  return;
127
122
  CameraUniformBlockTotemCache.release(this.globe);
128
123
  this.gl.deleteProgram(this.program);
129
- for (const vao of this._vaoCache)
130
- this.gl.deleteVertexArray(vao);
131
124
  this._isFreed = true;
132
125
  }
133
126
  }
@@ -2,7 +2,7 @@ import { createProgram } from "../../util/webglobjectbuilders";
2
2
  import { CameraUniformBlockTotemCache, CameraUniformBlockString } from "../totems";
3
3
  import { mercatorXYToGLPosition, cartesian3DToGLPosition } from "../../util/shaderfunctions/geometrytransformations";
4
4
  import { noRegisterGlobeProgramCache } from "../programcache";
5
- import { attributeLoader } from "../../util/gl-util/buffer/attribute-loader";
5
+ import { AttributeLoader } from "../../util/gl-util/buffer/attribute-loader";
6
6
  import { drawArrays } from "../../util/gl-util/draw-options/methods";
7
7
  import { UniformBlockManager } from "../../util/gl-util/uniform-block/manager";
8
8
  import { singularity } from "../../shaders/fragment-toy/singularity";
@@ -105,32 +105,28 @@ class Logic {
105
105
  uniformBlockManager.assignBindingPoint(this.gl, this.program);
106
106
  this._defaultUBO = uniformBlockManager.createUBO(this.gl);
107
107
  }
108
- createVAO(pos3DBuffer, pos2DBuffer, colorBuffer, sizeBuffer) {
109
- const { gl } = this;
110
- const vao = gl.createVertexArray();
111
- gl.bindVertexArray(vao);
112
- attributeLoader(gl, pos3DBuffer, 0, 3);
113
- attributeLoader(gl, pos2DBuffer, 1, 2);
114
- attributeLoader(gl, colorBuffer, 2, 4, { escapeValues: [-1, -1, -1, -1] });
115
- attributeLoader(gl, sizeBuffer, 3, 1, { escapeValues: [-1] });
116
- gl.bindVertexArray(null);
117
- gl.bindBuffer(gl.ARRAY_BUFFER, null);
118
- return vao;
108
+ createAttributeLoader(pos3DBuffer, pos2DBuffer, colorBuffer, sizeBuffer) {
109
+ return new AttributeLoader(this.gl, [
110
+ { bufferAndReadInfo: pos3DBuffer, index: 0, size: 3 },
111
+ { bufferAndReadInfo: pos2DBuffer, index: 1, size: 2 },
112
+ { bufferAndReadInfo: colorBuffer, index: 2, size: 4, options: { escapeValues: [-1, -1, -1, -1] } },
113
+ { bufferAndReadInfo: sizeBuffer, index: 3, size: 1, options: { escapeValues: [-1] } }
114
+ ]);
119
115
  }
120
116
  createUBO() {
121
117
  const ubo = uniformBlockManager.createUBO(this.gl);
122
118
  return ubo;
123
119
  }
124
- draw(vao, drawOptions, ubo = null) {
120
+ draw(attributeLoader, drawOptions, ubo = null) {
125
121
  const { gl, program, cameraBlockTotem } = this;
126
122
  gl.useProgram(program);
127
- gl.bindVertexArray(vao);
123
+ attributeLoader.bind();
128
124
  cameraBlockTotem.bind(cameraBlockBindingPoint);
129
125
  ubo = ubo || this._defaultUBO;
130
126
  ubo.bind();
131
127
  drawArrays(gl, gl.POINTS, drawOptions);
132
128
  ubo.unbind();
133
- gl.bindVertexArray(null);
129
+ attributeLoader.unbind();
134
130
  cameraBlockTotem.unbind(cameraBlockBindingPoint);
135
131
  this.globe.DrawRender();
136
132
  }
@@ -4,7 +4,7 @@ import { DemTextureManagerCache, DEM_TEXTURE_BLOCK_STRING } from "../totems/atta
4
4
  import { cartesian3DToGLPosition, mercatorXYToGLPosition, POLE_BY_PI } from "../../util/shaderfunctions/geometrytransformations";
5
5
  import { relativeBBoxPositionRadian } from "../../util/shaderfunctions/geometrytransformations";
6
6
  import { drawArrays } from "../../util/gl-util/draw-options/methods";
7
- import { attributeLoader, resetAttributeDefault, setDefaultAttributeValues } from "../../util/gl-util/buffer/attribute-loader";
7
+ import { AttributeLoader } from "../../util/gl-util/buffer/attribute-loader";
8
8
  import { WORLD_RADIUS_3D } from "../../Math/constants";
9
9
  import { UniformBlockManager } from "../../util/gl-util/uniform-block/manager";
10
10
  // const ESCAPE_VALUE = 0.123456;
@@ -84,7 +84,7 @@ void main() {
84
84
  break;
85
85
  }
86
86
  }
87
- vec3 position = a_position * (elevation + altitude);
87
+ vec3 position = a_position * (elevation + altitude * elevation_scale);
88
88
  gl_Position = cartesian3DToGLPosition(position);
89
89
  } else {
90
90
  vec2 mercatorXY = a_xy * POLE_BY_PI;
@@ -171,21 +171,23 @@ export class TextureDemTriangles {
171
171
  this.demTextureManager = DemTextureManagerCache.get(this.globe);
172
172
  this.demTextureManager.assignBindingPoint(this.program, uniformBindingPoints.dem);
173
173
  }
174
- createVAO(pos3dBufferInfo, longLatBufferInfo, indexBufferInfo, variativeColorBuffer) {
175
- const vao = this.gl.createVertexArray();
176
- this.gl.bindVertexArray(vao);
177
- attributeLoader(this.gl, pos3dBufferInfo, this.locations.attributes.a_position, 3);
178
- attributeLoader(this.gl, longLatBufferInfo, this.locations.attributes.a_xy, 2);
179
- attributeLoader(this.gl, indexBufferInfo, this.locations.attributes.a_index, 1, {
180
- dataType: "uint16",
181
- escapeValues: [IndexAttributeEscapeValue],
182
- });
183
- attributeLoader(this.gl, variativeColorBuffer, this.locations.attributes.a_color, 4, {
184
- dataType: "uint8",
185
- escapeValues: [0, 0, 0, 255]
186
- });
187
- this.gl.bindVertexArray(null);
188
- return vao;
174
+ createAttributeLoader(pos3dBufferInfo, longLatBufferInfo, indexBufferInfo, variativeColorBuffer) {
175
+ return new AttributeLoader(this.gl, [
176
+ { bufferAndReadInfo: pos3dBufferInfo, index: this.locations.attributes.a_position, size: 3, options: {} },
177
+ { bufferAndReadInfo: longLatBufferInfo, index: this.locations.attributes.a_xy, size: 2, options: {} },
178
+ {
179
+ bufferAndReadInfo: indexBufferInfo, index: this.locations.attributes.a_index, size: 1, options: {
180
+ dataType: "uint16",
181
+ escapeValues: [IndexAttributeEscapeValue],
182
+ }
183
+ },
184
+ {
185
+ bufferAndReadInfo: variativeColorBuffer, index: this.locations.attributes.a_color, size: 4, options: {
186
+ dataType: "uint8",
187
+ escapeValues: [0, 0, 0, 255]
188
+ }
189
+ },
190
+ ]);
189
191
  }
190
192
  createUBO(bufferReadType = "STATIC_DRAW") {
191
193
  const ubo = styleBlockManager.createUBO(this.gl, bufferReadType);
@@ -200,12 +202,12 @@ export class TextureDemTriangles {
200
202
  DemTextureManagerCache.release(this.globe);
201
203
  CameraUniformBlockTotemCache.release(this.globe);
202
204
  }
203
- draw(vao, drawOptions, ubo) {
205
+ draw(attributeLoader, drawOptions, ubo) {
204
206
  const gl = this.gl;
205
207
  gl.useProgram(this.program);
206
208
  this.cameraUniformBlock.bind(uniformBindingPoints.camera);
207
209
  this.demTextureManager.bindData(0, uniformBindingPoints.dem);
208
- gl.bindVertexArray(vao);
210
+ attributeLoader.bind();
209
211
  ubo.bind();
210
212
  // This program has two fragment outputs (location 0: color, location 1: index).
211
213
  // When rendering to the default framebuffer (no picking FBO bound), only location 0
@@ -226,24 +228,12 @@ export class TextureDemTriangles {
226
228
  // gl.drawBuffers([gl.BACK]);
227
229
  // }
228
230
  this.demTextureManager.unbindData(0, uniformBindingPoints.dem);
229
- gl.bindVertexArray(null);
231
+ attributeLoader.unbind();
230
232
  gl.bindTexture(gl.TEXTURE_2D_ARRAY, null);
231
233
  gl.useProgram(null);
232
234
  ubo.unbind();
233
235
  this.cameraUniformBlock.unbind(uniformBindingPoints.camera);
234
236
  }
235
- setDefaultDefaultAttributeValues() {
236
- const gl = this.gl;
237
- setDefaultAttributeValues(gl, this.locations.attributes.a_index, 1, [IndexAttributeEscapeValue], "uint16");
238
- setDefaultAttributeValues(gl, this.locations.attributes.a_color, 4, [0, 0, 0, 255], "uint8");
239
- }
240
- resetDefaultAttributeValues() {
241
- const gl = this.gl;
242
- gl.disableVertexAttribArray(this.locations.attributes.a_index);
243
- resetAttributeDefault(gl, this.locations.attributes.a_index);
244
- gl.disableVertexAttribArray(this.locations.attributes.a_color);
245
- resetAttributeDefault(gl, this.locations.attributes.a_color);
246
- }
247
237
  _getUniformBlockOffset(name) {
248
238
  // hardcoded offsets based on std140 layout rules
249
239
  const offsets = {
@@ -1,7 +1,7 @@
1
1
  import { createProgram } from "../../../util/webglobjectbuilders";
2
2
  import { CameraUniformBlockTotem, CameraUniformBlockString } from "../../totems/index";
3
3
  import { noRegisterGlobeProgramCache, globeProgramCache } from "../../programcache";
4
- import { attributeLoader } from "../../../util/gl-util/buffer/attribute-loader";
4
+ import { AttributeLoader } from "../../../util/gl-util/buffer/attribute-loader";
5
5
  import { UniformBlockManager } from "../../../util/gl-util/uniform-block/manager";
6
6
  import { POLE, PI, longLatRadToMercator, mercatorXYToGLPosition, longLatRadToCartesian3D, circleLimpFromLongLatRadCenterCartesian3D_accurate, circleLimpFromLongLatRadCenterMercatorCompass_accurate,
7
7
  //circleLimpFromLongLatRadCenterMercatorRealDistanceNew_accurate,
@@ -131,7 +131,6 @@ export class Logic {
131
131
  gl;
132
132
  _lastMode;
133
133
  _lastEdgeCount;
134
- _lastAlphaMultiplier;
135
134
  program;
136
135
  _edgeCountLocation;
137
136
  _draw_modeLocation;
@@ -144,7 +143,6 @@ export class Logic {
144
143
  this.gl = globe.gl;
145
144
  this._lastMode = 0;
146
145
  this._lastEdgeCount = 64;
147
- this._lastAlphaMultiplier = 1.0;
148
146
  this.program = createProgram(this.gl, vertexShaderSource, fragmentShaderSource);
149
147
  const { gl, program } = this;
150
148
  // set attributes locations
@@ -174,7 +172,7 @@ export class Logic {
174
172
  this._defaultFlexibleUBO = flexibleBlockManager.createUBO(gl);
175
173
  gl.useProgram(currentProgram);
176
174
  }
177
- draw(length, vao, edgeCount, drawMode, ubo = null) {
175
+ draw(length, attributeLoader, edgeCount, drawMode, ubo = null) {
178
176
  const { gl, program, cameraBlockTotem, cameraBlockBindingPoint } = this;
179
177
  gl.useProgram(program);
180
178
  if (drawModeMap[drawMode] !== this._lastMode) {
@@ -193,10 +191,10 @@ export class Logic {
193
191
  }
194
192
  const overdraw = drawModeMap[drawMode];
195
193
  cameraBlockTotem.bind(cameraBlockBindingPoint);
196
- gl.bindVertexArray(vao);
194
+ attributeLoader.bind();
197
195
  gl.drawArraysInstanced(gl[drawMode], 0, edgeCount + overdraw, length);
198
196
  cameraBlockTotem.unbind(cameraBlockBindingPoint);
199
- gl.bindVertexArray(null);
197
+ attributeLoader.unbind();
200
198
  if (ubo) {
201
199
  ubo.unbind();
202
200
  }
@@ -219,22 +217,18 @@ export class Logic {
219
217
  in float radius; // in meter
220
218
  in float filling_mode; // 0.0: constant, 1.0: fading, 2.0: hide
221
219
  */
222
- createVAO(center2dObj, center3dObj, startAngle2DObj, tailAngle2DObj, startAngle3DObj, tailAngle3DObj, colorObj, radiusObj, colorModeObj) {
223
- const { gl } = this;
224
- const vao = gl.createVertexArray();
225
- gl.bindVertexArray(vao);
226
- attributeLoader(gl, center2dObj, 0, 2, { divisor: 1 });
227
- attributeLoader(gl, center3dObj, 1, 3, { divisor: 1 });
228
- attributeLoader(gl, startAngle2DObj, 2, 1, { divisor: 1 });
229
- attributeLoader(gl, tailAngle2DObj, 3, 1, { divisor: 1 });
230
- attributeLoader(gl, startAngle3DObj, 4, 1, { divisor: 1 });
231
- attributeLoader(gl, tailAngle3DObj, 5, 1, { divisor: 1 });
232
- attributeLoader(gl, colorObj, 6, 4, { divisor: 1, escapeValues: [-1.0, -1.0, -1.0, -1.0] });
233
- attributeLoader(gl, radiusObj, 7, 1, { divisor: 1, escapeValues: [-1.0] });
234
- attributeLoader(gl, colorModeObj, 8, 1, { divisor: 1, escapeValues: [-1.0] });
235
- gl.bindVertexArray(null);
236
- gl.bindBuffer(gl.ARRAY_BUFFER, null);
237
- return vao;
220
+ createAttributeLoader(center2dObj, center3dObj, startAngle2DObj, tailAngle2DObj, startAngle3DObj, tailAngle3DObj, colorObj, radiusObj, colorModeObj) {
221
+ return new AttributeLoader(this.gl, [
222
+ { bufferAndReadInfo: center2dObj, index: 0, size: 2, options: { divisor: 1 } },
223
+ { bufferAndReadInfo: center3dObj, index: 1, size: 3, options: { divisor: 1 } },
224
+ { bufferAndReadInfo: startAngle2DObj, index: 2, size: 1, options: { divisor: 1 } },
225
+ { bufferAndReadInfo: tailAngle2DObj, index: 3, size: 1, options: { divisor: 1 } },
226
+ { bufferAndReadInfo: startAngle3DObj, index: 4, size: 1, options: { divisor: 1 } },
227
+ { bufferAndReadInfo: tailAngle3DObj, index: 5, size: 1, options: { divisor: 1 } },
228
+ { bufferAndReadInfo: colorObj, index: 6, size: 4, options: { divisor: 1, escapeValues: [-1.0, -1.0, -1.0, -1.0] } },
229
+ { bufferAndReadInfo: radiusObj, index: 7, size: 1, options: { divisor: 1, escapeValues: [-1.0] } },
230
+ { bufferAndReadInfo: colorModeObj, index: 8, size: 1, options: { divisor: 1, escapeValues: [-1.0] } }
231
+ ]);
238
232
  }
239
233
  createUBO() {
240
234
  const { gl } = this;
@@ -8,6 +8,7 @@ layout(std140) uniform DemTextureUniformBlock {
8
8
  vec4 u_textureDataCoverRatio[6]; // 96 bytes
9
9
  vec2 u_textureResolution; // 8 bytes
10
10
  int u_breakLoopIndex; // 4 bytes
11
+ float elevation_scale;
11
12
  };
12
13
  uniform sampler2DArray u_demTexture;
13
14
  `;
@@ -17,8 +18,9 @@ const MAXLAYERS = 6;
17
18
  // CoverRatio: 6 * 16 bytes = 96
18
19
  // Resolution: 8 bytes (offset 192)
19
20
  // BreakLoopIndex: 4 bytes (offset 200)
20
- // Total used: 204 bytes.
21
- // std140 blocks are typically padded to 16 bytes alignment -> 208 bytes.
21
+ // Elevation scale: 4 bytes (offset 204)
22
+ // Total used: 208 bytes.
23
+ // std140 blocks no need for padding -> 208 bytes.
22
24
  // 208 bytes / 4 bytes per float = 52 floats.
23
25
  const uniformBlockData = new Float32Array(52);
24
26
  function drawnedTilesHash(drawnTiles) {
@@ -162,6 +164,7 @@ export class DemTextureManager {
162
164
  uniformBlockData[49] = this.textureHeight;
163
165
  // Set break loop index (offset 200 bytes -> index 50)
164
166
  uniformBlockData[50] = this.mergedData.length;
167
+ uniformBlockData[51] = this._globe.api_GetZScale();
165
168
  // Unbind texture after updating
166
169
  gl.bindTexture(gl.TEXTURE_2D_ARRAY, null);
167
170
  gl.bindBuffer(gl.UNIFORM_BUFFER, this.uniformBuffer);
@@ -8,7 +8,7 @@ export class LinePlugin {
8
8
  globe = null;
9
9
  gl = null;
10
10
  program = null;
11
- vao = null;
11
+ attributeLoader = null;
12
12
  _options;
13
13
  _uboHandler = null;
14
14
  bufferOrchestrator;
@@ -36,21 +36,24 @@ export class LinePlugin {
36
36
  this._uboHandler = this.program.createUBO();
37
37
  this.setDefaultColor(this._options.defaultColor);
38
38
  this._fillManagerMap();
39
- this.vao = this.program.createVAO(...this._createSelectBufferNames().map((key) => {
40
- if (key === null) {
41
- return null;
42
- }
43
- const bufferManagerComp = this.bufferManagersMap.get(key);
44
- if (bufferManagerComp === undefined) {
45
- throw new Error(`Buffer key ${key} does not exist in bufferManagersMap`);
46
- }
47
- const { bufferManager } = bufferManagerComp;
48
- return {
49
- stride: 0,
50
- offset: 0,
51
- buffer: bufferManager.buffer
52
- };
53
- }));
39
+ if (this.program.createAttributeLoader) {
40
+ const data = this._createSelectBufferNames().map((key) => {
41
+ if (key === null) {
42
+ return null;
43
+ }
44
+ const bufferManagerComp = this.bufferManagersMap.get(key);
45
+ if (bufferManagerComp === undefined) {
46
+ throw new Error(`Buffer key ${key} does not exist in bufferManagersMap`);
47
+ }
48
+ const { bufferManager } = bufferManagerComp;
49
+ return {
50
+ stride: 0,
51
+ offset: 0,
52
+ buffer: bufferManager.buffer
53
+ };
54
+ });
55
+ this.attributeLoader = this.program.createAttributeLoader(...data);
56
+ }
54
57
  }
55
58
  // PLUGIN INTERFACE METHODS
56
59
  increaseSpace(amount) {
@@ -122,10 +125,10 @@ export class LinePlugin {
122
125
  console.warn("Plugin has been freed, cannot draw.");
123
126
  }
124
127
  ;
125
- if (!this.globe || !this.gl || !this.program || !this.vao) {
128
+ if (!this.globe || !this.gl || !this.program || !this.attributeLoader) {
126
129
  throw new Error("Globe, GL context or program is not initialized.");
127
130
  }
128
- const { bufferOrchestrator, _options, _uboHandler, vao } = this;
131
+ const { bufferOrchestrator, _options, _uboHandler, attributeLoader } = this;
129
132
  if (!bufferOrchestrator || !bufferOrchestrator || !_uboHandler) {
130
133
  throw new Error("Buffer orchestrator is not initialized.");
131
134
  }
@@ -140,18 +143,18 @@ export class LinePlugin {
140
143
  const currentGeometry = this.globe.api_GetCurrentGeometry();
141
144
  if (currentGeometry === 0 && globeViewOn) {
142
145
  // @ts-ignore
143
- this.program.draw(vao, drawOptions, opacity, _uboHandler);
146
+ this.program.draw(attributeLoader, drawOptions, opacity, _uboHandler);
144
147
  }
145
148
  else if (currentGeometry === 1 && flatViewOn) {
146
149
  // @ts-ignore
147
- this.program.draw(vao, drawOptions, opacity, _uboHandler);
150
+ this.program.draw(attributeLoader, drawOptions, opacity, _uboHandler);
148
151
  }
149
152
  this.gl.enable(this.gl.DEPTH_TEST); // Re-enable depth test after drawing
150
153
  }
151
154
  free() {
152
155
  if (this._freed)
153
156
  return;
154
- // TODO: FILL
157
+ this.attributeLoader.free();
155
158
  this.bufferManagersMap.forEach((manager) => {
156
159
  manager.bufferManager.free();
157
160
  });
@@ -11,7 +11,7 @@ export class PieceOfPiePlugin {
11
11
  globe = null;
12
12
  gl = null;
13
13
  program = null;
14
- vao = null;
14
+ attributeLoader = null;
15
15
  bufferManagersMap = null;
16
16
  bufferOrchestrator = new BufferOrchestrator({ capacity: INITIAL_CAPACITY });
17
17
  drawMode = "BOTH";
@@ -144,7 +144,7 @@ export class PieceOfPiePlugin {
144
144
  this.gl = gl;
145
145
  this.program = PieceOfPieProgramCache.get(globe);
146
146
  this._createBufferManagersMap();
147
- this.vao = this.program.createVAO(
147
+ this.attributeLoader = this.program.createAttributeLoader(
148
148
  //@ts-ignore
149
149
  ...['centerCoords2d',
150
150
  'centerCoords3d',
@@ -170,18 +170,18 @@ export class PieceOfPiePlugin {
170
170
  this._uboHandler.updateSingle("u_opacity", new Float32Array([this._pluginOptions.opacity ?? 1.0])); // Default opacity is 1.0
171
171
  }
172
172
  draw3D() {
173
- if (!this.gl || !this.program || !this.vao || !this.globe) {
173
+ if (!this.gl || !this.program || !this.attributeLoader || !this.globe) {
174
174
  console.warn("PieChartPlugin is not initialized properly Or unregistered from globe.");
175
175
  return;
176
176
  }
177
177
  const length = this.bufferOrchestrator.length;
178
178
  this.gl.disable(this.gl.DEPTH_TEST);
179
179
  if (this.drawMode === "BOTH") {
180
- this.program?.draw(length, this.vao, EDGE_COUNT, "LINE_STRIP", this._uboHandler);
181
- this.program?.draw(length, this.vao, EDGE_COUNT, "TRIANGLE_FAN", this._uboHandler);
180
+ this.program?.draw(length, this.attributeLoader, EDGE_COUNT, "LINE_STRIP", this._uboHandler);
181
+ this.program?.draw(length, this.attributeLoader, EDGE_COUNT, "TRIANGLE_FAN", this._uboHandler);
182
182
  }
183
183
  else {
184
- this.program?.draw(length, this.vao, EDGE_COUNT, this.drawMode, this._uboHandler);
184
+ this.program?.draw(length, this.attributeLoader, EDGE_COUNT, this.drawMode, this._uboHandler);
185
185
  }
186
186
  this.gl.enable(this.gl.DEPTH_TEST);
187
187
  }
@@ -191,7 +191,7 @@ export class PieceOfPiePlugin {
191
191
  return;
192
192
  }
193
193
  PieceOfPieProgramCache.release(this.globe);
194
- this.gl?.deleteVertexArray(this.vao);
194
+ this.attributeLoader?.free();
195
195
  this._isFreed = true;
196
196
  this.globe = null;
197
197
  this.gl = null;
@@ -1,6 +1,6 @@
1
1
  // import { ArcOnTerrainPluginOptions } from "./type";
2
2
  import { LineStripProgramCache } from "../../programs/line-on-globe/linestrip/linestrip";
3
- import { createBufferAndReadInfo } from "../../util/gl-util/buffer/attribute-loader";
3
+ import { AttributeLoader } from "../../util/gl-util/buffer/attribute-loader";
4
4
  import { BufferManager, BufferOrchestrator } from "../../util/account/single-attribute-buffer-management/index";
5
5
  import { globe3Dcoordinates, globe2Dcoordinates, RADIAN } from "../../Math/methods";
6
6
  import { generateArcPoints, evenlySpacedArcPoints } from "../../Math/arc-cdf-points";
@@ -25,11 +25,11 @@ function createArc(start, end) {
25
25
  export class ArcOnTerrainPlugin {
26
26
  id;
27
27
  program = null;
28
- bufferManagersMap = null;
28
+ bufferManagersMap = new Map();
29
29
  bufferOrchestrator = new BufferOrchestrator({ capacity: INITAL_CAPACITY });
30
30
  _opacity = 1;
31
31
  _arcUBOHandler = null;
32
- _vao = null;
32
+ _attributeLoader = null;
33
33
  globe = null;
34
34
  gl = null;
35
35
  _arcMap;
@@ -226,11 +226,11 @@ export class ArcOnTerrainPlugin {
226
226
  this.__buildDynamicArcs();
227
227
  });
228
228
  this.program = LineStripProgramCache.get(globe);
229
+ this._cameraUniformBlock = CameraUniformBlockTotemCache.get(globe);
230
+ this._fillbufferManagersMap();
229
231
  this._staticDynamicStrategy = new StaticDynamicStrategy(globe, DYNAMIC_STRATEGY_START_LOD, () => {
230
232
  this.__buildStaticArcs();
231
233
  }); // Initialize static-dynamic strategy with a transition level of 8
232
- this._cameraUniformBlock = CameraUniformBlockTotemCache.get(globe);
233
- this._fillbufferManagersMap();
234
234
  this.bufferOrchestrator = new BufferOrchestrator();
235
235
  this._arcUBOHandler = this.program.createUBO();
236
236
  this._arcUBOHandler.update(new Map([
@@ -245,12 +245,9 @@ export class ArcOnTerrainPlugin {
245
245
  }
246
246
  const globe = this.globe;
247
247
  this._staticDynamicStrategy?.updateState();
248
- // if (globe.api_IsScreenMoving()) {
249
- // this._buildArcs(); // can be async
250
- // }
251
248
  this._frameCounterTrigger?.trigger();
252
- const { gl, program, bufferOrchestrator, _vao, _arcUBOHandler, } = this;
253
- if (!gl || !program || !bufferOrchestrator || !_vao || !_arcUBOHandler) {
249
+ const { gl, program, bufferOrchestrator, _attributeLoader, _arcUBOHandler, } = this;
250
+ if (!gl || !program || !bufferOrchestrator || !_attributeLoader || !_arcUBOHandler) {
254
251
  console.warn("WebGL context, program, or buffer orchestrator is not initialized.");
255
252
  return;
256
253
  }
@@ -265,7 +262,7 @@ export class ArcOnTerrainPlugin {
265
262
  },
266
263
  indexes: null
267
264
  };
268
- program.draw(_vao, drawOptions, this._opacity, _arcUBOHandler);
265
+ program.draw(_attributeLoader, drawOptions, this._opacity, _arcUBOHandler);
269
266
  gl.enable(gl.DEPTH_TEST);
270
267
  }
271
268
  _buildArcs(subSetIDs = null) {
@@ -280,7 +277,7 @@ export class ArcOnTerrainPlugin {
280
277
  __buildStaticArcs(subSetIDs = null) {
281
278
  const { globe, _arcMap, _cameraUniformBlock, bufferManagersMap, bufferOrchestrator } = this;
282
279
  if (!globe || !_cameraUniformBlock || !bufferManagersMap || !bufferOrchestrator) {
283
- console.warn("Globe or camera uniform block is not initialized.");
280
+ console.warn(`Globe or camera uniform block is not initialized. ${globe} ${_cameraUniformBlock} ${bufferManagersMap} ${bufferOrchestrator}`);
284
281
  return;
285
282
  }
286
283
  const bufferKey = [this.globe.api_GetCurrentGeometry() === 0 ? "position3d" : "position2d"];
@@ -321,7 +318,7 @@ export class ArcOnTerrainPlugin {
321
318
  __buildDynamicArcs(subSetIDs = null) {
322
319
  const { globe, _arcMap, _cameraUniformBlock, bufferManagersMap } = this;
323
320
  if (!globe || !_cameraUniformBlock || !bufferManagersMap) {
324
- console.warn("Globe or camera uniform block is not initialized.");
321
+ console.warn(`Globe or camera uniform block is not initialized. ${globe} ${_cameraUniformBlock} ${bufferManagersMap}`);
325
322
  return;
326
323
  }
327
324
  const bufferKey = [
@@ -392,7 +389,6 @@ export class ArcOnTerrainPlugin {
392
389
  }
393
390
  const g2D = globe2Dcoordinates(globe);
394
391
  const { flatViewOn, globeViewOn, variativeColorsOn } = this._options;
395
- this.bufferManagersMap = new Map();
396
392
  if (globeViewOn) {
397
393
  this.bufferManagersMap.set("position3d", {
398
394
  bufferManager: new BufferManager(gl, 3 * (this._options.vertexCount + 1), { bufferType: "STREAM_DRAW", initialCapacity: INITAL_CAPACITY }),
@@ -441,10 +437,10 @@ export class ArcOnTerrainPlugin {
441
437
  // @ts-ignore
442
438
  const bufferManager = this.bufferManagersMap.get(key).bufferManager;
443
439
  // @ts-ignore
444
- return createBufferAndReadInfo(bufferManager.buffer);
440
+ return AttributeLoader.createBufferAndReadInfo(bufferManager.buffer);
445
441
  });
446
442
  // @ts-ignore
447
- this._vao = this.program.createVAO(bufferObjects[0], // position3d
443
+ this._attributeLoader = this.program?.createAttributeLoader(bufferObjects[0], // position3d
448
444
  bufferObjects[1], // position2d
449
445
  bufferObjects[2] // color
450
446
  );
@@ -474,6 +470,7 @@ export class ArcOnTerrainPlugin {
474
470
  CameraUniformBlockTotemCache.release(this.globe);
475
471
  LineStripProgramCache.release(this.globe);
476
472
  this.gl = null;
473
+ this.program = null;
477
474
  this.globe = null;
478
475
  this._arcMap.clear();
479
476
  this._coordinaateBufferKeysForUpdate = [];
@@ -1,7 +1,7 @@
1
1
  import { LineStripProgramCache } from "../../programs/line-on-globe/linestrip/linestrip";
2
2
  import { BufferManager, BufferOrchestrator } from "../../util/account/single-attribute-buffer-management/index";
3
3
  import { CameraUniformBlockTotemCache } from "../../programs/totems/camerauniformblock";
4
- import { createBufferAndReadInfo } from "../../util/gl-util/buffer/attribute-loader";
4
+ import { AttributeLoader } from "../../util/gl-util/buffer/attribute-loader";
5
5
  import * as CircleMethods from "../../Math/circle";
6
6
  import * as CircleCDF from "../../Math/circle-cdf-points";
7
7
  import * as vec3 from "../../Math/vec3";
@@ -66,7 +66,7 @@ export class CircleOnTerrainPlugin {
66
66
  _freed = false;
67
67
  _circleUBOHandler = null;
68
68
  _opacity = 1;
69
- _vao = null;
69
+ _attributeLoader = null;
70
70
  _dobuild = true; // This is used to trigger the build of circles when the camera position changes.
71
71
  _frameCounterTrigger = null;
72
72
  _staticDynamicStrategy = null;
@@ -76,7 +76,6 @@ export class CircleOnTerrainPlugin {
76
76
  defaultHeightFromGroundIn3D: 30.0,
77
77
  isMSL: false
78
78
  };
79
- _textDataPreAdaptor = undefined;
80
79
  constructor(id, styleOptions = null) {
81
80
  this.id = id;
82
81
  if (styleOptions) {
@@ -125,8 +124,8 @@ export class CircleOnTerrainPlugin {
125
124
  }
126
125
  });
127
126
  }
128
- this._vao = this.lineProgram.createVAO(createBufferAndReadInfo(this.bufferManagersMap.get("position3d")?.bufferManager.buffer), createBufferAndReadInfo(this.bufferManagersMap.get("position2d")?.bufferManager.buffer), this._options.variativeColorsOn ?
129
- createBufferAndReadInfo(this.bufferManagersMap.get("color")?.bufferManager.buffer) : null);
127
+ this._attributeLoader = this.lineProgram.createAttributeLoader(AttributeLoader.createBufferAndReadInfo(this.bufferManagersMap.get("position3d")?.bufferManager.buffer), AttributeLoader.createBufferAndReadInfo(this.bufferManagersMap.get("position2d")?.bufferManager.buffer), this._options.variativeColorsOn ?
128
+ AttributeLoader.createBufferAndReadInfo(this.bufferManagersMap.get("color")?.bufferManager.buffer) : null);
130
129
  this._circleUBOHandler = this.lineProgram.createUBO();
131
130
  this.setDefaultColor(this._options.defaultColor);
132
131
  this._cameraUniformBlock = CameraUniformBlockTotemCache.get(globe);
@@ -158,7 +157,7 @@ export class CircleOnTerrainPlugin {
158
157
  if (this._freed)
159
158
  return;
160
159
  if (!this.globe || !this.gl || !this.lineProgram || !this.bufferOrchestrator ||
161
- !this.bufferManagersMap || !this._vao || !this._circleUBOHandler) {
160
+ !this.bufferManagersMap || !this._attributeLoader || !this._circleUBOHandler) {
162
161
  throw new Error("Plugin not initialized properly");
163
162
  }
164
163
  const keys = [];
@@ -217,7 +216,7 @@ export class CircleOnTerrainPlugin {
217
216
  if (this._freed)
218
217
  return;
219
218
  if (!this.globe || !this.gl || !this.lineProgram || !this.bufferOrchestrator ||
220
- !this.bufferManagersMap || !this._vao || !this._circleUBOHandler) {
219
+ !this.bufferManagersMap || !this._attributeLoader || !this._circleUBOHandler) {
221
220
  throw new Error("Plugin not initialized properly");
222
221
  }
223
222
  this.bufferOrchestrator.deleteBulk(keys, this.bufferManagersMap);
@@ -408,9 +407,9 @@ export class CircleOnTerrainPlugin {
408
407
  }
409
408
  // GLOBE API INTERFACE
410
409
  draw3D() {
411
- const { _freed, globe, gl, lineProgram, bufferOrchestrator, bufferManagersMap, _vao, _circleUBOHandler } = this;
410
+ const { _freed, globe, gl, lineProgram, bufferOrchestrator, bufferManagersMap, _attributeLoader, _circleUBOHandler } = this;
412
411
  if (_freed || !globe || !gl || !lineProgram || !bufferOrchestrator ||
413
- !bufferManagersMap || !_vao || !_circleUBOHandler) {
412
+ !bufferManagersMap || !_circleUBOHandler) {
414
413
  return;
415
414
  }
416
415
  // if (globe.api_IsScreenMoving())
@@ -423,7 +422,7 @@ export class CircleOnTerrainPlugin {
423
422
  },
424
423
  };
425
424
  gl.disable(gl.DEPTH_TEST);
426
- lineProgram.draw(_vao, drawOptions, this._opacity, _circleUBOHandler);
425
+ lineProgram.draw(_attributeLoader, drawOptions, this._opacity, _circleUBOHandler);
427
426
  gl.enable(gl.DEPTH_TEST);
428
427
  }
429
428
  free() {
@@ -29,7 +29,7 @@ export class Padding1DegreePlugin {
29
29
  _float32Array = null; // this is used to forward the data to the buffer manager
30
30
  _uboHandler = null; // this is used to forward the data to the shader program
31
31
  _bufferNames = ["position2d", "position3d"];
32
- _vao = null; // this is used to store the VAO for the plugin
32
+ _attributeLoader = null; // this is used to store the VAO for the plugin
33
33
  _freed = false; // this is used to check if the plugin is freed or not
34
34
  _userOpacity = 1;
35
35
  _adaptiveOpacityMultiplier = 1;
@@ -347,7 +347,7 @@ export class Padding1DegreePlugin {
347
347
  offset: 0
348
348
  };
349
349
  });
350
- this._vao = this.lineProgram.createVAO(vaoInput[0], vaoInput[1], vaoInput[2]);
350
+ this._attributeLoader = this.lineProgram.createAttributeLoader(vaoInput[0], vaoInput[1], vaoInput[2]);
351
351
  this.bufferManagerMap = bufferManagerMap;
352
352
  this.bufferOrchestrator.resetWithCapacity(bufferManagerMap, initialCapacity);
353
353
  this._uboHandler = this.lineProgram.createUBO("STATIC_DRAW");
@@ -358,7 +358,7 @@ export class Padding1DegreePlugin {
358
358
  console.warn("Plugin is freed, cannot draw");
359
359
  return;
360
360
  }
361
- if (this.globe === null || this.lineProgram === null || this._vao === null) {
361
+ if (this.globe === null || this.lineProgram === null || this._attributeLoader === null) {
362
362
  console.warn("Globe or LineProgram or VAO is not initialized, cannot draw");
363
363
  return;
364
364
  }
@@ -372,7 +372,7 @@ export class Padding1DegreePlugin {
372
372
  },
373
373
  };
374
374
  gl.disable(gl.DEPTH_TEST);
375
- this.lineProgram.draw(this._vao, drawOptions, this._userOpacity * this._adaptiveOpacityMultiplier, this._uboHandler);
375
+ this.lineProgram.draw(this._attributeLoader, drawOptions, this._userOpacity * this._adaptiveOpacityMultiplier, this._uboHandler);
376
376
  gl.enable(gl.DEPTH_TEST);
377
377
  }
378
378
  free() {
@@ -390,9 +390,8 @@ export class Padding1DegreePlugin {
390
390
  this.lineProgram = null;
391
391
  this._uboHandler?.free();
392
392
  this._uboHandler = null;
393
- this.globe.gl.deleteVertexArray(this._vao);
393
+ this._attributeLoader?.free();
394
394
  this.globe = null;
395
- this._vao = null;
396
395
  this.bufferManagerMap.forEach((bufferManager) => {
397
396
  bufferManager.bufferManager.free();
398
397
  });
@@ -12,12 +12,13 @@ export class IndexPolygonMap {
12
12
  }
13
13
  insertBulk(polygons) {
14
14
  for (const poly of polygons) {
15
- if (this._polygonKeyMap.has(poly.key)) {
16
- this.deleteBulk([poly.key]);
17
- }
18
- const index = this.newIndex();
15
+ // Upsert semantics:
16
+ // - if the key already exists, keep its index stable
17
+ // - otherwise allocate a new index
18
+ const existingIndex = this._polygonKeyMap.get(poly.key);
19
+ const index = existingIndex ?? this.newIndex();
19
20
  // @ts-ignore
20
- poly.index = index; // Assign the new index to the polygon
21
+ poly.index = index; // Assign the (stable) index to the polygon
21
22
  this._indexPolygonMap.set(index, poly);
22
23
  this._polygonKeyMap.set(poly.key, index);
23
24
  }
@@ -14,7 +14,6 @@ let _batchInFlight = false;
14
14
  let _batchPending = 0;
15
15
  function initWorkers() {
16
16
  _maxWorkers = Math.max(1, ((navigator.hardwareConcurrency - 2) || 4) - 1);
17
- console.log(`TerrainPolygon: initializing ${_maxWorkers} workers.`);
18
17
  for (let i = 0; i < _maxWorkers; i++)
19
18
  addWorker();
20
19
  }
@@ -41,7 +41,7 @@ export class TerrainPolygonSemiPlugin {
41
41
  _pickIndexBuffer = null;
42
42
  _variativeColorBuffer = null;
43
43
  _mercatorXYBuffer = null;
44
- _vao = null;
44
+ _attributeLoader = null;
45
45
  _uboHandler = null;
46
46
  _uboForRealEdgeArcs = null;
47
47
  _drawPointsRangeIndexParams = {
@@ -85,7 +85,6 @@ export class TerrainPolygonSemiPlugin {
85
85
  ...(options.edgeStyle ?? {}),
86
86
  },
87
87
  };
88
- console.log("TerrainPolygonSemiPlugin options:", this._options);
89
88
  }
90
89
  ;
91
90
  _effectiveOpacity(target) {
@@ -132,7 +131,7 @@ export class TerrainPolygonSemiPlugin {
132
131
  if (this._options.variativeColorsOn) {
133
132
  this._variativeColorBuffer = gl.createBuffer();
134
133
  }
135
- this._vao = this._program.createVAO({
134
+ this._attributeLoader = this._program.createAttributeLoader({
136
135
  offset: 0,
137
136
  stride: 0,
138
137
  buffer: this._vec3Buffer
@@ -389,10 +388,9 @@ export class TerrainPolygonSemiPlugin {
389
388
  gl.disable(gl.DEPTH_TEST);
390
389
  gl.enable(gl.BLEND);
391
390
  defaultblendfunction(gl);
392
- this._program.setDefaultDefaultAttributeValues();
393
391
  // drawPoints
394
392
  if (this._options.showTesselationPoints) {
395
- this._program.draw(this._vao, this._drawPointsRangeIndexParams, this._uboHandler);
393
+ this._program.draw(this._attributeLoader, this._drawPointsRangeIndexParams, this._uboHandler);
396
394
  }
397
395
  if (this._pickerDisplayer && !this._options.pickablePause) {
398
396
  this._pickerDisplayer.bindFBO();
@@ -400,7 +398,7 @@ export class TerrainPolygonSemiPlugin {
400
398
  // gl.enable(gl.DEPTH_TEST);
401
399
  }
402
400
  gl.frontFace(gl.CW);
403
- this._program.draw(this._vao, this._drawRangeIndexParams, this._uboHandler);
401
+ this._program.draw(this._attributeLoader, this._drawRangeIndexParams, this._uboHandler);
404
402
  gl.frontFace(gl.CCW);
405
403
  if (this._pickerDisplayer && !this._options.pickablePause) {
406
404
  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
@@ -411,10 +409,9 @@ export class TerrainPolygonSemiPlugin {
411
409
  gl.disable(gl.DEPTH_TEST);
412
410
  // gl.enable(gl.POLYGON_OFFSET_FILL);
413
411
  // gl.polygonOffset(-3.0, -3.0);
414
- this._program.draw(this._vao, this._drawRealEdgeArcs, this._uboForRealEdgeArcs);
412
+ this._program.draw(this._attributeLoader, this._drawRealEdgeArcs, this._uboForRealEdgeArcs);
415
413
  // gl.disable(gl.POLYGON_OFFSET_FILL);
416
414
  }
417
- this._program.resetDefaultAttributeValues();
418
415
  gl.enable(gl.DEPTH_TEST);
419
416
  }
420
417
  free() {
@@ -52,18 +52,6 @@ const attributeLoader = (gl, bufferAndReadInfo, index, size, { divisor = null, d
52
52
  gl.vertexAttribDivisor(index, divisor);
53
53
  }
54
54
  };
55
- /**
56
- *
57
- * @param {WebGLBuffer} buffer
58
- * @param {number} stride
59
- * @param {number} offset
60
- * @returns {BufferAndReadInfo}
61
- */
62
- const createBufferAndReadInfo = (buffer, stride = 0, offset = 0) => {
63
- if (buffer == null)
64
- return null;
65
- return { buffer, stride, offset };
66
- };
67
55
  const setConstantAttribute = (gl, index, size, values, typeInfo) => {
68
56
  // Array should already be disabled by caller
69
57
  if (size < 1 || size > 4) {
@@ -96,7 +84,50 @@ const setConstantAttribute = (gl, index, size, values, typeInfo) => {
96
84
  function resetAttributeDefault(gl, index) {
97
85
  gl.vertexAttrib4f(index, 0, 0, 0, 1);
98
86
  }
99
- function setDefaultAttributeValues(gl, index, size, escapeValues, typeInfo) {
100
- setConstantAttribute(gl, index, size, escapeValues, DATA_TYPE_MAP[typeInfo]);
87
+ export class AttributeLoader {
88
+ gl;
89
+ meta;
90
+ vao;
91
+ stickyNotes = new Map();
92
+ constructor(gl, meta) {
93
+ this.gl = gl;
94
+ this.meta = meta;
95
+ this.vao = gl.createVertexArray();
96
+ gl.bindVertexArray(this.vao);
97
+ for (const { bufferAndReadInfo, index, size, options } of this.meta) {
98
+ if (bufferAndReadInfo != null && bufferAndReadInfo.buffer != null) {
99
+ attributeLoader(this.gl, bufferAndReadInfo, index, size, options);
100
+ }
101
+ else if (options.escapeValues) {
102
+ const dataType = options.dataType || "float";
103
+ const typeInfo = DATA_TYPE_MAP[dataType];
104
+ this.stickyNotes.set(index, { size, typeInfo, escapeValues: options.escapeValues });
105
+ }
106
+ else {
107
+ throw new Error("Either bufferAndReadInfo or escapeValues must be provided for AttributeLoader.");
108
+ }
109
+ }
110
+ gl.bindVertexArray(null);
111
+ }
112
+ bind() {
113
+ const { gl } = this;
114
+ gl.bindVertexArray(this.vao);
115
+ for (const [index, { size, typeInfo, escapeValues }] of this.stickyNotes) {
116
+ setConstantAttribute(gl, index, size, escapeValues, typeInfo);
117
+ }
118
+ }
119
+ unbind() {
120
+ this.gl.bindVertexArray(null);
121
+ for (const index of this.stickyNotes.keys()) {
122
+ resetAttributeDefault(this.gl, index);
123
+ }
124
+ }
125
+ free() {
126
+ this.gl.deleteVertexArray(this.vao);
127
+ }
128
+ static createBufferAndReadInfo(buffer, stride = 0, offset = 0) {
129
+ if (buffer == null)
130
+ return null;
131
+ return { buffer, stride, offset };
132
+ }
101
133
  }
102
- export { attributeLoader, createBufferAndReadInfo, resetAttributeDefault, setDefaultAttributeValues };