@mui/x-charts-premium 9.0.3 → 9.1.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.
Files changed (179) hide show
  1. package/BarChartPremium/BarChartPremium.js +2 -1183
  2. package/BarChartPremium/BarChartPremium.mjs +2 -1183
  3. package/BarChartPremium/RangeBar/FocusedRangeBar.js +3 -0
  4. package/BarChartPremium/RangeBar/FocusedRangeBar.mjs +3 -0
  5. package/BarChartPremium/RangeBar/seriesConfig/seriesProcessor.js +2 -0
  6. package/BarChartPremium/RangeBar/seriesConfig/seriesProcessor.mjs +2 -0
  7. package/CHANGELOG.md +220 -0
  8. package/CandlestickChart/CandlestickChart.d.mts +2 -2
  9. package/CandlestickChart/CandlestickChart.d.ts +2 -2
  10. package/CandlestickChart/CandlestickChart.js +2 -1183
  11. package/CandlestickChart/CandlestickChart.mjs +2 -1183
  12. package/CandlestickChart/CandlestickWebGLProgram.d.mts +6 -11
  13. package/CandlestickChart/CandlestickWebGLProgram.d.ts +6 -11
  14. package/CandlestickChart/CandlestickWebGLProgram.js +136 -121
  15. package/CandlestickChart/CandlestickWebGLProgram.mjs +137 -122
  16. package/CandlestickChart/useCandlestickPlotData.d.mts +2 -2
  17. package/CandlestickChart/useCandlestickPlotData.d.ts +2 -2
  18. package/CandlestickChart/useCandlestickPlotData.js +121 -61
  19. package/CandlestickChart/useCandlestickPlotData.mjs +122 -61
  20. package/ChartsAxisHighlightValue/index.d.mts +1 -0
  21. package/ChartsAxisHighlightValue/index.d.ts +1 -0
  22. package/ChartsAxisHighlightValue/index.js +16 -0
  23. package/ChartsAxisHighlightValue/index.mjs +2 -0
  24. package/ChartsDataProviderPremium/ChartsDataProviderPremium.js +2 -2
  25. package/ChartsDataProviderPremium/ChartsDataProviderPremium.mjs +2 -2
  26. package/ChartsRadialAxisHighlight/index.d.mts +1 -0
  27. package/ChartsRadialAxisHighlight/index.d.ts +1 -0
  28. package/ChartsRadialAxisHighlight/index.js +16 -0
  29. package/ChartsRadialAxisHighlight/index.mjs +2 -0
  30. package/ChartsRadialDataProviderPremium/ChartsRadialDataProviderPremium.js +2 -2
  31. package/ChartsRadialDataProviderPremium/ChartsRadialDataProviderPremium.mjs +2 -2
  32. package/HeatmapPremium/HeatmapPremium.js +2 -155
  33. package/HeatmapPremium/HeatmapPremium.mjs +2 -155
  34. package/HeatmapPremium/webgl/HeatmapWebGLPlot.js +19 -112
  35. package/HeatmapPremium/webgl/HeatmapWebGLPlot.mjs +19 -111
  36. package/HeatmapPremium/webgl/HeatmapWebGLProgram.d.mts +24 -0
  37. package/HeatmapPremium/webgl/HeatmapWebGLProgram.d.ts +24 -0
  38. package/HeatmapPremium/webgl/HeatmapWebGLProgram.js +132 -0
  39. package/HeatmapPremium/webgl/HeatmapWebGLProgram.mjs +125 -0
  40. package/HeatmapPremium/webgl/shaders.d.mts +1 -1
  41. package/HeatmapPremium/webgl/shaders.d.ts +1 -1
  42. package/HeatmapPremium/webgl/shaders.js +1 -1
  43. package/HeatmapPremium/webgl/shaders.mjs +1 -1
  44. package/HeatmapPremium/webgl/useHeatmapPlotData.d.mts +3 -3
  45. package/HeatmapPremium/webgl/useHeatmapPlotData.d.ts +3 -3
  46. package/HeatmapPremium/webgl/useHeatmapPlotData.js +78 -26
  47. package/HeatmapPremium/webgl/useHeatmapPlotData.mjs +80 -26
  48. package/LICENSE +3 -1
  49. package/RadialBarChart/RadialBarChart.d.mts +60 -0
  50. package/RadialBarChart/RadialBarChart.d.ts +60 -0
  51. package/RadialBarChart/RadialBarChart.js +298 -0
  52. package/RadialBarChart/RadialBarChart.mjs +292 -0
  53. package/RadialBarChart/RadialBarChart.plugins.d.mts +4 -0
  54. package/RadialBarChart/RadialBarChart.plugins.d.ts +4 -0
  55. package/RadialBarChart/RadialBarChart.plugins.js +9 -0
  56. package/RadialBarChart/RadialBarChart.plugins.mjs +3 -0
  57. package/RadialBarChart/RadialBarElement.d.mts +16 -0
  58. package/RadialBarChart/RadialBarElement.d.ts +16 -0
  59. package/RadialBarChart/RadialBarElement.js +54 -0
  60. package/RadialBarChart/RadialBarElement.mjs +48 -0
  61. package/RadialBarChart/RadialBarPlot.d.mts +21 -0
  62. package/RadialBarChart/RadialBarPlot.d.ts +21 -0
  63. package/RadialBarChart/RadialBarPlot.js +85 -0
  64. package/RadialBarChart/RadialBarPlot.mjs +79 -0
  65. package/RadialBarChart/index.d.mts +3 -0
  66. package/RadialBarChart/index.d.ts +3 -0
  67. package/RadialBarChart/index.js +39 -0
  68. package/RadialBarChart/index.mjs +3 -0
  69. package/RadialBarChart/radialBarClasses.d.mts +15 -0
  70. package/RadialBarChart/radialBarClasses.d.ts +15 -0
  71. package/RadialBarChart/radialBarClasses.js +26 -0
  72. package/RadialBarChart/radialBarClasses.mjs +18 -0
  73. package/RadialBarChart/seriesConfig/seriesProcessor.js +4 -0
  74. package/RadialBarChart/seriesConfig/seriesProcessor.mjs +4 -0
  75. package/RadialBarChart/useRadialBarChartProps.d.mts +28 -0
  76. package/RadialBarChart/useRadialBarChartProps.d.ts +28 -0
  77. package/RadialBarChart/useRadialBarChartProps.js +100 -0
  78. package/RadialBarChart/useRadialBarChartProps.mjs +93 -0
  79. package/RadialBarChart/useRadialBarPlotData.d.mts +23 -0
  80. package/RadialBarChart/useRadialBarPlotData.d.ts +23 -0
  81. package/RadialBarChart/useRadialBarPlotData.js +94 -0
  82. package/RadialBarChart/useRadialBarPlotData.mjs +87 -0
  83. package/RadialLineChart/RadialArea.js +13 -1
  84. package/RadialLineChart/RadialArea.mjs +13 -1
  85. package/RadialLineChart/RadialLine.js +13 -1
  86. package/RadialLineChart/RadialLine.mjs +13 -1
  87. package/RadialLineChart/RadialLineChart.d.mts +11 -3
  88. package/RadialLineChart/RadialLineChart.d.ts +11 -3
  89. package/RadialLineChart/RadialLineChart.js +24 -673
  90. package/RadialLineChart/RadialLineChart.mjs +24 -673
  91. package/RadialLineChart/RadialLineHighlightElement.d.mts +15 -0
  92. package/RadialLineChart/RadialLineHighlightElement.d.ts +15 -0
  93. package/RadialLineChart/RadialLineHighlightElement.js +46 -0
  94. package/RadialLineChart/RadialLineHighlightElement.mjs +39 -0
  95. package/RadialLineChart/RadialLineHighlightPlot.d.mts +23 -0
  96. package/RadialLineChart/RadialLineHighlightPlot.d.ts +23 -0
  97. package/RadialLineChart/RadialLineHighlightPlot.js +92 -0
  98. package/RadialLineChart/RadialLineHighlightPlot.mjs +86 -0
  99. package/RadialLineChart/RadialMarkPlot.js +32 -3
  100. package/RadialLineChart/RadialMarkPlot.mjs +32 -3
  101. package/RadialLineChart/index.d.mts +3 -1
  102. package/RadialLineChart/index.d.ts +3 -1
  103. package/RadialLineChart/index.js +22 -0
  104. package/RadialLineChart/index.mjs +3 -1
  105. package/RadialLineChart/radialLineClasses.d.mts +3 -1
  106. package/RadialLineChart/radialLineClasses.d.ts +3 -1
  107. package/RadialLineChart/radialLineClasses.js +2 -1
  108. package/RadialLineChart/radialLineClasses.mjs +2 -1
  109. package/RadialLineChart/seriesConfig/getItemAtPosition.d.mts +6 -0
  110. package/RadialLineChart/seriesConfig/getItemAtPosition.d.ts +6 -0
  111. package/RadialLineChart/seriesConfig/getItemAtPosition.js +353 -0
  112. package/RadialLineChart/seriesConfig/getItemAtPosition.mjs +348 -0
  113. package/RadialLineChart/seriesConfig/getSeriesWithDefaultValues.js +2 -1
  114. package/RadialLineChart/seriesConfig/getSeriesWithDefaultValues.mjs +2 -1
  115. package/RadialLineChart/seriesConfig/index.js +2 -1
  116. package/RadialLineChart/seriesConfig/index.mjs +2 -1
  117. package/RadialLineChart/seriesConfig/seriesProcessor.js +4 -0
  118. package/RadialLineChart/seriesConfig/seriesProcessor.mjs +4 -0
  119. package/RadialLineChart/useRadialLineChartProps.d.mts +2 -0
  120. package/RadialLineChart/useRadialLineChartProps.d.ts +2 -0
  121. package/RadialLineChart/useRadialLineChartProps.js +16 -8
  122. package/RadialLineChart/useRadialLineChartProps.mjs +16 -8
  123. package/RadialLineChart/useRadialLinePlotData.d.mts +3 -1
  124. package/RadialLineChart/useRadialLinePlotData.d.ts +3 -1
  125. package/RadialLineChart/useRadialLinePlotData.js +5 -1
  126. package/RadialLineChart/useRadialLinePlotData.mjs +6 -2
  127. package/ScatterChartPremium/ScatterChartPremium.d.mts +25 -0
  128. package/ScatterChartPremium/ScatterChartPremium.d.ts +25 -0
  129. package/ScatterChartPremium/ScatterChartPremium.js +507 -0
  130. package/ScatterChartPremium/ScatterChartPremium.mjs +501 -0
  131. package/ScatterChartPremium/ScatterChartPremium.plugins.d.mts +3 -0
  132. package/ScatterChartPremium/ScatterChartPremium.plugins.d.ts +3 -0
  133. package/ScatterChartPremium/ScatterChartPremium.plugins.js +8 -0
  134. package/ScatterChartPremium/ScatterChartPremium.plugins.mjs +2 -0
  135. package/ScatterChartPremium/ScatterPlotPremium.d.mts +14 -0
  136. package/ScatterChartPremium/ScatterPlotPremium.d.ts +14 -0
  137. package/ScatterChartPremium/ScatterPlotPremium.js +28 -0
  138. package/ScatterChartPremium/ScatterPlotPremium.mjs +21 -0
  139. package/ScatterChartPremium/index.d.mts +3 -0
  140. package/ScatterChartPremium/index.d.ts +3 -0
  141. package/ScatterChartPremium/index.js +26 -0
  142. package/ScatterChartPremium/index.mjs +3 -0
  143. package/ScatterChartPremium/webgl/ScatterWebGLPlot.d.mts +4 -0
  144. package/ScatterChartPremium/webgl/ScatterWebGLPlot.d.ts +4 -0
  145. package/ScatterChartPremium/webgl/ScatterWebGLPlot.js +70 -0
  146. package/ScatterChartPremium/webgl/ScatterWebGLPlot.mjs +65 -0
  147. package/ScatterChartPremium/webgl/ScatterWebGLProgram.d.mts +18 -0
  148. package/ScatterChartPremium/webgl/ScatterWebGLProgram.d.ts +18 -0
  149. package/ScatterChartPremium/webgl/ScatterWebGLProgram.js +129 -0
  150. package/ScatterChartPremium/webgl/ScatterWebGLProgram.mjs +122 -0
  151. package/ScatterChartPremium/webgl/shaders.d.mts +2 -0
  152. package/ScatterChartPremium/webgl/shaders.d.ts +2 -0
  153. package/ScatterChartPremium/webgl/shaders.js +57 -0
  154. package/ScatterChartPremium/webgl/shaders.mjs +51 -0
  155. package/ScatterChartPremium/webgl/useScatterWebGLPlotData.d.mts +7 -0
  156. package/ScatterChartPremium/webgl/useScatterWebGLPlotData.d.ts +7 -0
  157. package/ScatterChartPremium/webgl/useScatterWebGLPlotData.js +140 -0
  158. package/ScatterChartPremium/webgl/useScatterWebGLPlotData.mjs +134 -0
  159. package/index.d.mts +3 -1
  160. package/index.d.ts +3 -1
  161. package/index.js +25 -1
  162. package/index.mjs +4 -2
  163. package/internals/index.d.mts +1 -0
  164. package/internals/index.d.ts +1 -0
  165. package/internals/index.js +13 -0
  166. package/internals/index.mjs +1 -0
  167. package/models/seriesType/radialLine.d.mts +7 -1
  168. package/models/seriesType/radialLine.d.ts +7 -1
  169. package/package.json +185 -115
  170. package/plugins/selectors/useChartCandlestickPosition.selectors.d.mts +1 -1
  171. package/plugins/selectors/useChartCandlestickPosition.selectors.d.ts +1 -1
  172. package/utils/webgl/parseColor.d.mts +2 -1
  173. package/utils/webgl/parseColor.d.ts +2 -1
  174. package/utils/webgl/parseColor.js +8 -7
  175. package/utils/webgl/parseColor.mjs +8 -7
  176. package/utils/webgl/utils.d.mts +13 -0
  177. package/utils/webgl/utils.d.ts +13 -0
  178. package/utils/webgl/utils.js +29 -0
  179. package/utils/webgl/utils.mjs +27 -0
@@ -2,18 +2,13 @@ import { type CandlestickPlotData } from "./useCandlestickPlotData.mjs";
2
2
  export declare class CandlestickWebGLProgram {
3
3
  private gl;
4
4
  private readonly shaders;
5
- private readonly candleProgram;
6
- private readonly candleVao;
7
- private readonly candleCentersBuffer;
8
- private readonly candleHeightsBuffer;
9
- private readonly candleColorsBuffer;
10
- private readonly wickProgram;
11
- private readonly wickVao;
12
- private readonly wickVerticesBuffer;
13
- private readonly wickCentersBuffer;
14
- private readonly wickHeightsBuffer;
15
- private readonly wickColorsBuffer;
5
+ private readonly quadBuffer;
6
+ private readonly wickGeometryBuffer;
7
+ private readonly candle;
8
+ private readonly wick;
16
9
  constructor(gl: WebGL2RenderingContext);
10
+ private initCandleProgram;
11
+ private initWickProgram;
17
12
  setResolution(width: number, height: number): void;
18
13
  setCandleWidth(candleWidth: number): void;
19
14
  plot(plotData: CandlestickPlotData): void;
@@ -2,18 +2,13 @@ import { type CandlestickPlotData } from "./useCandlestickPlotData.js";
2
2
  export declare class CandlestickWebGLProgram {
3
3
  private gl;
4
4
  private readonly shaders;
5
- private readonly candleProgram;
6
- private readonly candleVao;
7
- private readonly candleCentersBuffer;
8
- private readonly candleHeightsBuffer;
9
- private readonly candleColorsBuffer;
10
- private readonly wickProgram;
11
- private readonly wickVao;
12
- private readonly wickVerticesBuffer;
13
- private readonly wickCentersBuffer;
14
- private readonly wickHeightsBuffer;
15
- private readonly wickColorsBuffer;
5
+ private readonly quadBuffer;
6
+ private readonly wickGeometryBuffer;
7
+ private readonly candle;
8
+ private readonly wick;
16
9
  constructor(gl: WebGL2RenderingContext);
10
+ private initCandleProgram;
11
+ private initWickProgram;
17
12
  setResolution(width: number, height: number): void;
18
13
  setCandleWidth(candleWidth: number): void;
19
14
  plot(plotData: CandlestickPlotData): void;
@@ -7,50 +7,103 @@ exports.CandlestickWebGLProgram = void 0;
7
7
  var _utils = require("../utils/webgl/utils");
8
8
  var _candleShaders = require("./candleShaders");
9
9
  var _wickShaders = require("./wickShaders");
10
+ const QUAD_VERTICES = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
11
+ const WICK_VERTICES = new Float32Array([0, -1, 0, 1]);
10
12
  class CandlestickWebGLProgram {
11
13
  shaders = [];
12
-
13
- // Candle program and buffers. If you add more WebGL resources, remember to dispose of them in the dispose() method.
14
-
15
- // Wick program and buffers. If you add more WebGL resources, remember to dispose of them in the dispose() method.
16
-
17
14
  constructor(gl) {
18
15
  this.gl = gl;
19
16
  /* Enable blending for transparency
20
17
  * These are global to the WebGL context and need to be set only once */
21
18
  gl.enable(gl.BLEND);
22
19
  gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
23
- const candleProg = initializeProgram(this.gl, _candleShaders.candleVertexShader, _candleShaders.candleFragmentShader);
24
- this.candleProgram = candleProg.program;
25
- this.shaders.push(candleProg.fragmentShader);
26
- this.shaders.push(candleProg.vertexShader);
27
- this.candleVao = this.gl.createVertexArray();
28
- this.candleCentersBuffer = this.gl.createBuffer();
29
- this.candleHeightsBuffer = this.gl.createBuffer();
30
- this.candleColorsBuffer = this.gl.createBuffer();
31
- const wickProg = initializeProgram(this.gl, _wickShaders.wickVertexShader, _wickShaders.wickFragmentShader);
32
- this.wickProgram = wickProg.program;
33
- this.shaders.push(wickProg.fragmentShader);
34
- this.shaders.push(wickProg.vertexShader);
35
- this.wickVao = this.gl.createVertexArray();
36
- this.wickVerticesBuffer = this.gl.createBuffer();
37
- this.wickCentersBuffer = this.gl.createBuffer();
38
- this.wickHeightsBuffer = this.gl.createBuffer();
39
- this.wickColorsBuffer = this.gl.createBuffer();
20
+
21
+ /* Shared, write-once geometry buffers */
22
+ this.quadBuffer = gl.createBuffer();
23
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.quadBuffer);
24
+ gl.bufferData(gl.ARRAY_BUFFER, QUAD_VERTICES, gl.STATIC_DRAW);
25
+ this.wickGeometryBuffer = gl.createBuffer();
26
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.wickGeometryBuffer);
27
+ gl.bufferData(gl.ARRAY_BUFFER, WICK_VERTICES, gl.STATIC_DRAW);
28
+ this.candle = this.initCandleProgram();
29
+ this.wick = this.initWickProgram();
30
+ }
31
+ initCandleProgram() {
32
+ const gl = this.gl;
33
+ const {
34
+ program,
35
+ fragmentShader,
36
+ vertexShader
37
+ } = initializeProgram(gl, _candleShaders.candleVertexShader, _candleShaders.candleFragmentShader);
38
+ this.shaders.push(fragmentShader, vertexShader);
39
+ const vao = gl.createVertexArray();
40
+ const centers = (0, _utils.createGrowableBuffer)(gl);
41
+ const heights = (0, _utils.createGrowableBuffer)(gl);
42
+ const colors = (0, _utils.createGrowableBuffer)(gl);
43
+ gl.bindVertexArray(vao);
44
+
45
+ /* Quad geometry — shared, instanced over per-candle attributes. */
46
+ bindAttribute(gl, program, 'a_position', this.quadBuffer, 2, 0);
47
+ bindAttribute(gl, program, 'a_center', centers.buffer, 2, 1);
48
+ bindAttribute(gl, program, 'a_height', heights.buffer, 1, 1);
49
+ /* Colors live in a Uint8(Clamped)Array — 1 byte per channel, normalized to [0, 1]
50
+ * in the shader. 4x less GPU traffic than Float32 RGBA. */
51
+ bindAttribute(gl, program, 'a_color', colors.buffer, 4, 1, gl.UNSIGNED_BYTE, true);
52
+ gl.bindVertexArray(null);
53
+ return {
54
+ program,
55
+ vao,
56
+ centers,
57
+ heights,
58
+ colors,
59
+ uResolution: gl.getUniformLocation(program, 'u_resolution'),
60
+ uCandleWidth: gl.getUniformLocation(program, 'u_candle_width')
61
+ };
62
+ }
63
+ initWickProgram() {
64
+ const gl = this.gl;
65
+ const {
66
+ program,
67
+ fragmentShader,
68
+ vertexShader
69
+ } = initializeProgram(gl, _wickShaders.wickVertexShader, _wickShaders.wickFragmentShader);
70
+ this.shaders.push(fragmentShader, vertexShader);
71
+ const vao = gl.createVertexArray();
72
+ const centers = (0, _utils.createGrowableBuffer)(gl);
73
+ const heights = (0, _utils.createGrowableBuffer)(gl);
74
+ const colors = (0, _utils.createGrowableBuffer)(gl);
75
+ gl.bindVertexArray(vao);
76
+ bindAttribute(gl, program, 'a_position', this.wickGeometryBuffer, 2, 0);
77
+ bindAttribute(gl, program, 'a_center', centers.buffer, 2, 1);
78
+ bindAttribute(gl, program, 'a_height', heights.buffer, 1, 1);
79
+ bindAttribute(gl, program, 'a_wick_color', colors.buffer, 4, 1, gl.UNSIGNED_BYTE, true);
80
+ gl.bindVertexArray(null);
81
+ return {
82
+ program,
83
+ vao,
84
+ centers,
85
+ heights,
86
+ colors,
87
+ uResolution: gl.getUniformLocation(program, 'u_resolution'),
88
+ uCandleWidth: gl.getUniformLocation(program, 'u_candle_width')
89
+ };
40
90
  }
41
91
  setResolution(width, height) {
42
- this.gl.useProgram(this.candleProgram);
43
- this.gl.uniform2f(this.gl.getUniformLocation(this.candleProgram, 'u_resolution'), width, height);
44
- this.gl.useProgram(this.wickProgram);
45
- this.gl.uniform2f(this.gl.getUniformLocation(this.wickProgram, 'u_resolution'), width, height);
92
+ this.gl.useProgram(this.candle.program);
93
+ this.gl.uniform2f(this.candle.uResolution, width, height);
94
+ this.gl.useProgram(this.wick.program);
95
+ this.gl.uniform2f(this.wick.uResolution, width, height);
46
96
  }
47
97
  setCandleWidth(candleWidth) {
48
- this.gl.useProgram(this.candleProgram);
49
- this.gl.uniform1f(this.gl.getUniformLocation(this.candleProgram, 'u_candle_width'), candleWidth);
50
- this.gl.useProgram(this.wickProgram);
51
- this.gl.uniform1f(this.gl.getUniformLocation(this.wickProgram, 'u_candle_width'), candleWidth);
98
+ this.gl.useProgram(this.candle.program);
99
+ this.gl.uniform1f(this.candle.uCandleWidth, candleWidth);
100
+ this.gl.useProgram(this.wick.program);
101
+ this.gl.uniform1f(this.wick.uCandleWidth, candleWidth);
52
102
  }
53
103
  plot(plotData) {
104
+ const {
105
+ gl
106
+ } = this;
54
107
  const {
55
108
  candleCenters,
56
109
  candleHeights,
@@ -59,99 +112,58 @@ class CandlestickWebGLProgram {
59
112
  candleColors,
60
113
  wickColors
61
114
  } = plotData;
62
-
63
- // Setup candle attributes
64
-
65
- this.gl.useProgram(this.candleProgram);
66
- this.gl.bindVertexArray(this.candleVao);
67
- (0, _utils.bindQuadBuffer)(this.gl, this.candleProgram, (0, _utils.uploadQuadBuffer)(this.gl));
68
-
69
- // Center attribute
70
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.candleCentersBuffer);
71
- this.gl.bufferData(this.gl.ARRAY_BUFFER, candleCenters, this.gl.STATIC_DRAW);
72
- const candleCenterLocation = this.gl.getAttribLocation(this.candleProgram, 'a_center');
73
- this.gl.enableVertexAttribArray(candleCenterLocation);
74
- this.gl.vertexAttribPointer(candleCenterLocation, 2, this.gl.FLOAT, false, 0, 0);
75
- this.gl.vertexAttribDivisor(candleCenterLocation, 1); // One per instance
76
-
77
- // Height attribute
78
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.candleHeightsBuffer);
79
- this.gl.bufferData(this.gl.ARRAY_BUFFER, candleHeights, this.gl.STATIC_DRAW);
80
- const candleHeightLocation = this.gl.getAttribLocation(this.candleProgram, 'a_height');
81
- this.gl.enableVertexAttribArray(candleHeightLocation);
82
- this.gl.vertexAttribPointer(candleHeightLocation, 1, this.gl.FLOAT, false, 0, 0);
83
- this.gl.vertexAttribDivisor(candleHeightLocation, 1); // One per instance
84
-
85
- // Color attribute
86
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.candleColorsBuffer);
87
- this.gl.bufferData(this.gl.ARRAY_BUFFER, candleColors, this.gl.STATIC_DRAW);
88
- const candleColorLocation = this.gl.getAttribLocation(this.candleProgram, 'a_color');
89
- this.gl.enableVertexAttribArray(candleColorLocation);
90
- this.gl.vertexAttribPointer(candleColorLocation, 4, this.gl.FLOAT, false, 0, 0);
91
- this.gl.vertexAttribDivisor(candleColorLocation, 1); // One per instance
92
-
93
- this.gl.bindVertexArray(null);
94
-
95
- // Setup wick attributes
96
- this.gl.useProgram(this.wickProgram);
97
- this.gl.bindVertexArray(this.wickVao);
98
- const wickVertices = new Float32Array([0, -1, 0, 1]);
99
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.wickVerticesBuffer);
100
- this.gl.bufferData(this.gl.ARRAY_BUFFER, wickVertices, this.gl.STATIC_DRAW);
101
- const aPosition = this.gl.getAttribLocation(this.wickProgram, 'a_position');
102
- this.gl.enableVertexAttribArray(aPosition);
103
- this.gl.vertexAttribPointer(aPosition, 2, this.gl.FLOAT, false, 0, 0);
104
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.wickCentersBuffer);
105
- this.gl.bufferData(this.gl.ARRAY_BUFFER, wickCenters, this.gl.STATIC_DRAW);
106
- const wickCenterLocation = this.gl.getAttribLocation(this.wickProgram, 'a_center');
107
- this.gl.enableVertexAttribArray(wickCenterLocation);
108
- this.gl.vertexAttribPointer(wickCenterLocation, 2, this.gl.FLOAT, false, 0, 0);
109
- this.gl.vertexAttribDivisor(wickCenterLocation, 1); // One per instance
110
-
111
- // Height attribute
112
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.wickHeightsBuffer);
113
- this.gl.bufferData(this.gl.ARRAY_BUFFER, wickHeights, this.gl.STATIC_DRAW);
114
- const wickHeightLocation = this.gl.getAttribLocation(this.wickProgram, 'a_height');
115
- this.gl.enableVertexAttribArray(wickHeightLocation);
116
- this.gl.vertexAttribPointer(wickHeightLocation, 1, this.gl.FLOAT, false, 0, 0);
117
- this.gl.vertexAttribDivisor(wickHeightLocation, 1); // One per instance
118
-
119
- // Color attribute
120
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.wickColorsBuffer);
121
- this.gl.bufferData(this.gl.ARRAY_BUFFER, wickColors, this.gl.STATIC_DRAW);
122
- const wickColorLocation = this.gl.getAttribLocation(this.wickProgram, 'a_wick_color');
123
- this.gl.enableVertexAttribArray(wickColorLocation);
124
- this.gl.vertexAttribPointer(wickColorLocation, 4, this.gl.FLOAT, false, 0, 0);
125
- this.gl.vertexAttribDivisor(wickColorLocation, 1); // One per instance
126
-
127
- this.gl.bindVertexArray(null);
115
+ (0, _utils.uploadGrowableBuffer)(gl, this.candle.centers, candleCenters);
116
+ (0, _utils.uploadGrowableBuffer)(gl, this.candle.heights, candleHeights);
117
+ (0, _utils.uploadGrowableBuffer)(gl, this.candle.colors, candleColors);
118
+ (0, _utils.uploadGrowableBuffer)(gl, this.wick.centers, wickCenters);
119
+ (0, _utils.uploadGrowableBuffer)(gl, this.wick.heights, wickHeights);
120
+ (0, _utils.uploadGrowableBuffer)(gl, this.wick.colors, wickColors);
128
121
  }
129
122
  render(dataLength) {
130
- this.gl.useProgram(this.wickProgram);
131
- (0, _utils.logWebGLErrors)(this.gl);
132
- this.gl.bindVertexArray(this.wickVao);
133
- this.gl.drawArraysInstanced(this.gl.LINES, 0, 2, dataLength * 2);
134
- this.gl.useProgram(this.candleProgram);
135
- (0, _utils.logWebGLErrors)(this.gl);
136
- this.gl.bindVertexArray(this.candleVao);
137
- this.gl.drawArraysInstanced(this.gl.TRIANGLE_STRIP, 0, 4, dataLength);
123
+ if (dataLength === 0) {
124
+ return;
125
+ }
126
+ const {
127
+ gl
128
+ } = this;
129
+ gl.useProgram(this.wick.program);
130
+ gl.bindVertexArray(this.wick.vao);
131
+ gl.drawArraysInstanced(gl.LINES, 0, 2, dataLength * 2);
132
+ (0, _utils.logWebGLErrors)(gl);
133
+ gl.useProgram(this.candle.program);
134
+ gl.bindVertexArray(this.candle.vao);
135
+ gl.drawArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, dataLength);
136
+ (0, _utils.logWebGLErrors)(gl);
138
137
  }
139
138
  dispose() {
140
- this.gl.deleteProgram(this.candleProgram);
141
- this.gl.deleteVertexArray(this.candleVao);
142
- this.gl.deleteBuffer(this.candleCentersBuffer);
143
- this.gl.deleteBuffer(this.candleHeightsBuffer);
144
- this.gl.deleteBuffer(this.candleColorsBuffer);
145
- this.gl.deleteProgram(this.wickProgram);
146
- this.gl.deleteVertexArray(this.wickVao);
147
- this.gl.deleteBuffer(this.wickVerticesBuffer);
148
- this.gl.deleteBuffer(this.wickCentersBuffer);
149
- this.gl.deleteBuffer(this.wickHeightsBuffer);
150
- this.gl.deleteBuffer(this.wickColorsBuffer);
151
- this.shaders.forEach(shader => this.gl.deleteShader(shader));
139
+ const {
140
+ gl
141
+ } = this;
142
+ gl.deleteBuffer(this.quadBuffer);
143
+ gl.deleteBuffer(this.wickGeometryBuffer);
144
+ gl.deleteProgram(this.candle.program);
145
+ gl.deleteVertexArray(this.candle.vao);
146
+ gl.deleteBuffer(this.candle.centers.buffer);
147
+ gl.deleteBuffer(this.candle.heights.buffer);
148
+ gl.deleteBuffer(this.candle.colors.buffer);
149
+ gl.deleteProgram(this.wick.program);
150
+ gl.deleteVertexArray(this.wick.vao);
151
+ gl.deleteBuffer(this.wick.centers.buffer);
152
+ gl.deleteBuffer(this.wick.heights.buffer);
153
+ gl.deleteBuffer(this.wick.colors.buffer);
154
+ this.shaders.forEach(shader => gl.deleteShader(shader));
152
155
  }
153
156
  }
154
157
  exports.CandlestickWebGLProgram = CandlestickWebGLProgram;
158
+ function bindAttribute(gl, program, name, buffer, size, divisor, type = gl.FLOAT, normalized = false) {
159
+ const location = gl.getAttribLocation(program, name);
160
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
161
+ gl.enableVertexAttribArray(location);
162
+ gl.vertexAttribPointer(location, size, type, normalized, 0, 0);
163
+ if (divisor !== 0) {
164
+ gl.vertexAttribDivisor(location, divisor);
165
+ }
166
+ }
155
167
  function initializeProgram(gl, vertexShaderSource, fragmentShaderSource) {
156
168
  const program = gl.createProgram();
157
169
  const vertexShader = (0, _utils.compileShader)(gl, vertexShaderSource, gl.VERTEX_SHADER);
@@ -160,11 +172,14 @@ function initializeProgram(gl, vertexShaderSource, fragmentShaderSource) {
160
172
  gl.attachShader(program, fragmentShader);
161
173
  gl.linkProgram(program);
162
174
 
163
- // https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#dont_check_shader_compile_status_unless_linking_fails
164
- if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
165
- console.error(`Program linking failed: ${gl.getProgramInfoLog(program)}`);
166
- console.error(`Vertex shader info-log: ${gl.getShaderInfoLog(vertexShader)}`);
167
- console.error(`Fragment shader info-log: ${gl.getShaderInfoLog(fragmentShader)}`);
175
+ /* Only inspect link status when linking actually failed; the parameter call stalls the pipeline.
176
+ * https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#dont_check_shader_compile_status_unless_linking_fails */
177
+ if (process.env.NODE_ENV !== 'production') {
178
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
179
+ console.error(`Program linking failed: ${gl.getProgramInfoLog(program)}`);
180
+ console.error(`Vertex shader info-log: ${gl.getShaderInfoLog(vertexShader)}`);
181
+ console.error(`Fragment shader info-log: ${gl.getShaderInfoLog(fragmentShader)}`);
182
+ }
168
183
  }
169
184
  return {
170
185
  program,
@@ -1,50 +1,103 @@
1
- import { bindQuadBuffer, compileShader, logWebGLErrors, uploadQuadBuffer } from "../utils/webgl/utils.mjs";
1
+ import { compileShader, createGrowableBuffer, logWebGLErrors, uploadGrowableBuffer } from "../utils/webgl/utils.mjs";
2
2
  import { candleFragmentShader, candleVertexShader } from "./candleShaders.mjs";
3
3
  import { wickFragmentShader, wickVertexShader } from "./wickShaders.mjs";
4
+ const QUAD_VERTICES = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
5
+ const WICK_VERTICES = new Float32Array([0, -1, 0, 1]);
4
6
  export class CandlestickWebGLProgram {
5
7
  shaders = [];
6
-
7
- // Candle program and buffers. If you add more WebGL resources, remember to dispose of them in the dispose() method.
8
-
9
- // Wick program and buffers. If you add more WebGL resources, remember to dispose of them in the dispose() method.
10
-
11
8
  constructor(gl) {
12
9
  this.gl = gl;
13
10
  /* Enable blending for transparency
14
11
  * These are global to the WebGL context and need to be set only once */
15
12
  gl.enable(gl.BLEND);
16
13
  gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
17
- const candleProg = initializeProgram(this.gl, candleVertexShader, candleFragmentShader);
18
- this.candleProgram = candleProg.program;
19
- this.shaders.push(candleProg.fragmentShader);
20
- this.shaders.push(candleProg.vertexShader);
21
- this.candleVao = this.gl.createVertexArray();
22
- this.candleCentersBuffer = this.gl.createBuffer();
23
- this.candleHeightsBuffer = this.gl.createBuffer();
24
- this.candleColorsBuffer = this.gl.createBuffer();
25
- const wickProg = initializeProgram(this.gl, wickVertexShader, wickFragmentShader);
26
- this.wickProgram = wickProg.program;
27
- this.shaders.push(wickProg.fragmentShader);
28
- this.shaders.push(wickProg.vertexShader);
29
- this.wickVao = this.gl.createVertexArray();
30
- this.wickVerticesBuffer = this.gl.createBuffer();
31
- this.wickCentersBuffer = this.gl.createBuffer();
32
- this.wickHeightsBuffer = this.gl.createBuffer();
33
- this.wickColorsBuffer = this.gl.createBuffer();
14
+
15
+ /* Shared, write-once geometry buffers */
16
+ this.quadBuffer = gl.createBuffer();
17
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.quadBuffer);
18
+ gl.bufferData(gl.ARRAY_BUFFER, QUAD_VERTICES, gl.STATIC_DRAW);
19
+ this.wickGeometryBuffer = gl.createBuffer();
20
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.wickGeometryBuffer);
21
+ gl.bufferData(gl.ARRAY_BUFFER, WICK_VERTICES, gl.STATIC_DRAW);
22
+ this.candle = this.initCandleProgram();
23
+ this.wick = this.initWickProgram();
24
+ }
25
+ initCandleProgram() {
26
+ const gl = this.gl;
27
+ const {
28
+ program,
29
+ fragmentShader,
30
+ vertexShader
31
+ } = initializeProgram(gl, candleVertexShader, candleFragmentShader);
32
+ this.shaders.push(fragmentShader, vertexShader);
33
+ const vao = gl.createVertexArray();
34
+ const centers = createGrowableBuffer(gl);
35
+ const heights = createGrowableBuffer(gl);
36
+ const colors = createGrowableBuffer(gl);
37
+ gl.bindVertexArray(vao);
38
+
39
+ /* Quad geometry — shared, instanced over per-candle attributes. */
40
+ bindAttribute(gl, program, 'a_position', this.quadBuffer, 2, 0);
41
+ bindAttribute(gl, program, 'a_center', centers.buffer, 2, 1);
42
+ bindAttribute(gl, program, 'a_height', heights.buffer, 1, 1);
43
+ /* Colors live in a Uint8(Clamped)Array — 1 byte per channel, normalized to [0, 1]
44
+ * in the shader. 4x less GPU traffic than Float32 RGBA. */
45
+ bindAttribute(gl, program, 'a_color', colors.buffer, 4, 1, gl.UNSIGNED_BYTE, true);
46
+ gl.bindVertexArray(null);
47
+ return {
48
+ program,
49
+ vao,
50
+ centers,
51
+ heights,
52
+ colors,
53
+ uResolution: gl.getUniformLocation(program, 'u_resolution'),
54
+ uCandleWidth: gl.getUniformLocation(program, 'u_candle_width')
55
+ };
56
+ }
57
+ initWickProgram() {
58
+ const gl = this.gl;
59
+ const {
60
+ program,
61
+ fragmentShader,
62
+ vertexShader
63
+ } = initializeProgram(gl, wickVertexShader, wickFragmentShader);
64
+ this.shaders.push(fragmentShader, vertexShader);
65
+ const vao = gl.createVertexArray();
66
+ const centers = createGrowableBuffer(gl);
67
+ const heights = createGrowableBuffer(gl);
68
+ const colors = createGrowableBuffer(gl);
69
+ gl.bindVertexArray(vao);
70
+ bindAttribute(gl, program, 'a_position', this.wickGeometryBuffer, 2, 0);
71
+ bindAttribute(gl, program, 'a_center', centers.buffer, 2, 1);
72
+ bindAttribute(gl, program, 'a_height', heights.buffer, 1, 1);
73
+ bindAttribute(gl, program, 'a_wick_color', colors.buffer, 4, 1, gl.UNSIGNED_BYTE, true);
74
+ gl.bindVertexArray(null);
75
+ return {
76
+ program,
77
+ vao,
78
+ centers,
79
+ heights,
80
+ colors,
81
+ uResolution: gl.getUniformLocation(program, 'u_resolution'),
82
+ uCandleWidth: gl.getUniformLocation(program, 'u_candle_width')
83
+ };
34
84
  }
35
85
  setResolution(width, height) {
36
- this.gl.useProgram(this.candleProgram);
37
- this.gl.uniform2f(this.gl.getUniformLocation(this.candleProgram, 'u_resolution'), width, height);
38
- this.gl.useProgram(this.wickProgram);
39
- this.gl.uniform2f(this.gl.getUniformLocation(this.wickProgram, 'u_resolution'), width, height);
86
+ this.gl.useProgram(this.candle.program);
87
+ this.gl.uniform2f(this.candle.uResolution, width, height);
88
+ this.gl.useProgram(this.wick.program);
89
+ this.gl.uniform2f(this.wick.uResolution, width, height);
40
90
  }
41
91
  setCandleWidth(candleWidth) {
42
- this.gl.useProgram(this.candleProgram);
43
- this.gl.uniform1f(this.gl.getUniformLocation(this.candleProgram, 'u_candle_width'), candleWidth);
44
- this.gl.useProgram(this.wickProgram);
45
- this.gl.uniform1f(this.gl.getUniformLocation(this.wickProgram, 'u_candle_width'), candleWidth);
92
+ this.gl.useProgram(this.candle.program);
93
+ this.gl.uniform1f(this.candle.uCandleWidth, candleWidth);
94
+ this.gl.useProgram(this.wick.program);
95
+ this.gl.uniform1f(this.wick.uCandleWidth, candleWidth);
46
96
  }
47
97
  plot(plotData) {
98
+ const {
99
+ gl
100
+ } = this;
48
101
  const {
49
102
  candleCenters,
50
103
  candleHeights,
@@ -53,96 +106,55 @@ export class CandlestickWebGLProgram {
53
106
  candleColors,
54
107
  wickColors
55
108
  } = plotData;
56
-
57
- // Setup candle attributes
58
-
59
- this.gl.useProgram(this.candleProgram);
60
- this.gl.bindVertexArray(this.candleVao);
61
- bindQuadBuffer(this.gl, this.candleProgram, uploadQuadBuffer(this.gl));
62
-
63
- // Center attribute
64
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.candleCentersBuffer);
65
- this.gl.bufferData(this.gl.ARRAY_BUFFER, candleCenters, this.gl.STATIC_DRAW);
66
- const candleCenterLocation = this.gl.getAttribLocation(this.candleProgram, 'a_center');
67
- this.gl.enableVertexAttribArray(candleCenterLocation);
68
- this.gl.vertexAttribPointer(candleCenterLocation, 2, this.gl.FLOAT, false, 0, 0);
69
- this.gl.vertexAttribDivisor(candleCenterLocation, 1); // One per instance
70
-
71
- // Height attribute
72
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.candleHeightsBuffer);
73
- this.gl.bufferData(this.gl.ARRAY_BUFFER, candleHeights, this.gl.STATIC_DRAW);
74
- const candleHeightLocation = this.gl.getAttribLocation(this.candleProgram, 'a_height');
75
- this.gl.enableVertexAttribArray(candleHeightLocation);
76
- this.gl.vertexAttribPointer(candleHeightLocation, 1, this.gl.FLOAT, false, 0, 0);
77
- this.gl.vertexAttribDivisor(candleHeightLocation, 1); // One per instance
78
-
79
- // Color attribute
80
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.candleColorsBuffer);
81
- this.gl.bufferData(this.gl.ARRAY_BUFFER, candleColors, this.gl.STATIC_DRAW);
82
- const candleColorLocation = this.gl.getAttribLocation(this.candleProgram, 'a_color');
83
- this.gl.enableVertexAttribArray(candleColorLocation);
84
- this.gl.vertexAttribPointer(candleColorLocation, 4, this.gl.FLOAT, false, 0, 0);
85
- this.gl.vertexAttribDivisor(candleColorLocation, 1); // One per instance
86
-
87
- this.gl.bindVertexArray(null);
88
-
89
- // Setup wick attributes
90
- this.gl.useProgram(this.wickProgram);
91
- this.gl.bindVertexArray(this.wickVao);
92
- const wickVertices = new Float32Array([0, -1, 0, 1]);
93
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.wickVerticesBuffer);
94
- this.gl.bufferData(this.gl.ARRAY_BUFFER, wickVertices, this.gl.STATIC_DRAW);
95
- const aPosition = this.gl.getAttribLocation(this.wickProgram, 'a_position');
96
- this.gl.enableVertexAttribArray(aPosition);
97
- this.gl.vertexAttribPointer(aPosition, 2, this.gl.FLOAT, false, 0, 0);
98
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.wickCentersBuffer);
99
- this.gl.bufferData(this.gl.ARRAY_BUFFER, wickCenters, this.gl.STATIC_DRAW);
100
- const wickCenterLocation = this.gl.getAttribLocation(this.wickProgram, 'a_center');
101
- this.gl.enableVertexAttribArray(wickCenterLocation);
102
- this.gl.vertexAttribPointer(wickCenterLocation, 2, this.gl.FLOAT, false, 0, 0);
103
- this.gl.vertexAttribDivisor(wickCenterLocation, 1); // One per instance
104
-
105
- // Height attribute
106
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.wickHeightsBuffer);
107
- this.gl.bufferData(this.gl.ARRAY_BUFFER, wickHeights, this.gl.STATIC_DRAW);
108
- const wickHeightLocation = this.gl.getAttribLocation(this.wickProgram, 'a_height');
109
- this.gl.enableVertexAttribArray(wickHeightLocation);
110
- this.gl.vertexAttribPointer(wickHeightLocation, 1, this.gl.FLOAT, false, 0, 0);
111
- this.gl.vertexAttribDivisor(wickHeightLocation, 1); // One per instance
112
-
113
- // Color attribute
114
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.wickColorsBuffer);
115
- this.gl.bufferData(this.gl.ARRAY_BUFFER, wickColors, this.gl.STATIC_DRAW);
116
- const wickColorLocation = this.gl.getAttribLocation(this.wickProgram, 'a_wick_color');
117
- this.gl.enableVertexAttribArray(wickColorLocation);
118
- this.gl.vertexAttribPointer(wickColorLocation, 4, this.gl.FLOAT, false, 0, 0);
119
- this.gl.vertexAttribDivisor(wickColorLocation, 1); // One per instance
120
-
121
- this.gl.bindVertexArray(null);
109
+ uploadGrowableBuffer(gl, this.candle.centers, candleCenters);
110
+ uploadGrowableBuffer(gl, this.candle.heights, candleHeights);
111
+ uploadGrowableBuffer(gl, this.candle.colors, candleColors);
112
+ uploadGrowableBuffer(gl, this.wick.centers, wickCenters);
113
+ uploadGrowableBuffer(gl, this.wick.heights, wickHeights);
114
+ uploadGrowableBuffer(gl, this.wick.colors, wickColors);
122
115
  }
123
116
  render(dataLength) {
124
- this.gl.useProgram(this.wickProgram);
125
- logWebGLErrors(this.gl);
126
- this.gl.bindVertexArray(this.wickVao);
127
- this.gl.drawArraysInstanced(this.gl.LINES, 0, 2, dataLength * 2);
128
- this.gl.useProgram(this.candleProgram);
129
- logWebGLErrors(this.gl);
130
- this.gl.bindVertexArray(this.candleVao);
131
- this.gl.drawArraysInstanced(this.gl.TRIANGLE_STRIP, 0, 4, dataLength);
117
+ if (dataLength === 0) {
118
+ return;
119
+ }
120
+ const {
121
+ gl
122
+ } = this;
123
+ gl.useProgram(this.wick.program);
124
+ gl.bindVertexArray(this.wick.vao);
125
+ gl.drawArraysInstanced(gl.LINES, 0, 2, dataLength * 2);
126
+ logWebGLErrors(gl);
127
+ gl.useProgram(this.candle.program);
128
+ gl.bindVertexArray(this.candle.vao);
129
+ gl.drawArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, dataLength);
130
+ logWebGLErrors(gl);
132
131
  }
133
132
  dispose() {
134
- this.gl.deleteProgram(this.candleProgram);
135
- this.gl.deleteVertexArray(this.candleVao);
136
- this.gl.deleteBuffer(this.candleCentersBuffer);
137
- this.gl.deleteBuffer(this.candleHeightsBuffer);
138
- this.gl.deleteBuffer(this.candleColorsBuffer);
139
- this.gl.deleteProgram(this.wickProgram);
140
- this.gl.deleteVertexArray(this.wickVao);
141
- this.gl.deleteBuffer(this.wickVerticesBuffer);
142
- this.gl.deleteBuffer(this.wickCentersBuffer);
143
- this.gl.deleteBuffer(this.wickHeightsBuffer);
144
- this.gl.deleteBuffer(this.wickColorsBuffer);
145
- this.shaders.forEach(shader => this.gl.deleteShader(shader));
133
+ const {
134
+ gl
135
+ } = this;
136
+ gl.deleteBuffer(this.quadBuffer);
137
+ gl.deleteBuffer(this.wickGeometryBuffer);
138
+ gl.deleteProgram(this.candle.program);
139
+ gl.deleteVertexArray(this.candle.vao);
140
+ gl.deleteBuffer(this.candle.centers.buffer);
141
+ gl.deleteBuffer(this.candle.heights.buffer);
142
+ gl.deleteBuffer(this.candle.colors.buffer);
143
+ gl.deleteProgram(this.wick.program);
144
+ gl.deleteVertexArray(this.wick.vao);
145
+ gl.deleteBuffer(this.wick.centers.buffer);
146
+ gl.deleteBuffer(this.wick.heights.buffer);
147
+ gl.deleteBuffer(this.wick.colors.buffer);
148
+ this.shaders.forEach(shader => gl.deleteShader(shader));
149
+ }
150
+ }
151
+ function bindAttribute(gl, program, name, buffer, size, divisor, type = gl.FLOAT, normalized = false) {
152
+ const location = gl.getAttribLocation(program, name);
153
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
154
+ gl.enableVertexAttribArray(location);
155
+ gl.vertexAttribPointer(location, size, type, normalized, 0, 0);
156
+ if (divisor !== 0) {
157
+ gl.vertexAttribDivisor(location, divisor);
146
158
  }
147
159
  }
148
160
  function initializeProgram(gl, vertexShaderSource, fragmentShaderSource) {
@@ -153,11 +165,14 @@ function initializeProgram(gl, vertexShaderSource, fragmentShaderSource) {
153
165
  gl.attachShader(program, fragmentShader);
154
166
  gl.linkProgram(program);
155
167
 
156
- // https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#dont_check_shader_compile_status_unless_linking_fails
157
- if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
158
- console.error(`Program linking failed: ${gl.getProgramInfoLog(program)}`);
159
- console.error(`Vertex shader info-log: ${gl.getShaderInfoLog(vertexShader)}`);
160
- console.error(`Fragment shader info-log: ${gl.getShaderInfoLog(fragmentShader)}`);
168
+ /* Only inspect link status when linking actually failed; the parameter call stalls the pipeline.
169
+ * https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#dont_check_shader_compile_status_unless_linking_fails */
170
+ if (process.env.NODE_ENV !== 'production') {
171
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
172
+ console.error(`Program linking failed: ${gl.getProgramInfoLog(program)}`);
173
+ console.error(`Vertex shader info-log: ${gl.getShaderInfoLog(vertexShader)}`);
174
+ console.error(`Fragment shader info-log: ${gl.getShaderInfoLog(fragmentShader)}`);
175
+ }
161
176
  }
162
177
  return {
163
178
  program,