@codexo/exojs 0.4.0 → 0.6.2

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 (151) hide show
  1. package/CHANGELOG.md +499 -163
  2. package/README.md +156 -141
  3. package/dist/esm/audio/AudioAnalyser.d.ts +0 -1
  4. package/dist/esm/audio/AudioAnalyser.js +0 -2
  5. package/dist/esm/audio/AudioAnalyser.js.map +1 -1
  6. package/dist/esm/core/Application.d.ts +4 -4
  7. package/dist/esm/core/Application.js +19 -19
  8. package/dist/esm/core/Application.js.map +1 -1
  9. package/dist/esm/core/Scene.d.ts +59 -24
  10. package/dist/esm/core/Scene.js +60 -18
  11. package/dist/esm/core/Scene.js.map +1 -1
  12. package/dist/esm/core/SceneManager.js +15 -9
  13. package/dist/esm/core/SceneManager.js.map +1 -1
  14. package/dist/esm/core/SceneNode.d.ts +45 -5
  15. package/dist/esm/core/SceneNode.js +136 -7
  16. package/dist/esm/core/SceneNode.js.map +1 -1
  17. package/dist/esm/index.js +6 -4
  18. package/dist/esm/index.js.map +1 -1
  19. package/dist/esm/math/index.d.ts +0 -1
  20. package/dist/esm/rendering/CallbackRenderPass.d.ts +3 -3
  21. package/dist/esm/rendering/CallbackRenderPass.js +2 -2
  22. package/dist/esm/rendering/CallbackRenderPass.js.map +1 -1
  23. package/dist/esm/rendering/Container.d.ts +10 -11
  24. package/dist/esm/rendering/Container.js +5 -5
  25. package/dist/esm/rendering/Container.js.map +1 -1
  26. package/dist/esm/rendering/Drawable.d.ts +2 -2
  27. package/dist/esm/rendering/Drawable.js +5 -5
  28. package/dist/esm/rendering/Drawable.js.map +1 -1
  29. package/dist/esm/rendering/{SceneRenderRuntime.d.ts → RenderBackend.d.ts} +21 -3
  30. package/dist/esm/rendering/RenderNode.d.ts +41 -5
  31. package/dist/esm/rendering/RenderNode.js +89 -24
  32. package/dist/esm/rendering/RenderNode.js.map +1 -1
  33. package/dist/esm/rendering/RenderPass.d.ts +2 -2
  34. package/dist/esm/rendering/RenderTargetPass.d.ts +3 -3
  35. package/dist/esm/rendering/RenderTargetPass.js +9 -9
  36. package/dist/esm/rendering/RenderTargetPass.js.map +1 -1
  37. package/dist/esm/rendering/Renderer.d.ts +3 -3
  38. package/dist/esm/rendering/RendererRegistry.d.ts +13 -7
  39. package/dist/esm/rendering/RendererRegistry.js +18 -10
  40. package/dist/esm/rendering/RendererRegistry.js.map +1 -1
  41. package/dist/esm/rendering/filters/BlurFilter.d.ts +2 -2
  42. package/dist/esm/rendering/filters/BlurFilter.js +5 -5
  43. package/dist/esm/rendering/filters/BlurFilter.js.map +1 -1
  44. package/dist/esm/rendering/filters/ColorFilter.d.ts +2 -2
  45. package/dist/esm/rendering/filters/ColorFilter.js +3 -3
  46. package/dist/esm/rendering/filters/ColorFilter.js.map +1 -1
  47. package/dist/esm/rendering/filters/Filter.d.ts +2 -2
  48. package/dist/esm/rendering/index.d.ts +9 -6
  49. package/dist/esm/rendering/mesh/Mesh.d.ts +69 -0
  50. package/dist/esm/rendering/mesh/Mesh.js +114 -0
  51. package/dist/esm/rendering/mesh/Mesh.js.map +1 -0
  52. package/dist/esm/rendering/primitives/Graphics.d.ts +3 -3
  53. package/dist/esm/rendering/primitives/Graphics.js.map +1 -1
  54. package/dist/esm/rendering/shader/Shader.d.ts +3 -3
  55. package/dist/esm/rendering/shader/Shader.js +10 -10
  56. package/dist/esm/rendering/text/Text.d.ts +2 -2
  57. package/dist/esm/rendering/text/Text.js +2 -2
  58. package/dist/esm/rendering/text/Text.js.map +1 -1
  59. package/dist/esm/rendering/texture/Sampler.d.ts +0 -3
  60. package/dist/esm/rendering/texture/Sampler.js +5 -7
  61. package/dist/esm/rendering/texture/Sampler.js.map +1 -1
  62. package/dist/esm/rendering/types.d.ts +4 -0
  63. package/dist/esm/rendering/types.js +4 -0
  64. package/dist/esm/rendering/types.js.map +1 -1
  65. package/dist/esm/rendering/video/Video.d.ts +2 -2
  66. package/dist/esm/rendering/video/Video.js +2 -2
  67. package/dist/esm/rendering/video/Video.js.map +1 -1
  68. package/dist/esm/rendering/webgl2/AbstractWebGl2BatchedRenderer.d.ts +2 -2
  69. package/dist/esm/rendering/webgl2/AbstractWebGl2BatchedRenderer.js +35 -11
  70. package/dist/esm/rendering/webgl2/AbstractWebGl2BatchedRenderer.js.map +1 -1
  71. package/dist/esm/rendering/webgl2/AbstractWebGl2Renderer.d.ts +13 -13
  72. package/dist/esm/rendering/webgl2/AbstractWebGl2Renderer.js +20 -20
  73. package/dist/esm/rendering/webgl2/AbstractWebGl2Renderer.js.map +1 -1
  74. package/dist/esm/rendering/webgl2/{WebGl2RenderManager.d.ts → WebGl2Backend.d.ts} +15 -12
  75. package/dist/esm/rendering/webgl2/{WebGl2RenderManager.js → WebGl2Backend.js} +63 -38
  76. package/dist/esm/rendering/webgl2/WebGl2Backend.js.map +1 -0
  77. package/dist/esm/rendering/webgl2/WebGl2MaskCompositor.d.ts +31 -0
  78. package/dist/esm/rendering/webgl2/WebGl2MaskCompositor.js +186 -0
  79. package/dist/esm/rendering/webgl2/WebGl2MaskCompositor.js.map +1 -0
  80. package/dist/esm/rendering/webgl2/WebGl2MeshRenderer.d.ts +27 -0
  81. package/dist/esm/rendering/webgl2/WebGl2MeshRenderer.js +242 -0
  82. package/dist/esm/rendering/webgl2/WebGl2MeshRenderer.js.map +1 -0
  83. package/dist/esm/rendering/webgl2/WebGl2ParticleRenderer.d.ts +38 -7
  84. package/dist/esm/rendering/webgl2/WebGl2ParticleRenderer.js +281 -90
  85. package/dist/esm/rendering/webgl2/WebGl2ParticleRenderer.js.map +1 -1
  86. package/dist/esm/rendering/webgl2/WebGl2PrimitiveRenderer.d.ts +2 -2
  87. package/dist/esm/rendering/webgl2/WebGl2PrimitiveRenderer.js +15 -10
  88. package/dist/esm/rendering/webgl2/WebGl2PrimitiveRenderer.js.map +1 -1
  89. package/dist/esm/rendering/webgl2/WebGl2ShaderMappings.js +12 -0
  90. package/dist/esm/rendering/webgl2/WebGl2ShaderMappings.js.map +1 -1
  91. package/dist/esm/rendering/webgl2/WebGl2ShaderProgram.d.ts +2 -0
  92. package/dist/esm/rendering/webgl2/{WebGl2ShaderRuntime.js → WebGl2ShaderProgram.js} +58 -18
  93. package/dist/esm/rendering/webgl2/WebGl2ShaderProgram.js.map +1 -0
  94. package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.d.ts +26 -7
  95. package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.js +260 -62
  96. package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.js.map +1 -1
  97. package/dist/esm/rendering/webgl2/WebGl2VertexArrayObject.d.ts +24 -1
  98. package/dist/esm/rendering/webgl2/WebGl2VertexArrayObject.js +6 -2
  99. package/dist/esm/rendering/webgl2/WebGl2VertexArrayObject.js.map +1 -1
  100. package/dist/esm/rendering/webgl2/glsl/mask-compose.frag.js +4 -0
  101. package/dist/esm/rendering/webgl2/glsl/mask-compose.frag.js.map +1 -0
  102. package/dist/esm/rendering/webgl2/glsl/mask-compose.vert.js +4 -0
  103. package/dist/esm/rendering/webgl2/glsl/mask-compose.vert.js.map +1 -0
  104. package/dist/esm/rendering/webgl2/glsl/mesh.frag.js +4 -0
  105. package/dist/esm/rendering/webgl2/glsl/mesh.frag.js.map +1 -0
  106. package/dist/esm/rendering/webgl2/glsl/mesh.vert.js +4 -0
  107. package/dist/esm/rendering/webgl2/glsl/mesh.vert.js.map +1 -0
  108. package/dist/esm/rendering/webgl2/glsl/particle.vert.js +1 -1
  109. package/dist/esm/rendering/webgl2/glsl/sprite.frag.js +1 -1
  110. package/dist/esm/rendering/webgl2/glsl/sprite.vert.js +1 -1
  111. package/dist/esm/rendering/webgpu/AbstractWebGpuRenderer.d.ts +9 -9
  112. package/dist/esm/rendering/webgpu/AbstractWebGpuRenderer.js +18 -18
  113. package/dist/esm/rendering/webgpu/AbstractWebGpuRenderer.js.map +1 -1
  114. package/dist/esm/rendering/webgpu/{WebGpuRenderManager.d.ts → WebGpuBackend.d.ts} +17 -14
  115. package/dist/esm/rendering/webgpu/{WebGpuRenderManager.js → WebGpuBackend.js} +77 -40
  116. package/dist/esm/rendering/webgpu/WebGpuBackend.js.map +1 -0
  117. package/dist/esm/rendering/webgpu/WebGpuMaskCompositor.d.ts +37 -0
  118. package/dist/esm/rendering/webgpu/WebGpuMaskCompositor.js +279 -0
  119. package/dist/esm/rendering/webgpu/WebGpuMaskCompositor.js.map +1 -0
  120. package/dist/esm/rendering/webgpu/WebGpuMeshRenderer.d.ts +40 -0
  121. package/dist/esm/rendering/webgpu/WebGpuMeshRenderer.js +439 -0
  122. package/dist/esm/rendering/webgpu/WebGpuMeshRenderer.js.map +1 -0
  123. package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.d.ts +2 -3
  124. package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.js +65 -82
  125. package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.js.map +1 -1
  126. package/dist/esm/rendering/webgpu/WebGpuPrimitiveRenderer.d.ts +2 -3
  127. package/dist/esm/rendering/webgpu/WebGpuPrimitiveRenderer.js +24 -25
  128. package/dist/esm/rendering/webgpu/WebGpuPrimitiveRenderer.js.map +1 -1
  129. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.d.ts +28 -13
  130. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.js +410 -382
  131. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.js.map +1 -1
  132. package/dist/esm/resources/Loader.js +5 -3
  133. package/dist/esm/resources/Loader.js.map +1 -1
  134. package/dist/exo.esm.js +3574 -1696
  135. package/dist/exo.esm.js.map +1 -1
  136. package/package.json +20 -11
  137. package/dist/esm/math/Transformable.d.ts +0 -47
  138. package/dist/esm/math/Transformable.js +0 -140
  139. package/dist/esm/math/Transformable.js.map +0 -1
  140. package/dist/esm/rendering/webgl2/WebGl2RenderManager.js.map +0 -1
  141. package/dist/esm/rendering/webgl2/WebGl2RendererRuntime.d.ts +0 -15
  142. package/dist/esm/rendering/webgl2/WebGl2ShaderRuntime.d.ts +0 -2
  143. package/dist/esm/rendering/webgl2/WebGl2ShaderRuntime.js.map +0 -1
  144. package/dist/esm/rendering/webgpu/WebGpuRenderManager.js.map +0 -1
  145. package/dist/esm/rendering/webgpu/WebGpuRendererRuntime.d.ts +0 -8
  146. package/dist/exo.esm.min.js +0 -2
  147. package/dist/exo.esm.min.js.map +0 -1
  148. package/dist/exo.global.js +0 -17328
  149. package/dist/exo.global.js.map +0 -1
  150. package/dist/exo.global.min.js +0 -2
  151. package/dist/exo.global.min.js.map +0 -1
@@ -4,6 +4,7 @@ import { WebGl2ShaderBlock } from './WebGl2ShaderBlock.js';
4
4
  import { ShaderPrimitives } from '../types.js';
5
5
  import { webGl2PrimitiveArrayConstructors, webGl2PrimitiveByteSizeMapping } from './WebGl2ShaderMappings.js';
6
6
 
7
+ const completionStatusEnumKhr = 0x91B1;
7
8
  const uniformUploadFunctions = {
8
9
  [ShaderPrimitives.Float]: (gl, location, value) => { gl.uniform1f(location, value[0]); },
9
10
  [ShaderPrimitives.FloatVec2]: (gl, location, value) => { gl.uniform2fv(location, value); },
@@ -22,22 +23,66 @@ const uniformUploadFunctions = {
22
23
  [ShaderPrimitives.FloatMat4]: (gl, location, value) => { gl.uniformMatrix4fv(location, false, value); },
23
24
  [ShaderPrimitives.Sampler2D]: (gl, location, value) => { gl.uniform1i(location, value[0]); },
24
25
  };
25
- function createWebGl2ShaderRuntime(gl) {
26
+ function createWebGl2ShaderProgram(gl) {
26
27
  let program = null;
27
28
  let vertexShader = null;
28
29
  let fragmentShader = null;
30
+ let pendingShader = null;
29
31
  const managedUniforms = [];
30
32
  const uniformBlocks = [];
33
+ // Detect KHR_parallel_shader_compile. When present, the GL driver may
34
+ // compile shaders on a worker thread; we can poll completion via
35
+ // COMPLETION_STATUS_KHR without blocking. When absent, the very first
36
+ // call to gl.getShaderParameter(COMPILE_STATUS) blocks until the driver
37
+ // finishes compilation.
38
+ //
39
+ // Either way, this runtime defers the actual COMPILE_STATUS / LINK_STATUS
40
+ // queries (and the attribute/uniform extraction that depends on them)
41
+ // from initialize() to bind()/sync(). That way the driver gets the entire
42
+ // window between renderer setup and first draw to compile in the
43
+ // background. With the extension, that window is non-blocking; without
44
+ // it, the eventual blocking query is hopefully a no-op because the work
45
+ // already finished during asset loading or scene init.
46
+ const parallelExt = gl.getExtension('KHR_parallel_shader_compile');
47
+ const completionStatus = parallelExt?.COMPLETION_STATUS_KHR ?? completionStatusEnumKhr;
31
48
  function initialize(shader) {
32
49
  if (program) {
33
50
  return;
34
51
  }
52
+ // Issue compile + link without querying status. The driver may
53
+ // service these on a worker; we'll collect the result at first bind.
35
54
  vertexShader = compileShader(gl, gl.VERTEX_SHADER, shader.vertexSource);
36
55
  fragmentShader = compileShader(gl, gl.FRAGMENT_SHADER, shader.fragmentSource);
37
56
  program = linkProgram(gl, vertexShader, fragmentShader);
38
- extractAttributes(gl, program, shader);
39
- extractUniforms(gl, program, shader, managedUniforms);
57
+ pendingShader = shader;
58
+ }
59
+ function finalize() {
60
+ if (pendingShader === null || program === null || vertexShader === null || fragmentShader === null) {
61
+ return;
62
+ }
63
+ // With the KHR extension we can poll completion non-blockingly
64
+ // before the actual status queries (which would otherwise block).
65
+ // Without the extension we simply skip the poll and let the status
66
+ // query block on its own (today's behaviour).
67
+ if (parallelExt !== null) {
68
+ void gl.getProgramParameter(program, completionStatus);
69
+ }
70
+ if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
71
+ const log = gl.getShaderInfoLog(vertexShader);
72
+ throw new Error(`Vertex shader compilation failed: ${log}`);
73
+ }
74
+ if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
75
+ const log = gl.getShaderInfoLog(fragmentShader);
76
+ throw new Error(`Fragment shader compilation failed: ${log}`);
77
+ }
78
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
79
+ const log = gl.getProgramInfoLog(program);
80
+ throw new Error(`Shader program linking failed: ${log}`);
81
+ }
82
+ extractAttributes(gl, program, pendingShader);
83
+ extractUniforms(gl, program, pendingShader, managedUniforms);
40
84
  extractUniformBlocks(gl, program, uniformBlocks);
85
+ pendingShader = null;
41
86
  }
42
87
  function syncUniforms() {
43
88
  for (const managed of managedUniforms) {
@@ -54,6 +99,7 @@ function createWebGl2ShaderRuntime(gl) {
54
99
  initialize,
55
100
  bind: (shader) => {
56
101
  initialize(shader);
102
+ finalize();
57
103
  gl.useProgram(program);
58
104
  syncUniforms();
59
105
  },
@@ -61,12 +107,13 @@ function createWebGl2ShaderRuntime(gl) {
61
107
  gl.useProgram(null);
62
108
  },
63
109
  sync: () => {
64
- // Bind the program before syncing uniforms. WebGl2RenderManager
110
+ // Bind the program before syncing uniforms. WebGl2Backend
65
111
  // does not call bindShader() on the active renderer's shader
66
112
  // during normal draw flow, so sync() is the first entry point
67
113
  // that must establish program binding — otherwise uniform*
68
114
  // targets the wrong (or no) program and the subsequent draw
69
115
  // call fails with "no valid shader program in use".
116
+ finalize();
70
117
  gl.useProgram(program);
71
118
  syncUniforms();
72
119
  },
@@ -80,12 +127,17 @@ function createWebGl2ShaderRuntime(gl) {
80
127
  vertexShader = null;
81
128
  fragmentShader = null;
82
129
  program = null;
130
+ pendingShader = null;
83
131
  managedUniforms.length = 0;
84
132
  uniformBlocks.length = 0;
85
133
  shader.disconnect();
86
134
  },
87
135
  };
88
136
  }
137
+ // compileShader / linkProgram intentionally do NOT query COMPILE_STATUS or
138
+ // LINK_STATUS here — those queries block on driver completion. Status checks
139
+ // happen in finalize() at first bind, after the driver has had time to
140
+ // compile in the background (especially with KHR_parallel_shader_compile).
89
141
  function compileShader(gl, type, source) {
90
142
  const shader = gl.createShader(type);
91
143
  if (!shader) {
@@ -93,11 +145,6 @@ function compileShader(gl, type, source) {
93
145
  }
94
146
  gl.shaderSource(shader, source);
95
147
  gl.compileShader(shader);
96
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
97
- const log = gl.getShaderInfoLog(shader);
98
- gl.deleteShader(shader);
99
- throw new Error(`Shader compilation failed: ${log}`);
100
- }
101
148
  return shader;
102
149
  }
103
150
  function linkProgram(gl, vertexShader, fragmentShader) {
@@ -108,13 +155,6 @@ function linkProgram(gl, vertexShader, fragmentShader) {
108
155
  gl.attachShader(program, vertexShader);
109
156
  gl.attachShader(program, fragmentShader);
110
157
  gl.linkProgram(program);
111
- if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
112
- const log = gl.getProgramInfoLog(program);
113
- gl.detachShader(program, vertexShader);
114
- gl.detachShader(program, fragmentShader);
115
- gl.deleteProgram(program);
116
- throw new Error(`Shader program linking failed: ${log}`);
117
- }
118
158
  return program;
119
159
  }
120
160
  function extractAttributes(gl, program, shader) {
@@ -157,5 +197,5 @@ function extractUniformBlocks(gl, program, uniformBlocks) {
157
197
  }
158
198
  }
159
199
 
160
- export { createWebGl2ShaderRuntime };
161
- //# sourceMappingURL=WebGl2ShaderRuntime.js.map
200
+ export { createWebGl2ShaderProgram };
201
+ //# sourceMappingURL=WebGl2ShaderProgram.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebGl2ShaderProgram.js","sources":["../../../../../src/rendering/webgl2/WebGl2ShaderProgram.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;AAuBA,MAAM,uBAAuB,GAAG,MAAM;AAEtC,MAAM,sBAAsB,GAA0C;IAClE,CAAC,gBAAgB,CAAC,KAAK,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,KAAU,EAAG,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9F,CAAC,gBAAgB,CAAC,SAAS,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,KAAU,EAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAChG,CAAC,gBAAgB,CAAC,SAAS,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,KAAU,EAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAChG,CAAC,gBAAgB,CAAC,SAAS,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,KAAU,EAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAEhG,CAAC,gBAAgB,CAAC,GAAG,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,KAAU,EAAG,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5F,CAAC,gBAAgB,CAAC,OAAO,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,KAAU,EAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAC9F,CAAC,gBAAgB,CAAC,OAAO,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,KAAU,EAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAC9F,CAAC,gBAAgB,CAAC,OAAO,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,KAAU,EAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAE9F,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,KAAU,EAAG,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7F,CAAC,gBAAgB,CAAC,QAAQ,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,KAAU,EAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAC/F,CAAC,gBAAgB,CAAC,QAAQ,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,KAAU,EAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAC/F,CAAC,gBAAgB,CAAC,QAAQ,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,KAAU,EAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAE/F,CAAC,gBAAgB,CAAC,SAAS,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,OAAa,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAC7G,CAAC,gBAAgB,CAAC,SAAS,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,OAAa,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAC7G,CAAC,gBAAgB,CAAC,SAAS,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,OAAa,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAE7G,CAAC,gBAAgB,CAAC,SAAS,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,KAAU,EAAG,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CACrG;AAEK,SAAU,yBAAyB,CAAC,EAA0B,EAAA;IAChE,IAAI,OAAO,GAAwB,IAAI;IACvC,IAAI,YAAY,GAAuB,IAAI;IAC3C,IAAI,cAAc,GAAuB,IAAI;IAC7C,IAAI,aAAa,GAAkB,IAAI;IACvC,MAAM,eAAe,GAA0B,EAAE;IACjD,MAAM,aAAa,GAA6B,EAAE;;;;;;;;;;;;;;IAelD,MAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,6BAA6B,CAAoC;AACrG,IAAA,MAAM,gBAAgB,GAAG,WAAW,EAAE,qBAAqB,IAAI,uBAAuB;IAEtF,SAAS,UAAU,CAAC,MAAc,EAAA;QAC9B,IAAI,OAAO,EAAE;YACT;QACJ;;;AAIA,QAAA,YAAY,GAAG,aAAa,CAAC,EAAE,EAAE,EAAE,CAAC,aAAa,EAAE,MAAM,CAAC,YAAY,CAAC;AACvE,QAAA,cAAc,GAAG,aAAa,CAAC,EAAE,EAAE,EAAE,CAAC,eAAe,EAAE,MAAM,CAAC,cAAc,CAAC;QAC7E,OAAO,GAAG,WAAW,CAAC,EAAE,EAAE,YAAY,EAAE,cAAc,CAAC;QAEvD,aAAa,GAAG,MAAM;IAC1B;AAEA,IAAA,SAAS,QAAQ,GAAA;AACb,QAAA,IAAI,aAAa,KAAK,IAAI,IAAI,OAAO,KAAK,IAAI,IAAI,YAAY,KAAK,IAAI,IAAI,cAAc,KAAK,IAAI,EAAE;YAChG;QACJ;;;;;AAMA,QAAA,IAAI,WAAW,KAAK,IAAI,EAAE;YACtB,KAAK,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,CAAC;QAC1D;AAEA,QAAA,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,YAAY,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE;YACzD,MAAM,GAAG,GAAG,EAAE,CAAC,gBAAgB,CAAC,YAAY,CAAC;AAE7C,YAAA,MAAM,IAAI,KAAK,CAAC,qCAAqC,GAAG,CAAA,CAAE,CAAC;QAC/D;AAEA,QAAA,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,cAAc,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE;YAC3D,MAAM,GAAG,GAAG,EAAE,CAAC,gBAAgB,CAAC,cAAc,CAAC;AAE/C,YAAA,MAAM,IAAI,KAAK,CAAC,uCAAuC,GAAG,CAAA,CAAE,CAAC;QACjE;AAEA,QAAA,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE;YAClD,MAAM,GAAG,GAAG,EAAE,CAAC,iBAAiB,CAAC,OAAO,CAAC;AAEzC,YAAA,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,CAAA,CAAE,CAAC;QAC5D;AAEA,QAAA,iBAAiB,CAAC,EAAE,EAAE,OAAO,EAAE,aAAa,CAAC;QAC7C,eAAe,CAAC,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE,eAAe,CAAC;AAC5D,QAAA,oBAAoB,CAAC,EAAE,EAAE,OAAO,EAAE,aAAa,CAAC;QAEhD,aAAa,GAAG,IAAI;IACxB;AAEA,IAAA,SAAS,YAAY,GAAA;AACjB,QAAA,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE;AACnC,YAAA,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE;AACvB,gBAAA,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;AAC7D,gBAAA,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE;YAC/B;QACJ;AAEA,QAAA,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE;YAC/B,KAAK,CAAC,MAAM,EAAE;QAClB;IACJ;IAEA,OAAO;QACH,UAAU;AACV,QAAA,IAAI,EAAE,CAAC,MAAc,KAAU;YAC3B,UAAU,CAAC,MAAM,CAAC;AAClB,YAAA,QAAQ,EAAE;AAEV,YAAA,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;AACtB,YAAA,YAAY,EAAE;QAClB,CAAC;QAED,MAAM,EAAE,MAAW;AACf,YAAA,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;QACvB,CAAC;QAED,IAAI,EAAE,MAAW;;;;;;;AAOb,YAAA,QAAQ,EAAE;AACV,YAAA,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;AACtB,YAAA,YAAY,EAAE;QAClB,CAAC;AAED,QAAA,OAAO,EAAE,CAAC,MAAc,KAAU;AAC9B,YAAA,EAAE,CAAC,YAAY,CAAC,YAAY,CAAC;AAC7B,YAAA,EAAE,CAAC,YAAY,CAAC,cAAc,CAAC;AAC/B,YAAA,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC;AAEzB,YAAA,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE;gBAC/B,KAAK,CAAC,OAAO,EAAE;YACnB;YAEA,YAAY,GAAG,IAAI;YACnB,cAAc,GAAG,IAAI;YACrB,OAAO,GAAG,IAAI;YACd,aAAa,GAAG,IAAI;AACpB,YAAA,eAAe,CAAC,MAAM,GAAG,CAAC;AAC1B,YAAA,aAAa,CAAC,MAAM,GAAG,CAAC;YAExB,MAAM,CAAC,UAAU,EAAE;QACvB,CAAC;KACJ;AACL;AAEA;AACA;AACA;AACA;AAEA,SAAS,aAAa,CAAC,EAA0B,EAAE,IAAY,EAAE,MAAc,EAAA;IAC3E,MAAM,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC;IAEpC,IAAI,CAAC,MAAM,EAAE;AACT,QAAA,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC;IAC/C;AAEA,IAAA,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC;AAC/B,IAAA,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC;AAExB,IAAA,OAAO,MAAM;AACjB;AAEA,SAAS,WAAW,CAAC,EAA0B,EAAE,YAAyB,EAAE,cAA2B,EAAA;AACnG,IAAA,MAAM,OAAO,GAAG,EAAE,CAAC,aAAa,EAAE;IAElC,IAAI,CAAC,OAAO,EAAE;AACV,QAAA,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC;IACvD;AAEA,IAAA,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC;AACtC,IAAA,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,cAAc,CAAC;AACxC,IAAA,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC;AAEvB,IAAA,OAAO,OAAO;AAClB;AAEA,SAAS,iBAAiB,CAAC,EAA0B,EAAE,OAAqB,EAAE,MAAc,EAAA;AACxF,IAAA,MAAM,gBAAgB,GAAG,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,EAAE,CAAC,iBAAiB,CAAC;AAE9E,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,gBAAgB,EAAE,CAAC,EAAE,EAAE;QACvC,MAAM,IAAI,GAAG,EAAE,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QAE3C,IAAI,CAAC,IAAI,EAAE;YACP;QACJ;AAEA,QAAA,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC;AAC9D,QAAA,SAAS,CAAC,QAAQ,GAAG,EAAE,CAAC,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC;QAC7D,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC;IAC/C;AACJ;AAEA,SAAS,eAAe,CAAC,EAA0B,EAAE,OAAqB,EAAE,MAAc,EAAE,eAAsC,EAAA;AAC9H,IAAA,MAAM,WAAW,GAAG,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,EAAE,CAAC,eAAe,CAAC;AACvE,IAAA,MAAM,aAAa,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,KAAK,CAAC;AAC1E,IAAA,MAAM,MAAM,GAAG,EAAE,CAAC,iBAAiB,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,CAAC,mBAAmB,CAAC;IACnF,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,KAAK,MAAM,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;AAEvE,IAAA,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE;QACzB,MAAM,IAAI,GAAG,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,CAAC;QAEhD,IAAI,CAAC,IAAI,EAAE;YACP;QACJ;QAEA,MAAM,IAAI,GAAG,IAAI,gCAAgC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,8BAA8B,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;QACnH,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;AAC/E,QAAA,MAAM,QAAQ,GAAG,EAAE,CAAC,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC;QAC7D,MAAM,QAAQ,GAAG,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC;QAElD,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;QAE1C,IAAI,QAAQ,EAAE;YACV,eAAe,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;QACzD;IACJ;AACJ;AAEA,SAAS,oBAAoB,CAAC,EAA0B,EAAE,OAAqB,EAAE,aAAuC,EAAA;AACpH,IAAA,MAAM,YAAY,GAAG,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,EAAE,CAAC,qBAAqB,CAAC;AAE9E,IAAA,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,YAAY,EAAE,KAAK,EAAE,EAAE;QAC/C,MAAM,KAAK,GAAG,IAAI,iBAAiB,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC;AACvD,QAAA,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;IAC7B;AACJ;;;;"}
@@ -1,11 +1,30 @@
1
- import { WebGl2VertexArrayObject } from './WebGl2VertexArrayObject';
2
- import type { WebGl2RenderBuffer } from './WebGl2RenderBuffer';
1
+ import { AbstractWebGl2Renderer } from './AbstractWebGl2Renderer';
3
2
  import type { Sprite } from '../sprite/Sprite';
4
- import { AbstractWebGl2BatchedRenderer } from './AbstractWebGl2BatchedRenderer';
5
- import type { View } from '../View';
6
- export declare class WebGl2SpriteRenderer extends AbstractWebGl2BatchedRenderer {
3
+ import type { WebGl2Backend } from './WebGl2Backend';
4
+ export declare class WebGl2SpriteRenderer extends AbstractWebGl2Renderer<Sprite> {
5
+ private readonly _shader;
6
+ private readonly _batchSize;
7
+ private readonly _instanceData;
8
+ private readonly _instanceFloat32;
9
+ private readonly _instanceUint32;
10
+ private readonly _activeTextures;
11
+ private readonly _textureSlots;
12
+ private _slotCount;
13
+ private _instanceCount;
14
+ private _currentBlendMode;
15
+ private _currentView;
16
+ private _currentViewId;
17
+ private _instanceBuffer;
18
+ private _vao;
19
+ private _connection;
7
20
  constructor(batchSize: number);
8
21
  render(sprite: Sprite): this;
9
- protected createVao(gl: WebGL2RenderingContext, indexBuffer: WebGl2RenderBuffer, vertexBuffer: WebGl2RenderBuffer): WebGl2VertexArrayObject;
10
- protected updateView(view: View): this;
22
+ flush(): void;
23
+ protected onConnect(backend: WebGl2Backend): void;
24
+ protected onDisconnect(): void;
25
+ destroy(): void;
26
+ private _resetSlots;
27
+ private _createConnection;
28
+ private _createBufferRuntime;
29
+ private _createVaoRuntime;
11
30
  }
@@ -1,80 +1,278 @@
1
+ import { AbstractWebGl2Renderer } from './AbstractWebGl2Renderer.js';
2
+ import { Shader } from '../shader/Shader.js';
3
+ import { createWebGl2ShaderProgram } from './WebGl2ShaderProgram.js';
4
+ import { WebGl2RenderBuffer } from './WebGl2RenderBuffer.js';
1
5
  import { WebGl2VertexArrayObject } from './WebGl2VertexArrayObject.js';
2
- import { AbstractWebGl2BatchedRenderer } from './AbstractWebGl2BatchedRenderer.js';
6
+ import { RenderingPrimitives, BufferTypes, BufferUsage } from '../types.js';
3
7
  import vertexSource from './glsl/sprite.vert.js';
4
8
  import fragmentSource from './glsl/sprite.frag.js';
5
9
 
6
- class WebGl2SpriteRenderer extends AbstractWebGl2BatchedRenderer {
10
+ /**
11
+ * Instanced sprite renderer for WebGL2.
12
+ *
13
+ * Each batch issues a single `drawArraysInstanced(TRIANGLE_STRIP, 0, 4, N)`
14
+ * with no per-vertex buffer — `gl_VertexID` 0..3 selects which corner of
15
+ * the quad each invocation is computing. All per-sprite data lives in a
16
+ * single per-instance buffer (divisor = 1).
17
+ *
18
+ * Per-instance layout (56 bytes per sprite, 6 attributes):
19
+ * ```
20
+ * localBounds f32x4 (offset 0, 16 bytes) — left, top, right, bottom
21
+ * transformAB f32x3 (offset 16, 12 bytes) — first row of 2D affine
22
+ * transformCD f32x3 (offset 28, 12 bytes) — second row of 2D affine
23
+ * uvBounds u16x4 norm (offset 40, 8 bytes) — uMin, vMin, uMax, vMax
24
+ * color u8x4 norm (offset 48, 4 bytes) — RGBA tint
25
+ * textureSlot u32 (offset 52, 4 bytes) — multi-texture slot
26
+ * ```
27
+ *
28
+ * vs. the previous per-vertex layout (80 bytes per quad), this saves
29
+ * roughly 30% bandwidth and ~75% of the CPU writes per sprite — the
30
+ * vertex shader expands one instance into four corners on the GPU
31
+ * instead of the CPU duplicating the same color/slot/transform across
32
+ * four vertex entries.
33
+ */
34
+ const maxBatchTextures = 8;
35
+ const instanceStrideBytes = 56;
36
+ const wordsPerInstance = instanceStrideBytes / Uint32Array.BYTES_PER_ELEMENT;
37
+ class WebGl2SpriteRenderer extends AbstractWebGl2Renderer {
38
+ _shader;
39
+ _batchSize;
40
+ _instanceData;
41
+ _instanceFloat32;
42
+ _instanceUint32;
43
+ _activeTextures = new Array(maxBatchTextures).fill(null);
44
+ _textureSlots = new Map();
45
+ _slotCount = 0;
46
+ _instanceCount = 0;
47
+ _currentBlendMode = null;
48
+ _currentView = null;
49
+ _currentViewId = -1;
50
+ _instanceBuffer = null;
51
+ _vao = null;
52
+ _connection = null;
7
53
  constructor(batchSize) {
8
- /**
9
- * 4 x 4 Attributes:
10
- * 2 = position (x, y) +
11
- * 1 = texCoord (packed uv) +
12
- * 1 = color (ARGB int)
13
- */
14
- super(batchSize, 16, vertexSource, fragmentSource);
54
+ super();
55
+ this._batchSize = batchSize;
56
+ this._shader = new Shader(vertexSource, fragmentSource);
57
+ this._instanceData = new ArrayBuffer(batchSize * instanceStrideBytes);
58
+ this._instanceFloat32 = new Float32Array(this._instanceData);
59
+ this._instanceUint32 = new Uint32Array(this._instanceData);
15
60
  }
16
61
  render(sprite) {
17
- const { texture, blendMode, tint, vertices, texCoords } = sprite;
18
- const batchFull = (this.batchIndex >= this.batchSize);
19
- const textureChanged = (texture !== this.currentTexture);
20
- const blendModeChanged = (blendMode !== this.currentBlendMode);
21
- const flush = (batchFull || textureChanged || blendModeChanged);
22
- const index = flush ? 0 : (this.batchIndex * this.attributeCount);
23
- const float32View = this.float32View;
24
- const uint32View = this.uint32View;
25
- const runtime = this.getRuntime();
26
- if (flush) {
62
+ const texture = sprite.texture;
63
+ if (texture === null) {
64
+ return this;
65
+ }
66
+ const backend = this.getBackend();
67
+ const blendMode = sprite.blendMode;
68
+ const batchFull = this._instanceCount >= this._batchSize;
69
+ const blendModeChanged = blendMode !== this._currentBlendMode;
70
+ const slotExhausted = !this._textureSlots.has(texture) && this._slotCount >= maxBatchTextures;
71
+ if (batchFull || blendModeChanged || slotExhausted) {
27
72
  this.flush();
28
- if (textureChanged) {
29
- this.currentTexture = texture;
30
- }
31
73
  if (blendModeChanged) {
32
- this.currentBlendMode = blendMode;
33
- runtime.setBlendMode(blendMode);
74
+ this._currentBlendMode = blendMode;
75
+ backend.setBlendMode(blendMode);
34
76
  }
35
77
  }
36
- if (textureChanged && texture) {
37
- runtime.bindTexture(texture);
78
+ let slot = this._textureSlots.get(texture);
79
+ if (slot === undefined) {
80
+ slot = this._slotCount++;
81
+ this._textureSlots.set(texture, slot);
82
+ this._activeTextures[slot] = texture;
83
+ backend.bindTexture(texture, slot);
38
84
  }
39
- // X / Y
40
- float32View[index + 0] = vertices[0];
41
- float32View[index + 1] = vertices[1];
42
- // X / Y
43
- float32View[index + 4] = vertices[2];
44
- float32View[index + 5] = vertices[3];
45
- // X / Y
46
- float32View[index + 8] = vertices[4];
47
- float32View[index + 9] = vertices[5];
48
- // X / Y
49
- float32View[index + 12] = vertices[6];
50
- float32View[index + 13] = vertices[7];
51
- // U / V
52
- uint32View[index + 2] = texCoords[0];
53
- uint32View[index + 6] = texCoords[1];
54
- // U / V
55
- uint32View[index + 10] = texCoords[2];
56
- uint32View[index + 14] = texCoords[3];
57
- // Tint
58
- uint32View[index + 3]
59
- = uint32View[index + 7]
60
- = uint32View[index + 11]
61
- = uint32View[index + 15]
62
- = tint.toRgba();
63
- this.batchIndex++;
85
+ const offset = this._instanceCount * wordsPerInstance;
86
+ const f32 = this._instanceFloat32;
87
+ const u32 = this._instanceUint32;
88
+ // localBounds: left, top, right, bottom (offset 0..3)
89
+ const bounds = sprite.getLocalBounds();
90
+ f32[offset + 0] = bounds.left;
91
+ f32[offset + 1] = bounds.top;
92
+ f32[offset + 2] = bounds.right;
93
+ f32[offset + 3] = bounds.bottom;
94
+ // transform rows (offset 4..6 = AB, 7..9 = CD)
95
+ const transform = sprite.getGlobalTransform();
96
+ f32[offset + 4] = transform.a;
97
+ f32[offset + 5] = transform.b;
98
+ f32[offset + 6] = transform.x;
99
+ f32[offset + 7] = transform.c;
100
+ f32[offset + 8] = transform.d;
101
+ f32[offset + 9] = transform.y;
102
+ // uvBounds at offset 10 — 8 bytes = 2 u32 slots, normalised u16x4.
103
+ // Pack (uMin, vMin, uMax, vMax) into two uint32s, with flipY swap
104
+ // applied at pack time so the shader can stay flip-agnostic.
105
+ const frame = sprite.textureFrame;
106
+ const texWidth = texture.width;
107
+ const texHeight = texture.height;
108
+ // Clamp to 16-bit unsigned range for normalisation.
109
+ const uMin = (frame.left / texWidth) * 0xFFFF & 0xFFFF;
110
+ const uMax = (frame.right / texWidth) * 0xFFFF & 0xFFFF;
111
+ const vMinRaw = (frame.top / texHeight) * 0xFFFF & 0xFFFF;
112
+ const vMaxRaw = (frame.bottom / texHeight) * 0xFFFF & 0xFFFF;
113
+ const vMin = texture.flipY ? vMaxRaw : vMinRaw;
114
+ const vMax = texture.flipY ? vMinRaw : vMaxRaw;
115
+ u32[offset + 10] = uMin | (vMin << 16);
116
+ u32[offset + 11] = uMax | (vMax << 16);
117
+ // color (u8x4 packed) at word 12
118
+ u32[offset + 12] = sprite.tint.toRgba();
119
+ // textureSlot (u32) at word 13
120
+ u32[offset + 13] = slot;
121
+ this._instanceCount++;
64
122
  return this;
65
123
  }
66
- createVao(gl, indexBuffer, vertexBuffer) {
67
- return new WebGl2VertexArrayObject()
68
- .addIndex(indexBuffer)
69
- .addAttribute(vertexBuffer, this.shader.getAttribute('a_position'), gl.FLOAT, false, this.attributeCount, 0)
70
- .addAttribute(vertexBuffer, this.shader.getAttribute('a_texcoord'), gl.UNSIGNED_SHORT, true, this.attributeCount, 8)
71
- .addAttribute(vertexBuffer, this.shader.getAttribute('a_color'), gl.UNSIGNED_BYTE, true, this.attributeCount, 12);
124
+ flush() {
125
+ const backend = this.getBackendOrNull();
126
+ const instanceBuffer = this._instanceBuffer;
127
+ const vao = this._vao;
128
+ if (this._instanceCount === 0 || backend === null || instanceBuffer === null || vao === null) {
129
+ this._resetSlots();
130
+ return;
131
+ }
132
+ const view = backend.view;
133
+ if (this._currentView !== view || this._currentViewId !== view.updateId) {
134
+ this._currentView = view;
135
+ this._currentViewId = view.updateId;
136
+ this._shader
137
+ .getUniform('u_projection')
138
+ .setValue(view.getTransform().toArray(false));
139
+ }
140
+ this._shader.sync();
141
+ backend.bindVertexArrayObject(vao);
142
+ instanceBuffer.upload(this._instanceFloat32.subarray(0, this._instanceCount * wordsPerInstance));
143
+ vao.drawInstanced(4, 0, this._instanceCount, RenderingPrimitives.TriangleStrip);
144
+ backend.stats.batches++;
145
+ backend.stats.drawCalls++;
146
+ this._instanceCount = 0;
147
+ this._resetSlots();
148
+ }
149
+ onConnect(backend) {
150
+ const gl = backend.context;
151
+ this._shader.connect(createWebGl2ShaderProgram(gl));
152
+ this._connection = this._createConnection(gl);
153
+ this._instanceBuffer = new WebGl2RenderBuffer(BufferTypes.ArrayBuffer, this._instanceData, BufferUsage.DynamicDraw)
154
+ .connect(this._createBufferRuntime(this._connection));
155
+ this._shader.sync();
156
+ this._vao = new WebGl2VertexArrayObject(RenderingPrimitives.TriangleStrip)
157
+ .addAttribute(this._instanceBuffer, this._shader.getAttribute('a_localBounds'), gl.FLOAT, false, instanceStrideBytes, 0, false, 1)
158
+ .addAttribute(this._instanceBuffer, this._shader.getAttribute('a_transformAB'), gl.FLOAT, false, instanceStrideBytes, 16, false, 1)
159
+ .addAttribute(this._instanceBuffer, this._shader.getAttribute('a_transformCD'), gl.FLOAT, false, instanceStrideBytes, 28, false, 1)
160
+ .addAttribute(this._instanceBuffer, this._shader.getAttribute('a_uvBounds'), gl.UNSIGNED_SHORT, true, instanceStrideBytes, 40, false, 1)
161
+ .addAttribute(this._instanceBuffer, this._shader.getAttribute('a_color'), gl.UNSIGNED_BYTE, true, instanceStrideBytes, 48, false, 1)
162
+ .addAttribute(this._instanceBuffer, this._shader.getAttribute('a_textureSlot'), gl.UNSIGNED_INT, false, instanceStrideBytes, 52, true, 1)
163
+ .connect(this._createVaoRuntime(this._connection));
164
+ // Pin the per-slot sampler uniforms to texture units 0..N-1.
165
+ const samplerUnit = new Int32Array(1);
166
+ for (let i = 0; i < maxBatchTextures; i++) {
167
+ samplerUnit[0] = i;
168
+ this._shader.getUniform(`u_texture${i}`).setValue(samplerUnit);
169
+ }
170
+ }
171
+ onDisconnect() {
172
+ this._shader.disconnect();
173
+ this._instanceBuffer?.destroy();
174
+ this._instanceBuffer = null;
175
+ this._vao?.destroy();
176
+ this._vao = null;
177
+ this._connection = null;
178
+ this._currentBlendMode = null;
179
+ this._currentView = null;
180
+ this._currentViewId = -1;
181
+ this._instanceCount = 0;
72
182
  }
73
- updateView(view) {
74
- this.shader
75
- .getUniform('u_projection')
76
- .setValue(view.getTransform().toArray(false));
77
- return this;
183
+ destroy() {
184
+ this.disconnect();
185
+ this._shader.destroy();
186
+ }
187
+ _resetSlots() {
188
+ if (this._slotCount > 0) {
189
+ for (let i = 0; i < this._slotCount; i++) {
190
+ this._activeTextures[i] = null;
191
+ }
192
+ this._textureSlots.clear();
193
+ this._slotCount = 0;
194
+ }
195
+ }
196
+ _createConnection(gl) {
197
+ const vaoHandle = gl.createVertexArray();
198
+ if (vaoHandle === null) {
199
+ throw new Error('WebGl2SpriteRenderer: could not create vertex array object.');
200
+ }
201
+ return {
202
+ gl,
203
+ buffers: new Map(),
204
+ vaoHandle,
205
+ };
206
+ }
207
+ _createBufferRuntime(connection) {
208
+ const handle = connection.gl.createBuffer();
209
+ if (handle === null) {
210
+ throw new Error('WebGl2SpriteRenderer: could not create render buffer.');
211
+ }
212
+ return {
213
+ bind: (buffer) => {
214
+ connection.gl.bindBuffer(buffer.type, handle);
215
+ },
216
+ upload: (buffer, offset) => {
217
+ const gl = connection.gl;
218
+ const data = buffer.data;
219
+ const state = connection.buffers.get(buffer);
220
+ gl.bindBuffer(buffer.type, handle);
221
+ if (state && state.dataByteLength >= data.byteLength) {
222
+ gl.bufferSubData(buffer.type, offset, data);
223
+ state.dataByteLength = data.byteLength;
224
+ }
225
+ else {
226
+ gl.bufferData(buffer.type, data, buffer.usage);
227
+ connection.buffers.set(buffer, { handle, dataByteLength: data.byteLength });
228
+ }
229
+ },
230
+ destroy: (buffer) => {
231
+ connection.gl.deleteBuffer(handle);
232
+ connection.buffers.delete(buffer);
233
+ buffer.disconnect();
234
+ },
235
+ };
236
+ }
237
+ _createVaoRuntime(connection) {
238
+ let appliedVersion = -1;
239
+ return {
240
+ bind: (vao) => {
241
+ const gl = connection.gl;
242
+ gl.bindVertexArray(connection.vaoHandle);
243
+ if (appliedVersion !== vao.version) {
244
+ let lastBuffer = null;
245
+ for (const attribute of vao.attributes) {
246
+ if (lastBuffer !== attribute.buffer) {
247
+ attribute.buffer.bind();
248
+ lastBuffer = attribute.buffer;
249
+ }
250
+ if (attribute.integer) {
251
+ gl.vertexAttribIPointer(attribute.location, attribute.size, attribute.type, attribute.stride, attribute.start);
252
+ }
253
+ else {
254
+ gl.vertexAttribPointer(attribute.location, attribute.size, attribute.type, attribute.normalized, attribute.stride, attribute.start);
255
+ }
256
+ gl.enableVertexAttribArray(attribute.location);
257
+ gl.vertexAttribDivisor(attribute.location, attribute.divisor);
258
+ }
259
+ appliedVersion = vao.version;
260
+ }
261
+ },
262
+ unbind: () => {
263
+ connection.gl.bindVertexArray(null);
264
+ },
265
+ draw: (vao, size, start, type) => {
266
+ connection.gl.drawArrays(type, start, size);
267
+ },
268
+ drawInstanced: (_vao, count, start, instanceCount, type) => {
269
+ connection.gl.drawArraysInstanced(type, start, count, instanceCount);
270
+ },
271
+ destroy: (vao) => {
272
+ connection.gl.deleteVertexArray(connection.vaoHandle);
273
+ vao.disconnect();
274
+ },
275
+ };
78
276
  }
79
277
  }
80
278
 
@@ -1 +1 @@
1
- {"version":3,"file":"WebGl2SpriteRenderer.js","sources":["../../../../../src/rendering/webgl2/WebGl2SpriteRenderer.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"WebGl2SpriteRenderer.js","sources":["../../../../../src/rendering/webgl2/WebGl2SpriteRenderer.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -9,11 +9,33 @@ interface VaoAttribute {
9
9
  readonly normalized: boolean;
10
10
  readonly stride: number;
11
11
  readonly start: number;
12
+ /**
13
+ * When true, the attribute is bound via `vertexAttribIPointer` so the
14
+ * shader receives the raw integer value (not normalised, not converted
15
+ * to float). Used for `uint`/`ivec`-typed shader inputs such as a
16
+ * batched-sprite texture-slot index.
17
+ */
18
+ readonly integer: boolean;
19
+ /**
20
+ * Vertex-attribute divisor passed to `gl.vertexAttribDivisor`. Zero
21
+ * means per-vertex (the default). One means per-instance — the
22
+ * attribute advances once per drawArraysInstanced / drawElementsInstanced
23
+ * instance instead of once per vertex.
24
+ */
25
+ readonly divisor: number;
12
26
  }
13
27
  export interface WebGl2VertexArrayObjectRuntime {
14
28
  bind(vao: WebGl2VertexArrayObject): void;
15
29
  unbind(vao: WebGl2VertexArrayObject): void;
16
30
  draw(vao: WebGl2VertexArrayObject, size: number, start: number, type: RenderingPrimitives): void;
31
+ /**
32
+ * Instanced draw — `count` vertices/indices replicated `instanceCount`
33
+ * times. Per-vertex attributes (divisor 0) are shared across instances;
34
+ * per-instance attributes (divisor 1) advance once per instance.
35
+ * Optional: runtimes that don't drive instanced rendering can omit this
36
+ * and the VAO's `drawInstanced()` then no-ops via the optional-chain.
37
+ */
38
+ drawInstanced?(vao: WebGl2VertexArrayObject, count: number, start: number, instanceCount: number, type: RenderingPrimitives): void;
17
39
  destroy(vao: WebGl2VertexArrayObject): void;
18
40
  }
19
41
  export declare class WebGl2VertexArrayObject {
@@ -31,10 +53,11 @@ export declare class WebGl2VertexArrayObject {
31
53
  disconnect(): this;
32
54
  bind(): this;
33
55
  unbind(): this;
34
- addAttribute(buffer: WebGl2RenderBuffer, attribute: ShaderAttribute, type?: number, normalized?: boolean, stride?: number, start?: number): this;
56
+ addAttribute(buffer: WebGl2RenderBuffer, attribute: ShaderAttribute, type?: number, normalized?: boolean, stride?: number, start?: number, integer?: boolean, divisor?: number): this;
35
57
  addIndex(buffer: WebGl2RenderBuffer): this;
36
58
  clear(): this;
37
59
  draw(size: number, start: number, type?: RenderingPrimitives): this;
60
+ drawInstanced(count: number, start: number, instanceCount: number, type?: RenderingPrimitives): this;
38
61
  destroy(): void;
39
62
  }
40
63
  export {};
@@ -37,9 +37,9 @@ class WebGl2VertexArrayObject {
37
37
  this._runtime?.unbind(this);
38
38
  return this;
39
39
  }
40
- addAttribute(buffer, attribute, type = ShaderPrimitives.Float, normalized = false, stride = 0, start = 0) {
40
+ addAttribute(buffer, attribute, type = ShaderPrimitives.Float, normalized = false, stride = 0, start = 0, integer = false, divisor = 0) {
41
41
  const { location, size } = attribute;
42
- this._attributes.push({ buffer, location, size, type, normalized, stride, start });
42
+ this._attributes.push({ buffer, location, size, type, normalized, stride, start, integer, divisor });
43
43
  this._version++;
44
44
  return this;
45
45
  }
@@ -58,6 +58,10 @@ class WebGl2VertexArrayObject {
58
58
  this._runtime?.draw(this, size, start, type);
59
59
  return this;
60
60
  }
61
+ drawInstanced(count, start, instanceCount, type = this._drawMode) {
62
+ this._runtime?.drawInstanced?.(this, count, start, instanceCount, type);
63
+ return this;
64
+ }
61
65
  destroy() {
62
66
  this._runtime?.destroy(this);
63
67
  this._runtime = null;