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.
- package/README.md +20 -45
- package/deno.json +2 -1
- package/package.json +2 -2
- package/q5.d.ts +4 -4
- package/q5.js +29 -27
- package/q5.min.js +2 -2
- package/q5js_brand.webp +0 -0
- package/q5js_icon.png +0 -0
- package/src/q5-2d-canvas.js +0 -202
- package/src/q5-2d-drawing.js +0 -399
- package/src/q5-2d-image.js +0 -330
- package/src/q5-2d-soft-filters.js +0 -145
- package/src/q5-2d-text.js +0 -279
- package/src/q5-ai.js +0 -65
- package/src/q5-canvas.js +0 -367
- package/src/q5-color.js +0 -322
- package/src/q5-core.js +0 -319
- package/src/q5-display.js +0 -101
- package/src/q5-dom.js +0 -2
- package/src/q5-input.js +0 -215
- package/src/q5-math.js +0 -424
- package/src/q5-noisier.js +0 -264
- package/src/q5-record.js +0 -366
- package/src/q5-sensors.js +0 -98
- package/src/q5-sound.js +0 -64
- package/src/q5-util.js +0 -50
- package/src/q5-vector.js +0 -305
- package/src/q5-webgpu-canvas.js +0 -565
- package/src/q5-webgpu-drawing.js +0 -638
- package/src/q5-webgpu-image.js +0 -268
- package/src/q5-webgpu-text.js +0 -594
- package/src/readme.md +0 -248
package/src/q5-webgpu-image.js
DELETED
|
@@ -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;
|