rapid-render 1.0.2 → 1.0.4
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 +39 -5
- package/dist/rapid-render.js +2 -2
- package/dist/rapid-render.umd.cjs +2 -2
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -72,8 +72,42 @@ Performance Comparison: Rapid vs. Other Renderers and Game Engines
|
|
|
72
72
|
</a>
|
|
73
73
|
</p>
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
[Run Interactive Benchmark Live](https://nightre.github.io/Rapid.js/benchmark/)
|
|
76
|
+
|
|
77
|
+
Tested on **Windows 11 / Intel i7-12850H / NVIDIA RTX 4070 Laptop GPU / Google Chrome (WebGL 2.0)**
|
|
78
|
+
|
|
79
|
+
## Who is using Rapid.js?
|
|
80
|
+
|
|
81
|
+
We'd love to feature your work! Please [**Submit a Pull Request**](https://github.com/Nightre/Rapid.js/pulls) or tell nightscratch1145@gmail.com to add your game or app to the showcase!
|
|
82
|
+
<table>
|
|
83
|
+
<tr>
|
|
84
|
+
<td width="96" valign="top">
|
|
85
|
+
<a href="https://www.instagram.com/p/DJboaWgMzhK/?img_index=3">
|
|
86
|
+
<img src="./docs/image/with-rapid-0.png" alt="Avoid the Zeros at the Sydney Opera House">
|
|
87
|
+
</a>
|
|
88
|
+
</td>
|
|
89
|
+
<td valign="top">
|
|
90
|
+
<strong><a href="https://www.instagram.com/p/DJboaWgMzhK/?img_index=3">Avoid the Zeros</a> by Foxdog Studios</strong><br>
|
|
91
|
+
Foxdog Studios used Rapid.js to deliver fast download times and smooth multi-sprite rendering for thousands of audience members playing simultaneously on their mobile phones at the <strong>Sydney Opera House</strong>.<br>
|
|
92
|
+
</td>
|
|
93
|
+
</tr>
|
|
94
|
+
<tr>
|
|
95
|
+
<td width="96" valign="top">
|
|
96
|
+
<a href="https://poki.com/zh/g/emoji-party">
|
|
97
|
+
<img src="./docs/image/with-rapid-1.png" alt="Emoji Party">
|
|
98
|
+
</a>
|
|
99
|
+
</td>
|
|
100
|
+
<td valign="top">
|
|
101
|
+
<strong><a href="https://poki.com/zh/g/emoji-party">Emoji Party</a> by illusivegames</strong><br>
|
|
102
|
+
A featured puzzle hit on Poki with over <strong>13,000+ player ratings</strong>. Rapid.js powers its snappy sprite animations and instant-play experience across hundreds of thousands of diverse mobile and desktop browsers.<br>
|
|
103
|
+
</td>
|
|
104
|
+
</tr>
|
|
105
|
+
</table>
|
|
106
|
+
|
|
107
|
+
## Contributing
|
|
108
|
+
|
|
109
|
+
Contributions, issues, and feature requests are welcome!
|
|
110
|
+
|
|
111
|
+
Before submitting a Pull Request, please ensure:
|
|
112
|
+
- **Strict TypeScript (Zero any)**: All code must pass strict type checking with zero `any`, loose casts, or `@ts-ignore` directives.
|
|
113
|
+
- **Passing Checks**: Run `npm run build` to ensure clean compilation with zero warnings or errors.
|
package/dist/rapid-render.js
CHANGED
|
@@ -1664,7 +1664,7 @@ class Rt {
|
|
|
1664
1664
|
}
|
|
1665
1665
|
useTexture(t, e = 0, i = 0) {
|
|
1666
1666
|
const r = this.findTextureUnit(t, e, i);
|
|
1667
|
-
return r == -1 ? (this.usedTextures.push(t), this.usedTexturePadding.push(e), this.usedTexturePadding.push(i), this.usedTextures.length - 1) : r;
|
|
1667
|
+
return r == -1 ? (this.freeTextureUnitNum === 0 && this.flush(), this.usedTextures.push(t), this.usedTexturePadding.push(e), this.usedTexturePadding.push(i), this.usedTextures.length - 1) : r;
|
|
1668
1668
|
}
|
|
1669
1669
|
createShader(t, e) {
|
|
1670
1670
|
return new yt(this.gl, t, e);
|
|
@@ -1893,7 +1893,7 @@ class at extends Rt {
|
|
|
1893
1893
|
);
|
|
1894
1894
|
}
|
|
1895
1895
|
drawSpriteAffine(t, e, i, r, n, a, o, h = 0, c = 0, u = 1, f = 1, l = 4294967295, p = 0, x = 0, g = !1, v = !1, y = !1) {
|
|
1896
|
-
|
|
1896
|
+
this.instanceCount > K && this.flush();
|
|
1897
1897
|
const w = t.base, T = t.scale ?? 1, S = t.rawWidth, F = t.rawHeight, O = t.offsetX, N = t.offsetY, A = this.useTexture(
|
|
1898
1898
|
t.glTexture,
|
|
1899
1899
|
p / T / w.width,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
(function(x,N){typeof exports=="object"&&typeof module<"u"?N(exports):typeof define=="function"&&define.amd?define(["exports"],N):(x=typeof globalThis<"u"?globalThis:x||self,N(x.RapidRender={}))})(this,(function(x){"use strict";var N=(s=>(s[s.Float32=0]="Float32",s[s.Uint32=1]="Uint32",s[s.Uint16=2]="Uint16",s))(N||{});class F{usedElemNum;typedArray;arrayType;maxElemNum;bytePerElem;arraybuffer;uint32;float32;uint16;constructor(t){this.usedElemNum=0,this.maxElemNum=512,this.bytePerElem=this.getArrayType(t).BYTES_PER_ELEMENT,this.arrayType=t,this.arraybuffer=new ArrayBuffer(this.maxElemNum*this.bytePerElem),this.updateTypedArray()}getArrayType(t){switch(t){case 0:return Float32Array;case 1:return Uint32Array;case 2:return Uint16Array;default:throw new Error("Unsupported ArrayType")}}updateTypedArray(){switch(this.uint32=new Uint32Array(this.arraybuffer),this.float32=new Float32Array(this.arraybuffer),this.uint16=new Uint16Array(this.arraybuffer),this.arrayType){case 0:this.typedArray=this.float32;break;case 1:this.typedArray=this.uint32;break;case 2:this.typedArray=this.uint16;break}}clear(){this.usedElemNum=0}resize(t=0){if(t+=this.usedElemNum,t>this.maxElemNum){for(;t>this.maxElemNum;)this.maxElemNum*=2;return this.setMaxSize(this.maxElemNum),!0}return!1}setMaxSize(t=this.maxElemNum){const e=this.typedArray;this.maxElemNum=t,this.arraybuffer=new ArrayBuffer(t*this.bytePerElem),this.updateTypedArray(),this.typedArray.set(e)}pushUint32(t){this.resize(1),this.uint32[this.usedElemNum++]=t}pushFloat32(t){this.resize(1),this.float32[this.usedElemNum++]=t}push(t){this.resize(1),this.typedArray[this.usedElemNum++]=t}pop(){return this.typedArray[--this.usedElemNum]}top(){return this.typedArray[this.usedElemNum-1]}get(t){return this.typedArray[t]}getArray(t=0,e){return e===void 0?this.typedArray:this.typedArray.subarray(t,e)}get length(){return this.usedElemNum}reset(){this.usedElemNum=0}}class K extends F{buffer;gl;dirty=!0;type;webglBufferSize=0;usage;constructor(t,e,i=t.ARRAY_BUFFER,r=t.DYNAMIC_DRAW){super(e),this.gl=t,this.buffer=t.createBuffer(),this.type=i,this.usage=r}makeDirty(){this.dirty=!0}clear(){super.clear(),this.dirty=!1}bindBuffer(){this.gl.bindBuffer(this.type,this.buffer)}bufferData(){if(this.dirty){const t=this.gl;this.maxElemNum>this.webglBufferSize&&(t.bufferData(this.type,this.maxElemNum*this.bytePerElem,this.usage),this.webglBufferSize=this.maxElemNum),t.bufferSubData(this.type,0,this.getArray(0,this.usedElemNum)),this.dirty=!1}}}class m{_r;_g;_b;_a;uint32;premultipliedUint32;static clampByte(t){return t<=0?0:t>=255?255:Math.round(t)}constructor(t,e,i,r=255){this._r=t,this._g=e,this._b=i,this._a=r,this.updateUint()}setClearColor(t){t.clearColor(this.r/255,this.g/255,this.b/255,this.a/255)}get r(){return this._r}set r(t){this._r=t,this.updateUint()}get g(){return this._g}set g(t){this._g=t,this.updateUint()}get b(){return this._b}set b(t){this._b=t,this.updateUint()}get a(){return this._a}set a(t){this._a=t,this.updateUint()}updateUint(){this.uint32=(this._a<<24|this._b<<16|this._g<<8|this._r)>>>0;const t=m.clampByte(this._a),e=m.clampByte(this._r*t/255),i=m.clampByte(this._g*t/255),r=m.clampByte(this._b*t/255);this.premultipliedUint32=(t<<24|r<<16|i<<8|e)>>>0}reset(){this._r=0,this._g=0,this._b=0,this._a=255,this.updateUint()}setRGBA(t,e,i,r){this.r=t,this.g=e,this.b=i,this.a=r,this.updateUint()}setHSL(t,e,i){t=(t%360+360)%360,e=Math.max(0,Math.min(100,e))/100,i=Math.max(0,Math.min(100,i))/100;const r=(1-Math.abs(2*i-1))*e,n=r*(1-Math.abs(t/60%2-1)),a=i-r/2;let o=0,h=0,c=0;return t<60?[o,h,c]=[r,n,0]:t<120?[o,h,c]=[n,r,0]:t<180?[o,h,c]=[0,r,n]:t<240?[o,h,c]=[0,n,r]:t<300?[o,h,c]=[n,0,r]:[o,h,c]=[r,0,n],this.setRGBA((o+a)*255,(h+a)*255,(c+a)*255,255),this}toHex(){const t=e=>Math.max(0,Math.min(255,Math.round(e))).toString(16).padStart(2,"0");return`#${t(this._r)}${t(this._g)}${t(this._b)}${t(this._a)}`}copy(t){this.setRGBA(t.r,t.g,t.b,t.a)}clone(){return new m(this._r,this._g,this._b,this._a)}toHexString(t=!0){const e=this.r.toString(16).padStart(2,"0"),i=this.g.toString(16).padStart(2,"0"),r=this.b.toString(16).padStart(2,"0"),n=this.a.toString(16).padStart(2,"0");return`#${e}${i}${r}${t?n:""}`}equal(t){return t.r===this.r&&t.g===this.g&&t.b===this.b&&t.a===this.a}equals(t){return this.equal(t)}static FromHSL(t,e,i){return new m(0,0,0).setHSL(t,e,i)}static FromRGB(t,e,i){return new m(t,e,i)}static fromNorm(t,e,i,r=1){return new m(Math.round(t*255),Math.round(e*255),Math.round(i*255),Math.round(r*255))}static fromHex(t){t.startsWith("#")&&(t=t.slice(1));const e=parseInt(t.slice(0,2),16),i=parseInt(t.slice(2,4),16),r=parseInt(t.slice(4,6),16);let n=255;return t.length>=8&&(n=parseInt(t.slice(6,8),16)),new m(e,i,r,n)}add(t){return new m(Math.min(this.r+t.r,255),Math.min(this.g+t.g,255),Math.min(this.b+t.b,255),Math.min(this.a+t.a,255))}subtract(t){return new m(this.r-t.r,this.g-t.g,this.b-t.b,this.a-t.a)}divide(t){return t instanceof m?new m(this.r/t.r,this.g/t.g,this.b/t.b,this.a/t.a):new m(this.r/t,this.g/t,this.b/t,this.a/t)}multiply(t){return t instanceof m?new m(this.r*t.r,this.g*t.g,this.b*t.b,this.a*t.a):new m(this.r*t,this.g*t,this.b*t,this.a*t)}clamp(){this.r=Math.max(0,Math.min(255,this.r)),this.g=Math.max(0,Math.min(255,this.g)),this.b=Math.max(0,Math.min(255,this.b)),this.a=Math.max(0,Math.min(255,this.a))}static Red=new m(255,0,0,255);static Green=new m(0,255,0,255);static Blue=new m(0,0,255,255);static Yellow=new m(255,255,0,255);static Purple=new m(128,0,128,255);static Orange=new m(255,165,0,255);static Pink=new m(255,192,203,255);static Gray=new m(128,128,128,255);static Brown=new m(139,69,19,255);static Cyan=new m(0,255,255,255);static Magenta=new m(255,0,255,255);static Lime=new m(192,255,0,255);static White=new m(255,255,255,255);static Black=new m(0,0,0,255);static Transparent=new m(0,0,0,0);static TRANSPARENT=new m(0,0,0,0)}const R=6;class mt{matrixCount=0;buffer;data;constructor(t=10){this.buffer=new F(N.Float32),this.buffer.resize(t*R),this.data=this.buffer.getArray()}alloc(){const t=this.allocDirty();return this.identity(t),t}allocDirty(){return this.buffer.resize(R)&&(this.data=this.buffer.getArray()),this.buffer.usedElemNum+=R,this.matrixCount++}reset(){this.matrixCount=0,this.buffer.usedElemNum=0}identity(t){const e=t*R,i=this.data;i[e]=1,i[e+1]=0,i[e+2]=0,i[e+3]=1,i[e+4]=0,i[e+5]=0}translate(t,e,i){const r=t*R,n=this.data;n[r+4]=n[r]*e+n[r+2]*i+n[r+4],n[r+5]=n[r+1]*e+n[r+3]*i+n[r+5]}scale(t,e,i){const r=t*R,n=this.data;n[r]*=e,n[r+1]*=e,n[r+2]*=i,n[r+3]*=i}rotate(t,e){const i=t*R,r=this.data,n=Math.cos(e),a=Math.sin(e),o=r[i],h=r[i+1],c=r[i+2],u=r[i+3];r[i]=o*n+c*a,r[i+1]=h*n+u*a,r[i+2]=o*-a+c*n,r[i+3]=h*-a+u*n}rotateWithOffset(t,e,i,r){this.translate(t,i,r),this.rotate(t,e),this.translate(t,-i,-r)}copy(t,e){const i=t*R,r=e*R,n=this.data;n[i]=n[r],n[i+1]=n[r+1],n[i+2]=n[r+2],n[i+3]=n[r+3],n[i+4]=n[r+4],n[i+5]=n[r+5]}multiply(t,e){this.multiplyOut(t,t,e)}multiplyOut(t,e,i){const r=t*R,n=e*R,a=i*R,o=this.data,h=o[n],c=o[n+1],u=o[n+2],f=o[n+3],l=o[n+4],g=o[n+5],p=o[a],v=o[a+1],T=o[a+2],E=o[a+3],S=o[a+4],y=o[a+5];o[r]=h*p+u*v,o[r+1]=c*p+f*v,o[r+2]=h*T+u*E,o[r+3]=c*T+f*E,o[r+4]=h*S+u*y+l,o[r+5]=c*S+f*y+g}invert(t){const e=t*R,i=this.data,r=i[e],n=i[e+1],a=i[e+2],o=i[e+3],h=i[e+4],c=i[e+5];let u=r*o-n*a;if(!u){this.identity(t);return}u=1/u,i[e]=o*u,i[e+1]=-n*u,i[e+2]=-a*u,i[e+3]=r*u,i[e+4]=(a*c-o*h)*u,i[e+5]=(n*h-r*c)*u}transformPoint(t,e,i){const r=t*R,n=this.data;return{x:e*n[r]+i*n[r+2]+n[r+4],y:e*n[r+1]+i*n[r+3]+n[r+5]}}worldToLocal(t,e,i){const r=this.allocDirty();this.copy(r,t),this.invert(r);const n=this.transformPoint(r,e,i);return this.matrixCount--,this.buffer.usedElemNum-=R,n}localToWorld(t,e,i){return this.transformPoint(t,e,i)}getPosition(t){const e=t*R,i=this.data;return{x:i[e+4],y:i[e+5]}}getScale(t){const e=t*R,i=this.data,r=Math.sqrt(i[e]*i[e]+i[e+1]*i[e+1]),n=Math.sqrt(i[e+2]*i[e+2]+i[e+3]*i[e+3]);return{x:r,y:n}}getRotation(t){const e=t*R,i=this.data;return Math.atan2(i[e+1],i[e])}toCSSMatrix(t,e=1,i=1){const r=t*R,n=this.data;return`matrix(${n[r]*e}, ${n[r+1]*i}, ${n[r+2]*e}, ${n[r+3]*i}, ${n[r+4]*e}, ${n[r+5]*i})`}getMatrix(t){const e=t*R;return this.data.slice(e,e+R)}getMatrixRef(t){const e=t*R;return this.data.subarray(e,e+R)}setMatrix(t,e){const i=t*R,r=this.data;r[i]=e[0],r[i+1]=e[1],r[i+2]=e[2],r[i+3]=e[3],r[i+4]=e[4],r[i+5]=e[5]}multiplyAffineInPlace(t,e,i,r,n,a,o){const h=t*6,c=this.data,u=c[h],f=c[h+1],l=c[h+2],g=c[h+3],p=c[h+4],v=c[h+5];c[h]=u*e+l*i,c[h+1]=f*e+g*i,c[h+2]=u*r+l*n,c[h+3]=f*r+g*n,c[h+4]=u*a+l*o+p,c[h+5]=f*a+g*o+v}}class xt{matrix=new mt;step=0;stack=new F(N.Uint32);stepWorldM=new F(N.Uint32);stepAction=new F(N.Uint32);stepParentM=new F(N.Uint32);parentStack=new F(N.Uint32);curLocalM=-1;curWorldM=-1;rapid;constructor(t){this.reset(),this.rapid=t}save(){this.stack.push(this.curWorldM);const t=this.curWorldM;return this.step++,this.curLocalM=this.matrix.alloc(),this.curWorldM=this.matrix.allocDirty(),this.stepWorldM.push(this.curWorldM),this.stepParentM.push(t),this.matrix.copy(this.curWorldM,t),this.stepAction.push(1),{world:this.curWorldM,local:this.curLocalM,step:this.step}}restore(){this.stack.length!=0&&(this.curWorldM=this.stack.pop(),this.curLocalM=this.curWorldM-1,this.stepAction.push(0))}updateMatrix(t){const e=(typeof t=="number"?t:t.step)-1,i=this.stepParentM.get(e);let r=0,n=e;const a=this.parentStack;for(a.reset(),a.push(i);n<this.stepAction.length;){if(this.stepAction.get(n)===1){const h=this.stepWorldM.get(n),c=h-1,u=a.top();this.matrix.multiplyOut(h,u,c),a.push(h),r++}else if(a.pop(),r--,r===0)break;n++}}translate(t,e){this.matrix.translate(this.curLocalM,t,e),this.matrix.translate(this.curWorldM,t,e)}scale(t,e=t){this.matrix.scale(this.curLocalM,t,e),this.matrix.scale(this.curWorldM,t,e)}rotate(t){this.matrix.rotate(this.curLocalM,t),this.matrix.rotate(this.curWorldM,t)}rotateWithOffset(t,e,i){this.matrix.rotateWithOffset(this.curLocalM,t,e,i),this.matrix.rotateWithOffset(this.curWorldM,t,e,i)}identity(){this.matrix.identity(this.curLocalM),this.matrix.identity(this.curWorldM)}reset(){this.matrix.reset(),this.stack.reset(),this.stepAction.reset(),this.stepWorldM.reset(),this.stepParentM.reset(),this.step=0,this.curLocalM=this.matrix.alloc(),this.curWorldM=this.matrix.alloc()}localToWorld(t,e){return this.matrix.localToWorld(this.curWorldM,t,e)}worldToLocal(t,e){return this.matrix.worldToLocal(this.curWorldM,t,e)}getGlobalPosition(){return this.matrix.getPosition(this.curWorldM)}getGlobalScale(){return this.matrix.getScale(this.curWorldM)}getGlobalRotation(){return this.matrix.getRotation(this.curWorldM)}toCSSMatrix(){return this.matrix.toCSSMatrix(this.curWorldM)}getTransform(){const t=this.curWorldM*R;return this.matrix.data.slice(t,t+R)}setTransform(t){const e=this.curWorldM*R,i=this.matrix.data;i[e]=t[0],i[e+1]=t[1],i[e+2]=t[2],i[e+3]=t[3],i[e+4]=t[4],i[e+5]=t[5]}transformPoint(t,e){return this.matrix.transformPoint(this.curLocalM,t,e)}applyTransform(t,e=0,i=0){(t.saveTransform??!0)&&this.save();let r=t.x??0,n=t.y??0;t.position&&(r+=t.position.x,n+=t.position.y);let a=1,o=1;const h=t.scale;h&&(typeof h=="number"?(a=h,o=h):(a=h.x,o=h.y));const c=t.rotation??0;let u=t.offsetX??0,f=t.offsetY??0;t.offset&&(u+=t.offset.x,f+=t.offset.y);const l=t.origin;l!==void 0&&(typeof l=="number"?(u-=l*e,f-=l*i):(u-=l.x*e,f-=l.y*i));const g=c?Math.cos(c):1,p=c?Math.sin(c):0,v=g*a,T=p*a,E=-p*o,S=g*o,y=r+v*u+E*f,b=n+T*u+S*f;(t.afterSave!==void 0||t.saveTransform===!1)&&this.matrix.multiplyAffineInPlace(this.curLocalM,v,T,E,S,y,b),this.matrix.multiplyAffineInPlace(this.curWorldM,v,T,E,S,y,b),t.afterSave?.()}}var G=(s=>(s[s.REPEAT=0]="REPEAT",s[s.CLAMP=1]="CLAMP",s[s.MIRRORED_REPEAT=2]="MIRRORED_REPEAT",s))(G||{});class pt{render;cache=new Map;constructor(t){this.render=t}async load(t,e){let i=this.cache.get(t);if(i)return new L(i);try{const r=await this._fetchImage(t);return i=D.fromSource(this.render,r,e),i.uid=t,this.cache.set(t,i),new L(i)}catch(r){throw console.error(`[TextureManager] Failed to load: ${t}`,r),r}}create(t,e){if(e?.key&&this.cache.has(e.key))return new L(this.cache.get(e.key));const i=D.fromSource(this.render,t,e);return e?.key&&(i.uid=e.key,this.cache.set(e.key,i)),new L(i)}createRenderTexture(t){return new gt(this.render,t)}createTextTexture(t){return new vt(this.render,t)}destroy(t,e=!1){let i,r;typeof t=="string"?(r=t,i=this.cache.get(r)):t instanceof L?(i=t.base,r=i?.uid,t.destroy()):(i=t,r=i.uid),i&&(i.refCount<=0||e)&&(i.destroy(this.render.gl),r&&this.cache.delete(r))}destroyAll(){for(const t of this.cache.values())t.destroy(this.render.gl);this.cache.clear()}_fetchImage(t){return new Promise((e,i)=>{const r=new Image;r.crossOrigin="anonymous",r.onload=()=>e(r),r.onerror=()=>i(new Error(`Failed to load image resource: ${t}`)),r.src=t})}}class D{glTexture=null;width;height;uid;refCount=0;constructor(t,e,i){this.glTexture=t,this.width=e,this.height=i}static fromSource(t,e,i={}){const r=q(t,e,i);return new D(r,e.width,e.height)}updateSource(t,e,i={}){this.glTexture&&(t.bindTexture(t.TEXTURE_2D,this.glTexture),i.textureFilter!==void 0&&st(t,i.textureFilter),i.wrap!==void 0&&rt(t,i.wrap),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,1),t.pixelStorei(t.UNPACK_ALIGNMENT,1),i.premultipliedAlpha!==void 0&&t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,i.premultipliedAlpha),this.width===e.width&&this.height===e.height?t.texSubImage2D(t.TEXTURE_2D,0,0,0,t.RGBA,t.UNSIGNED_BYTE,e):(t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e),this.width=e.width,this.height=e.height),i.premultipliedAlpha!==void 0&&t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1))}setFilterMode(t,e){this.glTexture&&(t.bindTexture(t.TEXTURE_2D,this.glTexture),st(t,e),t.bindTexture(t.TEXTURE_2D,null))}setWrapMode(t,e){this.glTexture&&(t.bindTexture(t.TEXTURE_2D,this.glTexture),rt(t,e),t.bindTexture(t.TEXTURE_2D,null))}destroy(t){this.glTexture&&(t.deleteTexture(this.glTexture),this.glTexture=null)}}class L{base;uvX=0;uvY=0;uvW=1;uvH=1;rawWidth=0;rawHeight=0;offsetX=0;offsetY=0;scale=1;isAtlas=!1;flipY=!1;isRotated=!1;glTexture=null;get width(){return(this.isRotated?this.rawHeight:this.rawWidth)*this.scale}get height(){return(this.isRotated?this.rawWidth:this.rawHeight)*this.scale}_px=0;_py=0;_pw=0;_ph=0;constructor(t){t&&this.setBase(t)}setBase(t){return this.base===t?this:(this.base&&this.base.refCount--,this.base=t,this.base.refCount++,this.setRegion(0,0,t.width,t.height),this.glTexture=t.glTexture,this)}setRegion(t,e,i,r){return this.base?(this._px=t,this._py=e,this._pw=i,this._ph=r,this.isAtlas=t!==0||e!==0||i!==this.base.width||r!==this.base.height,this.uvX=t/this.base.width,this.uvY=e/this.base.height,this.uvW=this.uvX+i/this.base.width,this.uvH=this.uvY+r/this.base.height,this.rawWidth=i,this.rawHeight=r,this):this}getSubTexture(t,e,i,r){if(!this.base)return new L;const n=this.clone(),a=this._px,o=this._py;return n.setRegion(a+t,o+e,i,r),n}clone(t){const e=t??new L(this.base);return t&&this.base&&t.setBase(this.base),e.scale=this.scale,e.uvX=this.uvX,e.uvY=this.uvY,e.uvW=this.uvW,e.uvH=this.uvH,e.rawWidth=this.rawWidth,e.rawHeight=this.rawHeight,e.offsetX=this.offsetX,e.offsetY=this.offsetY,e.flipY=this.flipY,e.isRotated=this.isRotated,e.isAtlas=this.isAtlas,e._px=this._px,e._py=this._py,e._pw=this._pw,e._ph=this._ph,e}splitGrid(t,e,i,r,n=0){if(!this.base)return[];const a=[],o=this.rawWidth,h=this.rawHeight,c=Math.max(0,n),u=t+c,f=e+c,l=i??Math.floor((o+c)/u),g=r??Math.floor((h+c)/f);for(let p=0;p<g;p++)for(let v=0;v<l;v++)a.push(this.getSubTexture(v*u,p*f,t,e));return a}static fromImageSource(t,e,i={}){const r=q(t,e,i);return new L(new D(r,e.width,e.height))}destroy(){this.base&&(this.base.refCount--,this.base=void 0),this.glTexture=null}}class gt extends L{framebuffer;renderbuffer;gl;flipY=!0;clearColor;_allocW=0;_allocH=0;constructor(t,e){super(),this.gl=t.gl,this.clearColor=e.clearColor??m.Black;const i=Math.max(Math.round(e.width),1),r=Math.max(Math.round(e.height),1),a=q(t,{width:i,height:r},{...e,onlySize:!0});if(this.setBase(new D(a,i,r)),this.framebuffer=this.gl.createFramebuffer(),this.renderbuffer=this.gl.createRenderbuffer(),!this.framebuffer||!this.renderbuffer)throw new Error("Failed to create Framebuffer or Renderbuffer");this.resize(i,r,!0)}resize(t,e,i=!1){t=Math.max(Math.round(t),1),e=Math.max(Math.round(e),1);const r=this.rawWidth===t&&this.rawHeight===e;if(!i&&r)return;const n=this.gl;(i||t>this._allocW||e>this._allocH)&&this.base&&(this._allocW=Math.max(this._allocW,t),this._allocH=Math.max(this._allocH,e),this.base.width=this._allocW,this.base.height=this._allocH,n.bindTexture(n.TEXTURE_2D,this.base.glTexture),n.texImage2D(n.TEXTURE_2D,0,n.RGBA,this._allocW,this._allocH,0,n.RGBA,n.UNSIGNED_BYTE,null),n.bindRenderbuffer(n.RENDERBUFFER,this.renderbuffer),n.renderbufferStorage(n.RENDERBUFFER,n.STENCIL_INDEX8,this._allocW,this._allocH),n.bindFramebuffer(n.FRAMEBUFFER,this.framebuffer),n.framebufferTexture2D(n.FRAMEBUFFER,n.COLOR_ATTACHMENT0,n.TEXTURE_2D,this.base.glTexture,0),n.framebufferRenderbuffer(n.FRAMEBUFFER,n.STENCIL_ATTACHMENT,n.RENDERBUFFER,this.renderbuffer),n.bindFramebuffer(n.FRAMEBUFFER,null),n.bindRenderbuffer(n.RENDERBUFFER,null),n.bindTexture(n.TEXTURE_2D,null)),this.rawWidth=t,this.rawHeight=e,this.uvX=0,this.uvW=t/this._allocW,this.uvY=0,this.uvH=e/this._allocH}activate(t=!1){if(!this.framebuffer)return;const e=this.gl;e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer),e.viewport(0,0,this.rawWidth,this.rawHeight),t&&this.clear()}clear(t){if(!this.framebuffer)return;const e=this.gl,i=t??this.clearColor;i&&(i.setClearColor(e),e.clear(e.COLOR_BUFFER_BIT|e.STENCIL_BUFFER_BIT))}deactivate(){const t=this.gl;t.bindFramebuffer(t.FRAMEBUFFER,null)}GetPixels(t=0,e=0,i=this.rawWidth,r=this.rawHeight){if(!this.framebuffer)return new Uint8Array(0);const n=Math.floor(t),a=Math.floor(e),o=Math.floor(i),h=Math.floor(r);if(o<=0||h<=0)return new Uint8Array(0);if(n<0||a<0||n>=this.rawWidth||a>=this.rawHeight)return new Uint8Array(0);const c=Math.min(o,this.rawWidth-n),u=Math.min(h,this.rawHeight-a),f=this.rawHeight-a-u,l=this.gl,g=l.getParameter(l.FRAMEBUFFER_BINDING);l.bindFramebuffer(l.FRAMEBUFFER,this.framebuffer);const p=new Uint8Array(c*u*4);return l.readPixels(n,f,c,u,l.RGBA,l.UNSIGNED_BYTE,p),l.bindFramebuffer(l.FRAMEBUFFER,g),p}GetColorAt(t,e){const i=this.GetPixels(t,e,1,1);return i.length<4?new m(0,0,0,0):new m(i[0],i[1],i[2],i[3])}destroy(){super.destroy(),this.framebuffer&&this.gl.deleteFramebuffer(this.framebuffer),this.renderbuffer&&this.gl.deleteRenderbuffer(this.renderbuffer),this.base?.destroy(this.gl)}}const $t={fontFamily:"Arial",fontSize:24,fontWeight:"normal",fill:"#000000",strokeThickness:1,align:"left",baseline:"top"};class vt extends L{canvas;ctx;render;_text;_style;options;flipY=!0;constructor(t,e){super(),this.render=t,this._style={...$t,...e},this._text=e?.text??"",this.options={premultipliedAlpha:t.premultipliedAlpha,...e},this.scale=1/t.dpr,this.canvas=document.createElement("canvas");const i=this.canvas.getContext("2d",{willReadFrequently:!0});if(!i)throw new Error("Failed to get 2d context for TextTexture");this.ctx=i,this.canvas.width=1,this.canvas.height=1;const r=q(t,this.canvas,this.options);this.setBase(new D(r,1,1)),this.update()}get text(){return this._text}set text(t){this._text!==t&&(this._text=t,this.update())}get style(){return this._style}set style(t){this._style={...this._style,...t},this.update()}updateOffset(t,e){switch(this._style.align){case"center":this.offsetX=-t/2;break;case"right":this.offsetX=-t;break;default:this.offsetX=0;break}switch(this._style.baseline){case"middle":this.offsetY=-e/2;break;case"bottom":this.offsetY=-e;break;default:this.offsetY=0;break}}update(){const t=this.ctx,e=this._style.fontSize,i=this._style.fontWeight,r=this._style.fontFamily,n=`${i} ${e}px ${r}`,a=this.render.dpr;t.font=n;const o=this._text.split(`
|
|
2
|
-
`);let h=0,c=0;t.textBaseline="alphabetic";const u=t.measureText(o[0]),f=u.fontBoundingBoxAscent,l=u.fontBoundingBoxDescent;for(const y of o){const b=t.measureText(y);b.width>h&&(h=b.width),c+=f+l}c-=l;const g=(this._style.strokeThickness||0)*2,p=Math.ceil(h+g)||1,v=Math.ceil(c+g)||1,T=p*a,E=v*a;(this.canvas.width!==T||this.canvas.height!==E)&&(this.canvas.width=T,this.canvas.height=E),t.setTransform(a,0,0,a,0,0),t.clearRect(0,0,p,v),t.font=n,t.textBaseline="top",t.textAlign="left",this.updateOffset(p,v);let S=g/2;for(const y of o){let b=g/2;this._style.stroke&&this._style.strokeThickness>0&&(t.lineWidth=this._style.strokeThickness,t.strokeStyle=this._style.stroke,t.strokeText(y,b,S)),this._style.fill&&(t.fillStyle=this._style.fill,t.fillText(y,b,S)),S+=f+l}this.base?.updateSource(this.render.gl,this.canvas,this.options),this.setRegion(0,0,this.canvas.width,this.canvas.height)}}const Kt=(s,t=!1,e=!0)=>{const i=s.getContext("webgl2",{stencil:!0,antialias:t,premultipliedAlpha:e});if(!i)throw new Error("WebGL2 is not supported in this browser.");return i},Tt=(s,t,e)=>{const i=s.createShader(e);if(!i)throw new Error("Unable to create webgl shader");if(s.shaderSource(i,t),s.compileShader(i),!s.getShaderParameter(i,s.COMPILE_STATUS)){const n=s.getShaderInfoLog(i);throw console.error("Shader compilation failed:",n),new Error("Unable to compile shader: "+n+t)}return i},qt=(s,t,e)=>{var i=s.createProgram(),r=Tt(s,t,35633),n=Tt(s,e,35632);if(!i)throw new Error("Unable to create program shader");if(s.attachShader(i,r),s.attachShader(i,n),s.linkProgram(i),!s.getProgramParameter(i,s.LINK_STATUS)){const o=s.getProgramInfoLog(i);throw new Error("Unable to link shader program: "+o)}return i};function rt(s,t){const e={[G.CLAMP]:s.CLAMP_TO_EDGE,[G.REPEAT]:s.REPEAT,[G.MIRRORED_REPEAT]:s.MIRRORED_REPEAT}[t]||s.CLAMP_TO_EDGE;s.texParameteri(s.TEXTURE_2D,s.TEXTURE_WRAP_S,e),s.texParameteri(s.TEXTURE_2D,s.TEXTURE_WRAP_T,e)}function st(s,t){const e={[et.LINEAR]:s.LINEAR,[et.NEAREST]:s.NEAREST}[t]??s.NEAREST;s.texParameteri(s.TEXTURE_2D,s.TEXTURE_MIN_FILTER,e),s.texParameteri(s.TEXTURE_2D,s.TEXTURE_MAG_FILTER,e)}function q(s,t,e){const i=s.gl,r=i.createTexture();if(!r)throw new Error("Unable to create WebGL texture");if(i.bindTexture(i.TEXTURE_2D,r),i.pixelStorei(i.UNPACK_FLIP_Y_WEBGL,0),i.pixelStorei(i.UNPACK_ALIGNMENT,1),rt(i,e.wrap??G.CLAMP),st(i,e.textureFilter??s.textureFilter),e.onlySize){const n=t;i.texImage2D(i.TEXTURE_2D,0,i.RGBA,n.width,n.height,0,i.RGBA,i.UNSIGNED_BYTE,null)}else{const n=e.premultipliedAlpha??s.premultipliedAlpha;n&&i.pixelStorei(i.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,i.RGBA,i.UNSIGNED_BYTE,t),n&&i.pixelStorei(i.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1)}return i.bindTexture(i.TEXTURE_2D,null),r}function B(s,t){if(s.includes("%TEXTURE_NUM%")&&(s=s.replace("%TEXTURE_NUM%",t.toString())),s.includes("%GET_COLOR%")){let e="";for(let i=0;i<t;i++)i==0?e+=`if(vTextureId == ${i})`:i==t-1?e+="else":e+=`else if(vTextureId == ${i})`,e+=`{return texture(uTextures[${i}], uv) * vColor;}`;s=s.replace("%GET_COLOR%",e)}return s}const Zt=5126,nt=5121;function Qt(s,t,e){s.vertexAttribDivisor(t,e)}function yt(s,t,e,i,r){s.drawArraysInstanced(t,e,i,r)}let Jt=0;class at{program;attributeLoc={};uniformLoc={};isCustom=!1;padding=0;uniformType={};uniformIsArray={};gl;shaderId=Jt++;vao;constructor(t,e,i,r){this.gl=t,this.program=qt(t,e,i),this.parseShader(e),this.parseShader(i),this.vao=t.createVertexArray(),r&&this.setAttributes(r)}use(){this.gl.useProgram(this.program)}bindVAO(){this.gl.bindVertexArray(this.vao)}unbindVAO(){this.gl.bindVertexArray(null)}setUniform(t,e){const i=this.uniformLoc[t];if(i===void 0)return;const r=this.uniformType[t],n=this.uniformIsArray[t];te(this.gl,i,r,e,n)}setUniforms(t){for(const e in t)this.setUniform(e,t[e])}setAttribute(t){const e=this.attributeLoc[t.name];if(e===void 0)return;const i=this.gl;i.vertexAttribPointer(e,t.size,t.type??Zt,t.normalized??!1,t.stride,t.offset??0),i.enableVertexAttribArray(e),Qt(i,e,t.divisor??0)}setAttributes(t){for(const e of t)this.setAttribute(e)}destroy(){this.gl.deleteProgram(this.program)}parseShader(t){const e=this.gl,i=t.match(/(?:in|attribute)\s+\w+\s+\w+/g);if(i)for(const n of i){const o=n.split(/\s+/)[2],h=e.getAttribLocation(this.program,o);h!==-1&&(this.attributeLoc[o]=h)}const r=t.match(/uniform\s+\w+\s+\w+(?:\[\d+\])?/g);if(r)for(const n of r){const a=n.split(/\s+/),o=a[1],h=a[2].replace(/\[\d+\]$/,""),c=e.getUniformLocation(this.program,h);c!==null&&(this.uniformLoc[h]=c,this.uniformType[h]=o,this.uniformIsArray[h]=/\[\d+\]$/.test(a[2]))}}}function te(s,t,e,i,r=!1){switch(e){case"float":return s.uniform1f(t,i);case"int":case"bool":case"sampler2D":case"samplerCube":return r?s.uniform1iv(t,i):s.uniform1i(t,i);case"vec2":return s.uniform2fv(t,i);case"vec3":return s.uniform3fv(t,i);case"vec4":return s.uniform4fv(t,i);case"ivec2":case"bvec2":return s.uniform2iv(t,i);case"ivec3":case"bvec3":return s.uniform3iv(t,i);case"ivec4":case"bvec4":return s.uniform4iv(t,i);case"mat2":return s.uniformMatrix2fv(t,!1,i);case"mat3":return s.uniformMatrix3fv(t,!1,i);case"mat4":return s.uniformMatrix4fv(t,!1,i);default:return ee(s,t,i)}}function ee(s,t,e){if(typeof e=="number")return s.uniform1f(t,e);const i=e;switch(i.length){case 2:return s.uniform2fv(t,i);case 3:return s.uniform3fv(t,i);case 4:return s.uniform4fv(t,i);case 9:return s.uniformMatrix3fv(t,!1,i);case 16:return s.uniformMatrix4fv(t,!1,i);default:return s.uniform1fv(t,i)}}class ht{vs;fs;glshader=new Map;uniforms={};uniformDirty=new Set;uniformTextures={};usedTextureUnitNum=0;padding=0;rapid;constructor(t,e,i,r=0,n){this.vs=e,this.fs=i,this.rapid=t,this.uniforms=n??{},this.usedTextureUnitNum=r}setUniforms(t){this.rapid.flush();const e={},i={};for(const[r,n]of Object.entries(t))n instanceof WebGLTexture?i[r]=n:e[r]=n;Object.assign(this.uniforms,e),Object.assign(this.uniformTextures,i);for(const r of this.glshader.keys())this.uniformDirty.add(r)}setPadding(t){this.padding=t;for(const e of this.glshader.values())e.padding=t;return this}applyUniform(t,e){const i=this.glshader.get(t);i&&(Object.keys(e).length>0&&i.setUniforms(e),this.uniformDirty.has(t)&&(i.setUniforms(this.uniforms),this.uniformDirty.delete(t)))}getGLShader(t,e,i,r){if(this.glshader.has(e))return this.glshader.get(e);if(r==null||i==null)return console.warn("CustomGlShader: missing base shader for "+e),null;i=i.replace("// CUSTOM_CODE_CALL","vertex(position, vRegion);"),r=r.replace("// CUSTOM_CODE_CALL","fragment(fragColor);"),i=i.replace("// CUSTOM_CODE",this.vs),r=r.replace("// CUSTOM_CODE",this.fs);const n=t.createShader(i,r);return n.isCustom=!0,n.padding=this.padding,this.glshader.set(e,n),this.uniformDirty.add(e),n}}const z=1/0;class ot{constructor(t){this.rapid=t,this.gl=t.gl,this.maxTextureUnits=t.maxTextureUnits,this.matrixStore=t.matrix}defaultShader;currentShader;customShader=null;customShaderUsedTextureNum=0;gl;maxTextureUnits;matrixStore;isDefaultShader=!0;KEY="default";vs="";fs="";usedTextures=[];usedTexturePadding=[];createBuffer(){}createDefaultShader(){}get freeTextureUnitNum(){return this.maxTextureUnits-this.usedTextures.length-this.customShaderUsedTextureNum}getTextureUnitList(){return Array.from({length:this.maxTextureUnits},(t,e)=>e)}findTextureUnit(t,e=0,i=0){for(let r=0;r<this.usedTextures.length;r++){const n=r*2;if(this.usedTextures[r]===t&&this.usedTexturePadding[n]===e&&this.usedTexturePadding[n+1]===i)return r}return-1}useTexture(t,e=0,i=0){const r=this.findTextureUnit(t,e,i);return r==-1?(this.usedTextures.push(t),this.usedTexturePadding.push(e),this.usedTexturePadding.push(i),this.usedTextures.length-1):r}createShader(t,e){return new at(this.gl,t,e)}createCustomShader(t){return t.getGLShader(this,this.KEY,this.vs,this.fs)}getCustomShader(t){if(!t)return this.defaultShader;if(t instanceof ht){const e=this.createCustomShader(t);return e??this.defaultShader}return t}isSameShader(t){return this.isDefaultShader&&!t?!0:this.getCustomShader(t)==this.currentShader}enter(t){this.resetRender(),this.currentShader=this.getCustomShader(t),t instanceof ht?(this.customShader=t,this.customShaderUsedTextureNum=t.usedTextureUnitNum):(this.customShader=null,this.customShaderUsedTextureNum=0),this.isDefaultShader=this.currentShader==this.defaultShader,this.currentShader.use(),this.currentShader.setUniform("u_projection",this.rapid.projection)}exit(){this.hasPendingContent()&&this.flush(),this.gl.bindVertexArray(null)}flush(){this.render(),this.resetRender()}render(){const t=this.currentShader;if(t.use(),this.customShader){const i=this.customShader,r={};for(const n in i.uniformTextures)r[n]=this.useTexture(i.uniformTextures[n]);this.customShader.applyUniform(this.KEY,r)}const e=this.gl;for(let i=0;i<this.usedTextures.length;i++)e.activeTexture(e.TEXTURE0+i),e.bindTexture(e.TEXTURE_2D,this.usedTextures[i]);t.setUniform("uTextures",Int32Array.from({length:this.usedTextures.length},(i,r)=>r)),t.setUniform("uPadding",Float32Array.from({length:this.usedTexturePadding.length},(i,r)=>this.usedTexturePadding[r]))}resetRender(){this.usedTextures.length=0,this.usedTexturePadding.length=0}hasPendingContent(){return!1}}const Z=`#version 300 es\r
|
|
2
|
+
`);let h=0,c=0;t.textBaseline="alphabetic";const u=t.measureText(o[0]),f=u.fontBoundingBoxAscent,l=u.fontBoundingBoxDescent;for(const y of o){const b=t.measureText(y);b.width>h&&(h=b.width),c+=f+l}c-=l;const g=(this._style.strokeThickness||0)*2,p=Math.ceil(h+g)||1,v=Math.ceil(c+g)||1,T=p*a,E=v*a;(this.canvas.width!==T||this.canvas.height!==E)&&(this.canvas.width=T,this.canvas.height=E),t.setTransform(a,0,0,a,0,0),t.clearRect(0,0,p,v),t.font=n,t.textBaseline="top",t.textAlign="left",this.updateOffset(p,v);let S=g/2;for(const y of o){let b=g/2;this._style.stroke&&this._style.strokeThickness>0&&(t.lineWidth=this._style.strokeThickness,t.strokeStyle=this._style.stroke,t.strokeText(y,b,S)),this._style.fill&&(t.fillStyle=this._style.fill,t.fillText(y,b,S)),S+=f+l}this.base?.updateSource(this.render.gl,this.canvas,this.options),this.setRegion(0,0,this.canvas.width,this.canvas.height)}}const Kt=(s,t=!1,e=!0)=>{const i=s.getContext("webgl2",{stencil:!0,antialias:t,premultipliedAlpha:e});if(!i)throw new Error("WebGL2 is not supported in this browser.");return i},Tt=(s,t,e)=>{const i=s.createShader(e);if(!i)throw new Error("Unable to create webgl shader");if(s.shaderSource(i,t),s.compileShader(i),!s.getShaderParameter(i,s.COMPILE_STATUS)){const n=s.getShaderInfoLog(i);throw console.error("Shader compilation failed:",n),new Error("Unable to compile shader: "+n+t)}return i},qt=(s,t,e)=>{var i=s.createProgram(),r=Tt(s,t,35633),n=Tt(s,e,35632);if(!i)throw new Error("Unable to create program shader");if(s.attachShader(i,r),s.attachShader(i,n),s.linkProgram(i),!s.getProgramParameter(i,s.LINK_STATUS)){const o=s.getProgramInfoLog(i);throw new Error("Unable to link shader program: "+o)}return i};function rt(s,t){const e={[G.CLAMP]:s.CLAMP_TO_EDGE,[G.REPEAT]:s.REPEAT,[G.MIRRORED_REPEAT]:s.MIRRORED_REPEAT}[t]||s.CLAMP_TO_EDGE;s.texParameteri(s.TEXTURE_2D,s.TEXTURE_WRAP_S,e),s.texParameteri(s.TEXTURE_2D,s.TEXTURE_WRAP_T,e)}function st(s,t){const e={[et.LINEAR]:s.LINEAR,[et.NEAREST]:s.NEAREST}[t]??s.NEAREST;s.texParameteri(s.TEXTURE_2D,s.TEXTURE_MIN_FILTER,e),s.texParameteri(s.TEXTURE_2D,s.TEXTURE_MAG_FILTER,e)}function q(s,t,e){const i=s.gl,r=i.createTexture();if(!r)throw new Error("Unable to create WebGL texture");if(i.bindTexture(i.TEXTURE_2D,r),i.pixelStorei(i.UNPACK_FLIP_Y_WEBGL,0),i.pixelStorei(i.UNPACK_ALIGNMENT,1),rt(i,e.wrap??G.CLAMP),st(i,e.textureFilter??s.textureFilter),e.onlySize){const n=t;i.texImage2D(i.TEXTURE_2D,0,i.RGBA,n.width,n.height,0,i.RGBA,i.UNSIGNED_BYTE,null)}else{const n=e.premultipliedAlpha??s.premultipliedAlpha;n&&i.pixelStorei(i.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,i.RGBA,i.UNSIGNED_BYTE,t),n&&i.pixelStorei(i.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1)}return i.bindTexture(i.TEXTURE_2D,null),r}function B(s,t){if(s.includes("%TEXTURE_NUM%")&&(s=s.replace("%TEXTURE_NUM%",t.toString())),s.includes("%GET_COLOR%")){let e="";for(let i=0;i<t;i++)i==0?e+=`if(vTextureId == ${i})`:i==t-1?e+="else":e+=`else if(vTextureId == ${i})`,e+=`{return texture(uTextures[${i}], uv) * vColor;}`;s=s.replace("%GET_COLOR%",e)}return s}const Zt=5126,nt=5121;function Qt(s,t,e){s.vertexAttribDivisor(t,e)}function yt(s,t,e,i,r){s.drawArraysInstanced(t,e,i,r)}let Jt=0;class at{program;attributeLoc={};uniformLoc={};isCustom=!1;padding=0;uniformType={};uniformIsArray={};gl;shaderId=Jt++;vao;constructor(t,e,i,r){this.gl=t,this.program=qt(t,e,i),this.parseShader(e),this.parseShader(i),this.vao=t.createVertexArray(),r&&this.setAttributes(r)}use(){this.gl.useProgram(this.program)}bindVAO(){this.gl.bindVertexArray(this.vao)}unbindVAO(){this.gl.bindVertexArray(null)}setUniform(t,e){const i=this.uniformLoc[t];if(i===void 0)return;const r=this.uniformType[t],n=this.uniformIsArray[t];te(this.gl,i,r,e,n)}setUniforms(t){for(const e in t)this.setUniform(e,t[e])}setAttribute(t){const e=this.attributeLoc[t.name];if(e===void 0)return;const i=this.gl;i.vertexAttribPointer(e,t.size,t.type??Zt,t.normalized??!1,t.stride,t.offset??0),i.enableVertexAttribArray(e),Qt(i,e,t.divisor??0)}setAttributes(t){for(const e of t)this.setAttribute(e)}destroy(){this.gl.deleteProgram(this.program)}parseShader(t){const e=this.gl,i=t.match(/(?:in|attribute)\s+\w+\s+\w+/g);if(i)for(const n of i){const o=n.split(/\s+/)[2],h=e.getAttribLocation(this.program,o);h!==-1&&(this.attributeLoc[o]=h)}const r=t.match(/uniform\s+\w+\s+\w+(?:\[\d+\])?/g);if(r)for(const n of r){const a=n.split(/\s+/),o=a[1],h=a[2].replace(/\[\d+\]$/,""),c=e.getUniformLocation(this.program,h);c!==null&&(this.uniformLoc[h]=c,this.uniformType[h]=o,this.uniformIsArray[h]=/\[\d+\]$/.test(a[2]))}}}function te(s,t,e,i,r=!1){switch(e){case"float":return s.uniform1f(t,i);case"int":case"bool":case"sampler2D":case"samplerCube":return r?s.uniform1iv(t,i):s.uniform1i(t,i);case"vec2":return s.uniform2fv(t,i);case"vec3":return s.uniform3fv(t,i);case"vec4":return s.uniform4fv(t,i);case"ivec2":case"bvec2":return s.uniform2iv(t,i);case"ivec3":case"bvec3":return s.uniform3iv(t,i);case"ivec4":case"bvec4":return s.uniform4iv(t,i);case"mat2":return s.uniformMatrix2fv(t,!1,i);case"mat3":return s.uniformMatrix3fv(t,!1,i);case"mat4":return s.uniformMatrix4fv(t,!1,i);default:return ee(s,t,i)}}function ee(s,t,e){if(typeof e=="number")return s.uniform1f(t,e);const i=e;switch(i.length){case 2:return s.uniform2fv(t,i);case 3:return s.uniform3fv(t,i);case 4:return s.uniform4fv(t,i);case 9:return s.uniformMatrix3fv(t,!1,i);case 16:return s.uniformMatrix4fv(t,!1,i);default:return s.uniform1fv(t,i)}}class ht{vs;fs;glshader=new Map;uniforms={};uniformDirty=new Set;uniformTextures={};usedTextureUnitNum=0;padding=0;rapid;constructor(t,e,i,r=0,n){this.vs=e,this.fs=i,this.rapid=t,this.uniforms=n??{},this.usedTextureUnitNum=r}setUniforms(t){this.rapid.flush();const e={},i={};for(const[r,n]of Object.entries(t))n instanceof WebGLTexture?i[r]=n:e[r]=n;Object.assign(this.uniforms,e),Object.assign(this.uniformTextures,i);for(const r of this.glshader.keys())this.uniformDirty.add(r)}setPadding(t){this.padding=t;for(const e of this.glshader.values())e.padding=t;return this}applyUniform(t,e){const i=this.glshader.get(t);i&&(Object.keys(e).length>0&&i.setUniforms(e),this.uniformDirty.has(t)&&(i.setUniforms(this.uniforms),this.uniformDirty.delete(t)))}getGLShader(t,e,i,r){if(this.glshader.has(e))return this.glshader.get(e);if(r==null||i==null)return console.warn("CustomGlShader: missing base shader for "+e),null;i=i.replace("// CUSTOM_CODE_CALL","vertex(position, vRegion);"),r=r.replace("// CUSTOM_CODE_CALL","fragment(fragColor);"),i=i.replace("// CUSTOM_CODE",this.vs),r=r.replace("// CUSTOM_CODE",this.fs);const n=t.createShader(i,r);return n.isCustom=!0,n.padding=this.padding,this.glshader.set(e,n),this.uniformDirty.add(e),n}}const z=1/0;class ot{constructor(t){this.rapid=t,this.gl=t.gl,this.maxTextureUnits=t.maxTextureUnits,this.matrixStore=t.matrix}defaultShader;currentShader;customShader=null;customShaderUsedTextureNum=0;gl;maxTextureUnits;matrixStore;isDefaultShader=!0;KEY="default";vs="";fs="";usedTextures=[];usedTexturePadding=[];createBuffer(){}createDefaultShader(){}get freeTextureUnitNum(){return this.maxTextureUnits-this.usedTextures.length-this.customShaderUsedTextureNum}getTextureUnitList(){return Array.from({length:this.maxTextureUnits},(t,e)=>e)}findTextureUnit(t,e=0,i=0){for(let r=0;r<this.usedTextures.length;r++){const n=r*2;if(this.usedTextures[r]===t&&this.usedTexturePadding[n]===e&&this.usedTexturePadding[n+1]===i)return r}return-1}useTexture(t,e=0,i=0){const r=this.findTextureUnit(t,e,i);return r==-1?(this.freeTextureUnitNum===0&&this.flush(),this.usedTextures.push(t),this.usedTexturePadding.push(e),this.usedTexturePadding.push(i),this.usedTextures.length-1):r}createShader(t,e){return new at(this.gl,t,e)}createCustomShader(t){return t.getGLShader(this,this.KEY,this.vs,this.fs)}getCustomShader(t){if(!t)return this.defaultShader;if(t instanceof ht){const e=this.createCustomShader(t);return e??this.defaultShader}return t}isSameShader(t){return this.isDefaultShader&&!t?!0:this.getCustomShader(t)==this.currentShader}enter(t){this.resetRender(),this.currentShader=this.getCustomShader(t),t instanceof ht?(this.customShader=t,this.customShaderUsedTextureNum=t.usedTextureUnitNum):(this.customShader=null,this.customShaderUsedTextureNum=0),this.isDefaultShader=this.currentShader==this.defaultShader,this.currentShader.use(),this.currentShader.setUniform("u_projection",this.rapid.projection)}exit(){this.hasPendingContent()&&this.flush(),this.gl.bindVertexArray(null)}flush(){this.render(),this.resetRender()}render(){const t=this.currentShader;if(t.use(),this.customShader){const i=this.customShader,r={};for(const n in i.uniformTextures)r[n]=this.useTexture(i.uniformTextures[n]);this.customShader.applyUniform(this.KEY,r)}const e=this.gl;for(let i=0;i<this.usedTextures.length;i++)e.activeTexture(e.TEXTURE0+i),e.bindTexture(e.TEXTURE_2D,this.usedTextures[i]);t.setUniform("uTextures",Int32Array.from({length:this.usedTextures.length},(i,r)=>r)),t.setUniform("uPadding",Float32Array.from({length:this.usedTexturePadding.length},(i,r)=>this.usedTexturePadding[r]))}resetRender(){this.usedTextures.length=0,this.usedTexturePadding.length=0}hasPendingContent(){return!1}}const Z=`#version 300 es\r
|
|
3
3
|
precision mediump float;\r
|
|
4
4
|
\r
|
|
5
5
|
// per-vertex\r
|
|
@@ -96,7 +96,7 @@ void main(void) {\r
|
|
|
96
96
|
\r
|
|
97
97
|
// CUSTOM_CODE_CALL\r
|
|
98
98
|
}\r
|
|
99
|
-
`,X=48,Et=new Float32Array([0,0,1,0,0,1,1,1]);class Q extends ot{instanceBuffer;quadBuffer;instanceCount=0;localSpriteMatrix=new Float32Array(6);worldSpriteMatrix=new Float32Array(6);KEY="Sprite";constructor(t){super(t),this.createBuffer(),this.createDefaultShader()}createBuffer(){const t=this.gl;this.quadBuffer=new K(t,N.Float32,t.ARRAY_BUFFER,t.STATIC_DRAW),this.quadBuffer.bindBuffer();for(const e of Et)this.quadBuffer.pushFloat32(e);this.quadBuffer.makeDirty(),this.quadBuffer.bufferData(),this.instanceBuffer=new K(t,N.Uint32,t.ARRAY_BUFFER,t.DYNAMIC_DRAW)}createDefaultShader(){const t=this.rapid,e=B(Rt,t.maxTextureUnits),i=B(Z,t.maxTextureUnits);return this.vs=i,this.fs=e,this.defaultShader=this.createShader(i,e),this.defaultShader}createShader(t,e){const i=super.createShader(t,e);return i.use(),i.bindVAO(),this.instanceBuffer.bindBuffer(),i.setAttributes([{name:"aMatrixRow0",size:3,stride:X,offset:0,divisor:1},{name:"aMatrixRow1",size:3,stride:X,offset:12,divisor:1},{name:"aUVRect",size:4,stride:X,offset:24,divisor:1},{name:"aColor",size:4,type:nt,normalized:!0,stride:X,offset:40,divisor:1},{name:"aTextureId",size:1,type:nt,stride:X,offset:44,divisor:1}]),this.quadBuffer.bindBuffer(),i.setAttributes([{name:"aVertex",size:2,stride:8,offset:0,divisor:0}]),i.unbindVAO(),this.currentShader&&this.currentShader.use(),i}createCustomShader(t){const e=B(Rt,this.rapid.maxTextureUnits-t.usedTextureUnitNum),i=B(Z,this.rapid.maxTextureUnits-t.usedTextureUnitNum);return t.getGLShader(this,this.KEY,i,e)}drawSprite(t,e,i=0,r=0,n=1,a=1,o=4294967295,h=0,c=0,u=!1,f=!1,l=!1){const g=e*6,p=this.matrixStore.data;this.drawSpriteAffine(t,p[g],p[g+1],p[g+2],p[g+3],p[g+4],p[g+5],i,r,n,a,o,h,c,u,f,l)}drawSpriteAffine(t,e,i,r,n,a,o,h=0,c=0,u=1,f=1,l=4294967295,g=0,p=0,v=!1,T=!1,E=!1){
|
|
99
|
+
`,X=48,Et=new Float32Array([0,0,1,0,0,1,1,1]);class Q extends ot{instanceBuffer;quadBuffer;instanceCount=0;localSpriteMatrix=new Float32Array(6);worldSpriteMatrix=new Float32Array(6);KEY="Sprite";constructor(t){super(t),this.createBuffer(),this.createDefaultShader()}createBuffer(){const t=this.gl;this.quadBuffer=new K(t,N.Float32,t.ARRAY_BUFFER,t.STATIC_DRAW),this.quadBuffer.bindBuffer();for(const e of Et)this.quadBuffer.pushFloat32(e);this.quadBuffer.makeDirty(),this.quadBuffer.bufferData(),this.instanceBuffer=new K(t,N.Uint32,t.ARRAY_BUFFER,t.DYNAMIC_DRAW)}createDefaultShader(){const t=this.rapid,e=B(Rt,t.maxTextureUnits),i=B(Z,t.maxTextureUnits);return this.vs=i,this.fs=e,this.defaultShader=this.createShader(i,e),this.defaultShader}createShader(t,e){const i=super.createShader(t,e);return i.use(),i.bindVAO(),this.instanceBuffer.bindBuffer(),i.setAttributes([{name:"aMatrixRow0",size:3,stride:X,offset:0,divisor:1},{name:"aMatrixRow1",size:3,stride:X,offset:12,divisor:1},{name:"aUVRect",size:4,stride:X,offset:24,divisor:1},{name:"aColor",size:4,type:nt,normalized:!0,stride:X,offset:40,divisor:1},{name:"aTextureId",size:1,type:nt,stride:X,offset:44,divisor:1}]),this.quadBuffer.bindBuffer(),i.setAttributes([{name:"aVertex",size:2,stride:8,offset:0,divisor:0}]),i.unbindVAO(),this.currentShader&&this.currentShader.use(),i}createCustomShader(t){const e=B(Rt,this.rapid.maxTextureUnits-t.usedTextureUnitNum),i=B(Z,this.rapid.maxTextureUnits-t.usedTextureUnitNum);return t.getGLShader(this,this.KEY,i,e)}drawSprite(t,e,i=0,r=0,n=1,a=1,o=4294967295,h=0,c=0,u=!1,f=!1,l=!1){const g=e*6,p=this.matrixStore.data;this.drawSpriteAffine(t,p[g],p[g+1],p[g+2],p[g+3],p[g+4],p[g+5],i,r,n,a,o,h,c,u,f,l)}drawSpriteAffine(t,e,i,r,n,a,o,h=0,c=0,u=1,f=1,l=4294967295,g=0,p=0,v=!1,T=!1,E=!1){this.instanceCount>z&&this.flush();const S=t.base,y=t.scale??1,b=t.rawWidth,k=t.rawHeight,W=t.offsetX,I=t.offsetY,U=this.useTexture(t.glTexture,g/y/S.width,p/y/S.height),M=this.instanceBuffer,A=M.usedElemNum;M.resize(12);const C=M.float32,O=M.uint32,it=(E?k:b)*y,ft=(E?b:k)*y,V=it+2*g,Y=ft+2*p,Xt=W-g,jt=I-p,w=this.localSpriteMatrix;E?(w[0]=0,w[1]=T?Y:-Y,w[2]=v?-V:V,w[3]=0,w[4]=Xt+(v?V:0),w[5]=jt+(T?0:Y)):(w[0]=v?-V:V,w[1]=0,w[2]=0,w[3]=T?-Y:Y,w[4]=Xt+(v?V:0),w[5]=jt+(T?Y:0));const P=this.worldSpriteMatrix;P[0]=e*w[0]+r*w[1],P[1]=i*w[0]+n*w[1],P[2]=e*w[2]+r*w[3],P[3]=i*w[2]+n*w[3],P[4]=a+e*w[4]+r*w[5],P[5]=o+i*w[4]+n*w[5],C[A+6]=h,C[A+7]=c,C[A+8]=u,C[A+9]=f,O[A+10]=l,O[A+11]=U,this.rapid.roundPixels&&(P[4]=Math.round(P[4]),P[5]=Math.round(P[5])),C[A]=P[0],C[A+1]=P[2],C[A+2]=P[4],C[A+3]=P[1],C[A+4]=P[3],C[A+5]=P[5],M.usedElemNum+=12,M.makeDirty(),this.instanceCount++}render(){if(this.instanceCount===0)return;super.render();const t=this.gl,e=this.currentShader;this.instanceBuffer.bindBuffer(),this.instanceBuffer.bufferData(),e.bindVAO(),yt(t,t.TRIANGLE_STRIP,0,4,this.instanceCount),this.rapid.drawcallCount++}resetRender(){super.resetRender(),this.instanceBuffer.clear(),this.instanceCount=0}hasPendingContent(){return this.instanceCount>0}}const ie=`#version 300 es\r
|
|
100
100
|
precision mediump float;\r
|
|
101
101
|
\r
|
|
102
102
|
in vec2 aPosition;\r
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rapid-render",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.4",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist",
|
|
8
8
|
"index.d.ts"
|
|
9
9
|
],
|
|
10
|
+
"license":"MIT",
|
|
10
11
|
"main": "./dist/rapid.umd.cjs",
|
|
11
12
|
"module": "./dist/rapid.js",
|
|
12
13
|
"types": "./dist/index.d.ts",
|