@pirireis/webglobeplugins 0.0.1

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 (82) hide show
  1. package/arrowfield/adaptor.js +11 -0
  2. package/arrowfield/index.js +4 -0
  3. package/arrowfield/plugin.js +128 -0
  4. package/compassrose/compassrose.js +394 -0
  5. package/compassrose/index.js +2 -0
  6. package/heatwavemaps/index.js +4 -0
  7. package/heatwavemaps/isobar/objectarraylabels.js +247 -0
  8. package/heatwavemaps/isobar/plugin.js +337 -0
  9. package/heatwavemaps/isobar/quadtreecontours.js +338 -0
  10. package/heatwavemaps/plugins/heatwaveglobeshell.js +257 -0
  11. package/index.js +8 -0
  12. package/package.json +7 -0
  13. package/programs/arrowfield/index.js +2 -0
  14. package/programs/arrowfield/logic.js +284 -0
  15. package/programs/arrowfield/object.js +89 -0
  16. package/programs/float2legendwithratio/index.js +3 -0
  17. package/programs/float2legendwithratio/logic.js +189 -0
  18. package/programs/float2legendwithratio/object.js +132 -0
  19. package/programs/globeshell/index.js +2 -0
  20. package/programs/globeshell/noise/noises.js +0 -0
  21. package/programs/globeshell/wiggle/index.js +6 -0
  22. package/programs/globeshell/wiggle/logic.js +374 -0
  23. package/programs/globeshell/wiggle/object.js +94 -0
  24. package/programs/helpers/blender/index.js +0 -0
  25. package/programs/helpers/blender/program.js +91 -0
  26. package/programs/helpers/fadeaway/index.js +3 -0
  27. package/programs/helpers/fadeaway/logic.js +76 -0
  28. package/programs/helpers/fadeaway/object.js +20 -0
  29. package/programs/helpers/index.js +2 -0
  30. package/programs/index.js +21 -0
  31. package/programs/programcache.js +119 -0
  32. package/programs/rings/distancering/circleflatprogram.js +135 -0
  33. package/programs/rings/distancering/circlepaddysharedbuffer.js +502 -0
  34. package/programs/rings/distancering/index.js +5 -0
  35. package/programs/rings/distancering/paddyflatprogram.js +131 -0
  36. package/programs/rings/distancering/shader.js +0 -0
  37. package/programs/rings/index.js +9 -0
  38. package/programs/totems/camerauniformblock.js +129 -0
  39. package/programs/totems/index.js +2 -0
  40. package/programs/util.js +17 -0
  41. package/programs/vectorfields/index.js +3 -0
  42. package/programs/vectorfields/logics/drawrectangleparticles.js +125 -0
  43. package/programs/vectorfields/logics/index.js +5 -0
  44. package/programs/vectorfields/logics/pixelbased.js +161 -0
  45. package/programs/vectorfields/logics/ubo.js +64 -0
  46. package/programs/vectorfields/pingpongbuffermanager.js +80 -0
  47. package/rangerings/index.js +3 -0
  48. package/rangerings/rangerings.js +88 -0
  49. package/timetracks/adaptors.js +133 -0
  50. package/timetracks/index.js +3 -0
  51. package/timetracks/plugin.js +304 -0
  52. package/timetracks/program.js +850 -0
  53. package/timetracks/programpoint.js +168 -0
  54. package/util/datamanager/datamanager.js +168 -0
  55. package/util/datamanager/index.js +3 -0
  56. package/util/datamanager/pointcoordinatesdatacalculator.js +133 -0
  57. package/util/datamanager/pointcoordsmeta.js +22 -0
  58. package/util/geometry/geodatafromtexture.js +52 -0
  59. package/util/geometry/index.js +44 -0
  60. package/util/index.js +13 -0
  61. package/util/jshelpers/index.js +1 -0
  62. package/util/jshelpers/timefilters.js +32 -0
  63. package/util/jshelpers/timemethods.js +19 -0
  64. package/util/programs/index.js +2 -0
  65. package/util/programs/shapesonglobe.js +248 -0
  66. package/util/programs/supersampletotextures.js +142 -0
  67. package/util/programs/texturetoglobe.js +203 -0
  68. package/util/shaderfunctions/geometrytransformations.js +129 -0
  69. package/util/shaderfunctions/index.js +2 -0
  70. package/util/shaderfunctions/nodata.js +10 -0
  71. package/util/shaderfunctions/noisefunctions.js +44 -0
  72. package/util/webglobe/gldefaultstates.js +4 -0
  73. package/util/webglobe/index.js +2 -0
  74. package/util/webglobe/rasteroverlay.js +96 -0
  75. package/util/webglobjectbuilders.js +256 -0
  76. package/waveparticles/adaptor.js +16 -0
  77. package/waveparticles/index.js +4 -0
  78. package/waveparticles/plugin.js +281 -0
  79. package/wind/imagetovectorfieldandmagnitude.js +39 -0
  80. package/wind/index.js +7 -0
  81. package/wind/plugin.js +1032 -0
  82. package/wind/vectorfieldimage.js +27 -0
@@ -0,0 +1,284 @@
1
+ import { createProgram } from "../../util";
2
+ import { globeProgramCache } from "../programcache";
3
+ import { CameraUniformBlockTotem } from "../totems";
4
+
5
+ const arrowVertexShader = `#version 300 es
6
+ #define R 6378.137
7
+ #define PI 3.1415926535897932384626433832795
8
+ #define POLE 20037508.34
9
+ #define POLE_BY_PI 6366198.2
10
+ #define HALF_PI 1.5707963267948966192313216916398
11
+
12
+ uniform sampler2D rotation; // rotation of arrow
13
+
14
+ out vec4 v_color;
15
+
16
+ layout(std140) uniform CameraBlock {
17
+ mat4 u_view;
18
+ mat4 u_projection;
19
+ vec3 u_translate;
20
+ bool u_is3D;
21
+ vec2 u_mapWH;
22
+ vec2 u_scrWH;
23
+ float u_zlevel;
24
+ };
25
+
26
+ layout(std140) uniform ArrowBlock {
27
+ vec4 u_color;
28
+ vec2 u_bbox_offset_rad;
29
+ vec2 u_bbox_size_rad;
30
+ vec2 u_resolution;
31
+ float u_length_ratio;
32
+ float u_width_ratio;
33
+ float u_height;
34
+ float u_no_data_value;
35
+ };
36
+
37
+ vec2 f_texCoord(){
38
+ float fID = float(gl_InstanceID);
39
+ float x = mod( fID, u_resolution.x ) / ( u_resolution.x - 1.0);
40
+ float y = 1.0 - floor( fID / u_resolution.x ) / ( u_resolution.y - 1.0);
41
+ return vec2(x, y);
42
+ }
43
+
44
+ vec2 f_radCoord(vec2 texCoord){
45
+ float x = (texCoord.x * u_bbox_size_rad.x ) + u_bbox_offset_rad.x;
46
+ float y = (texCoord.y * u_bbox_size_rad.y ) + u_bbox_offset_rad.y;
47
+ return vec2(x, y);
48
+ }
49
+
50
+ vec3 f_onSphere(vec2 radCoord){
51
+ float x = sin(radCoord.y) * cos(radCoord.x);
52
+ float y = sin(radCoord.y) * sin(radCoord.x);
53
+ float z = cos(radCoord.y);
54
+ return vec3(x, y, z) * (R + u_height);
55
+ }
56
+
57
+
58
+ vec2 f_onFlat(vec2 radCoord){
59
+ float mercX = radCoord.x * POLE_BY_PI;
60
+ float mercY = log(tan(HALF_PI - radCoord.y * 0.5)) * POLE_BY_PI;
61
+ float normX = ( mercX - u_translate.x ) / u_mapWH.x;
62
+ float normY = ( mercY - u_translate.y ) / u_mapWH.y;
63
+ return vec2(normX, normY);
64
+ }
65
+
66
+ void main() {
67
+ // escape if no data
68
+ vec2 texCoord = f_texCoord();
69
+ vec2 geoCoord = vec2( texCoord.x , 1.0 - texCoord.y );
70
+
71
+
72
+ float angle = texture(rotation, texCoord).r;
73
+
74
+ if ( angle == u_no_data_value ) {
75
+ gl_Position = vec4(-2.0, -2.0, 0.0, 1.0);
76
+ return;
77
+ }
78
+ vec2 arrowLimb;
79
+ if (0.0 == mod(float(gl_VertexID), 2.0)) {
80
+ arrowLimb = vec2(0.0, 0.0);
81
+ } else if (gl_VertexID == 1) {
82
+ // tail
83
+ arrowLimb = vec2( cos(angle), sin(angle)) * u_length_ratio / (170.0 );
84
+ } else if (gl_VertexID == 3) {
85
+ // right wing
86
+ arrowLimb = vec2( cos(angle + 0.45), sin(angle + 0.45)) * u_width_ratio / (170.0 );
87
+ } else if (gl_VertexID == 5) {
88
+ // left wing
89
+ arrowLimb = vec2( cos(angle - 0.45), sin(angle - 0.45)) * u_width_ratio / (170.0 );
90
+ }
91
+
92
+
93
+ vec2 radCoord = f_radCoord(geoCoord + arrowLimb);
94
+ if ( u_is3D ) {
95
+ vec3 spherePos = f_onSphere(radCoord);
96
+ gl_Position = u_projection * u_view * vec4(spherePos - u_translate, 1.0);
97
+ } else {
98
+ vec2 flatPos = f_onFlat(radCoord);
99
+ gl_Position = u_projection * vec4(
100
+ flatPos.x * u_scrWH.x,
101
+ (1.0 - flatPos.y) * u_scrWH.y,
102
+ 0.0, 1.0
103
+ );
104
+ }
105
+
106
+
107
+ v_color = u_color;
108
+ gl_PointSize = 4.0;
109
+ }
110
+ `;
111
+
112
+
113
+ const arrowFragmentShader = `#version 300 es
114
+ precision highp float;
115
+ in vec4 v_color;
116
+ out vec4 outColor;
117
+
118
+ void main() {
119
+ outColor = v_color;
120
+ }
121
+ `;
122
+
123
+
124
+ export default class ArrowFieldLogic {
125
+
126
+ constructor() {
127
+ this.gl = null;
128
+ this.globe = null;
129
+ this.cameraUniformBlockTotem = null;
130
+ this.program = null;
131
+ this.cameraBlockBindingPoint = 0;
132
+ this.arrayBlockBindingPoint = 1;
133
+ }
134
+
135
+ init(globe, gl) {
136
+ this.gl = gl;
137
+ this.globe = globe;
138
+ this.cameraUniformBlockTotem = globeProgramCache.getProgram(globe, CameraUniformBlockTotem);
139
+ this.program = this._createProgram();
140
+ }
141
+
142
+ _createProgram() {
143
+ const gl = this.gl;
144
+ const program = createProgram(gl, arrowVertexShader, arrowFragmentShader);
145
+
146
+ const cameraBlockIndex = gl.getUniformBlockIndex(program, "CameraBlock");
147
+ gl.uniformBlockBinding(program, cameraBlockIndex, this.cameraBlockBindingPoint);
148
+ const buffer = this.cameraUniformBlockTotem.getUBO();
149
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, this.cameraBlockBindingPoint, buffer);
150
+
151
+ const arrowBlockIndex = gl.getUniformBlockIndex(program, "ArrowBlock");
152
+ gl.uniformBlockBinding(program, arrowBlockIndex, this.arrayBlockBindingPoint);
153
+
154
+ this.textureLocations = {
155
+ rotationLocation: gl.getUniformLocation(program, "rotation"),
156
+ }
157
+
158
+ return program;
159
+ }
160
+
161
+ getArrowBlockBufferManager() {
162
+ return new ArrowBlockBufferManager(this.gl, this.arrayBlockBindingPoint);
163
+ }
164
+
165
+ // initial load type is static.
166
+ // after that, it is dynamic.
167
+ getTextureManager(width, height) {
168
+ return new TextureManager(this.gl, width, height, this.textureLocations);
169
+ }
170
+
171
+ draw(arrowBlockManager, textureManager, instanceCount) {
172
+ const { gl } = this;
173
+ gl.useProgram(this.program);
174
+ arrowBlockManager.bind();
175
+ textureManager.activate();
176
+ gl.drawArraysInstanced(gl.LINES, 0, 6, instanceCount);
177
+ // gl.drawArraysInstanced(gl.POINTS, 0, 4, instanceCount);
178
+ arrowBlockManager.unbind();
179
+ }
180
+
181
+ free() {
182
+ const { gl, program } = this;
183
+ gl.deleteProgram(program);
184
+ globeProgramCache.releaseProgram(this.globe, CameraUniformBlockTotem);
185
+ }
186
+ }
187
+
188
+
189
+ class ArrowBlockBufferManager {
190
+ constructor(gl, bindingPoint) {
191
+ this.gl = gl;
192
+ this.bindingPoint = bindingPoint;
193
+ this.ubo = gl.createBuffer();
194
+ gl.bindBuffer(gl.UNIFORM_BUFFER, this.ubo);
195
+ // 4 + 2+ 2 + 2 + 1 +1 +1 +1+1= 15 ~= 16
196
+ gl.bufferData(gl.UNIFORM_BUFFER, 56, gl.DYNAMIC_DRAW);
197
+
198
+ }
199
+
200
+ update({
201
+ color = null,
202
+ bboxOffsetRad = null,
203
+ bboxSizeRad = null,
204
+ resolution = null,
205
+ tailLengthRatio = null,
206
+ wingLengthRatio = null,
207
+ height = null,
208
+ opacity = null,
209
+ noDataValue = null,
210
+ } = {}) {
211
+ const { gl, ubo } = this;
212
+ gl.bindBuffer(gl.UNIFORM_BUFFER, ubo);
213
+ if (color !== null) gl.bufferSubData(gl.UNIFORM_BUFFER, 0, new Float32Array(color));
214
+ if (opacity !== null) gl.bufferSubData(gl.UNIFORM_BUFFER, 12, new Float32Array([opacity]));
215
+ if (bboxOffsetRad !== null) gl.bufferSubData(gl.UNIFORM_BUFFER, 16, new Float32Array(bboxOffsetRad));
216
+ if (bboxSizeRad !== null) gl.bufferSubData(gl.UNIFORM_BUFFER, 24, new Float32Array(bboxSizeRad));
217
+ if (resolution !== null) gl.bufferSubData(gl.UNIFORM_BUFFER, 32, new Float32Array(resolution));
218
+ if (tailLengthRatio !== null) gl.bufferSubData(gl.UNIFORM_BUFFER, 40, new Float32Array([tailLengthRatio]));
219
+ if (wingLengthRatio !== null) gl.bufferSubData(gl.UNIFORM_BUFFER, 44, new Float32Array([wingLengthRatio]));
220
+ if (height !== null) gl.bufferSubData(gl.UNIFORM_BUFFER, 48, new Float32Array([height]));
221
+ if (noDataValue !== null) gl.bufferSubData(gl.UNIFORM_BUFFER, 52, new Float32Array([noDataValue]));
222
+ gl.bindBuffer(gl.UNIFORM_BUFFER, null);
223
+ }
224
+
225
+ bind() {
226
+ const { gl, ubo, bindingPoint } = this;
227
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, bindingPoint, ubo);
228
+ }
229
+
230
+ unbind() {
231
+ const { gl, bindingPoint } = this;
232
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, bindingPoint, null);
233
+ }
234
+
235
+ free() {
236
+ const { gl, ubo } = this;
237
+ gl.deleteBuffer(ubo);
238
+ }
239
+ }
240
+
241
+ class TextureManager {
242
+
243
+ constructor(gl, width, height, { rotationLocation }) {
244
+ this.gl = gl;
245
+ this.width = width;
246
+ this.height = height;
247
+ this.rotationLocation = rotationLocation;
248
+ this.rotationTexture = this._createFloatTexture();
249
+ }
250
+
251
+ _createFloatTexture() {
252
+ const { gl, width, height } = this;
253
+ const texture = gl.createTexture();
254
+ gl.bindTexture(gl.TEXTURE_2D, texture);
255
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
256
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
257
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.R32F, width, height, 0, gl.RED, gl.FLOAT, null);
258
+ gl.bindTexture(gl.TEXTURE_2D, null);
259
+ return texture;
260
+ }
261
+
262
+ setData(rotation) {
263
+ const { gl, rotationTexture, width, height } = this;
264
+ // gl flip y axis
265
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
266
+ gl.bindTexture(gl.TEXTURE_2D, rotationTexture);
267
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.R32F, width, height, 0, gl.RED, gl.FLOAT, rotation);
268
+ gl.bindTexture(gl.TEXTURE_2D, null);
269
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
270
+ }
271
+
272
+ activate() {
273
+ const { gl, rotationTexture } = this;
274
+
275
+ gl.activeTexture(gl.TEXTURE0);
276
+ gl.bindTexture(gl.TEXTURE_2D, rotationTexture);
277
+ gl.uniform1i(this.rotationLocation, 0);
278
+ }
279
+
280
+ free() {
281
+ const { gl, rotationTexture } = this;
282
+ gl.deleteTexture(rotationTexture);
283
+ }
284
+ }
@@ -0,0 +1,89 @@
1
+ // this contains vao, drawCount, ArrowBufferBlock, vao,
2
+ // how to, where to set instanced parameters
3
+ // the vectorfield buffer should be managed outside, since it can be static or dynamic.
4
+
5
+ import Logic from './logic';
6
+ import { globeProgramCache } from '../programcache';
7
+ import { longlatbbox2normalbbox } from "../util";
8
+
9
+ export default class ArrowField {
10
+ constructor(gl, globe, {
11
+ minLon = -180,
12
+ maxLon = 180,
13
+ minLat = -90,
14
+ maxLat = 90,
15
+ height = 0,
16
+ opacity = 1,
17
+ color = [0.04, 0.2, 0.8],
18
+ targetWidth = 100,
19
+ targetHeight = 100,
20
+ dataWidth = null,
21
+ dataHeight = null,
22
+ tailLengthRatio = 1,
23
+ wingLengthRatio = 0.5,
24
+ noDataValue = null,
25
+ maxMagnitude = null
26
+ } = {}) {
27
+ this.gl = gl;
28
+ this.globe = globe;
29
+
30
+ this.program = globeProgramCache.getProgram(globe, Logic);
31
+ this.arrowBlockManager = this.program.getArrowBlockBufferManager();
32
+ this.instanceCount = targetWidth * targetHeight;
33
+ this.arrowBlockManager.update({ resolution: [targetWidth, targetHeight] });
34
+ this.textureManager = this.program.getTextureManager(dataWidth, dataHeight);
35
+ this.setBBox({ minLon, maxLon, minLat, maxLat });
36
+ this.update({ height, opacity, color, tailLengthRatio, wingLengthRatio, noDataValue });
37
+ }
38
+
39
+
40
+ setBBox({ minLon = -180, maxLon = 180, minLat = -90, maxLat = 90 } = {}) {
41
+ this.bbox = { minLon, maxLon, minLat, maxLat };
42
+ const { bboxSizeRad, bboxOffsetRad } = longlatbbox2normalbbox(this.bbox);
43
+ this.arrowBlockManager.update({ bboxSizeRad, bboxOffsetRad });
44
+ this.globe.DrawRender();
45
+ }
46
+
47
+
48
+ update({ height, opacity, color, resolution, tailLengthRatio, wingLengthRatio, noDataValue } = {}) {
49
+ if (resolution) {
50
+ this.instanceCount = resolution[0] * resolution[1];
51
+ }
52
+ this.arrowBlockManager.update({
53
+ color,
54
+ resolution,
55
+ height,
56
+ opacity,
57
+ tailLengthRatio,
58
+ wingLengthRatio,
59
+ noDataValue,
60
+ });
61
+ this.globe.DrawRender();
62
+ }
63
+
64
+ setTargetResolution(width, height) {
65
+ this.instanceCount = width * height;
66
+ this.arrowBlockManager.update({ resolution: [width, height] });
67
+
68
+ this.globe.DrawRender();
69
+ }
70
+
71
+ draw() {
72
+ const { program, arrowBlockManager, textureManager, instanceCount } = this;
73
+ program.draw(arrowBlockManager, textureManager, instanceCount);
74
+ }
75
+
76
+
77
+ setData(rotation) {
78
+ this.textureManager.setData(rotation);
79
+ this.globe.DrawRender();
80
+ }
81
+
82
+
83
+ free() {
84
+ this.arrowBlockManager.free();
85
+ this.textureManager.free();
86
+ globeProgramCache.releaseProgram(this.gl, Logic);
87
+ }
88
+ }
89
+
@@ -0,0 +1,3 @@
1
+ import Float2LegendWithRatio from './object';
2
+
3
+ export { Float2LegendWithRatio };
@@ -0,0 +1,189 @@
1
+ import { createProgram } from "../../util";
2
+
3
+ export default class {
4
+
5
+
6
+ constructor(gl) {
7
+ this.gl = gl;
8
+ // console.log("Float2LegendWithRatioProgram gl:", gl);
9
+ this._width = 1;
10
+ this._height = 1;
11
+
12
+ this._blendRatio = 0.0;
13
+ this.programWrapper = this._createProgramWrapper();
14
+ }
15
+
16
+
17
+ _createProgramWrapper() {
18
+ const vertexShaderSource = `#version 300 es
19
+ precision highp float;
20
+
21
+ in vec2 a_position;
22
+ out vec2 v_texcoord;
23
+
24
+ void main() {
25
+ gl_Position = vec4(a_position, 0.0, 1.0);
26
+ v_texcoord = a_position * 0.5 + 0.5;
27
+ v_texcoord.y = 1.0 - v_texcoord.y;
28
+ }
29
+ `;
30
+
31
+ const fragmentShaderSource = `#version 300 es
32
+ precision highp float;
33
+
34
+ in vec2 v_texcoord;
35
+ uniform sampler2D u_float_texture0;
36
+ uniform sampler2D u_float_texture1;
37
+ uniform sampler2D u_color_texture;
38
+
39
+ layout(std140) uniform HeatParametersBlock {
40
+ vec2 u_color_ramp_range; // x is min, y is range ( max - min)
41
+ vec2 u_min_max;
42
+ float u_escape_value;
43
+ float u_blend_ratio;
44
+ };
45
+
46
+ out vec4 outColor;
47
+
48
+ void main() {
49
+
50
+ float f0 = texture(u_float_texture0, v_texcoord).r;
51
+ float f1 = texture(u_float_texture1, v_texcoord).r;
52
+ // outColor = vec4(
53
+
54
+ if (f0 == u_escape_value || f1 == u_escape_value) {
55
+ outColor = vec4(0.0, 0.0, 0.0, 0.0);
56
+ return;
57
+ }
58
+ float x = mix(f0, f1, u_blend_ratio);
59
+ if ( x < u_min_max.x || x > u_min_max.y) {
60
+ outColor = vec4(0.0, 0.0, 0.0, 0.0);
61
+ return;
62
+ }
63
+ x = (x - u_color_ramp_range.x) / u_color_ramp_range.y;
64
+ outColor = texture(u_color_texture, vec2(x, 0.5));
65
+ }
66
+ `;
67
+
68
+ const gl = this.gl;
69
+ const program = createProgram(gl, vertexShaderSource, fragmentShaderSource);
70
+ const vao = gl.createVertexArray();
71
+ gl.bindVertexArray(vao);
72
+ const buffer = gl.createBuffer();
73
+ this._buffer = buffer;
74
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
75
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
76
+ -1, -1,
77
+ 1, -1,
78
+ 1, 1,
79
+ -1, 1
80
+ ]), gl.STATIC_DRAW);
81
+ const positionLocation = gl.getAttribLocation(program, "a_position");
82
+ gl.enableVertexAttribArray(positionLocation);
83
+ gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
84
+ gl.bindVertexArray(null);
85
+
86
+ this.heatParametersBlockBindingPoint = 0;
87
+
88
+ const heatParametersBlockIndex = gl.getUniformBlockIndex(program, "HeatParametersBlock");
89
+ gl.uniformBlockBinding(program, heatParametersBlockIndex, this.heatParametersBlockBindingPoint);
90
+
91
+
92
+ return {
93
+ program,
94
+ vao,
95
+ u_float_texture0: gl.getUniformLocation(program, "u_float_texture0"),
96
+ u_float_texture1: gl.getUniformLocation(program, "u_float_texture1"),
97
+ u_color_texture: gl.getUniformLocation(program, "u_color_texture"),
98
+ u_blend_ratio: gl.getUniformLocation(program, "u_blend_ratio"),
99
+ u_color_ramp_range: gl.getUniformLocation(program, "u_color_ramp_range"),
100
+ u_min_max: gl.getUniformLocation(program, "u_min_max"),
101
+ u_escape_value: gl.getUniformLocation(program, "u_escape_value")
102
+ };
103
+ }
104
+
105
+
106
+ getUniformBlockManager() {
107
+ return new HeatParametersBlockManager(this.gl);
108
+ }
109
+ draw(texture0, texture1, colorRampTexture, heatParametersBlockManager) {
110
+ const { gl, programWrapper } = this;
111
+ const { program, u_float_texture0, u_float_texture1, u_color_texture } = programWrapper;
112
+
113
+ gl.useProgram(program);
114
+ gl.bindVertexArray(programWrapper.vao);
115
+ gl.activeTexture(gl.TEXTURE1);
116
+ gl.bindTexture(gl.TEXTURE_2D, texture1);
117
+ gl.uniform1i(u_float_texture1, 1);
118
+ gl.activeTexture(gl.TEXTURE2);
119
+ gl.bindTexture(gl.TEXTURE_2D, colorRampTexture);
120
+ gl.uniform1i(u_color_texture, 2);
121
+ gl.activeTexture(gl.TEXTURE0);
122
+ gl.bindTexture(gl.TEXTURE_2D, texture0);
123
+ gl.uniform1i(u_float_texture0, 0);
124
+ heatParametersBlockManager.bind();
125
+ gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);
126
+ gl.bindVertexArray(null);
127
+ heatParametersBlockManager.unbind();
128
+ }
129
+
130
+
131
+ free() {
132
+ const gl = this.gl;
133
+ gl.deleteBuffer(this._buffer);
134
+ gl.deleteProgram(this.programWrapper.program);
135
+ gl.deleteVertexArray(this.programWrapper.vao);
136
+ }
137
+
138
+ }
139
+
140
+
141
+ class HeatParametersBlockManager {
142
+ constructor(gl) {
143
+ this.gl = gl;
144
+ this.buffer = gl.createBuffer();
145
+ gl.bindBuffer(gl.UNIFORM_BUFFER, this.buffer);
146
+ gl.bufferData(gl.UNIFORM_BUFFER, 24, gl.DYNAMIC_DRAW);
147
+ gl.bindBuffer(gl.UNIFORM_BUFFER, null);
148
+ }
149
+
150
+
151
+ /*
152
+ * @param {Array<number>} color_ramp_range [minValue,( maxValue - minValue)]
153
+ * @param {Array<number>} min_max [minEdge, maxEdge]
154
+ * @param {number} escape_value // value that will be ignored
155
+ * @param {number} blend_ratio // ratio of blending between two textures
156
+ * */
157
+ update({ color_ramp_range = null, min_max = null, escape_value = null, blend_ratio = null }) {
158
+ const { gl, buffer } = this;
159
+ gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);
160
+ if (color_ramp_range) {
161
+ gl.bufferSubData(gl.UNIFORM_BUFFER, 0, new Float32Array(color_ramp_range));
162
+ }
163
+ if (min_max) {
164
+ gl.bufferSubData(gl.UNIFORM_BUFFER, 8, new Float32Array(min_max));
165
+ }
166
+ if (escape_value) {
167
+ gl.bufferSubData(gl.UNIFORM_BUFFER, 16, new Float32Array([escape_value]));
168
+ }
169
+ if (blend_ratio) {
170
+ gl.bufferSubData(gl.UNIFORM_BUFFER, 20, new Float32Array([blend_ratio]));
171
+ }
172
+ gl.bindBuffer(gl.UNIFORM_BUFFER, null);
173
+ }
174
+
175
+ bind() {
176
+ const { gl, buffer } = this;
177
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, this.heatParametersBlockBindingPoint, buffer);
178
+ }
179
+
180
+ free() {
181
+ this.gl.deleteBuffer(this.buffer);
182
+ }
183
+
184
+ unbind() {
185
+ const { gl } = this;
186
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, this.heatParametersBlockBindingPoint, null);
187
+ }
188
+
189
+ }
@@ -0,0 +1,132 @@
1
+ import Float2LegentWithRatioProgram from './logic';
2
+ import { glProgramCache } from '../programcache';
3
+
4
+ // Uniform Buffer Objects use this
5
+
6
+ export default class {
7
+ constructor(gl, {
8
+ width = 1,
9
+ height = 1,
10
+ texture0 = null,
11
+ texture1 = null,
12
+ colorRampTexture = null,
13
+ colorRampRange = null,
14
+ escapeValue = 99999,
15
+ blendRatio = 0.0,
16
+ minMaxEdges = null,
17
+ } = {}) {
18
+ this.gl = gl;
19
+ this.programlogic = glProgramCache.getProgram(gl, Float2LegentWithRatioProgram);
20
+ this.heatParametersBlockManager = this.programlogic.getUniformBlockManager();
21
+ this.width = width;
22
+ this.height = height;
23
+ this.texture0 = texture0 || this._createColorRampTexture(width, height);
24
+ this.texture1 = texture1 || this._createColorRampTexture(width, height);
25
+ this.colorRampTexture = colorRampTexture || this._createColorRampTexture();
26
+ this.minMaxEdges = minMaxEdges || new Float32Array([-99999, 99999]);
27
+ this.heatParametersBlockManager.update({
28
+ escape_value: escapeValue,
29
+ blend_ratio: blendRatio,
30
+ min_max: minMaxEdges,
31
+ color_ramp_range: colorRampRange
32
+
33
+ });
34
+
35
+ }
36
+
37
+
38
+ _bindBlock() {
39
+ const gl = this.gl;
40
+ const program = this.programlogic.programWrapper.program;
41
+ gl.uniformBlockBinding(program, gl.getUniformBlockIndex(program, 'Block'), 0);
42
+
43
+ }
44
+
45
+
46
+ _createColorRampTexture() {
47
+ const { gl } = this;
48
+ const texture = gl.createTexture();
49
+ gl.bindTexture(gl.TEXTURE_2D, texture);
50
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
51
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
52
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
53
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
54
+ gl.bindTexture(gl.TEXTURE_2D, null);
55
+ return texture;
56
+ }
57
+
58
+ setBlendRatio(ratio) {
59
+ if (ratio < 0 || ratio > 1) {
60
+ console.warn('Invalid blend ratio');
61
+ return;
62
+ }
63
+ this.heatParametersBlockManager.update({ blend_ratio: ratio });
64
+ }
65
+
66
+ setEscapeValue(value) {
67
+ this.heatParametersBlockManager.update({ escape_value: value });
68
+ }
69
+
70
+
71
+ setTexture0(texture) {
72
+ this.texture0 = texture;
73
+ }
74
+
75
+ setTexture1(texture) {
76
+ this.texture1 = texture;
77
+ }
78
+
79
+ setColorRampTexture(texture) {
80
+ this.colorRampTexture = texture;
81
+ }
82
+
83
+
84
+ setDataWidthHeight(width, height) {
85
+ this.width = width;
86
+ this.height = height;
87
+ }
88
+
89
+
90
+ setFloatTextureData(data0, data1, width, height) {
91
+ const { texture0, texture1, gl } = this;
92
+ gl.bindTexture(gl.TEXTURE_2D, texture0);
93
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.R16F, width, height, 0, gl.RED, gl.FLOAT, data0);
94
+ gl.bindTexture(gl.TEXTURE_2D, texture1);
95
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.R16F, width, height, 0, gl.RED, gl.FLOAT, data1);
96
+ }
97
+
98
+
99
+ setColorRampTextureData(data, size) {
100
+ const { gl, colorRampTexture } = this;
101
+ gl.bindTexture(gl.TEXTURE_2D, colorRampTexture);
102
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
103
+ }
104
+
105
+ setColorRampRange(min, max) {
106
+ if (min > max) {
107
+ console.warn('Invalid min max values');
108
+ return;
109
+ }
110
+ const range = max - min;
111
+ this.heatParametersBlockManager.update({ color_ramp_range: new Float32Array([min, range]) });
112
+ }
113
+
114
+ setMinMaxEdges(min, max) {
115
+ if (min) this.minMaxEdges[0] = min;
116
+ if (max) this.minMaxEdges[1] = max;
117
+ this.heatParametersBlockManager.update({ min_max: this.minMaxEdges });
118
+ }
119
+
120
+ draw() {
121
+ this.programlogic.draw(this.texture0, this.texture1, this.colorRampTexture, this.heatParametersBlockManager);
122
+ }
123
+
124
+
125
+
126
+ free() {
127
+ // TODO: What else to free. Does textures and buffers need to be freed?
128
+ glProgramCache.releaseProgram(this.gl, Float2LegentWithRatioProgram);
129
+ this.heatParametersBlockManager.free();
130
+
131
+ }
132
+ }
@@ -0,0 +1,2 @@
1
+ import GlobeShellWiggle from "./globeshell/wiggle";
2
+ export { GlobeShellWiggle };
File without changes