fragment-tools 0.1.13 → 0.1.15

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 (184) hide show
  1. package/.prettierignore +1 -2
  2. package/.prettierrc +23 -7
  3. package/README.md +28 -9
  4. package/bin/index.js +70 -10
  5. package/package.json +14 -6
  6. package/src/cli/build.js +125 -0
  7. package/src/cli/create.js +238 -0
  8. package/src/cli/createConfig.js +82 -0
  9. package/src/cli/createFragmentFile.js +70 -0
  10. package/src/cli/getEntries.js +85 -0
  11. package/src/cli/log.js +36 -24
  12. package/src/cli/plugins/check-dependencies.js +88 -42
  13. package/src/cli/plugins/hot-shader-replacement.js +408 -0
  14. package/src/cli/plugins/hot-sketch-reload.js +21 -25
  15. package/src/cli/plugins/save.js +101 -0
  16. package/src/cli/preview.js +55 -0
  17. package/src/cli/prompts.js +260 -0
  18. package/src/cli/run.js +131 -0
  19. package/src/cli/templates/blank/index.js +33 -0
  20. package/src/cli/templates/blank/meta.json +4 -0
  21. package/src/cli/templates/default/index.js +39 -0
  22. package/src/cli/templates/default/meta.json +5 -0
  23. package/src/cli/templates/fragment-gl/index.js +37 -0
  24. package/src/cli/templates/fragment-gl/meta.json +4 -0
  25. package/src/cli/templates/p5/index.js +32 -0
  26. package/src/cli/templates/p5/meta.json +5 -0
  27. package/src/cli/templates/p5-webgl/fragment.fs +14 -0
  28. package/src/cli/templates/p5-webgl/index.js +67 -0
  29. package/src/cli/templates/p5-webgl/meta.json +5 -0
  30. package/src/cli/templates/three-fragment/fragment.fs +10 -0
  31. package/src/cli/templates/three-fragment/index.js +95 -0
  32. package/src/cli/templates/three-fragment/meta.json +5 -0
  33. package/src/cli/templates/three-orthographic/index.js +55 -0
  34. package/src/cli/templates/three-orthographic/meta.json +5 -0
  35. package/src/cli/templates/three-perspective/index.js +52 -0
  36. package/src/cli/templates/three-perspective/meta.json +5 -0
  37. package/src/cli/utils.js +70 -0
  38. package/src/cli/ws.js +87 -78
  39. package/src/client/app/App.svelte +3 -3
  40. package/src/client/app/client.js +55 -39
  41. package/src/client/app/components/IconCross.svelte +18 -18
  42. package/src/client/app/components/Init.svelte +40 -8
  43. package/src/client/app/components/KeyBinding.svelte +22 -22
  44. package/src/client/app/helpers.js +42 -0
  45. package/src/client/app/hooks.js +20 -0
  46. package/src/client/app/inputs/Input.js +9 -9
  47. package/src/client/app/inputs/Keyboard.js +13 -15
  48. package/src/client/app/inputs/MIDI.js +14 -15
  49. package/src/client/app/inputs/Mouse.js +1 -1
  50. package/src/client/app/inputs/Webcam.js +89 -88
  51. package/src/client/app/lib/canvas-recorder/CanvasRecorder.js +41 -21
  52. package/src/client/app/lib/canvas-recorder/FrameRecorder.js +7 -6
  53. package/src/client/app/lib/canvas-recorder/H264Recorder.js +45 -0
  54. package/src/client/app/lib/canvas-recorder/MP4Recorder.js +7 -9
  55. package/src/client/app/lib/canvas-recorder/WebMRecorder.js +3 -4
  56. package/src/client/app/lib/canvas-recorder/mp4.js +1649 -15
  57. package/src/client/app/lib/canvas-recorder/utils.js +33 -17
  58. package/src/client/app/lib/gl/Geometry.js +11 -8
  59. package/src/client/app/lib/gl/Program.js +38 -19
  60. package/src/client/app/lib/gl/Renderer.js +163 -156
  61. package/src/client/app/lib/gl/Texture.js +113 -85
  62. package/src/client/app/lib/gl/index.js +12 -12
  63. package/src/client/app/lib/gl/utils.js +1 -3
  64. package/src/client/app/lib/helpers/frameDebounce.js +30 -30
  65. package/src/client/app/lib/loader/index.js +10 -10
  66. package/src/client/app/lib/loader/loadImage.js +15 -15
  67. package/src/client/app/lib/loader/loadScript.js +1 -1
  68. package/src/client/app/lib/paper-sizes.js +75 -76
  69. package/src/client/app/lib/presets.js +25 -5
  70. package/src/client/app/lib/tempo/Analyser.js +18 -17
  71. package/src/client/app/lib/tempo/Range.js +15 -12
  72. package/src/client/app/lib/tempo/index.js +34 -27
  73. package/src/client/app/modules/AudioAnalyser/Range.svelte +69 -72
  74. package/src/client/app/modules/AudioAnalyser/Spectrum.svelte +20 -19
  75. package/src/client/app/modules/AudioAnalyser.svelte +52 -35
  76. package/src/client/app/modules/Console/ConsoleLine.svelte +193 -172
  77. package/src/client/app/modules/Console.svelte +76 -74
  78. package/src/client/app/modules/Exports.svelte +62 -43
  79. package/src/client/app/modules/MidiPanel.svelte +100 -101
  80. package/src/client/app/modules/Monitor.svelte +57 -57
  81. package/src/client/app/modules/Params.svelte +128 -103
  82. package/src/client/app/renderers/2DRenderer.js +3 -3
  83. package/src/client/app/renderers/FragmentRenderer.js +30 -23
  84. package/src/client/app/renderers/P5GLRenderer.js +144 -0
  85. package/src/client/app/renderers/P5Renderer.js +10 -7
  86. package/src/client/app/renderers/THREERenderer.js +136 -94
  87. package/src/client/app/stores/audioAnalysis.js +3 -4
  88. package/src/client/app/stores/console.js +9 -10
  89. package/src/client/app/stores/errors.js +1 -1
  90. package/src/client/app/stores/exports.js +36 -20
  91. package/src/client/app/stores/index.js +2 -2
  92. package/src/client/app/stores/layout.js +143 -138
  93. package/src/client/app/stores/multisampling.js +4 -4
  94. package/src/client/app/stores/props.js +76 -13
  95. package/src/client/app/stores/renderers.js +26 -15
  96. package/src/client/app/stores/rendering.js +108 -89
  97. package/src/client/app/stores/sketches.js +7 -9
  98. package/src/client/app/stores/time.js +18 -18
  99. package/src/client/app/stores/utils.js +95 -38
  100. package/src/client/app/transitions/fade.js +3 -3
  101. package/src/client/app/transitions/index.js +6 -7
  102. package/src/client/app/transitions/splitX.js +2 -2
  103. package/src/client/app/transitions/splitY.js +2 -2
  104. package/src/client/app/triggers/Keyboard.js +88 -79
  105. package/src/client/app/triggers/MIDI.js +110 -84
  106. package/src/client/app/triggers/Mouse.js +73 -65
  107. package/src/client/app/triggers/Trigger.js +59 -58
  108. package/src/client/app/triggers/index.js +7 -7
  109. package/src/client/app/triggers/shared.js +5 -5
  110. package/src/client/app/ui/Build.svelte +70 -71
  111. package/src/client/app/ui/ErrorOverlay.svelte +118 -104
  112. package/src/client/app/ui/Field.svelte +393 -258
  113. package/src/client/app/ui/FieldGroup.svelte +106 -94
  114. package/src/client/app/ui/FieldSection.svelte +127 -116
  115. package/src/client/app/ui/FieldSpace.svelte +29 -30
  116. package/src/client/app/ui/FieldTrigger.svelte +256 -244
  117. package/src/client/app/ui/FieldTriggers.svelte +46 -46
  118. package/src/client/app/ui/FloatingParams.svelte +29 -30
  119. package/src/client/app/ui/Layout.svelte +31 -32
  120. package/src/client/app/ui/LayoutColumn.svelte +4 -4
  121. package/src/client/app/ui/LayoutComponent.svelte +239 -225
  122. package/src/client/app/ui/LayoutResizer.svelte +195 -176
  123. package/src/client/app/ui/LayoutRoot.svelte +6 -6
  124. package/src/client/app/ui/LayoutRow.svelte +4 -4
  125. package/src/client/app/ui/LayoutToolbar.svelte +191 -194
  126. package/src/client/app/ui/Module.svelte +134 -135
  127. package/src/client/app/ui/ModuleHeaderAction.svelte +81 -78
  128. package/src/client/app/ui/ModuleHeaderButton.svelte +12 -12
  129. package/src/client/app/ui/ModuleHeaderSelect.svelte +47 -37
  130. package/src/client/app/ui/ModuleRenderer.svelte +26 -27
  131. package/src/client/app/ui/OutputRenderer.svelte +112 -105
  132. package/src/client/app/ui/ParamsMultisampling.svelte +96 -95
  133. package/src/client/app/ui/ParamsOutput.svelte +130 -113
  134. package/src/client/app/ui/Preview.svelte +7 -8
  135. package/src/client/app/ui/SelectChevrons.svelte +27 -15
  136. package/src/client/app/ui/SketchRenderer.svelte +780 -667
  137. package/src/client/app/ui/SketchSelect.svelte +50 -44
  138. package/src/client/app/ui/fields/ButtonInput.svelte +61 -48
  139. package/src/client/app/ui/fields/CheckboxInput.svelte +67 -61
  140. package/src/client/app/ui/fields/ColorInput.svelte +294 -238
  141. package/src/client/app/ui/fields/FieldInputRow.svelte +8 -8
  142. package/src/client/app/ui/fields/ImageInput.svelte +123 -121
  143. package/src/client/app/ui/fields/Input.svelte +100 -111
  144. package/src/client/app/ui/fields/IntervalInput.svelte +268 -0
  145. package/src/client/app/ui/fields/ListInput.svelte +96 -96
  146. package/src/client/app/ui/fields/NumberInput.svelte +120 -116
  147. package/src/client/app/ui/fields/ProgressInput.svelte +99 -73
  148. package/src/client/app/ui/fields/Select.svelte +137 -124
  149. package/src/client/app/ui/fields/TextInput.svelte +10 -11
  150. package/src/client/app/ui/fields/VectorInput.svelte +86 -82
  151. package/src/client/app/utils/canvas.utils.js +189 -208
  152. package/src/client/app/utils/color.utils.js +138 -101
  153. package/src/client/app/utils/fields.utils.js +131 -0
  154. package/src/client/app/utils/file.utils.js +209 -37
  155. package/src/client/app/utils/glsl.utils.js +2 -2
  156. package/src/client/app/utils/glslErrors.js +49 -31
  157. package/src/client/app/utils/index.js +32 -29
  158. package/src/client/app/utils/math.utils.js +14 -10
  159. package/src/client/index.html +16 -16
  160. package/src/client/main.js +4 -4
  161. package/src/client/public/css/global.css +26 -16
  162. package/src/cli/db.js +0 -17
  163. package/src/cli/index.js +0 -198
  164. package/src/cli/plugins/db.js +0 -12
  165. package/src/cli/plugins/hot-shader-reload.js +0 -86
  166. package/src/cli/plugins/screenshot.js +0 -46
  167. package/src/cli/server.js +0 -153
  168. package/src/cli/templates/2d.js +0 -15
  169. package/src/cli/templates/blank.js +0 -13
  170. package/src/cli/templates/fragment.js +0 -18
  171. package/src/cli/templates/index.js +0 -27
  172. package/src/cli/templates/p5.js +0 -13
  173. package/src/cli/templates/three-fragment.js +0 -53
  174. package/src/cli/templates/three-orthographic.js +0 -23
  175. package/src/cli/templates/three-perspective.js +0 -20
  176. package/src/client/app/lib/canvas-recorder/FFMPEGRecorder.js +0 -56
  177. package/src/client/app/utils/props.utils.js +0 -51
  178. package/src/client/public/fonts/Inter-Bold.woff2 +0 -0
  179. package/src/client/public/fonts/Inter-Italic.woff2 +0 -0
  180. package/src/client/public/fonts/Inter-Regular.woff2 +0 -0
  181. package/src/client/public/fonts/Inter-SemiBold.woff2 +0 -0
  182. package/src/client/public/js/ffmpeg.min.js +0 -2
  183. package/src/client/public/js/ffmpeg.min.js.map +0 -1
  184. /package/src/cli/templates/{fragment.fs → fragment-gl/fragment.fs} +0 -0
@@ -1,22 +1,38 @@
1
- const supportedEncodings = [
2
- 'image/png',
3
- 'image/jpeg',
4
- 'image/webp'
5
- ];
1
+ import { changeDpiDataUrl } from 'changedpi';
6
2
 
7
- export function exportCanvas (canvas, { encoding = 'image/png', encodingQuality = 0.92 } = {}) {
8
- if (!supportedEncodings.includes(encoding)) throw new Error(`Invalid canvas encoding ${encoding}`);
3
+ const supportedEncodings = ['image/png', 'image/jpeg', 'image/webp'];
9
4
 
10
- let extension = (encoding.split('/')[1] || '').replace(/jpeg/i, 'jpg');
11
- if (extension) {
12
- extension = `.${extension}`.toLowerCase();
13
- }
5
+ /**
6
+ * Create a Data URL from a canvas
7
+ * @param {HTMLCanvasElement} canvas
8
+ * @param {object} [options]
9
+ * @param {string} [encoding="image/png"]
10
+ * @param {number} [encodingQuality=0.92]
11
+ * @param {number} [pixelsPerInch=72]
12
+ * @returns {object} result
13
+ * @returns {string} result.dataURL
14
+ * @returns {string} result.extension
15
+ */
16
+ export function exportCanvas(
17
+ canvas,
18
+ { encoding = 'image/png', encodingQuality = 0.92, pixelsPerInch = 72 } = {},
19
+ ) {
20
+ if (!supportedEncodings.includes(encoding))
21
+ throw new Error(`Invalid canvas encoding ${encoding}`);
14
22
 
15
- let dataURL = canvas.toDataURL(encoding, encodingQuality);
23
+ let extension = (encoding.split('/')[1] || '').replace(/jpeg/i, 'jpg');
24
+ if (extension) {
25
+ extension = `.${extension}`.toLowerCase();
26
+ }
16
27
 
17
- return {
18
- extension,
19
- type: encoding,
20
- dataURL
21
- };
28
+ let dataURL = canvas.toDataURL(encoding, encodingQuality);
29
+
30
+ if (encoding !== 'image/webp' && pixelsPerInch !== 72) {
31
+ dataURL = changeDpiDataUrl(dataURL, pixelsPerInch);
32
+ }
33
+
34
+ return {
35
+ extension,
36
+ dataURL,
37
+ };
22
38
  }
@@ -1,10 +1,13 @@
1
1
  class Geometry {
2
- constructor(gl, {
3
- attributes = {
4
- position: { data: [-1, -1, 3, -1, -1, 3] },
5
- uv: { data: [0, 0, 2, 0, 0, 2] }
6
- }
7
- } = {}) {
2
+ constructor(
3
+ gl,
4
+ {
5
+ attributes = {
6
+ position: { data: [-1, -1, 3, -1, -1, 3] },
7
+ uv: { data: [0, 0, 2, 0, 0, 2] },
8
+ },
9
+ } = {},
10
+ ) {
8
11
  this.gl = gl;
9
12
  this.attributes = attributes;
10
13
  this.buffers = Object.keys(attributes).reduce((all, name) => {
@@ -14,7 +17,7 @@ class Geometry {
14
17
  gl.bufferData(
15
18
  gl.ARRAY_BUFFER,
16
19
  new Float32Array(attributes[name].data),
17
- gl.STATIC_DRAW
20
+ gl.STATIC_DRAW,
18
21
  );
19
22
 
20
23
  all[name] = buffer;
@@ -24,7 +27,7 @@ class Geometry {
24
27
  }
25
28
 
26
29
  destroy() {
27
- Object.keys(this.buffers).forEach(name => {
30
+ Object.keys(this.buffers).forEach((name) => {
28
31
  let buffer = this.buffers[name];
29
32
  this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
30
33
  this.gl.bufferData(this.gl.ARRAY_BUFFER, 1, this.gl.STATIC_DRAW);
@@ -1,20 +1,22 @@
1
1
  function createShader(gl, type, source) {
2
- let shader = gl.createShader(type);
3
- gl.shaderSource(shader, source);
4
- gl.compileShader(shader);
5
- let success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
6
-
7
- if (success) {
8
- return shader;
9
- }
2
+ let shader = gl.createShader(type);
3
+ gl.shaderSource(shader, source);
4
+ gl.compileShader(shader);
5
+ let success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
6
+
7
+ if (success) {
8
+ return shader;
9
+ }
10
10
 
11
- console.warn(`fragment-gl.Program: Shader Info Log: ${gl.getShaderInfoLog(shader)}`);
12
- gl.deleteShader(shader);
11
+ console.warn(
12
+ `fragment-gl.Program: Shader Info Log: ${gl.getShaderInfoLog(shader)}`,
13
+ );
14
+ gl.deleteShader(shader);
13
15
  }
14
16
 
15
17
  let P_ID = 0;
16
18
 
17
- let defaultVertex = /* glsl */`
19
+ let defaultVertex = /* glsl */ `
18
20
  attribute vec4 position;
19
21
  attribute vec2 uv;
20
22
 
@@ -26,7 +28,7 @@ let defaultVertex = /* glsl */`
26
28
  }
27
29
  `;
28
30
 
29
- let defaultFragment = /* glsl */`
31
+ let defaultFragment = /* glsl */ `
30
32
  precision highp float;
31
33
 
32
34
  varying vec2 vUv;
@@ -37,15 +39,21 @@ let defaultFragment = /* glsl */`
37
39
  `;
38
40
 
39
41
  class Program {
40
-
41
- constructor(gl, { vertex = defaultVertex, fragment = defaultFragment, uniforms = {} } = {}) {
42
+ constructor(
43
+ gl,
44
+ {
45
+ vertex = defaultVertex,
46
+ fragment = defaultFragment,
47
+ uniforms = {},
48
+ } = {},
49
+ ) {
42
50
  this.gl = gl;
43
51
 
44
52
  this.vertexShader = vertex;
45
53
  this.fragmentShader = fragment;
46
54
  this.uniforms = uniforms;
47
55
  this.needsUpdate = true;
48
-
56
+
49
57
  this._program = gl.createProgram();
50
58
  this.id = P_ID++;
51
59
 
@@ -64,7 +72,11 @@ class Program {
64
72
 
65
73
  set fragmentShader(text) {
66
74
  this.fragment = text;
67
- this._fragmentShader = createShader(this.gl, this.gl.FRAGMENT_SHADER, text);
75
+ this._fragmentShader = createShader(
76
+ this.gl,
77
+ this.gl.FRAGMENT_SHADER,
78
+ text,
79
+ );
68
80
  this.needsUpdate = true;
69
81
  }
70
82
 
@@ -91,12 +103,16 @@ class Program {
91
103
  ${fragmentLog}
92
104
  `);
93
105
  } else if (programLog !== '') {
94
- console.warn(`fragment-gl.Program: Program Info Log: ${programLog}`);
106
+ console.warn(
107
+ `fragment-gl.Program: Program Info Log: ${programLog}`,
108
+ );
95
109
  }
96
110
 
97
111
  let success = gl.getProgramParameter(_program, gl.LINK_STATUS);
98
112
  if (!success) {
99
- console.warn(`fragment-gl.Program: Program Info Log: ${gl.getProgramInfoLog(_program)}`);
113
+ console.warn(
114
+ `fragment-gl.Program: Program Info Log: ${gl.getProgramInfoLog(_program)}`,
115
+ );
100
116
  gl.deleteProgram(_program);
101
117
  }
102
118
 
@@ -106,7 +122,10 @@ class Program {
106
122
  return all;
107
123
  }, {});
108
124
 
109
- let attributesCount = gl.getProgramParameter(_program, gl.ACTIVE_ATTRIBUTES);
125
+ let attributesCount = gl.getProgramParameter(
126
+ _program,
127
+ gl.ACTIVE_ATTRIBUTES,
128
+ );
110
129
  let attributesLocations = {};
111
130
 
112
131
  for (let aIndex = 0; aIndex < attributesCount; aIndex++) {
@@ -1,160 +1,167 @@
1
1
  class Renderer {
2
- constructor({
3
- canvas = document.createElement("canvas"),
4
- antialias = false,
5
- alpha = true,
6
- depth = false,
7
- stencil = false,
8
- premultipliedAlpha = false,
9
- pixelRatio = window.devicePixelRatio,
10
- webgl = 2,
11
- }) {
12
- let gl;
13
- let attributes = {
14
- depth,
15
- stencil,
16
- antialias,
17
- alpha,
18
- premultipliedAlpha,
19
- preserveDrawingBuffer: true,
20
- };
21
-
22
- this.canvas = canvas;
23
-
24
- if (webgl === 2) gl = canvas.getContext("webgl2", attributes);
25
- if (!gl) {
26
- gl =
27
- canvas.getContext("webgl", attributes) ||
28
- canvas.getContext("experimental-webgl", attributes);
29
- }
30
-
31
- this.gl = gl;
32
-
33
- this.state = {
34
- activeTextureUnit: 0,
35
- textureUnits: [],
36
- flipY: false,
37
- viewport: { width: 0, height: 0 },
38
- pixelRatio,
39
- width: 0,
40
- height: 0,
41
- };
42
- this.gl.state = this.state;
43
- }
44
-
45
- render({
46
- geometry,
47
- program,
48
- primitiveType = this.gl.TRIANGLES,
49
- offset = 0,
50
- count = 3,
51
- }) {
52
- if (program.needsUpdate) {
53
- program.compile();
54
- }
55
-
56
- this.gl.clear(this.gl.COLOR_BUFFER_BIT);
57
-
58
- this.gl.useProgram(program._program);
59
-
60
- for (let attributeName in program.attributesLocations) {
61
- let location = program.attributesLocations[attributeName];
62
- let buffer = geometry.buffers[attributeName];
63
-
64
- this.gl.enableVertexAttribArray(location);
65
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
66
-
67
- const size = 2; // 2 components per iteration
68
- const type = this.gl.FLOAT; // the data is 32bit floats
69
- const normalize = false; // don't normalize the data
70
- const stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
71
- const bufferOffset = 0; // start at the beginning of the buffer
72
- this.gl.vertexAttribPointer(
73
- location,
74
- size,
75
- type,
76
- normalize,
77
- stride,
78
- bufferOffset
79
- );
80
- }
81
-
82
- let textureUnit = -1;
83
-
84
- for (let uniformName in program.uniforms) {
85
- let location = program.uniformsLocations[uniformName];
86
- if (location) {
87
- let uniform = program.uniforms[uniformName];
88
-
89
- if (uniform.type === "float") {
90
- this.gl.uniform1f(location, uniform.value);
91
- } else if (uniform.type === "vec2") {
92
- this.gl.uniform2f(location, uniform.value[0], uniform.value[1]);
93
- } else if (uniform.type === "vec3") {
94
- this.gl.uniform3f(
95
- location,
96
- uniform.value[0],
97
- uniform.value[1],
98
- uniform.value[2]
99
- );
100
- } else if (uniform.type === "vec4") {
101
- this.gl.uniform4f(
102
- location,
103
- uniform.value[0],
104
- uniform.value[1],
105
- uniform.value[2],
106
- uniform.value[3]
107
- );
108
- } else if (uniform.type === "sampler2D") {
109
- if (uniform.value) {
110
- textureUnit = textureUnit + 1;
111
- uniform.value.update(textureUnit);
112
-
113
- this.gl.uniform1i(location, textureUnit);
114
- }
115
- }
116
- }
117
- }
118
-
119
- this.gl.drawArrays(primitiveType, offset, count);
120
- }
121
-
122
- setPixelRatio(pixelRatio = this.state.pixelRatio) {
123
- if (this.state.pixelRatio !== pixelRatio) {
124
- this.state.pixelRatio = pixelRatio;
125
- this.setSize();
126
- }
127
- }
128
-
129
- setSize({ width = this.state.width, height = this.state.height } = {}) {
130
- this.state.width = width;
131
- this.state.height = height;
132
-
133
- this.canvas.width = this.state.width * this.state.pixelRatio;
134
- this.canvas.height = this.state.height * this.state.pixelRatio;
135
-
136
- this.setViewport();
137
- }
138
-
139
- setViewport({ width = this.state.width, height = this.state.height } = {}) {
140
- let w = Math.floor(width * this.state.pixelRatio);
141
- let h = Math.floor(height * this.state.pixelRatio);
142
-
143
- if (this.state.viewport.width !== w || this.state.viewport.height !== h) {
144
- this.gl.viewport(0, 0, w, h);
145
-
146
- this.state.viewport.width = w;
147
- this.state.viewport.height = h;
148
- }
149
- }
150
-
151
- destroy() {
152
- let extension = this.gl.getExtension("WEBGL_lose_context");
153
-
154
- if (extension) {
155
- extension.loseContext();
156
- }
157
- }
2
+ constructor({
3
+ canvas = document.createElement('canvas'),
4
+ antialias = false,
5
+ alpha = true,
6
+ depth = false,
7
+ stencil = false,
8
+ premultipliedAlpha = false,
9
+ pixelRatio = window.devicePixelRatio,
10
+ webgl = 2,
11
+ }) {
12
+ let gl;
13
+ let attributes = {
14
+ depth,
15
+ stencil,
16
+ antialias,
17
+ alpha,
18
+ premultipliedAlpha,
19
+ preserveDrawingBuffer: true,
20
+ };
21
+
22
+ this.canvas = canvas;
23
+
24
+ if (webgl === 2) gl = canvas.getContext('webgl2', attributes);
25
+ if (!gl) {
26
+ gl =
27
+ canvas.getContext('webgl', attributes) ||
28
+ canvas.getContext('experimental-webgl', attributes);
29
+ }
30
+
31
+ this.gl = gl;
32
+
33
+ this.state = {
34
+ activeTextureUnit: 0,
35
+ textureUnits: [],
36
+ flipY: false,
37
+ viewport: { width: 0, height: 0 },
38
+ pixelRatio,
39
+ width: 0,
40
+ height: 0,
41
+ };
42
+ this.gl.state = this.state;
43
+ }
44
+
45
+ render({
46
+ geometry,
47
+ program,
48
+ primitiveType = this.gl.TRIANGLES,
49
+ offset = 0,
50
+ count = 3,
51
+ }) {
52
+ if (program.needsUpdate) {
53
+ program.compile();
54
+ }
55
+
56
+ this.gl.clear(this.gl.COLOR_BUFFER_BIT);
57
+
58
+ this.gl.useProgram(program._program);
59
+
60
+ for (let attributeName in program.attributesLocations) {
61
+ let location = program.attributesLocations[attributeName];
62
+ let buffer = geometry.buffers[attributeName];
63
+
64
+ this.gl.enableVertexAttribArray(location);
65
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
66
+
67
+ const size = 2; // 2 components per iteration
68
+ const type = this.gl.FLOAT; // the data is 32bit floats
69
+ const normalize = false; // don't normalize the data
70
+ const stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
71
+ const bufferOffset = 0; // start at the beginning of the buffer
72
+ this.gl.vertexAttribPointer(
73
+ location,
74
+ size,
75
+ type,
76
+ normalize,
77
+ stride,
78
+ bufferOffset,
79
+ );
80
+ }
81
+
82
+ let textureUnit = -1;
83
+
84
+ for (let uniformName in program.uniforms) {
85
+ let location = program.uniformsLocations[uniformName];
86
+ if (location) {
87
+ let uniform = program.uniforms[uniformName];
88
+
89
+ if (uniform.type === 'float') {
90
+ this.gl.uniform1f(location, uniform.value);
91
+ } else if (uniform.type === 'vec2') {
92
+ this.gl.uniform2f(
93
+ location,
94
+ uniform.value[0],
95
+ uniform.value[1],
96
+ );
97
+ } else if (uniform.type === 'vec3') {
98
+ this.gl.uniform3f(
99
+ location,
100
+ uniform.value[0],
101
+ uniform.value[1],
102
+ uniform.value[2],
103
+ );
104
+ } else if (uniform.type === 'vec4') {
105
+ this.gl.uniform4f(
106
+ location,
107
+ uniform.value[0],
108
+ uniform.value[1],
109
+ uniform.value[2],
110
+ uniform.value[3],
111
+ );
112
+ } else if (uniform.type === 'sampler2D') {
113
+ if (uniform.value) {
114
+ textureUnit = textureUnit + 1;
115
+ uniform.value.update(textureUnit);
116
+
117
+ this.gl.uniform1i(location, textureUnit);
118
+ }
119
+ }
120
+ }
121
+ }
122
+
123
+ this.gl.drawArrays(primitiveType, offset, count);
124
+ }
125
+
126
+ setPixelRatio(pixelRatio = this.state.pixelRatio) {
127
+ if (this.state.pixelRatio !== pixelRatio) {
128
+ this.state.pixelRatio = pixelRatio;
129
+ this.setSize();
130
+ }
131
+ }
132
+
133
+ setSize({ width = this.state.width, height = this.state.height } = {}) {
134
+ this.state.width = width;
135
+ this.state.height = height;
136
+
137
+ this.canvas.width = this.state.width * this.state.pixelRatio;
138
+ this.canvas.height = this.state.height * this.state.pixelRatio;
139
+
140
+ this.setViewport();
141
+ }
142
+
143
+ setViewport({ width = this.state.width, height = this.state.height } = {}) {
144
+ let w = Math.floor(width * this.state.pixelRatio);
145
+ let h = Math.floor(height * this.state.pixelRatio);
146
+
147
+ if (
148
+ this.state.viewport.width !== w ||
149
+ this.state.viewport.height !== h
150
+ ) {
151
+ this.gl.viewport(0, 0, w, h);
152
+
153
+ this.state.viewport.width = w;
154
+ this.state.viewport.height = h;
155
+ }
156
+ }
157
+
158
+ destroy() {
159
+ let extension = this.gl.getExtension('WEBGL_lose_context');
160
+
161
+ if (extension) {
162
+ extension.loseContext();
163
+ }
164
+ }
158
165
  }
159
166
 
160
167
  export default Renderer;