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 CHANGED
@@ -72,8 +72,42 @@ Performance Comparison: Rapid vs. Other Renderers and Game Engines
72
72
  </a>
73
73
  </p>
74
74
 
75
- <p align="center">
76
- 🎮 <strong><a href="https://nightre.github.io/Rapid.js/benchmark/">Run Interactive Benchmark Live &rarr;</a></strong>
77
- </p>
78
-
79
- Tested on **NVIDIA GeForce RTX 4070 Laptop GPU** (Chrome / WebGL 2.0)
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.
@@ -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
- (this.freeTextureUnitNum === 0 || this.instanceCount > K) && this.flush();
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){(this.freeTextureUnitNum===0||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
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.2",
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",