q5 2.14.4 → 2.15.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.
@@ -1,268 +0,0 @@
1
- Q5.renderers.webgpu.image = ($, q) => {
2
- let vertexStack = new Float32Array(1e7),
3
- vertIndex = 0;
4
-
5
- let imageShader = Q5.device.createShaderModule({
6
- label: 'imageShader',
7
- code: `
8
- struct Uniforms {
9
- halfWidth: f32,
10
- halfHeight: f32
11
- }
12
- struct VertexParams {
13
- @location(0) pos: vec2f,
14
- @location(1) texCoord: vec2f,
15
- @location(2) tintIndex: f32,
16
- @location(3) matrixIndex: f32,
17
- @location(4) globalAlpha: f32
18
- }
19
- struct FragmentParams {
20
- @builtin(position) position: vec4f,
21
- @location(0) texCoord: vec2f,
22
- @location(1) tintIndex: f32,
23
- @location(2) globalAlpha: f32
24
- }
25
-
26
- @group(0) @binding(0) var<uniform> uniforms: Uniforms;
27
- @group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;
28
- @group(0) @binding(2) var<storage> colors : array<vec4f>;
29
-
30
- @group(1) @binding(0) var samp: sampler;
31
- @group(1) @binding(1) var texture: texture_2d<f32>;
32
-
33
- @vertex
34
- fn vertexMain(v: VertexParams) -> FragmentParams {
35
- var vert = vec4f(v.pos, 0.0, 1.0);
36
- vert = transforms[i32(v.matrixIndex)] * vert;
37
- vert.x /= uniforms.halfWidth;
38
- vert.y /= uniforms.halfHeight;
39
-
40
- var f: FragmentParams;
41
- f.position = vert;
42
- f.texCoord = v.texCoord;
43
- f.tintIndex = v.tintIndex;
44
- f.globalAlpha = v.globalAlpha;
45
- return f;
46
- }
47
-
48
- @fragment
49
- fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
50
- let texColor = textureSample(texture, samp, f.texCoord);
51
- let tintColor = colors[i32(f.tintIndex)];
52
-
53
- // Mix original and tinted colors using tint alpha as blend factor
54
- let tinted = vec4f(texColor.rgb * tintColor.rgb, texColor.a * f.globalAlpha);
55
- return mix(texColor, tinted, tintColor.a);
56
- }
57
- `
58
- });
59
-
60
- $._textureBindGroups = [];
61
-
62
- let textureLayout = Q5.device.createBindGroupLayout({
63
- label: 'textureLayout',
64
- entries: [
65
- {
66
- binding: 0,
67
- visibility: GPUShaderStage.FRAGMENT,
68
- sampler: { type: 'filtering' }
69
- },
70
- {
71
- binding: 1,
72
- visibility: GPUShaderStage.FRAGMENT,
73
- texture: { viewDimension: '2d', sampleType: 'float' }
74
- }
75
- ]
76
- });
77
-
78
- const vertexBufferLayout = {
79
- arrayStride: 28,
80
- attributes: [
81
- { shaderLocation: 0, offset: 0, format: 'float32x2' },
82
- { shaderLocation: 1, offset: 8, format: 'float32x2' },
83
- { shaderLocation: 2, offset: 16, format: 'float32' }, // tintIndex
84
- { shaderLocation: 3, offset: 20, format: 'float32' }, // matrixIndex
85
- { shaderLocation: 4, offset: 24, format: 'float32' } // globalAlpha
86
- ]
87
- };
88
-
89
- const pipelineLayout = Q5.device.createPipelineLayout({
90
- label: 'imagePipelineLayout',
91
- bindGroupLayouts: [...$.bindGroupLayouts, textureLayout]
92
- });
93
-
94
- $._pipelineConfigs[1] = {
95
- label: 'imagePipeline',
96
- layout: pipelineLayout,
97
- vertex: {
98
- module: imageShader,
99
- entryPoint: 'vertexMain',
100
- buffers: [{ arrayStride: 0, attributes: [] }, vertexBufferLayout]
101
- },
102
- fragment: {
103
- module: imageShader,
104
- entryPoint: 'fragmentMain',
105
- targets: [{ format: 'bgra8unorm', blend: $.blendConfigs.normal }]
106
- },
107
- primitive: { topology: 'triangle-strip', stripIndexFormat: 'uint32' },
108
- multisample: { count: 4 }
109
- };
110
-
111
- $._pipelines[1] = Q5.device.createRenderPipeline($._pipelineConfigs[1]);
112
-
113
- let sampler;
114
-
115
- let makeSampler = (filter) => {
116
- sampler = Q5.device.createSampler({
117
- magFilter: filter,
118
- minFilter: filter
119
- });
120
- };
121
-
122
- $.smooth = () => makeSampler('linear');
123
- $.noSmooth = () => makeSampler('nearest');
124
-
125
- $.smooth();
126
-
127
- let MAX_TEXTURES = 12000;
128
-
129
- $._textures = [];
130
- let tIdx = 0;
131
-
132
- $._createTexture = (img) => {
133
- if (img.canvas) img = img.canvas;
134
-
135
- let textureSize = [img.width, img.height, 1];
136
-
137
- let texture = Q5.device.createTexture({
138
- size: textureSize,
139
- format: 'bgra8unorm',
140
- usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT
141
- });
142
-
143
- Q5.device.queue.copyExternalImageToTexture(
144
- { source: img },
145
- {
146
- texture,
147
- colorSpace: $.canvas.colorSpace
148
- },
149
- textureSize
150
- );
151
-
152
- $._textures[tIdx] = texture;
153
- img.textureIndex = tIdx;
154
-
155
- const textureBindGroup = Q5.device.createBindGroup({
156
- layout: textureLayout,
157
- entries: [
158
- { binding: 0, resource: sampler },
159
- { binding: 1, resource: texture.createView() }
160
- ]
161
- });
162
- $._textureBindGroups[tIdx] = textureBindGroup;
163
-
164
- tIdx = (tIdx + 1) % MAX_TEXTURES;
165
-
166
- // if the texture array is full, destroy the oldest texture
167
- if ($._textures[tIdx]) {
168
- $._textures[tIdx].destroy();
169
- delete $._textures[tIdx];
170
- delete $._textureBindGroups[tIdx];
171
- }
172
- };
173
-
174
- $.loadImage = (src, cb) => {
175
- q._preloadCount++;
176
- let g = $._g.loadImage(src, (img) => {
177
- g.defaultWidth = img.width * $._defaultImageScale;
178
- g.defaultHeight = img.height * $._defaultImageScale;
179
- $._createTexture(img);
180
- q._preloadCount--;
181
- if (cb) cb(img);
182
- });
183
- return g;
184
- };
185
-
186
- $.imageMode = (x) => ($._imageMode = x);
187
-
188
- const addVert = (x, y, u, v, ci, ti, ga) => {
189
- let s = vertexStack,
190
- i = vertIndex;
191
- s[i++] = x;
192
- s[i++] = y;
193
- s[i++] = u;
194
- s[i++] = v;
195
- s[i++] = ci;
196
- s[i++] = ti;
197
- s[i++] = ga;
198
- vertIndex = i;
199
- };
200
-
201
- $.image = (img, dx = 0, dy = 0, dw, dh, sx = 0, sy = 0, sw, sh) => {
202
- let g = img;
203
- if (img.canvas) img = img.canvas;
204
- if (img.textureIndex == undefined) return;
205
-
206
- if ($._matrixDirty) $._saveMatrix();
207
-
208
- let w = img.width,
209
- h = img.height,
210
- pd = g._pixelDensity || 1;
211
-
212
- dw ??= g.defaultWidth;
213
- dh ??= g.defaultHeight;
214
- sw ??= w;
215
- sh ??= h;
216
-
217
- dw *= pd;
218
- dh *= pd;
219
-
220
- let [l, r, t, b] = $._calcBox(dx, dy, dw, dh, $._imageMode);
221
-
222
- let u0 = sx / w,
223
- v0 = sy / h,
224
- u1 = (sx + sw) / w,
225
- v1 = (sy + sh) / h,
226
- ti = $._matrixIndex,
227
- ci = $._tint,
228
- ga = $._globalAlpha;
229
-
230
- addVert(l, t, u0, v0, ci, ti, ga);
231
- addVert(r, t, u1, v0, ci, ti, ga);
232
- addVert(l, b, u0, v1, ci, ti, ga);
233
- addVert(r, b, u1, v1, ci, ti, ga);
234
-
235
- $.drawStack.push(1, img.textureIndex);
236
- };
237
-
238
- $._hooks.preRender.push(() => {
239
- if (!$._textureBindGroups.length) return;
240
-
241
- // Switch to image pipeline
242
- $.pass.setPipeline($._pipelines[1]);
243
-
244
- let vertexBuffer = Q5.device.createBuffer({
245
- size: vertIndex * 5,
246
- usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
247
- mappedAtCreation: true
248
- });
249
-
250
- new Float32Array(vertexBuffer.getMappedRange()).set(vertexStack.slice(0, vertIndex));
251
- vertexBuffer.unmap();
252
-
253
- $.pass.setVertexBuffer(1, vertexBuffer);
254
- });
255
-
256
- $._hooks.postRender.push(() => {
257
- vertIndex = 0;
258
- });
259
- };
260
-
261
- Q5.THRESHOLD = 1;
262
- Q5.GRAY = 2;
263
- Q5.OPAQUE = 3;
264
- Q5.INVERT = 4;
265
- Q5.POSTERIZE = 5;
266
- Q5.DILATE = 6;
267
- Q5.ERODE = 7;
268
- Q5.BLUR = 8;