nova64 0.2.5 → 0.2.7

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 (185) hide show
  1. package/README.md +25 -8
  2. package/bin/nova64.js +165 -0
  3. package/dist/assets/console-CY_kygm3.js +14 -0
  4. package/dist/assets/console-CY_kygm3.js.map +1 -0
  5. package/dist/assets/main-l0sNRNKZ.js.map +1 -0
  6. package/dist/assets/sky/studio/nx.png +0 -0
  7. package/dist/assets/sky/studio/ny.png +0 -0
  8. package/dist/assets/sky/studio/nz.png +0 -0
  9. package/dist/assets/sky/studio/px.png +0 -0
  10. package/dist/assets/sky/studio/py.png +0 -0
  11. package/dist/assets/sky/studio/pz.png +0 -0
  12. package/dist/assets/vanilla-Dcuy32gi.js +2 -0
  13. package/dist/assets/vanilla-Dcuy32gi.js.map +1 -0
  14. package/dist/console.html +899 -0
  15. package/dist/docs/BENCHMARK.md +77 -0
  16. package/dist/docs/CHEATSHEET.md +255 -0
  17. package/dist/docs/EFFECTS_API_GUIDE.md +577 -0
  18. package/dist/docs/EFFECTS_QUICK_REFERENCE.md +331 -0
  19. package/dist/docs/FONT_CHARACTER_REFERENCE.md +219 -0
  20. package/dist/docs/FREE_GLB_ASSETS.md +330 -0
  21. package/dist/docs/FULLSCREEN_BUTTON_FEATURE.md +296 -0
  22. package/dist/docs/GAMEPAD_SUPPORT.md +348 -0
  23. package/dist/docs/GAME_IMPROVEMENTS.md +278 -0
  24. package/dist/docs/GAME_QUALITY_STATUS.md +300 -0
  25. package/dist/docs/MIGRATION_GUIDE.md +553 -0
  26. package/dist/docs/NOVA64_3D_API.md +356 -0
  27. package/dist/docs/NOVA64_API_REFERENCE.md +1406 -0
  28. package/dist/docs/NOVA64_UI_API.md +503 -0
  29. package/dist/docs/UI_SYSTEM_SUMMARY.md +445 -0
  30. package/dist/docs/VOXEL_ENGINE_GUIDE.md +662 -0
  31. package/dist/docs/VOXEL_QUICK_REFERENCE.md +386 -0
  32. package/dist/docs/api-3d.html +750 -0
  33. package/dist/docs/api-effects.html +385 -0
  34. package/dist/docs/api-improvements.md +121 -0
  35. package/dist/docs/api-skybox.html +407 -0
  36. package/dist/docs/api-sprites.html +321 -0
  37. package/dist/docs/api-voxel.html +337 -0
  38. package/dist/docs/api.html +543 -0
  39. package/dist/docs/assets.html +306 -0
  40. package/dist/docs/audio.html +340 -0
  41. package/dist/docs/blogs.html +286 -0
  42. package/dist/docs/collision.html +316 -0
  43. package/dist/docs/console.html +247 -0
  44. package/dist/docs/editor.html +297 -0
  45. package/dist/docs/font.html +247 -0
  46. package/dist/docs/framebuffer.html +247 -0
  47. package/dist/docs/fullscreen-button.html +297 -0
  48. package/dist/docs/gpu-systems.html +247 -0
  49. package/dist/docs/index.html +580 -0
  50. package/dist/docs/input.html +491 -0
  51. package/dist/docs/physics.html +311 -0
  52. package/dist/docs/screens.html +311 -0
  53. package/dist/docs/storage.html +311 -0
  54. package/dist/docs/textinput.html +332 -0
  55. package/dist/docs/ui.html +488 -0
  56. package/dist/examples/3d-advanced/code.js +695 -0
  57. package/dist/examples/adventure-comic-3d/code.js +342 -0
  58. package/dist/examples/audio-lab/code.js +150 -0
  59. package/dist/examples/boids-flocking/code.js +270 -0
  60. package/dist/examples/crystal-cathedral-3d/code.js +706 -0
  61. package/dist/examples/cyberpunk-city-3d/code.js +1383 -0
  62. package/dist/examples/demoscene/README.md +192 -0
  63. package/dist/examples/demoscene/code.js +1081 -0
  64. package/dist/examples/demoscene/meta.json +21 -0
  65. package/dist/examples/dungeon-crawler-3d/code.js +1117 -0
  66. package/dist/examples/f-zero-nova-3d/code.js +865 -0
  67. package/dist/examples/f-zero-nova-3d/code_old.js +1555 -0
  68. package/dist/examples/fps-demo-3d/code.js +744 -0
  69. package/dist/examples/game-of-life-3d/code.js +338 -0
  70. package/dist/examples/generative-art/code.js +632 -0
  71. package/dist/examples/hello-3d/code.js +325 -0
  72. package/dist/examples/hello-skybox/code.js +183 -0
  73. package/dist/examples/hello-world/code.js +19 -0
  74. package/dist/examples/input-showcase/code.js +109 -0
  75. package/dist/examples/instancing-demo/code.js +315 -0
  76. package/dist/examples/minecraft-demo/code.js +387 -0
  77. package/dist/examples/model-viewer-3d/code.js +114 -0
  78. package/dist/examples/mystical-realm-3d/code.js +1203 -0
  79. package/dist/examples/nature-explorer-3d/code.js +1318 -0
  80. package/dist/examples/particles-demo/code.js +522 -0
  81. package/dist/examples/pbr-showcase/code.js +140 -0
  82. package/dist/examples/physics-demo-3d/code.js +948 -0
  83. package/dist/examples/screen-demo/code.js +267 -0
  84. package/dist/examples/shooter-demo-3d/code.js +1286 -0
  85. package/dist/examples/space-combat-3d/IMPLEMENTATION_SUMMARY.md +109 -0
  86. package/dist/examples/space-combat-3d/README.md +135 -0
  87. package/dist/examples/space-combat-3d/code.js +1332 -0
  88. package/dist/examples/space-harrier-3d/code.js +923 -0
  89. package/dist/examples/star-fox-nova-3d/code.js +1116 -0
  90. package/dist/examples/star-fox-nova-3d/code_backup.js +410 -0
  91. package/dist/examples/star-fox-nova-3d/code_broken.js +1821 -0
  92. package/dist/examples/storage-quest/code.js +209 -0
  93. package/dist/examples/strider-demo-3d/IMPROVEMENT_OPTIONS.md +285 -0
  94. package/dist/examples/strider-demo-3d/cache-test.html +132 -0
  95. package/dist/examples/strider-demo-3d/code-fixed.js +582 -0
  96. package/dist/examples/strider-demo-3d/code-old.js +1537 -0
  97. package/dist/examples/strider-demo-3d/code.js +1462 -0
  98. package/dist/examples/strider-demo-3d/code.js.bak2 +1169 -0
  99. package/dist/examples/strider-demo-3d/fix-game.sh +53 -0
  100. package/dist/examples/super-plumber-64/README.md +128 -0
  101. package/dist/examples/super-plumber-64/code.js +1185 -0
  102. package/dist/examples/super-plumber-64/index.html +88 -0
  103. package/dist/examples/test-2d-overlay/code.js +32 -0
  104. package/dist/examples/test-font/code.js +51 -0
  105. package/dist/examples/test-minimal/code.js +21 -0
  106. package/dist/examples/ui-demo/code.js +306 -0
  107. package/dist/examples/wing-commander-space/README.md +180 -0
  108. package/dist/examples/wing-commander-space/code.js +1285 -0
  109. package/dist/examples/wizardry-3d/CHANGELOG.md +366 -0
  110. package/dist/examples/wizardry-3d/code.js +3928 -0
  111. package/dist/index.html +666 -0
  112. package/dist/os9-shell/assets/index-DIHfrTaW.css +1 -0
  113. package/dist/os9-shell/assets/index-KchE_ngx.js +483 -0
  114. package/dist/os9-shell/assets/index-KchE_ngx.js.map +1 -0
  115. package/dist/os9-shell/index.html +23 -0
  116. package/dist/os9-shell/nova-icon.svg +12 -0
  117. package/dist/runtime/api-2d.js +1158 -0
  118. package/dist/runtime/api-3d/camera.js +73 -0
  119. package/dist/runtime/api-3d/instancing.js +180 -0
  120. package/dist/runtime/api-3d/lights.js +51 -0
  121. package/dist/runtime/api-3d/materials.js +47 -0
  122. package/dist/runtime/api-3d/models.js +84 -0
  123. package/dist/runtime/api-3d/particles.js +296 -0
  124. package/dist/runtime/api-3d/pbr.js +113 -0
  125. package/dist/runtime/api-3d/primitives.js +304 -0
  126. package/dist/runtime/api-3d/scene.js +169 -0
  127. package/dist/runtime/api-3d/transforms.js +161 -0
  128. package/dist/runtime/api-3d.js +166 -0
  129. package/dist/runtime/api-effects.js +840 -0
  130. package/dist/runtime/api-gameutils.js +476 -0
  131. package/dist/runtime/api-generative.js +610 -0
  132. package/dist/runtime/api-presets.js +85 -0
  133. package/dist/runtime/api-skybox.js +232 -0
  134. package/dist/runtime/api-sprites.js +100 -0
  135. package/dist/runtime/api-voxel.js +712 -0
  136. package/dist/runtime/api.js +201 -0
  137. package/dist/runtime/assets.js +27 -0
  138. package/dist/runtime/audio.js +114 -0
  139. package/dist/runtime/collision.js +47 -0
  140. package/dist/runtime/console.js +101 -0
  141. package/dist/runtime/editor.js +233 -0
  142. package/dist/runtime/font.js +233 -0
  143. package/dist/runtime/framebuffer.js +28 -0
  144. package/dist/runtime/fullscreen-button.js +185 -0
  145. package/dist/runtime/gpu-canvas2d.js +47 -0
  146. package/dist/runtime/gpu-threejs.js +643 -0
  147. package/dist/runtime/gpu-webgl2.js +310 -0
  148. package/dist/runtime/index.d.ts +682 -0
  149. package/dist/runtime/index.js +22 -0
  150. package/dist/runtime/input.js +225 -0
  151. package/dist/runtime/logger.js +60 -0
  152. package/dist/runtime/physics.js +101 -0
  153. package/dist/runtime/screens.js +213 -0
  154. package/dist/runtime/storage.js +38 -0
  155. package/dist/runtime/store.js +151 -0
  156. package/dist/runtime/textinput.js +68 -0
  157. package/dist/runtime/ui/buttons.js +124 -0
  158. package/dist/runtime/ui/panels.js +105 -0
  159. package/dist/runtime/ui/text.js +86 -0
  160. package/dist/runtime/ui/widgets.js +141 -0
  161. package/dist/runtime/ui.js +111 -0
  162. package/index.html +6 -1
  163. package/package.json +9 -2
  164. package/public/assets/sky/studio/nx.png +0 -0
  165. package/public/assets/sky/studio/ny.png +0 -0
  166. package/public/assets/sky/studio/nz.png +0 -0
  167. package/public/assets/sky/studio/px.png +0 -0
  168. package/public/assets/sky/studio/py.png +0 -0
  169. package/public/assets/sky/studio/pz.png +0 -0
  170. package/public/os9-shell/assets/index-KchE_ngx.js +483 -0
  171. package/public/os9-shell/assets/index-KchE_ngx.js.map +1 -0
  172. package/public/os9-shell/index.html +10 -1
  173. package/runtime/api-2d.js +301 -21
  174. package/runtime/api-3d/pbr.js +45 -1
  175. package/runtime/api-3d.js +1 -0
  176. package/runtime/api-effects.js +90 -3
  177. package/runtime/api-gameutils.js +476 -0
  178. package/runtime/api-generative.js +610 -0
  179. package/runtime/api-skybox.js +54 -0
  180. package/runtime/api-voxel.js +139 -28
  181. package/runtime/gpu-threejs.js +13 -9
  182. package/runtime/ui.js +2 -2
  183. package/src/main.js +20 -0
  184. package/public/os9-shell/assets/index-B1Uvacma.js +0 -32825
  185. package/public/os9-shell/assets/index-B1Uvacma.js.map +0 -1
@@ -0,0 +1,310 @@
1
+ // runtime/gpu-webgl2.js
2
+ // WebGL2 backend with RGBA16F upload + tone mapping and a simple sprite renderer.
3
+ import { Framebuffer64 } from './framebuffer.js';
4
+
5
+ const VERT_FSQ = `#version 300 es
6
+ precision highp float;
7
+ layout(location=0) in vec2 a_pos;
8
+ out vec2 v_uv;
9
+ void main() {
10
+ v_uv = 0.5 * (a_pos + 1.0);
11
+ gl_Position = vec4(a_pos, 0.0, 1.0);
12
+ }`;
13
+
14
+ const FRAG_TONEMAP = `#version 300 es
15
+ precision highp float;
16
+ in vec2 v_uv;
17
+ out vec4 o_col;
18
+ uniform sampler2D u_tex;
19
+ // Simple ACES-like tonemapper (approx) then gamma to sRGB.
20
+ vec3 tonemapACES( vec3 x ) {
21
+ float a = 2.51, b = 0.03, c = 2.43, d = 0.59, e = 0.14;
22
+ return clamp((x*(a*x+b))/(x*(c*x+d)+e), 0.0, 1.0);
23
+ }
24
+ void main() {
25
+ vec4 c = texture(u_tex, v_uv);
26
+ c.rgb = tonemapACES(c.rgb);
27
+ c.rgb = pow(c.rgb, vec3(1.0/2.2));
28
+ o_col = c;
29
+ }`;
30
+
31
+ // Sprite shader (screen-space)
32
+ const VERT_SPR = `#version 300 es
33
+ precision highp float;
34
+ layout(location=0) in vec2 a_pos; // quad verts in pixels (0..1) scaled in VS
35
+ layout(location=1) in vec2 i_pos; // instance: screen position (pixels)
36
+ layout(location=2) in vec2 i_size; // instance: size in pixels
37
+ layout(location=3) in vec4 i_uv; // instance: uv rect (u0,v0,u1,v1)
38
+ out vec2 v_uv;
39
+ uniform vec2 u_resolution;
40
+ void main() {
41
+ vec2 px = i_pos + a_pos * i_size; // pixel space
42
+ v_uv = mix(i_uv.xy, i_uv.zw, a_pos);
43
+ vec2 ndc = (px / u_resolution)*2.0 - 1.0;
44
+ ndc.y = -ndc.y;
45
+ gl_Position = vec4(ndc, 0.0, 1.0);
46
+ }`;
47
+
48
+ const FRAG_SPR = `#version 300 es
49
+ precision highp float;
50
+ in vec2 v_uv;
51
+ out vec4 o_col;
52
+ uniform sampler2D u_tex;
53
+ void main(){
54
+ vec4 c = texture(u_tex, v_uv);
55
+ o_col = c;
56
+ }`;
57
+
58
+ export class GpuWebGL2 {
59
+ constructor(canvas, w, h) {
60
+ this.canvas = canvas;
61
+ /** @type {WebGL2RenderingContext} */
62
+ const gl = canvas.getContext('webgl2', {
63
+ antialias: false,
64
+ alpha: false,
65
+ premultipliedAlpha: false,
66
+ });
67
+ if (!gl) throw new Error('WebGL2 not supported');
68
+ this.gl = gl;
69
+ this.fb = new Framebuffer64(w, h);
70
+ this.w = w;
71
+ this.h = h;
72
+
73
+ // Programs
74
+ this.progFSQ = this._makeProgram(VERT_FSQ, FRAG_TONEMAP);
75
+ this.progSPR = this._makeProgram(VERT_SPR, FRAG_SPR);
76
+
77
+ // Fullscreen triangle VBO
78
+ this.vboFSQ = gl.createBuffer();
79
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vboFSQ);
80
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 3, -1, -1, 3]), gl.STATIC_DRAW);
81
+
82
+ // Quad for sprites (two-triangle unit quad encoded as [0,0]-[1,1])
83
+ this.vboQuad = gl.createBuffer();
84
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vboQuad);
85
+ gl.bufferData(
86
+ gl.ARRAY_BUFFER,
87
+ new Float32Array([0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1]),
88
+ gl.STATIC_DRAW
89
+ );
90
+
91
+ // Instance buffers
92
+ this.instPos = gl.createBuffer();
93
+ this.instSize = gl.createBuffer();
94
+ this.instUV = gl.createBuffer();
95
+
96
+ // Texture for framebuffer upload (RGBA16F, accepts FLOAT data)
97
+ this.texFB = gl.createTexture();
98
+ gl.bindTexture(gl.TEXTURE_2D, this.texFB);
99
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
100
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
101
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
102
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
103
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
104
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA16F, w, h, 0, gl.RGBA, gl.FLOAT, null);
105
+
106
+ this.tmpF32 = new Float32Array(w * h * 4); // normalized 0..1
107
+
108
+ // Sprite batch state
109
+ this.spriteBatches = new Map(); // texture -> array of instances
110
+ this.texCache = new WeakMap(); // HTMLImageElement -> WebGLTexture
111
+
112
+ gl.enable(gl.BLEND);
113
+ gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
114
+ gl.viewport(0, 0, canvas.width, canvas.height);
115
+ }
116
+
117
+ _makeProgram(vsSrc, fsSrc) {
118
+ const gl = this.gl;
119
+ const vs = gl.createShader(gl.VERTEX_SHADER);
120
+ gl.shaderSource(vs, vsSrc);
121
+ gl.compileShader(vs);
122
+ if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) throw new Error(gl.getShaderInfoLog(vs));
123
+ const fs = gl.createShader(gl.FRAGMENT_SHADER);
124
+ gl.shaderSource(fs, fsSrc);
125
+ gl.compileShader(fs);
126
+ if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) throw new Error(gl.getShaderInfoLog(fs));
127
+ const p = gl.createProgram();
128
+ gl.attachShader(p, vs);
129
+ gl.attachShader(p, fs);
130
+ gl.linkProgram(p);
131
+ if (!gl.getProgramParameter(p, gl.LINK_STATUS)) throw new Error(gl.getProgramInfoLog(p));
132
+ return p;
133
+ }
134
+
135
+ beginFrame() {
136
+ const gl = this.gl;
137
+ gl.viewport(0, 0, this.canvas.width, this.canvas.height);
138
+ gl.clearColor(0, 0, 0, 1);
139
+ gl.clear(gl.COLOR_BUFFER_BIT);
140
+ }
141
+
142
+ // Queue a sprite instance; img is HTMLImageElement, uv rect in pixels of the image
143
+ queueSprite(img, sx, sy, sw, sh, dx, dy, scale = 1) {
144
+ const gltex = this._getTexture(img);
145
+ let arr = this.spriteBatches.get(gltex);
146
+ if (!arr) {
147
+ arr = [];
148
+ this.spriteBatches.set(gltex, arr);
149
+ }
150
+ arr.push({
151
+ sx,
152
+ sy,
153
+ sw,
154
+ sh,
155
+ dx,
156
+ dy,
157
+ scale,
158
+ tex: gltex,
159
+ iw: img.naturalWidth,
160
+ ih: img.naturalHeight,
161
+ });
162
+ }
163
+
164
+ _getTexture(img) {
165
+ let tex = this.texCache.get(img);
166
+ if (tex) return tex;
167
+ const gl = this.gl;
168
+ tex = gl.createTexture();
169
+ gl.bindTexture(gl.TEXTURE_2D, tex);
170
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
171
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
172
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
173
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
174
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
175
+ gl.texImage2D(
176
+ gl.TEXTURE_2D,
177
+ 0,
178
+ gl.RGBA,
179
+ img.naturalWidth,
180
+ img.naturalHeight,
181
+ 0,
182
+ gl.RGBA,
183
+ gl.UNSIGNED_BYTE,
184
+ img
185
+ );
186
+ this.texCache.set(img, tex);
187
+ return tex;
188
+ }
189
+
190
+ endFrame() {
191
+ const gl = this.gl;
192
+
193
+ // Upload framebuffer as RGBA16F using Float32 normalized data
194
+ const p = this.fb.pixels;
195
+ const f = this.tmpF32;
196
+ let k = 0;
197
+ for (let i = 0; i < p.length; i += 4) {
198
+ f[k++] = p[i] / 65535.0;
199
+ f[k++] = p[i + 1] / 65535.0;
200
+ f[k++] = p[i + 2] / 65535.0;
201
+ f[k++] = p[i + 3] / 65535.0;
202
+ }
203
+ gl.bindTexture(gl.TEXTURE_2D, this.texFB);
204
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, this.w, this.h, gl.RGBA, gl.FLOAT, f);
205
+
206
+ // Draw FSQ with tone mapping
207
+ gl.useProgram(this.progFSQ);
208
+ gl.activeTexture(gl.TEXTURE0);
209
+ gl.bindTexture(gl.TEXTURE_2D, this.texFB);
210
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vboFSQ);
211
+ gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
212
+ gl.enableVertexAttribArray(0);
213
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
214
+
215
+ // Draw sprite batches on top
216
+ if (this.spriteBatches.size) {
217
+ gl.useProgram(this.progSPR);
218
+ const uRes = gl.getUniformLocation(this.progSPR, 'u_resolution');
219
+ gl.uniform2f(uRes, this.canvas.width, this.canvas.height);
220
+ // bind quad verts
221
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vboQuad);
222
+ gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
223
+ gl.enableVertexAttribArray(0);
224
+
225
+ // instance attribute locations
226
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.instPos);
227
+ gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
228
+ gl.enableVertexAttribArray(1);
229
+ gl.vertexAttribDivisor(1, 1);
230
+
231
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.instSize);
232
+ gl.vertexAttribPointer(2, 2, gl.FLOAT, false, 0, 0);
233
+ gl.enableVertexAttribArray(2);
234
+ gl.vertexAttribDivisor(2, 1);
235
+
236
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.instUV);
237
+ gl.vertexAttribPointer(3, 4, gl.FLOAT, false, 0, 0);
238
+ gl.enableVertexAttribArray(3);
239
+ gl.vertexAttribDivisor(3, 1);
240
+
241
+ for (const [tex, arr] of this.spriteBatches.entries()) {
242
+ const n = arr.length;
243
+ const pos = new Float32Array(n * 2);
244
+ const size = new Float32Array(n * 2);
245
+ const uvs = new Float32Array(n * 4);
246
+ for (let i = 0; i < n; i++) {
247
+ const s = arr[i];
248
+ pos[i * 2 + 0] = s.dx;
249
+ pos[i * 2 + 1] = s.dy;
250
+ size[i * 2 + 0] = s.sw * s.scale;
251
+ size[i * 2 + 1] = s.sh * s.scale;
252
+ const u0 = s.sx / s.iw,
253
+ v0 = s.sy / s.ih;
254
+ const u1 = (s.sx + s.sw) / s.iw,
255
+ v1 = (s.sy + s.sh) / s.ih;
256
+ uvs[i * 4 + 0] = u0;
257
+ uvs[i * 4 + 1] = v0;
258
+ uvs[i * 4 + 2] = u1;
259
+ uvs[i * 4 + 3] = v1;
260
+ }
261
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.instPos);
262
+ gl.bufferData(gl.ARRAY_BUFFER, pos, gl.DYNAMIC_DRAW);
263
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.instSize);
264
+ gl.bufferData(gl.ARRAY_BUFFER, size, gl.DYNAMIC_DRAW);
265
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.instUV);
266
+ gl.bufferData(gl.ARRAY_BUFFER, uvs, gl.DYNAMIC_DRAW);
267
+
268
+ gl.activeTexture(gl.TEXTURE0);
269
+ gl.bindTexture(gl.TEXTURE_2D, tex);
270
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, n);
271
+ }
272
+
273
+ this.spriteBatches.clear();
274
+ }
275
+ }
276
+
277
+ // API surface hooks needed by higher-level APIs
278
+ getFramebuffer() {
279
+ return this.fb;
280
+ }
281
+ supportsSpriteBatch() {
282
+ return true;
283
+ }
284
+
285
+ updateTextureForImage(img) {
286
+ const gl = this.gl;
287
+ let tex = this.texCache.get(img);
288
+ if (!tex) {
289
+ tex = gl.createTexture();
290
+ this.texCache.set(img, tex);
291
+ }
292
+ gl.bindTexture(gl.TEXTURE_2D, tex);
293
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
294
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
295
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
296
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
297
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
298
+ gl.texImage2D(
299
+ gl.TEXTURE_2D,
300
+ 0,
301
+ gl.RGBA,
302
+ img.naturalWidth,
303
+ img.naturalHeight,
304
+ 0,
305
+ gl.RGBA,
306
+ gl.UNSIGNED_BYTE,
307
+ img
308
+ );
309
+ }
310
+ }