@pirireis/webglobeplugins 0.1.10 → 0.3.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.
@@ -1,11 +1,12 @@
1
1
  import { CameraUniformBlockString, CameraUniformBlockTotem } from "../totems";
2
- import { longLatRadToMercator, longLatRadToCartesian3D, cartesian3DToGLPosition, mercatorXYTo2DPoint } from "../../util/shaderfunctions/geometrytransformations";
2
+ import { longLatRadToMercator, longLatRadToCartesian3D, cartesian3DToGLPosition, mercatorXYToGLPosition, POLE } from "../../util/shaderfunctions/geometrytransformations";
3
3
  import { createProgram } from "../../util";
4
4
  import { noRegisterGlobeProgramCache, globeProgramCache } from "../programcache";
5
5
  import BufferOffsetManger from "../../util/account/bufferoffsetmanager";
6
+ import { programCache } from "../rings/distancering/circleflatprogram";
6
7
  const Radian = Math.PI / 180.0;
7
8
  const GLOBE_MIDPOINT_COUNT = 100;
8
- const ITEM_SIZE = 8;
9
+ const ITEM_SIZE = 9;
9
10
 
10
11
  const vertexShader = `#version 300 es
11
12
  precision highp float;
@@ -13,42 +14,63 @@ ${CameraUniformBlockString}
13
14
  ${longLatRadToMercator}
14
15
  ${longLatRadToCartesian3D}
15
16
  ${cartesian3DToGLPosition}
16
- ${mercatorXYTo2DPoint}
17
+ ${mercatorXYToGLPosition}
18
+
17
19
 
18
20
  in vec2 start_position;
19
21
  in vec2 end_position;
22
+ in float dash_ratio;
20
23
  in vec4 color;
21
24
  out vec4 v_color;
25
+ out vec2 v_limp;
26
+ out float interpolation;
27
+ out float v_dash_ratio;
28
+
22
29
 
23
30
  void main() {
24
-
25
31
  vec2 longLat;
26
32
  if (is3D) {
27
- float interpolation = float(gl_VertexID) / ${GLOBE_MIDPOINT_COUNT}.0;
33
+ interpolation = float(gl_VertexID) / ${GLOBE_MIDPOINT_COUNT - 1}.0;
28
34
  longLat = mix(start_position, end_position, interpolation);
29
35
  vec3 cartesian = longLatRadToCartesian3D(longLat);
30
36
  gl_Position = cartesian3DToGLPosition(cartesian);
37
+ v_limp = vec2(0.0, 0.0);
31
38
  } else {
32
- if ( gl_VertexID == 0 ) {
39
+ interpolation = float(gl_VertexID);
40
+ if (gl_VertexID % 2 == 0) {
33
41
  longLat = start_position;
34
42
  } else {
35
43
  longLat = end_position;
36
44
  }
37
45
  vec2 mercator = longLatRadToMercator(longLat);
38
- gl_Position = mercatorXYTo2DPoint(mercator);
46
+ v_limp = mercator;
47
+ gl_Position = mercatorXYToGLPosition(mercator);
39
48
  }
49
+ // if ( gl_VertexID % 2 == 0) {v_color = color;}
50
+ // else {v_color = vec4(0.0, 0.0, 0.0, 0.0);}
40
51
  v_color = color;
52
+ v_dash_ratio = dash_ratio;
41
53
  }
42
- `
54
+ `;
43
55
 
44
56
  const fragmentShader = `#version 300 es
57
+ ${POLE}
45
58
  precision highp float;
59
+ uniform float opacity;
46
60
  in vec4 v_color;
47
61
  out vec4 color;
62
+ in float interpolation;
63
+ in float v_dash_ratio;
64
+ in vec2 v_limp;
48
65
  void main() {
66
+ if (v_limp.x < -POLE || v_limp.x > POLE || v_limp.y < -POLE || v_limp.y > POLE) { discard; }
49
67
  color = v_color;
68
+ color.a *= opacity;
69
+ if (interpolation > 0.95) { return; }
70
+ if (fract(interpolation / (2.0 * v_dash_ratio)) < 0.5) { color.a /= 4.0; }
71
+
50
72
  }
51
- `
73
+ `;
52
74
 
53
75
 
54
76
  class Logic {
@@ -57,14 +79,24 @@ class Logic {
57
79
  this.globe = globe;
58
80
  this.gl = globe.gl;
59
81
  this.program = createProgram(this.gl, vertexShader, fragmentShader);
82
+ this._lastOpacity = 1.0;
60
83
  const { gl, program } = this;
61
84
  {
62
85
  // assign attribute locations
63
86
  gl.bindAttribLocation(program, 0, "start_position");
64
87
  gl.bindAttribLocation(program, 1, "end_position");
65
- gl.bindAttribLocation(program, 2, "color");
88
+ gl.bindAttribLocation(program, 2, "dash_ratio");
89
+ gl.bindAttribLocation(program, 3, "color");
66
90
  }
67
91
 
92
+ {
93
+ this._opacityLocation = gl.getUniformLocation(program, "opacity");
94
+ const currentProgram = gl.getParameter(gl.CURRENT_PROGRAM);
95
+ gl.useProgram(program);
96
+ gl.uniform1f(this._opacityLocation, this._lastOpacity);
97
+ gl.useProgram(currentProgram);
98
+
99
+ }
68
100
 
69
101
  this.cameraBlockBindingPoint = 0;
70
102
  const cameraBlockIndex = this.gl.getUniformBlockIndex(this.program, "CameraUniformBlock");
@@ -75,30 +107,85 @@ class Logic {
75
107
  }
76
108
 
77
109
 
78
- draw(bufferManager) {
79
- const { gl, program, globe } = this;
110
+ draw(vao, length, opacity) {
111
+ const { gl, program, globe, cameraBlockTotem, cameraBlockBindingPoint } = this;
80
112
  gl.useProgram(program);
81
- const { cameraBlockTotem, cameraBlockBindingPoint } = this;
82
113
  cameraBlockTotem.bind(cameraBlockBindingPoint);
83
- gl.bindVertexArray(bufferManager.vao);
114
+ gl.bindVertexArray(vao);
115
+ if (opacity !== this._lastOpacity) {
116
+ gl.uniform1f(this._opacityLocation, opacity);
117
+ this._lastOpacity = opacity;
118
+ }
84
119
  const drawCount = globe.api_GetCurrentGeometry() === 0 ? GLOBE_MIDPOINT_COUNT : 2;
85
- gl.disable(gl.DEPTH_TEST);
86
- gl.drawArraysInstanced(gl.LINE_STRIP, 0, drawCount, bufferManager.length);
87
- gl.enable(gl.DEPTH_TEST);
120
+ // gl.disable(gl.DEPTH_TEST);
121
+ gl.drawArraysInstanced(gl.LINE_STRIP, 0, drawCount, length);
88
122
  gl.bindVertexArray(null);
89
123
  cameraBlockTotem.unbind(cameraBlockBindingPoint);
124
+ // gl.enable(gl.DEPTH_TEST);
90
125
  }
91
126
 
92
127
 
93
128
  createBufferManager({ capacity = 10, bufferType = "DYNAMIC_DRAW" } = {}) {
94
129
  return new BufferManager(this.globe, { capacity, bufferType });
95
130
  }
131
+
132
+
133
+
134
+ //
135
+ createVAO(startPotisionBufferObj, endPositionBufferObj, dashRatioBufferObj, colorBufferObj) {
136
+ const { gl } = this;
137
+ const vao = gl.createVertexArray();
138
+ gl.bindVertexArray(vao);
139
+ {
140
+ const { buffer, stride = 0, offset = 0 } = startPotisionBufferObj;
141
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
142
+ gl.enableVertexAttribArray(0);
143
+ gl.vertexAttribPointer(0, 2, gl.FLOAT, false, stride, offset);
144
+ gl.vertexAttribDivisor(0, 1);
145
+ }
146
+ {
147
+
148
+ const { buffer, stride = 0, offset = 0 } = endPositionBufferObj;
149
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
150
+ gl.enableVertexAttribArray(1);
151
+ gl.vertexAttribPointer(1, 2, gl.FLOAT, false, stride, offset);
152
+ gl.vertexAttribDivisor(1, 1);
153
+ }
154
+
155
+ {
156
+ const { buffer, stride = 0, offset = 0 } = dashRatioBufferObj;
157
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
158
+ gl.enableVertexAttribArray(2);
159
+ gl.vertexAttribPointer(2, 1, gl.FLOAT, false, stride, offset);
160
+ gl.vertexAttribDivisor(2, 1);
161
+ }
162
+
163
+ {
164
+ const { buffer, stride = 0, offset = 0 } = colorBufferObj;
165
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
166
+ gl.enableVertexAttribArray(3);
167
+ gl.vertexAttribPointer(3, 4, gl.FLOAT, false, stride, offset);
168
+ gl.vertexAttribDivisor(3, 1);
169
+ }
170
+ gl.bindVertexArray(null);
171
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
172
+ return vao;
173
+
174
+ }
175
+
176
+
177
+ free() {
178
+ if (this.isFreed) return;
179
+ programCache.releaseProgram(this.globe, CameraUniformBlockTotem);
180
+ this.gl.deleteProgram(this.program);
181
+ this.isFreed = true;
182
+ }
96
183
  }
97
184
 
98
185
 
99
186
  class BufferManager extends BufferOffsetManger {
100
187
 
101
- constructor(globe, { capacity = 10, bufferType = "DYNAMIC_DRAW" } = {}) {
188
+ constructor(globe, { capacity = 10, bufferType = "DYNAMIC_DRAW", } = {}) {
102
189
  super(ITEM_SIZE, { capacity, bufferType });
103
190
  this.globe = globe
104
191
  this.gl = globe.gl;
@@ -118,10 +205,13 @@ class BufferManager extends BufferOffsetManger {
118
205
  gl.enableVertexAttribArray(1);
119
206
  gl.vertexAttribPointer(1, 2, gl.FLOAT, false, ITEM_SIZE * 4, 8);
120
207
  gl.enableVertexAttribArray(2);
121
- gl.vertexAttribPointer(2, 4, gl.FLOAT, false, ITEM_SIZE * 4, 16);
208
+ gl.vertexAttribPointer(2, 1, gl.FLOAT, false, ITEM_SIZE * 4, 16);
209
+ gl.enableVertexAttribArray(3);
210
+ gl.vertexAttribPointer(3, 4, gl.FLOAT, false, ITEM_SIZE * 4, 20);
122
211
  gl.vertexAttribDivisor(0, 1);
123
212
  gl.vertexAttribDivisor(1, 1);
124
213
  gl.vertexAttribDivisor(2, 1);
214
+ gl.vertexAttribDivisor(3, 1);
125
215
  gl.bindVertexArray(null);
126
216
  }
127
217
  }
@@ -129,19 +219,22 @@ class BufferManager extends BufferOffsetManger {
129
219
 
130
220
  /**
131
221
  *
132
- * @param {Array<{key:string, startLong:number, startLat:number, endLong:number, endLat:number, rgba:[4numbers] }} items
222
+ * @param {Array<{key:string, long:number, lat:number, endLong:number, endLat:number, rgba:[4numbers] }} items
133
223
  */
134
224
  insertBulk(items) {
135
225
  this.autoExtendBuffer(items.length)
136
226
  const { gl, buffer, globe } = this;
137
227
  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
138
- for (let { key, startLong, startLat, endLong, endLat, rgba } of items) {
228
+ for (let { key, long, lat, endLong, endLat, rgba, dashRatio = 1 } of items) {
229
+ console.log(key, dashRatio, "dashRatio");
139
230
  const payload = new Float32Array([
140
- Radian * startLong,
141
- Radian * startLat,
142
- Radian * endLong,
143
- Radian * endLat,
231
+ long,
232
+ lat,
233
+ endLong,
234
+ endLat,
235
+ dashRatio,
144
236
  ...rgba]);
237
+
145
238
  const offset = this.getOffset(key) | this.nextOffset();
146
239
  gl.bufferSubData(gl.ARRAY_BUFFER, offset, payload);
147
240
  this.setOffset(key, offset);
@@ -152,17 +245,18 @@ class BufferManager extends BufferOffsetManger {
152
245
 
153
246
  /**
154
247
  *
155
- * @param {Array<{key:string, startLong:number, startLat:number, endLong:number, endLat:number, rgba:[4numbers] }} items
248
+ * @param {Array<{key:string, long:number, lat:number, endLong:number, endLat:number, rgba:[4numbers] }} items
156
249
  */
157
250
  updateBulk(items) {
158
251
  const { gl, buffer, globe } = this;
159
252
  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
160
- for (let { key, startLong, startLat, endLong, endLat, rgba } of items) {
253
+ for (let { key, long, lat, endLong, endLat, rgba, dashRatio = 1 } of items) {
161
254
  const payload = new Float32Array([
162
- Radian * startLong,
163
- Radian * startLat,
164
- Radian * endLong,
165
- Radian * endLat,
255
+ long,
256
+ lat,
257
+ endLong,
258
+ endLat,
259
+ dashRatio,
166
260
  ...rgba]);
167
261
  const offset = this.getOffset(key);
168
262
  if (offset !== undefined) {
@@ -177,17 +271,18 @@ class BufferManager extends BufferOffsetManger {
177
271
 
178
272
  /**
179
273
  *
180
- * @param {Array<{key:string, startLong:number, startLat:number, endLong:number, endLat:number }} items
274
+ * @param {Array<{key:string, long:number, lat:number, endLong:number, endLat:number }} items
181
275
  */
182
276
  updateCoordinatesBulk(items) {
183
277
  const { gl, buffer, globe } = this;
184
278
  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
185
- for (let { key, startLong, startLat, endLong, endLat } of items) {
279
+ for (let { key, long, lat, endLong, endLat, dashRatio = 1 } of items) {
186
280
  const payload = new Float32Array([
187
- Radian * startLong,
188
- Radian * startLat,
189
- Radian * endLong,
190
- Radian * endLat]);
281
+ long,
282
+ lat,
283
+ endLong,
284
+ endLat,
285
+ dashRatio]);
191
286
  const offset = this.getOffset(key);
192
287
  if (offset !== undefined) {
193
288
  gl.bufferSubData(gl.ARRAY_BUFFER, offset, payload);
@@ -195,6 +290,7 @@ class BufferManager extends BufferOffsetManger {
195
290
  console.warn("key not found", key);
196
291
  }
197
292
  }
293
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
198
294
  globe.DrawRender();
199
295
  }
200
296
 
@@ -210,7 +306,7 @@ class BufferManager extends BufferOffsetManger {
210
306
  const payload = new Float32Array([...rgba]);
211
307
  const offset = this.getOffset(key);
212
308
  if (offset !== undefined) {
213
- gl.bufferSubData(gl.ARRAY_BUFFER, offset + 16, payload);
309
+ gl.bufferSubData(gl.ARRAY_BUFFER, offset + 20, payload);
214
310
  } else {
215
311
  console.warn("key not found", key);
216
312
  }
@@ -245,6 +341,6 @@ class BufferManager extends BufferOffsetManger {
245
341
 
246
342
  export const LineOnGlobeCache = Object.freeze({
247
343
  get: (globe) => { return noRegisterGlobeProgramCache.getProgram(globe, Logic) },
248
- free: (globe) => { return noRegisterGlobeProgramCache.releaseProgram(globe, Logic) }
344
+ release: (globe) => { return noRegisterGlobeProgramCache.releaseProgram(globe, Logic) }
249
345
  });
250
346
 
@@ -9,7 +9,7 @@ const vertexShader = `#version 300 es ` +
9
9
  shaderfunctions.R +
10
10
  shaderfunctions.POLE +
11
11
  CameraUniformBlockString +
12
- shaderfunctions.mercatorXYTo2DPoint +
12
+ shaderfunctions.mercatorXYToGLPosition +
13
13
  shaderfunctions.longLatRadToMercator +
14
14
  shaderfunctions.longLatRadToCartesian3D +
15
15
  shaderfunctions.circleLimpFromLongLatRadCenterCartesian3D +
@@ -46,7 +46,7 @@ void main() {
46
46
  limp = circleLimpFromLongLatRadCenterMercatorRealDistance(center, radius, angle);
47
47
  }
48
48
  v_limp = limp;
49
- gl_Position = mercatorXYTo2DPoint(limp);
49
+ gl_Position = mercatorXYToGLPosition(limp);
50
50
 
51
51
  }`;
52
52
 
@@ -9,7 +9,7 @@ const vertexShader = `#version 300 es ` +
9
9
  shaderfunctions.R +
10
10
  shaderfunctions.POLE +
11
11
  CameraUniformBlockString +
12
- shaderfunctions.mercatorXYTo2DPoint +
12
+ shaderfunctions.mercatorXYToGLPosition +
13
13
  shaderfunctions.longLatRadToMercator +
14
14
  shaderfunctions.longLatRadToCartesian3D +
15
15
  shaderfunctions.circleLimpFromLongLatRadCenterCartesian3D +
@@ -56,7 +56,7 @@ void main() {
56
56
  limp = circleLimpFromLongLatRadCenterMercatorRealDistance(center, radius_, angle);
57
57
  }
58
58
  v_limp = limp;
59
- gl_Position = mercatorXYTo2DPoint(limp);
59
+ gl_Position = mercatorXYToGLPosition(limp);
60
60
  }`;
61
61
 
62
62
  const fragmentShader = `#version 300 es
@@ -128,8 +128,8 @@ class Logic {
128
128
  }
129
129
  gl.disable(gl.DEPTH_TEST);
130
130
  gl.drawArraysInstanced(gl.LINES, 0, 2, attrBufferManager.length);
131
- gl.enable(gl.DEPTH_TEST);
132
131
  cameraBlockTotem.unbind(cameraBlockBindingPoint);
132
+ gl.enable(gl.DEPTH_TEST);
133
133
  gl.bindVertexArray(null);
134
134
 
135
135
  }
@@ -7,7 +7,7 @@ const vertexShader = `#version 300 es ` +
7
7
  shaderfunctions.R +
8
8
  shaderfunctions.POLE +
9
9
  CameraUniformBlockString +
10
- shaderfunctions.mercatorXYTo2DPoint +
10
+ shaderfunctions.mercatorXYToGLPosition +
11
11
  shaderfunctions.longLatRadToMercator +
12
12
  shaderfunctions.longLatRadToCartesian3D +
13
13
  shaderfunctions.circleLimpFromLongLatRadCenterCartesian3D +
@@ -58,7 +58,7 @@ void main() {
58
58
  limp = circleLimpFromLongLatRadCenterMercatorRealDistance(center, radius_, angle);
59
59
  }
60
60
  v_limp = limp;
61
- gl_Position = mercatorXYTo2DPoint(limp);
61
+ gl_Position = mercatorXYToGLPosition(limp);
62
62
  }`;
63
63
 
64
64
  const fragmentShader = `#version 300 es
@@ -1,3 +1,6 @@
1
+ import { globeProgramCache } from "../programcache";
2
+
3
+
1
4
  export const CameraUniformBlockString = `
2
5
  layout(std140) uniform CameraUniformBlock {
3
6
  mat4 view; // 64 bytes 0
@@ -126,3 +129,9 @@ export default class
126
129
  }
127
130
  }
128
131
  }
132
+
133
+
134
+ export const CameraUniformBlockTotemCache = Object.freeze({
135
+ get: (globe) => { return globeProgramCache.getProgram(globe, CameraUniformBlockTotem) },
136
+ release: (globe) => { return globeProgramCache.releaseProgram(globe, CameraUniformBlockTotem) }
137
+ });
@@ -1,2 +1,2 @@
1
- import CameraUniformBlockTotem, { CameraUniformBlockString } from "./camerauniformblock";
2
- export { CameraUniformBlockTotem, CameraUniformBlockString };
1
+ import CameraUniformBlockTotem, { CameraUniformBlockString, CameraUniformBlockTotemCache } from "./camerauniformblock";
2
+ export { CameraUniformBlockTotem, CameraUniformBlockString, CameraUniformBlockTotemCache };
@@ -59,6 +59,9 @@ export default class {
59
59
  this.circleProgramCache?.releaseProgram(this.globe);
60
60
  this.PaddingProgramCache?.releaseProgram(this.globe);
61
61
  this.PaddingFreeAngleCache?.releaseProgram(this.globe);
62
+ this.gl.deleteVertexArray(this.bufferManager?.vao);
63
+ this.gl.deleteVertexArray(this.paddingBufferManager?.vao);
64
+ this.paddingBufferManager?.free();
62
65
  this.bufferManager?.free();
63
66
  this.textPlugin?.free();
64
67
  this.circleFlatProgram = null;
@@ -84,8 +87,6 @@ export default class {
84
87
  const { circleFlatProgram, paddyFlatProgram, paddingFreeAngleProgram, bufferManager, compass, gl, circleEdgeCount, paddingBufferManager, _opacity } = this;
85
88
  if (this.bufferManager !== null && bufferManager.length > 0) {
86
89
  gl.disable(gl.DEPTH_TEST);
87
- // gl.enable(gl.BLEND);
88
- // gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
89
90
  console.log("the opacity", _opacity);
90
91
  circleFlatProgram.draw(bufferManager, compass, circleEdgeCount, _opacity);
91
92
  if (this._onedegreepaddingOn) paddyFlatProgram.draw(bufferManager, 360, compass, _opacity);
@@ -75,7 +75,19 @@ export default class {
75
75
  }
76
76
  }
77
77
 
78
-
78
+ _deleteBulk(keys) {
79
+ const { gl, buffer } = this;
80
+ const emptyBlock = new Float32Array(this.itemSize).fill(0)
81
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
82
+ for (let key of keys) {
83
+ const offset = this.getOffset(key);
84
+ if (offset !== undefined) {
85
+ this.deleteFromAccount(key);
86
+ gl.bufferSubData(gl.ARRAY_BUFFER, offset, emptyBlock);
87
+ }
88
+ }
89
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
90
+ }
79
91
 
80
92
  offsetMapIterator() { // can be used for defraging the real buffer.
81
93
  return this.offSetMap.entries();
@@ -90,7 +102,6 @@ export default class {
90
102
  const itemSize = this.itemSize;
91
103
  const itemCount = this.itemCount;
92
104
  const capacity = (newCapacity && newCapacity > itemCount) ? newCapacity : itemCount;
93
- console.log("defrag", itemCount, capacity);
94
105
 
95
106
  const newArray = new Float32Array(itemCount * itemSize);
96
107
 
@@ -98,7 +109,6 @@ export default class {
98
109
  let newOffSet = 0;
99
110
  const newOffSetMap = new Map();
100
111
  for (const [key, offSet] of this.offSetMap) {
101
- console.log(key, offSet);
102
112
  const itemOffSet = offSet / 4;
103
113
  newArray.set(bufferData.slice(itemOffSet, itemOffSet + itemSize), newOffSet);
104
114
  // this.offSetMap.set(key, newOffSet * 4);
@@ -147,8 +157,8 @@ export default class {
147
157
  */
148
158
  _updatePartial(items, partOffset) {
149
159
  const { gl, buffer } = this;
150
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
151
160
  const partStart = partOffset * 4;
161
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
152
162
  for (let { key, payload } of items) {
153
163
  let offset = this.getOffset(key);
154
164
  if (offset !== undefined) {
@@ -183,9 +193,11 @@ export default class {
183
193
  gl.bindBuffer(gl.ARRAY_BUFFER, null);
184
194
  }
185
195
 
196
+
197
+
198
+
186
199
  free() {
187
200
  this.gl.deleteBuffer(this.buffer);
188
- this.gl.deleteVertexArray(this.vao);
189
201
  this.buffer = null;
190
202
  this.vao = null;
191
203
  this.gl = null;
@@ -1,3 +1,7 @@
1
1
  import BufferOffsetManager from './bufferoffsetmanager.js';
2
2
 
3
- export { BufferOffsetManager };
3
+ export { BufferOffsetManager };
4
+
5
+
6
+
7
+ export * from './single-attribute-buffer-management';
@@ -0,0 +1,119 @@
1
+ /**
2
+ * BufferOffsetManager
3
+ * Purpose: To manage the offset of the buffer. Plus extend and defrag the buffer.
4
+ * ------------------------------------------------------------------------------------------------------------------------------------------- * Functions:
5
+ * 1. getOffet(key) : return the offset of the key if not found return false.
6
+ * 2. setOffset(key, offset) : set the offset of the key.
7
+ * 3. nextOffset() : return the next available offset if not return false.
8
+ * 4. delete(key) : delete the key and return true if not found return false.
9
+ * 5. defragBuffer(gl, buffer, bufferType, newCapacity = null) : defrag the buffer. if newCapacity is not provided the buffer is vacumed.
10
+ * 6. extendBuffer(gl, buffer, bufferType, newCapacity) : extend the buffer.
11
+ * -------------------------------------------------------------------------------------------------------------------------------------------
12
+ * What this class does NOT do:
13
+ * ADD, DELETE, READ
14
+ * ADD, inputs needs to be turn into a block and put into buffer. Bulk will be more performant.
15
+ * DELETE, might be a set to single byte to indicate the tombstone.
16
+ * READ, most of the time is not needed to be read, unless for defraging.
17
+ * This unpredicatable behavior is not handled by this class.
18
+ */
19
+
20
+ export class BufferManager {
21
+ constructor(gl, itemSize, { bufferType = "STATIC_DRAW", buffer = null, initialCapacity = null } = {}) {
22
+ this.gl = gl;
23
+ this.itemSize = itemSize;
24
+ this.bufferType = bufferType;
25
+ this.buffer = buffer === null ? gl.createBuffer() : buffer;
26
+ if (initialCapacity !== null) this.resetWithCapacity(initialCapacity);
27
+ }
28
+
29
+ resetWithCapacity(capacity) {
30
+ const { gl, buffer, bufferType, itemSize } = this;
31
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
32
+ gl.bufferData(gl.ARRAY_BUFFER, capacity * itemSize * 4, gl[bufferType]);
33
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
34
+ }
35
+
36
+ deleteBulk(offsets) {
37
+ const { gl, buffer, itemSize } = this;
38
+ const emptyBlock = new Float32Array(this.itemSize).fill(0)
39
+ const offsetMultiplier = itemSize * 4;
40
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
41
+ for (let offset of offsets) {
42
+ if (offset !== undefined) {
43
+
44
+ gl.bufferSubData(gl.ARRAY_BUFFER, offset * offsetMultiplier, emptyBlock);
45
+ }
46
+ }
47
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
48
+ }
49
+
50
+
51
+ insertBulk(blocks, offsets) {
52
+ const { gl, buffer, itemSize } = this;
53
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
54
+ const offsetMultiplier = itemSize * 4;
55
+ for (let i = 0; i < blocks.length; i++) {
56
+ const block = blocks[i];
57
+ const offset = offsets[i] * offsetMultiplier;
58
+ if (offset !== undefined) gl.bufferSubData(gl.ARRAY_BUFFER, offset, block);
59
+ }
60
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
61
+ }
62
+
63
+
64
+ // TODO: this is broken
65
+ defrag(offsetValues, occupiedCapacity, newCapacity) {
66
+ const { gl, buffer, bufferType, itemSize } = this;
67
+
68
+ const newArray = new Float32Array(newCapacity * itemSize);
69
+ const bufferData = this._getBufferData(occupiedCapacity);
70
+ console.log("bufferData", bufferData);
71
+ let newOffset = 0;
72
+ for (const offset of offsetValues) {
73
+ const itemOffset = offset * itemSize;
74
+ newArray.set(bufferData.slice(itemOffset, itemOffset + itemSize), newOffset);
75
+ console.log("oldOffset", itemOffset, "newOffset", newOffset);
76
+ newOffset += itemSize;
77
+ }
78
+
79
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
80
+ gl.bufferData(gl.ARRAY_BUFFER, newCapacity * itemSize * 4, gl[bufferType]);
81
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, newArray);
82
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
83
+
84
+ }
85
+
86
+ extendBuffer(occupiedCapacity, newCapacity) {
87
+ const { gl, buffer, bufferType } = this;
88
+ const itemSize = this.itemSize;
89
+ const bufferData = this._getBufferData(occupiedCapacity);
90
+ console.log("extending buffer from", occupiedCapacity, "to", newCapacity, 'item size', itemSize);
91
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
92
+ gl.bufferData(gl.ARRAY_BUFFER, newCapacity * itemSize * 4, gl[bufferType]);
93
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, bufferData);
94
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
95
+ }
96
+
97
+ _getBufferData(occupiedCapacity) {
98
+ const { gl, buffer } = this;
99
+ console.log(occupiedCapacity, this.itemSize)
100
+ const size = occupiedCapacity * this.itemSize;
101
+ console.log("size", size);
102
+ const bufferData = new Float32Array(size);
103
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
104
+ gl.getBufferSubData(gl.ARRAY_BUFFER, 0, bufferData);
105
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
106
+ return bufferData;
107
+ }
108
+
109
+ free() {
110
+ if (this.isFreed) return;
111
+ this.gl.deleteBuffer(this.buffer);
112
+ this.buffer = null;
113
+ this.gl = null;
114
+ this.isFreed = true;
115
+ }
116
+ }
117
+
118
+
119
+