@codexo/exojs 0.12.0 → 0.13.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.
- package/CHANGELOG.md +125 -0
- package/dist/esm/core/BuildInfo.js +2 -2
- package/dist/esm/extensions/Extension.d.ts +39 -7
- package/dist/esm/extensions/Extension.d.ts.map +1 -1
- package/dist/esm/extensions/ExtensionRegistry.d.ts.map +1 -1
- package/dist/esm/extensions/ExtensionRegistry.js.map +1 -1
- package/dist/esm/extensions/snapshot.d.ts +12 -2
- package/dist/esm/extensions/snapshot.d.ts.map +1 -1
- package/dist/esm/extensions/snapshot.js +43 -14
- package/dist/esm/extensions/snapshot.js.map +1 -1
- package/dist/esm/index.js +8 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/rendering/Drawable.d.ts +23 -0
- package/dist/esm/rendering/Drawable.d.ts.map +1 -1
- package/dist/esm/rendering/Drawable.js +34 -0
- package/dist/esm/rendering/Drawable.js.map +1 -1
- package/dist/esm/rendering/coreRendererBindings.d.ts.map +1 -1
- package/dist/esm/rendering/coreRendererBindings.js +22 -0
- package/dist/esm/rendering/coreRendererBindings.js.map +1 -1
- package/dist/esm/rendering/index.d.ts +13 -0
- package/dist/esm/rendering/index.d.ts.map +1 -1
- package/dist/esm/rendering/pixelSnap.d.ts +219 -0
- package/dist/esm/rendering/pixelSnap.d.ts.map +1 -0
- package/dist/esm/rendering/pixelSnap.js +186 -0
- package/dist/esm/rendering/pixelSnap.js.map +1 -0
- package/dist/esm/rendering/plan/RenderPlanPlayer.d.ts.map +1 -1
- package/dist/esm/rendering/plan/RenderPlanPlayer.js +21 -1
- package/dist/esm/rendering/plan/RenderPlanPlayer.js.map +1 -1
- package/dist/esm/rendering/sprite/NineSliceSprite.d.ts +69 -0
- package/dist/esm/rendering/sprite/NineSliceSprite.d.ts.map +1 -0
- package/dist/esm/rendering/sprite/NineSliceSprite.js +207 -0
- package/dist/esm/rendering/sprite/NineSliceSprite.js.map +1 -0
- package/dist/esm/rendering/sprite/RepeatingSprite.d.ts +120 -0
- package/dist/esm/rendering/sprite/RepeatingSprite.d.ts.map +1 -0
- package/dist/esm/rendering/sprite/RepeatingSprite.js +279 -0
- package/dist/esm/rendering/sprite/RepeatingSprite.js.map +1 -0
- package/dist/esm/rendering/sprite/Sprite.d.ts +13 -0
- package/dist/esm/rendering/sprite/Sprite.d.ts.map +1 -1
- package/dist/esm/rendering/sprite/Sprite.js +23 -0
- package/dist/esm/rendering/sprite/Sprite.js.map +1 -1
- package/dist/esm/rendering/sprite/nineSlice.d.ts +53 -0
- package/dist/esm/rendering/sprite/nineSlice.d.ts.map +1 -0
- package/dist/esm/rendering/sprite/nineSlice.js +340 -0
- package/dist/esm/rendering/sprite/nineSlice.js.map +1 -0
- package/dist/esm/rendering/sprite/repeatingSpritePlan.d.ts +57 -0
- package/dist/esm/rendering/sprite/repeatingSpritePlan.d.ts.map +1 -0
- package/dist/esm/rendering/sprite/repeatingSpritePlan.js +156 -0
- package/dist/esm/rendering/sprite/repeatingSpritePlan.js.map +1 -0
- package/dist/esm/rendering/texture/TextureRegion.d.ts +100 -0
- package/dist/esm/rendering/texture/TextureRegion.d.ts.map +1 -0
- package/dist/esm/rendering/texture/TextureRegion.js +144 -0
- package/dist/esm/rendering/texture/TextureRegion.js.map +1 -0
- package/dist/esm/rendering/texture/repeat.d.ts +96 -0
- package/dist/esm/rendering/texture/repeat.d.ts.map +1 -0
- package/dist/esm/rendering/texture/repeat.js +158 -0
- package/dist/esm/rendering/texture/repeat.js.map +1 -0
- package/dist/esm/rendering/webgl2/WebGl2Backend.d.ts +20 -0
- package/dist/esm/rendering/webgl2/WebGl2Backend.d.ts.map +1 -1
- package/dist/esm/rendering/webgl2/WebGl2Backend.js +31 -2
- package/dist/esm/rendering/webgl2/WebGl2Backend.js.map +1 -1
- package/dist/esm/rendering/webgl2/WebGl2NineSliceSpriteRenderer.d.ts +32 -0
- package/dist/esm/rendering/webgl2/WebGl2NineSliceSpriteRenderer.d.ts.map +1 -0
- package/dist/esm/rendering/webgl2/WebGl2NineSliceSpriteRenderer.js +308 -0
- package/dist/esm/rendering/webgl2/WebGl2NineSliceSpriteRenderer.js.map +1 -0
- package/dist/esm/rendering/webgl2/WebGl2RepeatingSpriteRenderer.d.ts +49 -0
- package/dist/esm/rendering/webgl2/WebGl2RepeatingSpriteRenderer.d.ts.map +1 -0
- package/dist/esm/rendering/webgl2/WebGl2RepeatingSpriteRenderer.js +535 -0
- package/dist/esm/rendering/webgl2/WebGl2RepeatingSpriteRenderer.js.map +1 -0
- package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.d.ts +9 -0
- package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.d.ts.map +1 -1
- package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.js +22 -2
- package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.js.map +1 -1
- package/dist/esm/rendering/webgpu/WebGpuBackend.d.ts +21 -1
- package/dist/esm/rendering/webgpu/WebGpuBackend.d.ts.map +1 -1
- package/dist/esm/rendering/webgpu/WebGpuBackend.js +29 -2
- package/dist/esm/rendering/webgpu/WebGpuBackend.js.map +1 -1
- package/dist/esm/rendering/webgpu/WebGpuNineSliceSpriteRenderer.d.ts +36 -0
- package/dist/esm/rendering/webgpu/WebGpuNineSliceSpriteRenderer.d.ts.map +1 -0
- package/dist/esm/rendering/webgpu/WebGpuNineSliceSpriteRenderer.js +358 -0
- package/dist/esm/rendering/webgpu/WebGpuNineSliceSpriteRenderer.js.map +1 -0
- package/dist/esm/rendering/webgpu/WebGpuRepeatingSpriteRenderer.d.ts +52 -0
- package/dist/esm/rendering/webgpu/WebGpuRepeatingSpriteRenderer.d.ts.map +1 -0
- package/dist/esm/rendering/webgpu/WebGpuRepeatingSpriteRenderer.js +556 -0
- package/dist/esm/rendering/webgpu/WebGpuRepeatingSpriteRenderer.js.map +1 -0
- package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.d.ts +9 -0
- package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.d.ts.map +1 -1
- package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.js +22 -2
- package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.js.map +1 -1
- package/dist/esm/rendering/webgpu/WebGpuTransformStorage.d.ts +3 -2
- package/dist/esm/rendering/webgpu/WebGpuTransformStorage.d.ts.map +1 -1
- package/dist/esm/rendering/webgpu/WebGpuTransformStorage.js +4 -4
- package/dist/esm/rendering/webgpu/WebGpuTransformStorage.js.map +1 -1
- package/dist/esm/rendering.d.ts +1 -0
- package/dist/esm/rendering.d.ts.map +1 -1
- package/dist/esm/resources/Loader.d.ts +36 -8
- package/dist/esm/resources/Loader.d.ts.map +1 -1
- package/dist/esm/resources/Loader.js +30 -11
- package/dist/esm/resources/Loader.js.map +1 -1
- package/dist/exo.esm.js +3449 -59
- package/dist/exo.esm.js.map +1 -1
- package/package.json +10 -3
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
import { Rectangle } from '../../math/Rectangle.js';
|
|
2
|
+
import { Shader } from '../shader/Shader.js';
|
|
3
|
+
import { computeShaderTiling } from '../sprite/repeatingSpritePlan.js';
|
|
4
|
+
import { Texture } from '../texture/Texture.js';
|
|
5
|
+
import { ScaleModes, RenderingPrimitives, BufferTypes, BufferUsage, WrapModes } from '../types.js';
|
|
6
|
+
import { AbstractWebGl2Renderer } from './AbstractWebGl2Renderer.js';
|
|
7
|
+
import { WebGl2RenderBuffer } from './WebGl2RenderBuffer.js';
|
|
8
|
+
import { createWebGl2ShaderProgram } from './WebGl2ShaderProgram.js';
|
|
9
|
+
import { WebGl2VertexArrayObject } from './WebGl2VertexArrayObject.js';
|
|
10
|
+
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Shader path: one quad per sprite, UVs computed in vertex shader.
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
const shaderPathVertSource = `#version 300 es
|
|
15
|
+
precision mediump float;
|
|
16
|
+
precision highp int;
|
|
17
|
+
|
|
18
|
+
layout(location = 0) in vec4 a_quadBounds; // x0,y0,x1,y1 (local space)
|
|
19
|
+
layout(location = 1) in vec4 a_uvParams; // tilingX, tilingY, offsetU, offsetV
|
|
20
|
+
layout(location = 2) in vec4 a_color; // RGBA tint (normalised)
|
|
21
|
+
layout(location = 3) in uint a_nodeIndex; // transform row
|
|
22
|
+
|
|
23
|
+
uniform mat3 u_projection;
|
|
24
|
+
uniform sampler2D u_transforms;
|
|
25
|
+
|
|
26
|
+
out vec2 v_texcoord;
|
|
27
|
+
out vec4 v_color;
|
|
28
|
+
|
|
29
|
+
void main(void) {
|
|
30
|
+
int vid = gl_VertexID;
|
|
31
|
+
int cx = vid & 1;
|
|
32
|
+
int cy = (vid >> 1) & 1;
|
|
33
|
+
|
|
34
|
+
float lx = (cx == 0) ? a_quadBounds.x : a_quadBounds.z;
|
|
35
|
+
float ly = (cy == 0) ? a_quadBounds.y : a_quadBounds.w;
|
|
36
|
+
|
|
37
|
+
float destW = a_quadBounds.z - a_quadBounds.x;
|
|
38
|
+
float destH = a_quadBounds.w - a_quadBounds.y;
|
|
39
|
+
|
|
40
|
+
int row = int(a_nodeIndex);
|
|
41
|
+
vec4 m0 = texelFetch(u_transforms, ivec2(0, row), 0);
|
|
42
|
+
vec4 m1 = texelFetch(u_transforms, ivec2(1, row), 0);
|
|
43
|
+
|
|
44
|
+
float wx = m0.x * lx + m0.y * ly + m1.x;
|
|
45
|
+
float wy = m0.z * lx + m0.w * ly + m1.y;
|
|
46
|
+
gl_Position = vec4((u_projection * vec3(wx, wy, 1.0)).xy, 0.0, 1.0);
|
|
47
|
+
|
|
48
|
+
float u = (destW > 0.0)
|
|
49
|
+
? ((lx - a_quadBounds.x) / destW) * a_uvParams.x + a_uvParams.z
|
|
50
|
+
: a_uvParams.z;
|
|
51
|
+
float v = (destH > 0.0)
|
|
52
|
+
? ((ly - a_quadBounds.y) / destH) * a_uvParams.y + a_uvParams.w
|
|
53
|
+
: a_uvParams.w;
|
|
54
|
+
v_texcoord = vec2(u, v);
|
|
55
|
+
|
|
56
|
+
v_color = vec4(a_color.rgb * a_color.a, a_color.a);
|
|
57
|
+
}`;
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// Geometry path: N quads per sprite, UVs pre-computed in CPU (like NineSlice).
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
const geoPathVertSource = `#version 300 es
|
|
62
|
+
precision lowp float;
|
|
63
|
+
precision highp int;
|
|
64
|
+
|
|
65
|
+
layout(location = 0) in vec4 a_quadBounds; // x0,y0,x1,y1 (local space)
|
|
66
|
+
layout(location = 1) in vec4 a_uvBounds; // u0,v0,u1,v1 (normalised, flipY pre-applied)
|
|
67
|
+
layout(location = 2) in vec4 a_color; // RGBA tint
|
|
68
|
+
layout(location = 3) in uint a_nodeIndex; // transform row
|
|
69
|
+
|
|
70
|
+
uniform mat3 u_projection;
|
|
71
|
+
uniform sampler2D u_transforms;
|
|
72
|
+
|
|
73
|
+
out vec2 v_texcoord;
|
|
74
|
+
out vec4 v_color;
|
|
75
|
+
|
|
76
|
+
void main(void) {
|
|
77
|
+
int vid = gl_VertexID;
|
|
78
|
+
int cx = vid & 1;
|
|
79
|
+
int cy = (vid >> 1) & 1;
|
|
80
|
+
|
|
81
|
+
float lx = (cx == 0) ? a_quadBounds.x : a_quadBounds.z;
|
|
82
|
+
float ly = (cy == 0) ? a_quadBounds.y : a_quadBounds.w;
|
|
83
|
+
|
|
84
|
+
int row = int(a_nodeIndex);
|
|
85
|
+
vec4 m0 = texelFetch(u_transforms, ivec2(0, row), 0);
|
|
86
|
+
vec4 m1 = texelFetch(u_transforms, ivec2(1, row), 0);
|
|
87
|
+
|
|
88
|
+
float wx = m0.x * lx + m0.y * ly + m1.x;
|
|
89
|
+
float wy = m0.z * lx + m0.w * ly + m1.y;
|
|
90
|
+
gl_Position = vec4((u_projection * vec3(wx, wy, 1.0)).xy, 0.0, 1.0);
|
|
91
|
+
|
|
92
|
+
float u = (cx == 0) ? a_uvBounds.x : a_uvBounds.z;
|
|
93
|
+
float v = (cy == 0) ? a_uvBounds.y : a_uvBounds.w;
|
|
94
|
+
v_texcoord = vec2(u, v);
|
|
95
|
+
|
|
96
|
+
v_color = vec4(a_color.rgb * a_color.a, a_color.a);
|
|
97
|
+
}`;
|
|
98
|
+
const sharedFragSource = `#version 300 es
|
|
99
|
+
precision lowp float;
|
|
100
|
+
|
|
101
|
+
uniform sampler2D u_texture;
|
|
102
|
+
|
|
103
|
+
in vec2 v_texcoord;
|
|
104
|
+
in vec4 v_color;
|
|
105
|
+
|
|
106
|
+
layout(location = 0) out vec4 fragColor;
|
|
107
|
+
|
|
108
|
+
void main(void) {
|
|
109
|
+
fragColor = texture(u_texture, v_texcoord) * v_color;
|
|
110
|
+
}`;
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
// Layout constants
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
const shaderStrideBytes = 40; // 10 × float32
|
|
115
|
+
const shaderWordsPerInstance = shaderStrideBytes / Uint32Array.BYTES_PER_ELEMENT;
|
|
116
|
+
const geoStrideBytes = 32; // 8 × uint32 (matches NineSlice layout)
|
|
117
|
+
const geoWordsPerInstance = geoStrideBytes / Uint32Array.BYTES_PER_ELEMENT;
|
|
118
|
+
const transformTextureUnit = 1;
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
// Sampler cache helper
|
|
121
|
+
// ---------------------------------------------------------------------------
|
|
122
|
+
function repeatModeToWrap(mode) {
|
|
123
|
+
if (mode === 'repeat')
|
|
124
|
+
return WrapModes.Repeat;
|
|
125
|
+
if (mode === 'mirror-repeat')
|
|
126
|
+
return WrapModes.MirroredRepeat;
|
|
127
|
+
return WrapModes.ClampToEdge;
|
|
128
|
+
}
|
|
129
|
+
/** Instanced renderer for {@link RepeatingSprite} using WebGL2. Handles both shader and geometry paths internally. */
|
|
130
|
+
class WebGl2RepeatingSpriteRenderer extends AbstractWebGl2Renderer {
|
|
131
|
+
_shaderPathShader;
|
|
132
|
+
_geoPathShader;
|
|
133
|
+
_batchSize;
|
|
134
|
+
// Shader-path buffers
|
|
135
|
+
_shaderData;
|
|
136
|
+
_shaderF32;
|
|
137
|
+
_shaderU32;
|
|
138
|
+
_shaderBuf = null;
|
|
139
|
+
_shaderVao = null;
|
|
140
|
+
_shaderQuadCount = 0;
|
|
141
|
+
// Geometry-path buffers
|
|
142
|
+
_geoData;
|
|
143
|
+
_geoF32;
|
|
144
|
+
_geoU32;
|
|
145
|
+
_geoBuf = null;
|
|
146
|
+
_geoVao = null;
|
|
147
|
+
_geoQuadCount = 0;
|
|
148
|
+
// Sampler cache keyed by "wrapS:wrapT:scaleMode"
|
|
149
|
+
_samplers = new Map();
|
|
150
|
+
// Shared batch state
|
|
151
|
+
_maxNodeIndex = 0;
|
|
152
|
+
_currentTexture = null;
|
|
153
|
+
_currentBlendMode = null;
|
|
154
|
+
_currentModeX = null;
|
|
155
|
+
_currentModeY = null;
|
|
156
|
+
_currentPath = null;
|
|
157
|
+
_connection = null;
|
|
158
|
+
_transformUnitScratch = new Int32Array([transformTextureUnit]);
|
|
159
|
+
_snapBounds = new Rectangle();
|
|
160
|
+
_currentView = null;
|
|
161
|
+
_currentViewId = -1;
|
|
162
|
+
constructor(batchSize) {
|
|
163
|
+
super();
|
|
164
|
+
this._batchSize = batchSize;
|
|
165
|
+
this._shaderPathShader = new Shader(shaderPathVertSource, sharedFragSource);
|
|
166
|
+
this._geoPathShader = new Shader(geoPathVertSource, sharedFragSource);
|
|
167
|
+
this._shaderData = new ArrayBuffer(batchSize * shaderStrideBytes);
|
|
168
|
+
this._shaderF32 = new Float32Array(this._shaderData);
|
|
169
|
+
this._shaderU32 = new Uint32Array(this._shaderData);
|
|
170
|
+
this._geoData = new ArrayBuffer(batchSize * geoStrideBytes);
|
|
171
|
+
this._geoF32 = new Float32Array(this._geoData);
|
|
172
|
+
this._geoU32 = new Uint32Array(this._geoData);
|
|
173
|
+
}
|
|
174
|
+
render(sprite) {
|
|
175
|
+
const strategy = sprite.resolvedStrategy;
|
|
176
|
+
const texture = sprite.texture;
|
|
177
|
+
const blendMode = sprite.blendMode;
|
|
178
|
+
const modeX = sprite.modeX;
|
|
179
|
+
const modeY = sprite.modeY;
|
|
180
|
+
const hasData = this._shaderQuadCount > 0 || this._geoQuadCount > 0;
|
|
181
|
+
if (hasData) {
|
|
182
|
+
const pathChanged = this._currentPath !== strategy;
|
|
183
|
+
const texChanged = this._currentTexture !== texture;
|
|
184
|
+
const blendChanged = this._currentBlendMode !== blendMode;
|
|
185
|
+
const modeChanged = strategy === 'shader'
|
|
186
|
+
&& (this._currentModeX !== modeX || this._currentModeY !== modeY);
|
|
187
|
+
if (pathChanged || texChanged || blendChanged || modeChanged) {
|
|
188
|
+
this.flush();
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const backend = this.getBackend();
|
|
192
|
+
if (this._currentTexture !== texture) {
|
|
193
|
+
this._currentTexture = texture;
|
|
194
|
+
backend.bindTexture(texture, 0);
|
|
195
|
+
}
|
|
196
|
+
if (this._currentBlendMode !== blendMode) {
|
|
197
|
+
this._currentBlendMode = blendMode;
|
|
198
|
+
backend.setBlendMode(blendMode);
|
|
199
|
+
}
|
|
200
|
+
this._currentPath = strategy;
|
|
201
|
+
const command = backend.activeDrawCommand;
|
|
202
|
+
const nodeIndex = command !== null ? command.nodeIndex : backend._pushTransform(sprite);
|
|
203
|
+
if (nodeIndex > this._maxNodeIndex) {
|
|
204
|
+
this._maxNodeIndex = nodeIndex;
|
|
205
|
+
}
|
|
206
|
+
if (strategy === 'shader') {
|
|
207
|
+
this._currentModeX = modeX;
|
|
208
|
+
this._currentModeY = modeY;
|
|
209
|
+
this._writeShaderInstance(sprite, nodeIndex);
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
this._writeGeoQuads(sprite, nodeIndex);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
_writeShaderInstance(sprite, nodeIndex) {
|
|
216
|
+
const texture = sprite.texture;
|
|
217
|
+
const srcW = sprite.region.width;
|
|
218
|
+
const srcH = sprite.region.height;
|
|
219
|
+
let destW = sprite.width;
|
|
220
|
+
let destH = sprite.height;
|
|
221
|
+
const flipY = texture instanceof Texture && texture.flipY;
|
|
222
|
+
// 'geometry' mode: snap the destination quad to the device grid. Repetition
|
|
223
|
+
// stays shader-based; only the outer rectangle (and the tiling derived from
|
|
224
|
+
// it) moves. Position/none leave the destination unchanged.
|
|
225
|
+
if (sprite.pixelSnapMode === 'geometry') {
|
|
226
|
+
const backend = this.getBackend();
|
|
227
|
+
const snap = backend._getSnapPixelSize();
|
|
228
|
+
const rb = sprite.getRenderBounds(backend.view, snap.width, snap.height, this._snapBounds);
|
|
229
|
+
destW = rb.width;
|
|
230
|
+
destH = rb.height;
|
|
231
|
+
}
|
|
232
|
+
const tilingX = computeShaderTiling(srcW, destW, sprite.modeX, sprite.fitX);
|
|
233
|
+
const tilingY = computeShaderTiling(srcH, destH, sprite.modeY, sprite.fitY);
|
|
234
|
+
const offsetU = sprite.offsetX / (srcW > 0 ? srcW : 1);
|
|
235
|
+
const offsetV = sprite.offsetY / (srcH > 0 ? srcH : 1);
|
|
236
|
+
// When flipY, negate tilingY and start from tilingY so V runs top→bottom.
|
|
237
|
+
const uvParamY = flipY ? -tilingY : tilingY;
|
|
238
|
+
const uvParamW = flipY ? tilingY + offsetV : offsetV;
|
|
239
|
+
if (this._shaderQuadCount >= this._batchSize) {
|
|
240
|
+
this.flush();
|
|
241
|
+
}
|
|
242
|
+
const idx = this._shaderQuadCount * shaderWordsPerInstance;
|
|
243
|
+
const f32 = this._shaderF32;
|
|
244
|
+
const u32 = this._shaderU32;
|
|
245
|
+
f32[idx + 0] = 0;
|
|
246
|
+
f32[idx + 1] = 0;
|
|
247
|
+
f32[idx + 2] = destW;
|
|
248
|
+
f32[idx + 3] = destH;
|
|
249
|
+
f32[idx + 4] = tilingX;
|
|
250
|
+
f32[idx + 5] = uvParamY;
|
|
251
|
+
f32[idx + 6] = offsetU;
|
|
252
|
+
f32[idx + 7] = uvParamW;
|
|
253
|
+
u32[idx + 8] = sprite.tint.toRgba();
|
|
254
|
+
u32[idx + 9] = nodeIndex >>> 0;
|
|
255
|
+
this._shaderQuadCount++;
|
|
256
|
+
}
|
|
257
|
+
_writeGeoQuads(sprite, nodeIndex) {
|
|
258
|
+
let quads = sprite.quads;
|
|
259
|
+
// 'geometry' mode: snap shared segment boundaries once (gap-free), like NineSlice.
|
|
260
|
+
if (sprite.pixelSnapMode === 'geometry') {
|
|
261
|
+
const backend = this.getBackend();
|
|
262
|
+
const snap = backend._getSnapPixelSize();
|
|
263
|
+
quads = sprite.getRenderQuads(backend.view, snap.width, snap.height);
|
|
264
|
+
}
|
|
265
|
+
const flipY = (sprite.texture instanceof Texture) && sprite.texture.flipY;
|
|
266
|
+
const tint = sprite.tint.toRgba();
|
|
267
|
+
let offset = 0;
|
|
268
|
+
while (offset < quads.length) {
|
|
269
|
+
const remaining = quads.length - offset;
|
|
270
|
+
const chunk = Math.min(remaining, this._batchSize - this._geoQuadCount);
|
|
271
|
+
if (chunk <= 0) {
|
|
272
|
+
this.flush();
|
|
273
|
+
// Re-establish texture/blend after flush
|
|
274
|
+
const backend = this.getBackend();
|
|
275
|
+
backend.bindTexture(sprite.texture, 0);
|
|
276
|
+
backend.setBlendMode(sprite.blendMode);
|
|
277
|
+
this._currentTexture = sprite.texture;
|
|
278
|
+
this._currentBlendMode = sprite.blendMode;
|
|
279
|
+
this._currentPath = 'geometry';
|
|
280
|
+
if (nodeIndex > this._maxNodeIndex) {
|
|
281
|
+
this._maxNodeIndex = nodeIndex;
|
|
282
|
+
}
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
const f32 = this._geoF32;
|
|
286
|
+
const u32 = this._geoU32;
|
|
287
|
+
for (let i = 0; i < chunk; i++) {
|
|
288
|
+
const q = quads[offset + i];
|
|
289
|
+
const idx = (this._geoQuadCount + i) * geoWordsPerInstance;
|
|
290
|
+
f32[idx + 0] = q.x0;
|
|
291
|
+
f32[idx + 1] = q.y0;
|
|
292
|
+
f32[idx + 2] = q.x1;
|
|
293
|
+
f32[idx + 3] = q.y1;
|
|
294
|
+
const uMin = (q.u0 * 0xffff) & 0xffff;
|
|
295
|
+
const uMax = (q.u1 * 0xffff) & 0xffff;
|
|
296
|
+
const v0Raw = (q.v0 * 0xffff) & 0xffff;
|
|
297
|
+
const v1Raw = (q.v1 * 0xffff) & 0xffff;
|
|
298
|
+
const vMin = flipY ? v1Raw : v0Raw;
|
|
299
|
+
const vMax = flipY ? v0Raw : v1Raw;
|
|
300
|
+
u32[idx + 4] = uMin | (vMin << 16);
|
|
301
|
+
u32[idx + 5] = uMax | (vMax << 16);
|
|
302
|
+
u32[idx + 6] = tint;
|
|
303
|
+
u32[idx + 7] = nodeIndex >>> 0;
|
|
304
|
+
}
|
|
305
|
+
this._geoQuadCount += chunk;
|
|
306
|
+
offset += chunk;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
flush() {
|
|
310
|
+
const backend = this.getBackendOrNull();
|
|
311
|
+
if (backend === null) {
|
|
312
|
+
this._resetBatchState();
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
const view = backend.view;
|
|
316
|
+
if (this._currentView !== view || this._currentViewId !== view.updateId) {
|
|
317
|
+
this._currentView = view;
|
|
318
|
+
this._currentViewId = view.updateId;
|
|
319
|
+
const proj = view.getTransform().toArray(false);
|
|
320
|
+
this._shaderPathShader.getUniform('u_projection').setValue(proj);
|
|
321
|
+
this._geoPathShader.getUniform('u_projection').setValue(proj);
|
|
322
|
+
}
|
|
323
|
+
if (this._shaderQuadCount > 0) {
|
|
324
|
+
this._flushShaderBatch(backend);
|
|
325
|
+
}
|
|
326
|
+
if (this._geoQuadCount > 0) {
|
|
327
|
+
this._flushGeoBatch(backend);
|
|
328
|
+
}
|
|
329
|
+
this._resetBatchState();
|
|
330
|
+
}
|
|
331
|
+
_flushShaderBatch(backend) {
|
|
332
|
+
const conn = this._connection;
|
|
333
|
+
const buf = this._shaderBuf;
|
|
334
|
+
const vao = this._shaderVao;
|
|
335
|
+
if (!conn || !buf || !vao || this._shaderQuadCount === 0)
|
|
336
|
+
return;
|
|
337
|
+
const gl = conn.gl;
|
|
338
|
+
const texture = this._currentTexture;
|
|
339
|
+
const scaleMode = (texture instanceof Texture) ? texture.scaleMode : ScaleModes.Linear;
|
|
340
|
+
const wrapS = repeatModeToWrap(this._currentModeX ?? 'repeat');
|
|
341
|
+
const wrapT = repeatModeToWrap(this._currentModeY ?? 'repeat');
|
|
342
|
+
// Bind repeat sampler (overrides texture's own wrap params for this unit).
|
|
343
|
+
const samplerHandle = this._getOrCreateSampler(gl, wrapS, wrapT, scaleMode);
|
|
344
|
+
gl.bindSampler(0, samplerHandle);
|
|
345
|
+
backend.bindTransformBufferTexture(transformTextureUnit, this._maxNodeIndex + 1);
|
|
346
|
+
this._shaderPathShader.getUniform('u_texture').setValue(new Int32Array([0]));
|
|
347
|
+
this._shaderPathShader.getUniform('u_transforms').setValue(this._transformUnitScratch);
|
|
348
|
+
this._shaderPathShader.sync();
|
|
349
|
+
backend.bindVertexArrayObject(vao);
|
|
350
|
+
buf.upload(this._shaderF32.subarray(0, this._shaderQuadCount * shaderWordsPerInstance));
|
|
351
|
+
vao.drawInstanced(4, 0, this._shaderQuadCount, RenderingPrimitives.TriangleStrip);
|
|
352
|
+
backend.stats.batches++;
|
|
353
|
+
backend.stats.drawCalls++;
|
|
354
|
+
// Unbind sampler so subsequent draws use the texture's own wrap params.
|
|
355
|
+
gl.bindSampler(0, null);
|
|
356
|
+
this._shaderQuadCount = 0;
|
|
357
|
+
}
|
|
358
|
+
_flushGeoBatch(backend) {
|
|
359
|
+
const conn = this._connection;
|
|
360
|
+
const buf = this._geoBuf;
|
|
361
|
+
const vao = this._geoVao;
|
|
362
|
+
if (!conn || !buf || !vao || this._geoQuadCount === 0)
|
|
363
|
+
return;
|
|
364
|
+
backend.bindTransformBufferTexture(transformTextureUnit, this._maxNodeIndex + 1);
|
|
365
|
+
this._geoPathShader.getUniform('u_texture').setValue(new Int32Array([0]));
|
|
366
|
+
this._geoPathShader.getUniform('u_transforms').setValue(this._transformUnitScratch);
|
|
367
|
+
this._geoPathShader.sync();
|
|
368
|
+
backend.bindVertexArrayObject(vao);
|
|
369
|
+
buf.upload(this._geoF32.subarray(0, this._geoQuadCount * geoWordsPerInstance));
|
|
370
|
+
vao.drawInstanced(4, 0, this._geoQuadCount, RenderingPrimitives.TriangleStrip);
|
|
371
|
+
backend.stats.batches++;
|
|
372
|
+
backend.stats.drawCalls++;
|
|
373
|
+
this._geoQuadCount = 0;
|
|
374
|
+
}
|
|
375
|
+
_resetBatchState() {
|
|
376
|
+
this._shaderQuadCount = 0;
|
|
377
|
+
this._geoQuadCount = 0;
|
|
378
|
+
this._maxNodeIndex = 0;
|
|
379
|
+
this._currentTexture = null;
|
|
380
|
+
this._currentBlendMode = null;
|
|
381
|
+
this._currentModeX = null;
|
|
382
|
+
this._currentModeY = null;
|
|
383
|
+
this._currentPath = null;
|
|
384
|
+
}
|
|
385
|
+
_getOrCreateSampler(gl, wrapS, wrapT, scaleMode) {
|
|
386
|
+
const key = `${wrapS}:${wrapT}:${scaleMode}`;
|
|
387
|
+
const existing = this._samplers.get(key);
|
|
388
|
+
if (existing !== undefined)
|
|
389
|
+
return existing;
|
|
390
|
+
const sampler = gl.createSampler();
|
|
391
|
+
if (sampler === null)
|
|
392
|
+
throw new Error('WebGl2RepeatingSpriteRenderer: could not create sampler.');
|
|
393
|
+
gl.samplerParameteri(sampler, gl.TEXTURE_WRAP_S, wrapS);
|
|
394
|
+
gl.samplerParameteri(sampler, gl.TEXTURE_WRAP_T, wrapT);
|
|
395
|
+
gl.samplerParameteri(sampler, gl.TEXTURE_MAG_FILTER, scaleMode);
|
|
396
|
+
gl.samplerParameteri(sampler, gl.TEXTURE_MIN_FILTER, scaleMode);
|
|
397
|
+
this._samplers.set(key, sampler);
|
|
398
|
+
return sampler;
|
|
399
|
+
}
|
|
400
|
+
onConnect(backend) {
|
|
401
|
+
const gl = backend.context;
|
|
402
|
+
this._shaderPathShader.connect(createWebGl2ShaderProgram(gl));
|
|
403
|
+
this._geoPathShader.connect(createWebGl2ShaderProgram(gl));
|
|
404
|
+
// sync() triggers finalize() which compiles the shaders and populates the
|
|
405
|
+
// attributes/uniforms maps — must happen before any getAttribute() call.
|
|
406
|
+
this._shaderPathShader.sync();
|
|
407
|
+
this._geoPathShader.sync();
|
|
408
|
+
const conn = this._createConnection(gl);
|
|
409
|
+
this._connection = conn;
|
|
410
|
+
// Shader-path VAO (uses float4 uvParams, not packed unorm16)
|
|
411
|
+
this._shaderBuf = new WebGl2RenderBuffer(BufferTypes.ArrayBuffer, this._shaderData, BufferUsage.DynamicDraw)
|
|
412
|
+
.connect(this._createBufRuntime(conn, 'shader'));
|
|
413
|
+
this._shaderVao = new WebGl2VertexArrayObject(RenderingPrimitives.TriangleStrip)
|
|
414
|
+
.addAttribute(this._shaderBuf, this._shaderPathShader.getAttribute('a_quadBounds'), gl.FLOAT, false, shaderStrideBytes, 0, false, 1)
|
|
415
|
+
.addAttribute(this._shaderBuf, this._shaderPathShader.getAttribute('a_uvParams'), gl.FLOAT, false, shaderStrideBytes, 16, false, 1)
|
|
416
|
+
.addAttribute(this._shaderBuf, this._shaderPathShader.getAttribute('a_color'), gl.UNSIGNED_BYTE, true, shaderStrideBytes, 32, false, 1)
|
|
417
|
+
.addAttribute(this._shaderBuf, this._shaderPathShader.getAttribute('a_nodeIndex'), gl.UNSIGNED_INT, false, shaderStrideBytes, 36, true, 1)
|
|
418
|
+
.connect(this._createVaoRuntime(conn, 'shader'));
|
|
419
|
+
// Geometry-path VAO (packed unorm16 UVs, same layout as NineSlice)
|
|
420
|
+
this._geoBuf = new WebGl2RenderBuffer(BufferTypes.ArrayBuffer, this._geoData, BufferUsage.DynamicDraw)
|
|
421
|
+
.connect(this._createBufRuntime(conn, 'geo'));
|
|
422
|
+
this._geoVao = new WebGl2VertexArrayObject(RenderingPrimitives.TriangleStrip)
|
|
423
|
+
.addAttribute(this._geoBuf, this._geoPathShader.getAttribute('a_quadBounds'), gl.FLOAT, false, geoStrideBytes, 0, false, 1)
|
|
424
|
+
.addAttribute(this._geoBuf, this._geoPathShader.getAttribute('a_uvBounds'), gl.UNSIGNED_SHORT, true, geoStrideBytes, 16, false, 1)
|
|
425
|
+
.addAttribute(this._geoBuf, this._geoPathShader.getAttribute('a_color'), gl.UNSIGNED_BYTE, true, geoStrideBytes, 24, false, 1)
|
|
426
|
+
.addAttribute(this._geoBuf, this._geoPathShader.getAttribute('a_nodeIndex'), gl.UNSIGNED_INT, false, geoStrideBytes, 28, true, 1)
|
|
427
|
+
.connect(this._createVaoRuntime(conn, 'geo'));
|
|
428
|
+
}
|
|
429
|
+
onDisconnect() {
|
|
430
|
+
const gl = this._connection?.gl;
|
|
431
|
+
if (gl !== undefined) {
|
|
432
|
+
for (const sampler of this._samplers.values()) {
|
|
433
|
+
gl.deleteSampler(sampler);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
this._samplers.clear();
|
|
437
|
+
this._shaderPathShader.disconnect();
|
|
438
|
+
this._geoPathShader.disconnect();
|
|
439
|
+
this._shaderBuf?.destroy();
|
|
440
|
+
this._shaderBuf = null;
|
|
441
|
+
this._shaderVao?.destroy();
|
|
442
|
+
this._shaderVao = null;
|
|
443
|
+
this._geoBuf?.destroy();
|
|
444
|
+
this._geoBuf = null;
|
|
445
|
+
this._geoVao?.destroy();
|
|
446
|
+
this._geoVao = null;
|
|
447
|
+
this._connection = null;
|
|
448
|
+
this._currentView = null;
|
|
449
|
+
this._currentViewId = -1;
|
|
450
|
+
this._resetBatchState();
|
|
451
|
+
}
|
|
452
|
+
destroy() {
|
|
453
|
+
this.disconnect();
|
|
454
|
+
this._shaderPathShader.destroy();
|
|
455
|
+
this._geoPathShader.destroy();
|
|
456
|
+
}
|
|
457
|
+
// -----------------------------------------------------------------------
|
|
458
|
+
// Private GL helpers
|
|
459
|
+
// -----------------------------------------------------------------------
|
|
460
|
+
_createConnection(gl) {
|
|
461
|
+
const shaderVaoHandle = gl.createVertexArray();
|
|
462
|
+
const geoVaoHandle = gl.createVertexArray();
|
|
463
|
+
if (shaderVaoHandle === null || geoVaoHandle === null) {
|
|
464
|
+
throw new Error('WebGl2RepeatingSpriteRenderer: could not create vertex array object.');
|
|
465
|
+
}
|
|
466
|
+
return { gl, buffers: new Map(), shaderVaoHandle, geoVaoHandle };
|
|
467
|
+
}
|
|
468
|
+
_createBufRuntime(conn, _kind) {
|
|
469
|
+
const handle = conn.gl.createBuffer();
|
|
470
|
+
if (handle === null)
|
|
471
|
+
throw new Error('WebGl2RepeatingSpriteRenderer: could not create render buffer.');
|
|
472
|
+
return {
|
|
473
|
+
bind: (buffer) => { conn.gl.bindBuffer(buffer.type, handle); },
|
|
474
|
+
upload: (buffer, offset) => {
|
|
475
|
+
const gl = conn.gl;
|
|
476
|
+
const data = buffer.data;
|
|
477
|
+
const state = conn.buffers.get(buffer);
|
|
478
|
+
gl.bindBuffer(buffer.type, handle);
|
|
479
|
+
if (state && state.dataByteLength >= data.byteLength) {
|
|
480
|
+
gl.bufferSubData(buffer.type, offset, data);
|
|
481
|
+
state.dataByteLength = data.byteLength;
|
|
482
|
+
}
|
|
483
|
+
else {
|
|
484
|
+
gl.bufferData(buffer.type, data, buffer.usage);
|
|
485
|
+
conn.buffers.set(buffer, { handle, dataByteLength: data.byteLength });
|
|
486
|
+
}
|
|
487
|
+
},
|
|
488
|
+
destroy: (buffer) => {
|
|
489
|
+
conn.gl.deleteBuffer(handle);
|
|
490
|
+
conn.buffers.delete(buffer);
|
|
491
|
+
buffer.disconnect();
|
|
492
|
+
},
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
_createVaoRuntime(conn, kind) {
|
|
496
|
+
const vaoHandle = kind === 'shader' ? conn.shaderVaoHandle : conn.geoVaoHandle;
|
|
497
|
+
let appliedVersion = -1;
|
|
498
|
+
return {
|
|
499
|
+
bind: (vao) => {
|
|
500
|
+
const gl = conn.gl;
|
|
501
|
+
gl.bindVertexArray(vaoHandle);
|
|
502
|
+
if (appliedVersion !== vao.version) {
|
|
503
|
+
let lastBuffer = null;
|
|
504
|
+
for (const attr of vao.attributes) {
|
|
505
|
+
if (lastBuffer !== attr.buffer) {
|
|
506
|
+
attr.buffer.bind();
|
|
507
|
+
lastBuffer = attr.buffer;
|
|
508
|
+
}
|
|
509
|
+
if (attr.integer) {
|
|
510
|
+
gl.vertexAttribIPointer(attr.location, attr.size, attr.type, attr.stride, attr.start);
|
|
511
|
+
}
|
|
512
|
+
else {
|
|
513
|
+
gl.vertexAttribPointer(attr.location, attr.size, attr.type, attr.normalized, attr.stride, attr.start);
|
|
514
|
+
}
|
|
515
|
+
gl.enableVertexAttribArray(attr.location);
|
|
516
|
+
gl.vertexAttribDivisor(attr.location, attr.divisor);
|
|
517
|
+
}
|
|
518
|
+
appliedVersion = vao.version;
|
|
519
|
+
}
|
|
520
|
+
},
|
|
521
|
+
unbind: () => { conn.gl.bindVertexArray(null); },
|
|
522
|
+
draw: (_vao, size, start, type) => { conn.gl.drawArrays(type, start, size); },
|
|
523
|
+
drawInstanced: (_vao, count, start, instanceCount, type) => {
|
|
524
|
+
conn.gl.drawArraysInstanced(type, start, count, instanceCount);
|
|
525
|
+
},
|
|
526
|
+
destroy: (vao) => {
|
|
527
|
+
conn.gl.deleteVertexArray(vaoHandle);
|
|
528
|
+
vao.disconnect();
|
|
529
|
+
},
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
export { WebGl2RepeatingSpriteRenderer };
|
|
535
|
+
//# sourceMappingURL=WebGl2RepeatingSpriteRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebGl2RepeatingSpriteRenderer.js","sources":["../../../../../src/rendering/webgl2/WebGl2RepeatingSpriteRenderer.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,8 @@ export declare class WebGl2SpriteRenderer extends AbstractWebGl2Renderer<Sprite>
|
|
|
15
15
|
private readonly _transformUnitScratch;
|
|
16
16
|
private _currentMaterial;
|
|
17
17
|
private _currentBaseTexture;
|
|
18
|
+
private readonly _snapBounds;
|
|
19
|
+
private _activeBounds;
|
|
18
20
|
private _instanceCount;
|
|
19
21
|
private _maxNodeIndex;
|
|
20
22
|
private _currentBlendMode;
|
|
@@ -25,6 +27,13 @@ export declare class WebGl2SpriteRenderer extends AbstractWebGl2Renderer<Sprite>
|
|
|
25
27
|
private _connection;
|
|
26
28
|
constructor(batchSize: number);
|
|
27
29
|
render(sprite: Sprite): this;
|
|
30
|
+
/**
|
|
31
|
+
* Local bounds to upload for `sprite` this draw: device-pixel-snapped in
|
|
32
|
+
* `'geometry'` pixel-snap mode (axis-aligned only), otherwise the sprite's
|
|
33
|
+
* logical local bounds. Reuses a scratch rectangle and never mutates logical
|
|
34
|
+
* state. Consumed synchronously by {@link _packInstance}.
|
|
35
|
+
*/
|
|
36
|
+
private _resolveBounds;
|
|
28
37
|
flush(): void;
|
|
29
38
|
protected onConnect(backend: WebGl2Backend): void;
|
|
30
39
|
protected onDisconnect(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebGl2SpriteRenderer.d.ts","sourceRoot":"","sources":["../../../../src/rendering/webgl2/WebGl2SpriteRenderer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"WebGl2SpriteRenderer.d.ts","sourceRoot":"","sources":["../../../../src/rendering/webgl2/WebGl2SpriteRenderer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAOvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAwDrD,qBAAa,oBAAqB,SAAQ,sBAAsB,CAAC,MAAM,CAAC;IACtE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAc;IAC5C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAe;IAChD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAc;IAE9C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiF;IACjH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA8C;IAC5E,OAAO,CAAC,UAAU,CAAK;IAIvB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqC;IAGpE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyF;IAExH,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAsD;IAC5F,OAAO,CAAC,gBAAgB,CAA+B;IACvD,OAAO,CAAC,mBAAmB,CAAwC;IAGnE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA8B;IAC1D,OAAO,CAAC,aAAa,CAA0B;IAE/C,OAAO,CAAC,cAAc,CAAK;IAG3B,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,iBAAiB,CAA2B;IACpD,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,cAAc,CAAM;IAE5B,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,IAAI,CAAwC;IACpD,OAAO,CAAC,WAAW,CAAyC;gBAEzC,SAAS,EAAE,MAAM;IAU7B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IA4BnC;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAUf,KAAK,IAAI,IAAI;IA+DpB,SAAS,CAAC,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IA2BjD,SAAS,CAAC,YAAY,IAAI,IAAI;IAsBvB,OAAO,IAAI,IAAI;IAKtB,2EAA2E;IAC3E,OAAO,CAAC,cAAc;IAgCtB,sEAAsE;IACtE,OAAO,CAAC,aAAa;IA0BrB,OAAO,CAAC,aAAa;IA+CrB,OAAO,CAAC,wBAAwB;IAmChC,OAAO,CAAC,mBAAmB;IA8C3B,OAAO,CAAC,oBAAoB;IAY5B,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,oBAAoB;IAkC5B,OAAO,CAAC,iBAAiB;CA8C1B"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Rectangle } from '../../math/Rectangle.js';
|
|
1
2
|
import { Shader } from '../shader/Shader.js';
|
|
2
3
|
import { spriteVertexGlsl } from '../sprite/spriteMaterialSources.js';
|
|
3
4
|
import { RenderTexture } from '../texture/RenderTexture.js';
|
|
@@ -72,6 +73,10 @@ class WebGl2SpriteRenderer extends AbstractWebGl2Renderer {
|
|
|
72
73
|
_transformUnitScratch = new Int32Array([transformTextureUnit]);
|
|
73
74
|
_currentMaterial = null;
|
|
74
75
|
_currentBaseTexture = null;
|
|
76
|
+
// Reusable scratch for device-snapped local bounds ('geometry' mode), and the
|
|
77
|
+
// bounds resolved for the sprite currently being packed (snapped or logical).
|
|
78
|
+
_snapBounds = new Rectangle();
|
|
79
|
+
_activeBounds = null;
|
|
75
80
|
_instanceCount = 0;
|
|
76
81
|
// Highest transform-buffer row referenced by the pending batch; drives the
|
|
77
82
|
// minimum row count uploaded for the transform texture at flush time.
|
|
@@ -103,6 +108,7 @@ class WebGl2SpriteRenderer extends AbstractWebGl2Renderer {
|
|
|
103
108
|
// sprite's transform into the buffer and use the freshly-allocated slot.
|
|
104
109
|
const command = backend.activeDrawCommand;
|
|
105
110
|
const nodeIndex = command !== null ? command.nodeIndex : backend._pushTransform(sprite);
|
|
111
|
+
this._activeBounds = this._resolveBounds(sprite, backend);
|
|
106
112
|
if (material === null) {
|
|
107
113
|
this._renderDefault(sprite, texture, backend, nodeIndex);
|
|
108
114
|
}
|
|
@@ -111,6 +117,19 @@ class WebGl2SpriteRenderer extends AbstractWebGl2Renderer {
|
|
|
111
117
|
}
|
|
112
118
|
return this;
|
|
113
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Local bounds to upload for `sprite` this draw: device-pixel-snapped in
|
|
122
|
+
* `'geometry'` pixel-snap mode (axis-aligned only), otherwise the sprite's
|
|
123
|
+
* logical local bounds. Reuses a scratch rectangle and never mutates logical
|
|
124
|
+
* state. Consumed synchronously by {@link _packInstance}.
|
|
125
|
+
*/
|
|
126
|
+
_resolveBounds(sprite, backend) {
|
|
127
|
+
if (sprite.pixelSnapMode !== 'geometry') {
|
|
128
|
+
return sprite.getLocalBounds();
|
|
129
|
+
}
|
|
130
|
+
const snap = backend._getSnapPixelSize();
|
|
131
|
+
return sprite.getRenderBounds(backend.view, snap.width, snap.height, this._snapBounds);
|
|
132
|
+
}
|
|
114
133
|
flush() {
|
|
115
134
|
const backend = this.getBackendOrNull();
|
|
116
135
|
const instanceBuffer = this._instanceBuffer;
|
|
@@ -257,8 +276,9 @@ class WebGl2SpriteRenderer extends AbstractWebGl2Renderer {
|
|
|
257
276
|
const offset = this._instanceCount * wordsPerInstance;
|
|
258
277
|
const f32 = this._instanceFloat32;
|
|
259
278
|
const u32 = this._instanceUint32;
|
|
260
|
-
// localBounds: left, top, right, bottom (offset 0..3)
|
|
261
|
-
|
|
279
|
+
// localBounds: left, top, right, bottom (offset 0..3) — device-snapped in
|
|
280
|
+
// 'geometry' pixel-snap mode, otherwise the logical local bounds.
|
|
281
|
+
const bounds = this._activeBounds ?? sprite.getLocalBounds();
|
|
262
282
|
f32[offset + 0] = bounds.left;
|
|
263
283
|
f32[offset + 1] = bounds.top;
|
|
264
284
|
f32[offset + 2] = bounds.right;
|