rapid-render 0.1.21 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,268 @@
1
+ (function(f,A){typeof exports=="object"&&typeof module<"u"?A(exports):typeof define=="function"&&define.amd?define(["exports"],A):(f=typeof globalThis<"u"?globalThis:f||self,A(f.RapidRender={}))})(this,(function(f){"use strict";var A=(s=>(s[s.Float32=0]="Float32",s[s.Uint32=1]="Uint32",s[s.Uint16=2]="Uint16",s))(A||{});class W{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 z extends W{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 d{_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=d.clampByte(this._a),e=d.clampByte(this._r*t/255),i=d.clampByte(this._g*t/255),r=d.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,u=0;return t<60?[o,h,u]=[r,n,0]:t<120?[o,h,u]=[n,r,0]:t<180?[o,h,u]=[0,r,n]:t<240?[o,h,u]=[0,n,r]:t<300?[o,h,u]=[n,0,r]:[o,h,u]=[r,0,n],this.setRGBA((o+a)*255,(h+a)*255,(u+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 d(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 d(0,0,0).setHSL(t,e,i)}static FromRGB(t,e,i){return new d(t,e,i)}static fromNorm(t,e,i,r=1){return new d(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 d(e,i,r,n)}add(t){return new d(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 d(Math.max(0,this.r-t.r),Math.max(0,this.g-t.g),Math.max(0,this.b-t.b),Math.max(0,this.a-t.a))}divide(t){return t instanceof d?new d(this.r/t.r,this.g/t.g,this.b/t.b,this.a/t.a):new d(this.r/t,this.g/t,this.b/t,this.a/t)}multiply(t){return t instanceof d?new d(this.r*t.r,this.g*t.g,this.b*t.b,this.a*t.a):new d(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 d(255,0,0,255);static Green=new d(0,255,0,255);static Blue=new d(0,0,255,255);static Yellow=new d(255,255,0,255);static Purple=new d(128,0,128,255);static Orange=new d(255,165,0,255);static Pink=new d(255,192,203,255);static Gray=new d(128,128,128,255);static Brown=new d(139,69,19,255);static Cyan=new d(0,255,255,255);static Magenta=new d(255,0,255,255);static Lime=new d(192,255,0,255);static White=new d(255,255,255,255);static Black=new d(0,0,0,255);static Transparent=new d(0,0,0,0);static TRANSPARENT=new d(0,0,0,0)}const g=6;class ot{matrixCount=0;buffer;data;constructor(t=10){this.buffer=new W(A.Float32),this.buffer.resize(t*g),this.data=this.buffer.getArray()}alloc(){const t=this.allocDirty();return this.identity(t),t}allocDirty(){return this.buffer.resize(g)&&(this.data=this.buffer.getArray()),this.buffer.usedElemNum+=g,this.matrixCount++}reset(){this.matrixCount=0,this.buffer.usedElemNum=0}identity(t){const e=t*g,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*g,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*g,n=this.data;n[r]*=e,n[r+1]*=e,n[r+2]*=i,n[r+3]*=i}rotate(t,e){const i=t*g,r=this.data,n=Math.cos(e),a=Math.sin(e),o=r[i],h=r[i+1],u=r[i+2],c=r[i+3];r[i]=o*n+u*a,r[i+1]=h*n+c*a,r[i+2]=o*-a+u*n,r[i+3]=h*-a+c*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*g,r=e*g,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*g,n=e*g,a=i*g,o=this.data,h=o[n],u=o[n+1],c=o[n+2],x=o[n+3],m=o[n+4],T=o[n+5],p=o[a],y=o[a+1],E=o[a+2],M=o[a+3],P=o[a+4],_=o[a+5];o[r]=h*p+c*y,o[r+1]=u*p+x*y,o[r+2]=h*E+c*M,o[r+3]=u*E+x*M,o[r+4]=h*P+c*_+m,o[r+5]=u*P+x*_+T}invert(t){const e=t*g,i=this.data,r=i[e],n=i[e+1],a=i[e+2],o=i[e+3],h=i[e+4],u=i[e+5];let c=r*o-n*a;if(!c){this.identity(t);return}c=1/c,i[e]=o*c,i[e+1]=-n*c,i[e+2]=-a*c,i[e+3]=r*c,i[e+4]=(a*u-o*h)*c,i[e+5]=(n*h-r*u)*c}transformPoint(t,e,i){const r=t*g,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-=g,n}localToWorld(t,e,i){return this.transformPoint(t,e,i)}getPosition(t){const e=t*g,i=this.data;return{x:i[e+4],y:i[e+5]}}getScale(t){const e=t*g,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*g,i=this.data;return Math.atan2(i[e+1],i[e])}toCSSMatrix(t,e=1,i=1){const r=t*g,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*g;return this.data.slice(e,e+g)}getMatrixRef(t){const e=t*g;return this.data.subarray(e,e+g)}setMatrix(t,e){const i=t*g,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]}}class ut{matrix=new ot;step=0;stack=new W(A.Uint32);stepWorldM=new W(A.Uint32);stepAction=new W(A.Uint32);stepParentM=new W(A.Uint32);parentStack=new W(A.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),u=h-1,c=a.top();this.matrix.multiplyOut(h,c,u),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*g;return this.matrix.data.slice(t,t+g)}setTransform(t){const e=this.curWorldM*g,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(),t.afterSave?.();const r=t.x??0,n=t.y??0;(r||n)&&this.translate(r,n),t.position&&this.translate(t.position.x,t.position.y),t.rotation&&this.rotate(t.rotation);const a=t.scale,o=typeof a=="number";a&&this.scale(o?a:a.x,o?a:a.y);let h=t.offsetX??0,u=t.offsetY??0;t.offset&&(h+=t.offset.x,u+=t.offset.y);const c=t.origin;c!==void 0&&(typeof c=="number"?(h-=c*e,u-=c*i):(h-=c.x*e,u-=c.y*i)),this.translate(h,u)}}var k=(s=>(s[s.REPEAT=0]="REPEAT",s[s.CLAMP=1]="CLAMP",s[s.MIRRORED_REPEAT=2]="MIRRORED_REPEAT",s))(k||{});class ct{render;cache=new Map;constructor(t){this.render=t}async load(t,e){let i=this.cache.get(t);if(i)return new U(i);try{const r=await this._fetchImage(t);return i=F.fromSource(this.render,r,e),i.uid=t,this.cache.set(t,i),new U(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 U(this.cache.get(e.key));const i=F.fromSource(this.render,t,e);return e?.key&&(i.uid=e.key,this.cache.set(e.key,i)),new U(i)}createRenderTexture(t){return new lt(this.render,t)}createTextTexture(t){return new dt(this.render,t)}destroy(t,e=!1){let i,r;typeof t=="string"?(r=t,i=this.cache.get(r)):t instanceof U?(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 F{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=X(t,e,i);return new F(r,e.width,e.height)}updateSource(t,e,i={}){this.glTexture&&(t.bindTexture(t.TEXTURE_2D,this.glTexture),i.textureFilter!==void 0&&Z(t,i.textureFilter),i.wrap!==void 0&&q(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),Z(t,e),t.bindTexture(t.TEXTURE_2D,null))}setWrapMode(t,e){this.glTexture&&(t.bindTexture(t.TEXTURE_2D,this.glTexture),q(t,e),t.bindTexture(t.TEXTURE_2D,null))}destroy(t){this.glTexture&&(t.deleteTexture(this.glTexture),this.glTexture=null)}}class U{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 U;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 U(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,u=Math.max(0,n),c=t+u,x=e+u,m=i??Math.floor((o+u)/c),T=r??Math.floor((h+u)/x);for(let p=0;p<T;p++)for(let y=0;y<m;y++)a.push(this.getSubTexture(y*c,p*x,t,e));return a}static fromImageSource(t,e,i={}){const r=X(t,e,i);return new U(new F(r,e.width,e.height))}destroy(){this.base&&(this.base.refCount--,this.base=void 0),this.glTexture=null}}class lt extends U{framebuffer;renderbuffer;gl;flipY=!0;clearColor;_allocW=0;_allocH=0;constructor(t,e){super(),this.gl=t.gl,this.clearColor=e.clearColor??d.Black;const i=Math.max(Math.round(e.width),1),r=Math.max(Math.round(e.height),1),a=X(t,{width:i,height:r},{...e,onlySize:!0});if(this.setBase(new F(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 u=Math.min(o,this.rawWidth-n),c=Math.min(h,this.rawHeight-a),x=this.rawHeight-a-c,m=this.gl,T=m.getParameter(m.FRAMEBUFFER_BINDING);m.bindFramebuffer(m.FRAMEBUFFER,this.framebuffer);const p=new Uint8Array(u*c*4);return m.readPixels(n,x,u,c,m.RGBA,m.UNSIGNED_BYTE,p),m.bindFramebuffer(m.FRAMEBUFFER,T),p}GetColorAt(t,e){const i=this.GetPixels(t,e,1,1);return i.length<4?new d(0,0,0,0):new d(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 Lt={fontFamily:"Arial",fontSize:24,fontWeight:"normal",fill:"#000000",strokeThickness:1,align:"left",baseline:"top"};class dt extends U{canvas;ctx;render;_text;_style;options;flipY=!0;constructor(t,e){super(),this.render=t,this._style={...Lt,...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=X(t,this.canvas,this.options);this.setBase(new F(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,u=0;t.textBaseline="alphabetic";const c=t.measureText(o[0]),x=c.fontBoundingBoxAscent,m=c.fontBoundingBoxDescent;for(const _ of o){const v=t.measureText(_);v.width>h&&(h=v.width),u+=x+m}u-=m;const T=(this._style.strokeThickness||0)*2,p=Math.ceil(h+T)||1,y=Math.ceil(u+T)||1,E=p*a,M=y*a;(this.canvas.width!==E||this.canvas.height!==M)&&(this.canvas.width=E,this.canvas.height=M),t.setTransform(a,0,0,a,0,0),t.clearRect(0,0,p,y),t.font=n,t.textBaseline="top",t.textAlign="left",this.updateOffset(p,y);let P=T/2;for(const _ of o){let v=T/2;this._style.stroke&&this._style.strokeThickness>0&&(t.lineWidth=this._style.strokeThickness,t.strokeStyle=this._style.stroke,t.strokeText(_,v,P)),this._style.fill&&(t.fillStyle=this._style.fill,t.fillText(_,v,P)),P+=x+m}this.base?.updateSource(this.render.gl,this.canvas,this.options),this.setRegion(0,0,this.canvas.width,this.canvas.height)}}const It=(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},ft=(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},Ot=(s,t,e)=>{var i=s.createProgram(),r=ft(s,t,35633),n=ft(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 q(s,t){const e={[k.CLAMP]:s.CLAMP_TO_EDGE,[k.REPEAT]:s.REPEAT,[k.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 Z(s,t){const e={[$.LINEAR]:s.LINEAR,[$.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 X(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),q(i,e.wrap??k.CLAMP),Z(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 Wt=5126,mt=5121;function Ft(s,t,e){s.vertexAttribDivisor(t,e)}function Bt(s,t,e,i,r){s.drawArraysInstanced(t,e,i,r)}let Dt=0;class Q{program;attributeLoc={};uniformLoc={};isCustom=!1;padding=0;uniformType={};uniformIsArray={};gl;shaderId=Dt++;vao;constructor(t,e,i,r){this.gl=t,this.program=Ot(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];kt(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??Wt,t.normalized??!1,t.stride,t.offset??0),i.enableVertexAttribArray(e),Ft(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+\]$/,""),u=e.getUniformLocation(this.program,h);u!==null&&(this.uniformLoc[h]=u,this.uniformType[h]=o,this.uniformIsArray[h]=/\[\d+\]$/.test(a[2]))}}}function kt(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 Gt(s,t,i)}}function Gt(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 J{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}}class tt{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 Q(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 J){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 J?(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 K=`#version 300 es\r
3
+ precision mediump float;\r
4
+ \r
5
+ // per-vertex\r
6
+ in vec2 aVertex;\r
7
+ \r
8
+ // per-instance:2x3 仿射矩阵,拆成两个 vec3\r
9
+ in vec3 aMatrixRow0; // [a, c, tx]\r
10
+ in vec3 aMatrixRow1; // [b, d, ty]\r
11
+ \r
12
+ // per-instance:UV 区域 (u0, v0, u1, v1)\r
13
+ in vec4 aUVRect;\r
14
+ \r
15
+ // per-instance:tint color\r
16
+ in vec4 aColor;\r
17
+ \r
18
+ // per-instance:纹理索引\r
19
+ in float aTextureId;\r
20
+ \r
21
+ uniform mat4 u_projection;\r
22
+ uniform vec2 uPadding[%TEXTURE_NUM%];\r
23
+ \r
24
+ out vec2 vRegion;\r
25
+ flat out int vTextureId;\r
26
+ out vec4 vColor;\r
27
+ \r
28
+ out vec4 vUVRect;\r
29
+ out vec2 vPadding;\r
30
+ // CUSTOM_CODE\r
31
+ \r
32
+ void main(void) {\r
33
+ vPadding = uPadding[int(aTextureId)];\r
34
+ vUVRect = aUVRect;\r
35
+ vRegion = mix(aUVRect.xy - vPadding, aUVRect.zw + vPadding, aVertex.xy);\r
36
+ \r
37
+ vTextureId = int(aTextureId);\r
38
+ vColor = aColor;\r
39
+ \r
40
+ vec4 position = vec4(\r
41
+ dot(aMatrixRow0.xyz, vec3(aVertex.xy, 1.0)), \r
42
+ dot(aMatrixRow1.xyz, vec3(aVertex.xy, 1.0)), \r
43
+ 0.0, \r
44
+ 1.0\r
45
+ );\r
46
+ // CUSTOM_CODE_CALL\r
47
+ \r
48
+ gl_Position = u_projection * position;\r
49
+ }\r
50
+ `,xt=`#version 300 es\r
51
+ precision mediump float;\r
52
+ \r
53
+ uniform sampler2D uTextures[%TEXTURE_NUM%];\r
54
+ \r
55
+ in vec2 vRegion;\r
56
+ flat in int vTextureId;\r
57
+ in vec4 vColor;\r
58
+ \r
59
+ in vec4 vUVRect;\r
60
+ \r
61
+ out vec4 fragColor;\r
62
+ in vec2 vPadding;\r
63
+ \r
64
+ bool clampUV(vec2 uv) {\r
65
+ return uv.x < vUVRect.x || uv.x > vUVRect.z || uv.y < vUVRect.y || uv.y > vUVRect.w;\r
66
+ }\r
67
+ \r
68
+ vec4 sampleTexture(vec2 uv) {\r
69
+ %GET_COLOR%\r
70
+ }\r
71
+ \r
72
+ vec4 sampleClampTexture(vec2 uv) {\r
73
+ if (clampUV(uv)) {\r
74
+ return vec4(0.0, 0.0, 0.0, 0.0);\r
75
+ }\r
76
+ return sampleTexture(uv);\r
77
+ }\r
78
+ \r
79
+ vec4 sampleTextureLocal(vec2 uv){\r
80
+ vec2 gUV = mix(vUVRect.xy, vUVRect.zw, uv);\r
81
+ if (clampUV(gUV)) {\r
82
+ return vec4(0.0, 0.0, 0.0, 0.0);\r
83
+ }\r
84
+ return sampleTexture(gUV);\r
85
+ }\r
86
+ \r
87
+ // CUSTOM_CODE\r
88
+ \r
89
+ void main(void) {\r
90
+ fragColor = sampleTexture(vRegion);\r
91
+ // if (vPadding.x != 0.0) {\r
92
+ // if (clampUV(vRegion)) {\r
93
+ // fragColor = vec4(0.0, 0.0, 0.0, 0.0);\r
94
+ // }\r
95
+ // }\r
96
+ \r
97
+ // CUSTOM_CODE_CALL\r
98
+ }\r
99
+ `,H=48,Ht=new Float32Array([0,0,1,0,0,1,1,1]);class et extends tt{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 z(t,A.Float32,t.ARRAY_BUFFER,t.STATIC_DRAW),this.quadBuffer.bindBuffer();for(const e of Ht)this.quadBuffer.pushFloat32(e);this.quadBuffer.makeDirty(),this.quadBuffer.bufferData(),this.instanceBuffer=new z(t,A.Uint32,t.ARRAY_BUFFER,t.DYNAMIC_DRAW)}createDefaultShader(){const t=this.rapid,e=B(xt,t.maxTextureUnits),i=B(K,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:H,offset:0,divisor:1},{name:"aMatrixRow1",size:3,stride:H,offset:12,divisor:1},{name:"aUVRect",size:4,stride:H,offset:24,divisor:1},{name:"aColor",size:4,type:mt,normalized:!0,stride:H,offset:40,divisor:1},{name:"aTextureId",size:1,type:mt,stride:H,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(xt,this.rapid.maxTextureUnits-t.usedTextureUnitNum),i=B(K,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,u=0,c=!1,x=!1,m=!1){this.freeTextureUnitNum===0&&this.flush();const T=t.base,p=t.scale||1,y=t.rawWidth,E=t.rawHeight,M=t.offsetX,P=t.offsetY,_=this.useTexture(t.glTexture,h/p/T.width,u/p/T.height),v=e*6,w=this.matrixStore.data,L=this.instanceBuffer,C=L.usedElemNum;L.resize(12);const N=L.float32,D=L.uint32,G=(m?E:y)*p,ht=(m?y:E)*p,I=G+2*h,O=ht+2*u,j=M-h,Pt=P-u,R=this.localSpriteMatrix;m?(R[0]=0,R[1]=x?O:-O,R[2]=c?-I:I,R[3]=0,R[4]=j+(c?I:0),R[5]=Pt+(x?0:O)):(R[0]=c?-I:I,R[1]=0,R[2]=0,R[3]=x?-O:O,R[4]=j+(c?I:0),R[5]=Pt+(x?O:0));const S=this.worldSpriteMatrix;S[0]=w[v]*R[0]+w[v+2]*R[1],S[1]=w[v+1]*R[0]+w[v+3]*R[1],S[2]=w[v]*R[2]+w[v+2]*R[3],S[3]=w[v+1]*R[2]+w[v+3]*R[3],S[4]=w[v+4]+w[v]*R[4]+w[v+2]*R[5],S[5]=w[v+5]+w[v+1]*R[4]+w[v+3]*R[5],N[C+6]=i,N[C+7]=r,N[C+8]=n,N[C+9]=a,D[C+10]=o,D[C+11]=_,this.rapid.roundPixels&&(S[4]=Math.round(S[4]),S[5]=Math.round(S[5])),N[C]=S[0],N[C+1]=S[2],N[C+2]=S[4],N[C+3]=S[1],N[C+4]=S[3],N[C+5]=S[5],L.usedElemNum+=12,L.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(),Bt(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 Vt=`#version 300 es\r
100
+ precision mediump float;\r
101
+ \r
102
+ in vec2 aPosition;\r
103
+ in vec4 aColor;\r
104
+ in vec2 aUV;\r
105
+ \r
106
+ uniform mat4 u_projection;\r
107
+ uniform vec3 uMatrixRow0; // [a, c, tx]\r
108
+ uniform vec3 uMatrixRow1; // [b, d, ty]\r
109
+ uniform vec4 uUVRect;\r
110
+ \r
111
+ out vec4 vColor;\r
112
+ out vec2 vRegion;\r
113
+ out vec4 vUVRect;\r
114
+ \r
115
+ // CUSTOM_CODE\r
116
+ \r
117
+ void main(void) {\r
118
+ vColor = aColor;\r
119
+ vUVRect = uUVRect;\r
120
+ vRegion = mix(uUVRect.xy, uUVRect.zw, aUV);\r
121
+ vec4 position = vec4(\r
122
+ dot(uMatrixRow0.xyz, vec3(aPosition.xy, 1.0)), \r
123
+ dot(uMatrixRow1.xyz, vec3(aPosition.xy, 1.0)), \r
124
+ 0.0, \r
125
+ 1.0\r
126
+ );\r
127
+ // CUSTOM_CODE_CALL\r
128
+ gl_Position = u_projection * position;\r
129
+ }\r
130
+ `,Yt=`#version 300 es\r
131
+ precision mediump float;\r
132
+ \r
133
+ in vec4 vColor;\r
134
+ in vec2 vRegion;\r
135
+ in vec4 vUVRect;\r
136
+ \r
137
+ uniform sampler2D uTexture;\r
138
+ uniform int uUseTexture;\r
139
+ \r
140
+ out vec4 fragColor;\r
141
+ \r
142
+ bool clampUV(vec2 uv) {\r
143
+ vec2 uvMin = min(vUVRect.xy, vUVRect.zw);\r
144
+ vec2 uvMax = max(vUVRect.xy, vUVRect.zw);\r
145
+ return uv.x < uvMin.x || uv.x > uvMax.x || uv.y < uvMin.y || uv.y > uvMax.y;\r
146
+ }\r
147
+ \r
148
+ vec4 sampleTexture(vec2 uv) {\r
149
+ if (uUseTexture > 0) {\r
150
+ return texture(uTexture, uv) * vColor;\r
151
+ }\r
152
+ return vColor;\r
153
+ }\r
154
+ \r
155
+ vec4 sampleClampTexture(vec2 uv) {\r
156
+ if (clampUV(uv)) {\r
157
+ return vec4(0.0, 0.0, 0.0, 0.0);\r
158
+ }\r
159
+ return sampleTexture(uv);\r
160
+ }\r
161
+ \r
162
+ vec4 sampleTextureLocal(vec2 uv) {\r
163
+ vec2 gUV = mix(vUVRect.xy, vUVRect.zw, uv);\r
164
+ if (clampUV(gUV)) {\r
165
+ return vec4(0.0, 0.0, 0.0, 0.0);\r
166
+ }\r
167
+ return sampleTexture(gUV);\r
168
+ }\r
169
+ \r
170
+ // CUSTOM_CODE\r
171
+ \r
172
+ void main(void) {\r
173
+ fragColor = sampleTexture(vRegion);\r
174
+ // CUSTOM_CODE_CALL\r
175
+ }\r
176
+ `,zt=`#version 300 es\r
177
+ precision mediump float;\r
178
+ \r
179
+ in vec2 aPosition;\r
180
+ in vec2 aUV;\r
181
+ \r
182
+ uniform mat4 u_projection;\r
183
+ uniform vec3 uMatrixRow0; // [a, c, tx]\r
184
+ uniform vec3 uMatrixRow1; // [b, d, ty]\r
185
+ uniform vec4 uUVRect;\r
186
+ \r
187
+ out vec2 vRegion;\r
188
+ \r
189
+ void main(void) {\r
190
+ vRegion = mix(uUVRect.xy, uUVRect.zw, aUV);\r
191
+ vec4 position = vec4(\r
192
+ dot(uMatrixRow0.xyz, vec3(aPosition.xy, 1.0)), \r
193
+ dot(uMatrixRow1.xyz, vec3(aPosition.xy, 1.0)), \r
194
+ 0.0, \r
195
+ 1.0\r
196
+ );\r
197
+ gl_Position = u_projection * position;\r
198
+ }\r
199
+ `,Xt=`#version 300 es\r
200
+ precision mediump float;\r
201
+ \r
202
+ in vec2 vRegion;\r
203
+ \r
204
+ uniform sampler2D uTexture;\r
205
+ uniform int uUseTexture;\r
206
+ \r
207
+ out vec4 fragColor;\r
208
+ \r
209
+ void main(void) {\r
210
+ if (uUseTexture > 0) {\r
211
+ fragColor = texture(uTexture, vRegion);\r
212
+ } else {\r
213
+ fragColor = vec4(1.0);\r
214
+ }\r
215
+ if(fragColor.a == 0.0) {\r
216
+ discard;\r
217
+ }\r
218
+ }\r
219
+ `,V=20;class pt extends tt{vertexBuffer;vertexCount=0;matrixIndex=-1;drawMode=this.gl.TRIANGLES;texture;maskShader;KEY="Graphic";constructor(t){super(t),this.createBuffer(),this.createDefaultShader()}createBuffer(){const t=this.gl;this.vertexBuffer=new z(t,A.Float32,t.ARRAY_BUFFER,t.DYNAMIC_DRAW),this.maskShader=this.createMaskShader(zt,Xt)}createDefaultShader(){return this.vs=Vt,this.fs=Yt,this.defaultShader=this.createShader(this.vs,this.fs),this.defaultShader}createMaskShader(t,e){const i=this.gl,r=new Q(i,t,e);return r.use(),r.bindVAO(),this.vertexBuffer.bindBuffer(),r.setAttributes([{name:"aPosition",size:2,type:i.FLOAT,stride:V-4,offset:0,divisor:0},{name:"aUV",size:2,type:i.FLOAT,stride:V-4,offset:8,divisor:0}]),r.unbindVAO(),this.currentShader&&this.currentShader.use(),r}createShader(t,e){const i=this.gl,r=super.createShader(t,e);return r.use(),r.bindVAO(),this.vertexBuffer.bindBuffer(),r.setAttributes([{name:"aPosition",size:2,type:i.FLOAT,stride:V,offset:0,divisor:0},{name:"aColor",size:4,type:i.UNSIGNED_BYTE,normalized:!0,stride:V,offset:8,divisor:0},{name:"aUV",size:2,type:i.FLOAT,stride:V,offset:12,divisor:0}]),r.unbindVAO(),this.currentShader&&this.currentShader.use(),r}startGraphic(t,e=this.gl.TRIANGLES,i){this.vertexBuffer.clear(),this.vertexCount=0,this.matrixIndex=t,this.drawMode=e,this.texture=i}addVertex(t,e,i=0,r=0,n=4294967295){const a=this.vertexBuffer;a.pushFloat32(t),a.pushFloat32(e),this.currentShader!=this.maskShader&&a.pushUint32(n),a.pushFloat32(i),a.pushFloat32(r),this.vertexCount++,this.vertexBuffer.makeDirty()}endGraphic(){this.render()}render(){if(this.vertexCount===0)return;super.render();const t=this.gl,e=this.currentShader,i=this.matrixIndex*6,r=this.matrixStore.data;let n=r[i+4],a=r[i+5];this.rapid.roundPixels&&(n=Math.round(n),a=Math.round(a)),e.setUniform("uMatrixRow0",[r[i],r[i+2],n]),e.setUniform("uMatrixRow1",[r[i+1],r[i+3],a]),e.setUniform("uUVRect",this.texture?[this.texture.uvX,this.texture.uvY,this.texture.uvW,this.texture.uvH]:[0,0,1,1]),this.texture?.glTexture?(t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.texture.glTexture),e.setUniform("uTexture",0),e.setUniform("uUseTexture",1)):e.setUniform("uUseTexture",0),this.vertexBuffer.bindBuffer(),this.vertexBuffer.bufferData(),e.bindVAO(),t.drawArrays(this.drawMode,0,this.vertexCount),this.rapid.drawcallCount++}hasPendingContent(){return!1}}class l{x;y;static ZERO=new l(0,0);static ONE=new l(1,1);static UP=new l(0,1);static DOWN=new l(0,-1);static LEFT=new l(-1,0);static RIGHT=new l(1,0);constructor(t,e){this.x=t!==void 0?t:0,this.y=e!==void 0?e:0}set(t,e){return e===void 0?(this.x=t,this.y=t):(this.x=t,this.y=e),this}add(t){return new l(this.x+t.x,this.y+t.y)}subtract(t){return new l(this.x-t.x,this.y-t.y)}sub(t){return new l(this.x-t.x,this.y-t.y)}multiply(t){return t instanceof l?new l(this.x*t.x,this.y*t.y):new l(this.x*t,this.y*t)}mul(t){return this.multiply(t)}divide(t){return t instanceof l?new l(this.x/t.x,this.y/t.y):new l(this.x/t,this.y/t)}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}distanceTo(t){const e=this.x-t.x,i=this.y-t.y;return Math.sqrt(e*e+i*i)}clone(){return new l(this.x,this.y)}to(t){this.x=t.x,this.y=t.y}copy(){return new l(this.x,this.y)}equals(t){return t.x==this.x&&t.y==this.y}perpendicular(){const t=this.x;return this.x=-this.y,this.y=t,this}invert(){return this.x=-this.x,this.y=-this.y,this}inverted(){return new l(this.x*-1,this.y*-1)}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}squaredLength(){return this.x*this.x+this.y*this.y}normalize(){const t=this.length();return this.x=this.x/t||0,this.y=this.y/t||0,this}normalized(){const t=this.length();return new l(this.x/t||0,this.y/t||0)}fix(t=1e-13){this.x=Math.abs(this.x)<t?0:this.x,this.y=Math.abs(this.y)<t?0:this.y}fixed(t=1e-13){return new l(Math.abs(this.x)<t?0:this.x,Math.abs(this.y)<t?0:this.y)}angle(){return Math.atan2(this.y,this.x)}abs(){return new l(Math.abs(this.x),Math.abs(this.y))}floor(){return new l(Math.floor(this.x),Math.floor(this.y))}ceil(){return new l(Math.ceil(this.x),Math.ceil(this.y))}stringify(){return`Vec2(${this.x}, ${this.y})`}clear(){this.x=0,this.y=0}isPrettyMuchZero(){return Math.abs(this.x)<1e-4&&Math.abs(this.y)<1e-4}isZero(){return this.x==0&&this.y==0}isNotZero(){return this.x!==0||this.y!==0}setToPolar(t,e=1){return this.x=Math.cos(t)*e,this.y=Math.sin(t)*e,this}static FromArray(t){return t.map(e=>new l(e[0],e[1]))}static fromAngle(t){return new l(Math.cos(t),Math.sin(t))}}const it=10,gt=(s,t,e,i,r,n)=>{const a=[],o=[],h=i?Math.atan2(t.y,t.x):Math.atan2(-t.y,-t.x),u=Math.PI,c=new l(t.y,-t.x);for(let x=0;x<it;x++){const m=x/it,T=(x+1)/it,p=h+m*u,y=h+T*u,E=new l(Math.cos(p)*e,Math.sin(p)*e),M=new l(Math.cos(y)*e,Math.sin(y)*e);a.push(s),o.push(new l(r,.5)),a.push(s.add(E)),o.push(new l(r+E.dot(c)*n,.5-.5*E.dot(t)/e)),a.push(s.add(M)),o.push(new l(r+M.dot(c)*n,.5-.5*M.dot(t)/e))}return{vertices:a,uv:o}},Kt=(s,t=!1)=>{const e=[];if(s.length<2||t&&s.length<3)return{normals:e,length:0};const i=4,r=.001,n=s.length;let a=0;if(t)for(let h=0;h<n;h++){const u=s[h],c=s[(h+1)%n];a+=u.distanceTo(c)}else for(let h=0;h<n-1;h++)a+=s[h].distanceTo(s[h+1]);const o=(h,u,c)=>{const x=u.subtract(h).normalize(),m=u.subtract(c).normalize(),T=m.dot(x);if(T<-1+r)return{normal:x.perpendicular(),miters:1};{let p=m.add(x).normalize();x.cross(m)<0&&(p=p.multiply(-1));let y=1/Math.sqrt((1-T)/2);return{normal:p,miters:Math.min(y,i)}}};if(t)for(let h=0;h<n;h++){const u=h===0?s[n-1]:s[h-1],c=s[h],x=h===n-1?s[0]:s[h+1];e.push(o(u,c,x))}else for(let h=0;h<n;h++)if(h===0){const u=s[1].subtract(s[0]).normalize();e.push({normal:u.perpendicular(),miters:1})}else if(h===n-1){const u=s[h].subtract(s[h-1]).normalize();e.push({normal:u.perpendicular(),miters:1})}else e.push(o(s[h-1],s[h],s[h+1]));return{normals:e,length:a}},$t=s=>{const t=s.points;if(t.length<2)return{vertices:[],uv:[]};const{normals:e,length:i}=Kt(t,s.closed),r=(s.width||1)/2,n=[],a=[],o=s.roundCap||!1,h=s.textureMode||0;let u=0;const c=s.texture?.rawWidth||1,x=s.closed?t.length:t.length-1;for(let m=0;m<x;m++){const T=t[m],p=e[m].normal,y=e[m].miters,E=(m+1)%t.length,M=t[E],P=e[E].normal,_=e[E].miters,v=T.add(p.multiply(y*r)),w=T.subtract(p.multiply(y*r)),L=M.add(P.multiply(_*r)),C=M.subtract(P.multiply(_*r)),N=T.distanceTo(M);let D=0,G=0;h===0?(D=u/i,G=(u+N)/i):(D=u/c,G=D+N/c);const ht=new l(D,0),I=new l(D,1),O=new l(G,0),j=new l(G,1);n.push(v),a.push(ht),n.push(w),a.push(I),n.push(L),a.push(O),n.push(L),a.push(O),n.push(C),a.push(j),n.push(w),a.push(I),u+=N}if(o&&!s.closed){const m=t[0],T=e[0].normal,p=h===0?i>0?1/i:0:1/c,y=gt(m,T,r,!0,0,p);n.push(...y.vertices),a.push(...y.uv);const E=t[t.length-1],M=e[t.length-1].normal,P=h===0?1:u/c,_=h===0?i>0?1/i:0:1/c,v=gt(E,M,r,!1,P,_);n.push(...v.vertices),a.push(...v.uv)}return{vertices:n,uv:a}},jt=s=>s.saveTransform!==void 0||s.afterSave!==void 0||s.x!==void 0||s.y!==void 0||s.position!==void 0||s.rotation!==void 0||s.scale!==void 0||s.offsetX!==void 0||s.offsetY!==void 0||s.offset!==void 0||s.origin!==void 0,Y=(s,t,e,i,r)=>{if(!jt(t)){r();return}s.matrixStack.applyTransform(t,e,i);try{r()}finally{(t.saveTransform??!0)&&s.matrixStack.restore()}},rt=(s,t)=>t?s.premultipliedAlpha?t.premultipliedUint32:t.uint32:4294967295,qt=2,st=(s,t)=>{const e=t.texture;if(!e?.base||s.inCreateMask)return;const i=e.isAtlas?s.atlasSpriteRegion:s.spriteRegion;s.enterRegion(i,t.shader);let r=e.uvX,n=e.uvY,a=e.uvW,o=e.uvH;const h=!!t.flipX,u=!!t.flipY!=!!e.flipY;let c=t.padding??i.currentShader.padding;e.isAtlas&&(c+=qt);const x=r<=a?c:-c,m=n<=o?c:-c;i.drawSprite(e,t.customMatrix??s.matrixStack.curWorldM,r,n,a,o,rt(s,t.color),x,m,h,u,e.isRotated)},vt=(s,t)=>{Y(s,t,t.texture.rawWidth,t.texture.rawHeight,()=>{st(s,t)})},nt=(s,t)=>{t.points.length!==0&&Y(s,t,0,0,()=>{s.startGraphic(t.drawMode??s.gl.TRIANGLES,t.texture,t.shader,t.customMatrix);for(let e=0;e<t.points.length;e++){const i=t.points[e],r=t.uv?.[e],n=Array.isArray(t.color)?t.color[e]:t.color;s.addGraphicVertex(i.x,i.y,r?.x??0,r?.y??0,rt(s,n))}s.endGraphic()})},Tt=(s,t)=>{if(s.inCreateMask)return;const{vertices:e,uv:i}=$t(t);nt(s,{...t,points:e,uv:i,drawMode:s.gl.TRIANGLES})},yt=(s,t)=>{Y(s,t,t.texture.rawWidth,t.texture.rawHeight,()=>{s.startMaskGraphic(s.gl.TRIANGLE_FAN,t.texture,t.customMatrix),s.addRectVertex(t.texture.rawWidth,t.texture.rawHeight),s.endGraphic()})},Rt=(s,t)=>{Y(s,t,t.width,t.height,()=>{s.startGraphic(s.gl.TRIANGLE_FAN,t.texture,t.shader,t.customMatrix),s.addRectVertex(t.width,t.height,t.color),s.endGraphic()})},Et=(s,t)=>{const e=t.segments??32;Y(s,t,0,0,()=>{s.startGraphic(s.gl.TRIANGLE_FAN,void 0,t.shader,t.customMatrix);const i=rt(s,t.color);s.addGraphicVertex(0,0,.5,.5,i),s.addCircleVertex(t.radius,t.color,e),s.addGraphicVertex(t.radius,0,1,.5,i),s.endGraphic()})},Mt=`#version 300 es\r
220
+ precision mediump float;\r
221
+ \r
222
+ uniform sampler2D uTextures[%TEXTURE_NUM%];\r
223
+ \r
224
+ in vec2 vRegion;\r
225
+ flat in int vTextureId;\r
226
+ in vec4 vColor;\r
227
+ \r
228
+ in vec4 vUVRect;\r
229
+ \r
230
+ out vec4 fragColor;\r
231
+ in vec2 vPadding;\r
232
+ \r
233
+ bool clampUV(vec2 uv) {\r
234
+ return uv.x < vUVRect.x || uv.x > vUVRect.z || uv.y < vUVRect.y || uv.y > vUVRect.w;\r
235
+ }\r
236
+ \r
237
+ vec4 sampleTexture(vec2 uv) {\r
238
+ %GET_COLOR%\r
239
+ }\r
240
+ \r
241
+ vec4 sampleClampTexture(vec2 uv) {\r
242
+ if (clampUV(uv)) {\r
243
+ return vec4(0.0, 0.0, 0.0, 0.0);\r
244
+ }\r
245
+ return sampleTexture(uv);\r
246
+ }\r
247
+ \r
248
+ vec4 sampleTextureLocal(vec2 uv){\r
249
+ vec2 gUV = mix(vUVRect.xy, vUVRect.zw, uv);\r
250
+ if (clampUV(gUV)) {\r
251
+ return vec4(0.0, 0.0, 0.0, 0.0);\r
252
+ }\r
253
+ return sampleTexture(gUV);\r
254
+ }\r
255
+ \r
256
+ // CUSTOM_CODE\r
257
+ \r
258
+ void main(void) {\r
259
+ fragColor = sampleClampTexture(vRegion);\r
260
+ // if (vPadding.x != 0.0) {\r
261
+ // if (clampUV(vRegion)) {\r
262
+ // fragColor = vec4(0.0, 0.0, 0.0, 0.0);\r
263
+ // }\r
264
+ // }\r
265
+ \r
266
+ // CUSTOM_CODE_CALL\r
267
+ }\r
268
+ `;class Zt extends et{KEY="AtlasSprite";constructor(t){super(t)}createCustomShader(t){const e=B(Mt,this.rapid.maxTextureUnits-t.usedTextureUnitNum),i=B(K,this.rapid.maxTextureUnits-t.usedTextureUnitNum);return t.getGLShader(this,this.KEY,i,e)}createDefaultShader(){const t=this.rapid,e=B(Mt,t.maxTextureUnits),i=B(K,t.maxTextureUnits);return this.vs=i,this.fs=e,this.defaultShader=this.createShader(i,e),this.defaultShader}}var wt=(s=>(s[s.EQUAL=0]="EQUAL",s[s.NOT_EQUAL=1]="NOT_EQUAL",s))(wt||{}),bt=(s=>(s[s.NORMAL=0]="NORMAL",s[s.ADD=1]="ADD",s[s.MULTIPLY=2]="MULTIPLY",s[s.SCREEN=3]="SCREEN",s[s.ERASE=4]="ERASE",s))(bt||{}),$=(s=>(s[s.LINEAR=0]="LINEAR",s[s.NEAREST=1]="NEAREST",s))($||{}),St=(s=>(s[s.CanvasItem=0]="CanvasItem",s[s.Viewport=1]="Viewport",s))(St||{});class Qt{gl;canvas;projection=new Float32Array(16);projectionDirty=!0;dpr;backgroundColor=d.Black;logicWidth=0;logicHeight=0;physicsWidth=0;physicsHeight=0;currentRegion=null;maxTextureUnits=0;matrixStack=new ut(this);matrix;spriteRegion;graphicRegion;atlasSpriteRegion;drawcallCount=0;inCreateMask=!1;texture;premultipliedAlpha;antialias;roundPixels;textureFilter;scaleMode;_filterRT=[null,null];_filterInput=new U;get height(){return this.logicHeight}get width(){return this.logicWidth}constructor(t){this.canvas=t.canvas,this.dpr=window.devicePixelRatio||1,this.antialias=t.antialias??!1,this.textureFilter=t.textureFilter??1,this.premultipliedAlpha=t.premultipliedAlpha??!0,this.roundPixels=t.roundPixels??!1,this.scaleMode=t.scaleMode??0;const e=It(this.canvas,this.antialias,this.premultipliedAlpha);this.gl=e,this.maxTextureUnits=e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS),this.matrix=this.matrixStack.matrix,this.spriteRegion=new et(this),this.graphicRegion=new pt(this),this.atlasSpriteRegion=new Zt(this);const i=this.canvas.clientWidth||this.canvas.width,r=this.canvas.clientHeight||this.canvas.height;this.physicsWidth=t.physicsWidth||Math.round(i*this.dpr),this.physicsHeight=t.physicsHeight||Math.round(r*this.dpr),this.logicWidth=t.logicWidth||this.physicsWidth/this.dpr,this.logicHeight=t.logicHeight||this.physicsHeight/this.dpr,this.resize(this.logicWidth,this.logicHeight,this.physicsWidth,this.physicsHeight),this.texture=new ct(this),t.backgroundColor&&(this.backgroundColor=t.backgroundColor),e.enable(e.BLEND),this.premultipliedAlpha?e.blendFunc(e.ONE,e.ONE_MINUS_SRC_ALPHA):e.blendFunc(e.SRC_ALPHA,e.ONE_MINUS_SRC_ALPHA),e.enable(e.STENCIL_TEST),e.stencilFunc(e.ALWAYS,1,255),e.stencilOp(e.KEEP,e.KEEP,e.KEEP)}setTextureFilter(t){this.textureFilter=t}setAntialias(t){this.antialias=t}getColorUint32(t){return t?this.premultipliedAlpha?t.premultipliedUint32:t.uint32:4294967295}enterRegion(t,e){this.currentRegion===t&&this.currentRegion.isSameShader(e)||(this.flush(),this.currentRegion=t,t.enter(e))}drawSprite(t){vt(this,t)}drawLine(t){Tt(this,t)}drawGraphic(t){nt(this,t)}drawRect(t){Rt(this,t)}drawCircle(t){Et(this,t)}startGraphic(t=this.gl.TRIANGLES,e,i,r){this.enterRegion(this.graphicRegion,i),this.graphicRegion.startGraphic(r??this.matrixStack.curWorldM,t,e)}startMaskGraphic(t=this.gl.TRIANGLES,e,i){this.startGraphic(t,e,this.graphicRegion.maskShader,i)}drawMaskImage(t){yt(this,t)}addRectVertex(t,e,i){const r=this.getColorUint32(i);this.addGraphicVertex(0,0,0,0,r),this.addGraphicVertex(t,0,1,0,r),this.addGraphicVertex(t,e,1,1,r),this.addGraphicVertex(0,e,0,1,r)}addCircleVertex(t,e,i=32){const r=Math.PI*2/i,n=this.getColorUint32(e);for(let a=0;a<i;a++){const o=r*a,h=Math.cos(o)*t,u=Math.sin(o)*t,c=.5+Math.cos(o)*.5,x=.5+Math.sin(o)*.5;this.addGraphicVertex(h,u,c,x,n)}}addGraphicVertex(t,e,i=0,r=0,n=4294967295){this.graphicRegion.addVertex(t,e,i,r,n)}endGraphic(){this.graphicRegion.endGraphic()}resize(t,e,i,r){this.flush();const n=i??this.canvas.clientWidth??this.canvas.width,a=r??this.canvas.clientHeight??this.canvas.height;switch(i!==void 0&&(this.canvas.style.width=n+"px"),r!==void 0&&(this.canvas.style.height=a+"px"),this.physicsWidth=n*this.dpr,this.physicsHeight=a*this.dpr,this.logicWidth=t,this.logicHeight=e,this.scaleMode){case 1:this.canvas.width=t,this.canvas.height=e,this.canvas.style.imageRendering="pixelated",this.gl.viewport(0,0,t,e);break;case 0:this.canvas.width=this.physicsWidth,this.canvas.height=this.physicsHeight,this.canvas.style.imageRendering="auto",this.gl.viewport(0,0,this.physicsWidth,this.physicsHeight);break;default:throw new Error("scaleMode can only be CanvasScaleMode.Viewport or CanvasScaleMode.CanvasItem")}this.updateProjection(0,this.logicWidth,this.logicHeight,0)}updateProjection(t,e,i,r){this.updateOrthMatrix(this.projection,t,e,i,r),this.projectionDirty=!0}clear(){const t=this.gl;this.backgroundColor.setClearColor(t),t.clear(t.COLOR_BUFFER_BIT|t.STENCIL_BUFFER_BIT),this.drawcallCount=0,this.matrixStack.reset()}updateOrthMatrix(t,e,i,r,n){t[0]=2/(i-e),t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2/(n-r),t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=-1,t[11]=0,t[12]=-(i+e)/(i-e),t[13]=-(n+r)/(n-r),t[14]=0,t[15]=1}flush(){this.currentRegion&&(this.currentRegion.exit(),this.currentRegion=null)}applyFilters(t,e){if(e.length===0)throw new Error("applyFilters: shaders array must not be empty.");const i=Math.max(...e.map(u=>u.padding)),r=i,n=t.rawWidth+i*2,a=t.rawHeight+i*2;for(let u=0;u<2;u++)this._filterRT[u]?this._filterRT[u].resize(n,a):this._filterRT[u]=this.texture.createRenderTexture({width:n,height:a});let o=t.clone(this._filterInput),h=0;this.matrixStack.save(),this.matrixStack.identity();for(let u=0;u<e.length;u++){const c=this._filterRT[h%2];c.offsetX=0,c.offsetY=0,this.enterRenderTexture(c),this.clearRenderTexture(),this.drawSprite({texture:o,shader:e[u],offsetX:u==0?r:0,offsetY:u==0?r:0,padding:i}),this.leaveRenderTexture(),o=c,h++}return this.matrixStack.restore(),o.offsetX=-r,o.offsetY=-r,o}enterRenderTexture(t){this.flush(),t.activate(),this.gl.viewport(0,0,t.rawWidth,t.rawHeight),this.updateProjection(0,t.rawWidth,t.rawHeight,0)}clearRenderTexture(t=new d(0,0,0,0)){this.flush();const e=this.gl;t.setClearColor(e),e.clear(e.COLOR_BUFFER_BIT)}leaveRenderTexture(){this.flush(),this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,null),this.gl.viewport(0,0,this.physicsWidth,this.physicsHeight),this.updateProjection(0,this.logicWidth,this.logicHeight,0)}drawToRenderTexture(t,e,i=new d(0,0,0,0)){this.enterRenderTexture(t);try{i!==null&&this.clearRenderTexture(i),e()}finally{this.leaveRenderTexture()}}withMask(t,e,i=0,r=1){this.clearMask(),this.startDrawMask(r);try{t()}finally{this.endDrawMask()}this.enterMask(i,r);try{e()}finally{this.exitMask()}}withTransform(t,e,i=0,r=0){if(e){const n=e.saveTransform??!0;try{this.matrixStack.applyTransform(e,i,r),t()}finally{n&&this.matrixStack.restore()}}else{this.matrixStack.save();try{t()}finally{this.matrixStack.restore()}}}withScissor(t,e,i,r,n){this.startScissor(t,e,i,r);try{n()}finally{this.endScissor()}}withBlendMode(t,e){this.setBlendMode(t);try{e()}finally{this.setBlendMode(0)}}startDrawMask(t=1,e=255){this.flush();const i=this.gl;i.stencilMask(e),i.colorMask(!1,!1,!1,!1),i.stencilFunc(i.ALWAYS,t,e),i.stencilOp(i.KEEP,i.KEEP,i.REPLACE),this.enterRegion(this.graphicRegion,this.graphicRegion.maskShader),this.inCreateMask=!0}endDrawMask(){this.flush();const t=this.gl;t.colorMask(!0,!0,!0,!0),t.stencilMask(0),this.inCreateMask=!1}clearMask(t=255){this.flush();const e=this.gl;e.stencilMask(t),e.clear(e.STENCIL_BUFFER_BIT),this.inCreateMask=!1}enterMask(t,e=1,i=255){this.flush();const r=this.gl;r.colorMask(!0,!0,!0,!0),r.stencilMask(0),r.stencilFunc(t===0?r.EQUAL:r.NOTEQUAL,e,i),r.stencilOp(r.KEEP,r.KEEP,r.KEEP),this.inCreateMask=!1}exitMask(){this.flush();const t=this.gl;t.colorMask(!0,!0,!0,!0),t.stencilMask(255),t.stencilFunc(t.ALWAYS,1,255),t.stencilOp(t.KEEP,t.KEEP,t.KEEP),this.inCreateMask=!1}setBlendMode(t){this.flush();const e=this.gl;switch(t){case 0:this.premultipliedAlpha?e.blendFuncSeparate(e.ONE,e.ONE_MINUS_SRC_ALPHA,e.ONE,e.ONE_MINUS_SRC_ALPHA):e.blendFuncSeparate(e.SRC_ALPHA,e.ONE_MINUS_SRC_ALPHA,e.ONE,e.ONE_MINUS_SRC_ALPHA);break;case 1:e.blendFuncSeparate(e.ONE,e.ONE,e.ONE,e.ONE);break;case 2:e.blendFuncSeparate(e.DST_COLOR,e.ONE_MINUS_SRC_ALPHA,e.ONE,e.ONE_MINUS_SRC_ALPHA);break;case 3:e.blendFuncSeparate(e.ONE,e.ONE_MINUS_SRC_COLOR,e.ONE,e.ONE_MINUS_SRC_ALPHA);break;case 4:e.blendFuncSeparate(e.ZERO,e.ONE_MINUS_SRC_ALPHA,e.ZERO,e.ONE_MINUS_SRC_ALPHA);break}}startScissor(t,e,i,r){this.flush();const n=this.gl,a=this.physicsWidth/this.logicWidth,o=this.physicsHeight/this.logicHeight,h=Math.round(t*a),u=Math.round(this.physicsHeight-(e+r)*o),c=Math.round(i*a),x=Math.round(r*o);n.enable(n.SCISSOR_TEST),n.scissor(h,u,c,x)}endScissor(){this.flush(),this.gl.disable(this.gl.SCISSOR_TEST)}renderCamera(t){this.matrixStack.applyTransform(t);const e=this.matrixStack.curWorldM;this.matrix.invert(e)}logicToPhysics(t){return t.multiply(new l(this.physicsWidth/this.logicWidth,this.physicsHeight/this.logicHeight))}physicsToLogic(t){return t.multiply(new l(this.logicWidth/this.physicsWidth,this.logicHeight/this.physicsHeight))}cssToDevicePixel(t){return t.mul(this.dpr)}cssToLogic(t){const e=this.cssToDevicePixel(t);return this.physicsToLogic(e)}devicePixelToCss(t){return t.divide(this.dpr)}toCSSMatrix(t){const e=this.physicsWidth/this.dpr/this.logicWidth,i=this.physicsHeight/this.dpr/this.logicHeight;return this.matrix.toCSSMatrix(t??this.matrixStack.curWorldM,e,i)}}function Jt(s){return!(s===null||typeof s!="object"||Array.isArray(s)||s instanceof l||s instanceof d)}class b{static float(t,e){return Math.random()*(e-t)+t}static int(t,e){return Math.floor(Math.random()*(e-t+1))+t}static angle(){return Math.random()*Math.PI*2}static vector(t,e,i,r){return new l(b.float(t,e),b.float(i,r))}static randomColor(t,e){return new d(b.float(t.r,e.r),b.float(t.g,e.g),b.float(t.b,e.b),b.float(t.a,e.a))}static pick(t){return t[b.int(0,t.length-1)]}static pickWeight(t){if(!t||t.length===0)return null;let e=0;for(const[,r]of t)e+=r;let i=Math.random()*e;for(const[r,n]of t)if(i-=n,i<=0)return r;return t[t.length-1][0]}static scalarOrRange(t,e){if(t==null)return e;if(Array.isArray(t)){const[i,r]=t;if(typeof i=="number")return b.float(i,r);if(i instanceof l)return b.vector(i.x,r.x,i.y,r.y);if(i instanceof d)return b.randomColor(i,r)}return typeof t=="number"?t:t.clone()}}var At=(s=>(s.POINT="point",s.CIRCLE="circle",s.RECT="rect",s))(At||{});const Ut=10,_t=0,Ct=!0;class Nt{life=0;maxLife;texture;options;position;datas;rapid;constructor(t,e){this.rapid=t,this.options=e,e.texture instanceof U?this.texture=e.texture:e.texture instanceof Array&&e.texture[0]instanceof Array?this.texture=b.pickWeight(e.texture):e.texture instanceof Array&&(this.texture=b.pick(e.texture)),this.maxLife=b.scalarOrRange(e.life,1),this.datas={speed:this.processAttribute(e.animation.speed,0),rotation:this.processAttribute(e.animation.rotation,0),scale:this.processAttribute(e.animation.scale,1),color:this.processAttribute(e.animation.color,d.White.clone()),velocity:this.processAttribute(e.animation.velocity,l.ZERO),acceleration:this.processAttribute(e.animation.acceleration,l.ZERO)},this.position=l.ZERO,this.initializePosition()}processAttribute(t,e){if(t==null)return{value:e};if(Jt(t)){const i=t,r=b.scalarOrRange(i.start,e),n=i.end===void 0?r:b.scalarOrRange(i.end,e);return{delta:i.delta??this.getDelta(r,n,this.maxLife),value:r,damping:i.damping}}else return this.processAttribute({start:t},e)}updateNumberAttribute(t,e){t.damping!==void 0&&(t.value*=Math.pow(t.damping,e)),t.delta!==void 0&&(t.value+=t.delta*e)}updateVec2Attribute(t,e){t.damping!==void 0&&(t.value=t.value.multiply(Math.pow(t.damping,e))),t.delta!==void 0&&(t.value=t.value.add(t.delta.multiply(e)))}updateColorAttribute(t,e){t.damping!==void 0&&(t.value=t.value.multiply(Math.pow(t.damping,e))),t.delta!==void 0&&(t.value=t.value.add(t.delta.multiply(e))),t.value.clamp()}updateAttributes(t){const e=this.datas;this.updateNumberAttribute(e.speed,t),this.updateNumberAttribute(e.rotation,t),this.updateNumberAttribute(e.scale,t),this.updateColorAttribute(e.color,t),this.updateVec2Attribute(e.velocity,t),this.updateVec2Attribute(e.acceleration,t),e.velocity.value=e.velocity.value.add(e.acceleration.value.multiply(t));const r=l.fromAngle(e.rotation.value).multiply(e.speed.value*t);this.position=this.position.add(r).add(e.velocity.value.multiply(t))}getDelta(t,e,i){return typeof t=="number"&&typeof e=="number"?(e-t)/i:t instanceof l&&e instanceof l||t instanceof d&&e instanceof d?e.subtract(t).divide(i):t}update(t){return this.life+=t,this.life>=this.maxLife?!1:(this.updateAttributes(t),!0)}render(){const t=this.rapid.matrixStack,e=this.datas.scale.value,i=this.datas.rotation.value,r=this.datas.color.value;t.save(),t.translate(this.position.x,this.position.y),i!==0&&t.rotate(i),e!==1&&t.scale(e,e);const n=this.options.origin?this.options.origin.x:.5,a=this.options.origin?this.options.origin.y:.5;(n!==0||a!==0)&&t.translate(-n*this.texture.rawWidth,-a*this.texture.rawHeight),st(this.rapid,{texture:this.texture,color:r}),t.restore()}initializePosition(){switch(this.options.emitShape){case"circle":{const t=Math.random()*Math.PI*2,e=(this.options.emitRadius??0)*Math.sqrt(Math.random());this.position=new l(Math.cos(t)*e,Math.sin(t)*e);break}case"rect":{this.position=new l((Math.random()-.5)*(this.options.emitRect?.width??0),(Math.random()-.5)*(this.options.emitRect?.height??0));break}default:this.position=l.ZERO;break}!this.options.localSpace&&this.options.position&&(this.position=this.position.add(this.options.position))}}class at{particles=[];options;emitting=!1;emitTimer=0;emitRate=Ut;emitTime=_t;emitTimeCounter=0;localSpace=Ct;position=l.ZERO;rapid;gameObject;constructor(t,e){this.rapid=t,this.options=e,this.emitRate=e.emitRate!==void 0?e.emitRate:Ut,this.emitTime=e.emitTime!==void 0?e.emitTime:_t,this.localSpace=e.localSpace!==void 0?e.localSpace:Ct,this.position=e.position??l.ZERO}setTexture(t){this.options.texture=t}clone(){return new at(this.rapid,{...this.options})}setEmitRate(t){this.emitRate=t}setEmitTime(t){this.emitTime=t}start(){this.emitting=!0,this.emitTimeCounter=0}stop(){this.emitting=!1}clear(){this.particles=[],this.emitTimeCounter=0}emit(t){const e=this.options.maxParticles??1/0,i=Math.min(t,e-this.particles.length);for(let r=0;r<i;r++)this.particles.push(new Nt(this.rapid,{...this.options}))}update(t){if(this.emitting&&this.emitRate>0)if(this.emitTime>0){if(this.emitTimeCounter+=t,this.emitTimeCounter>=this.emitTime){const e=Math.floor(this.emitTimeCounter/this.emitTime);this.emit(this.emitRate*e),this.emitTimeCounter-=e*this.emitTime}}else{this.emitTimer+=t;const e=Math.floor(this.emitTimer*this.emitRate);e>0&&(this.emit(e),this.emitTimer-=e/this.emitRate)}for(let e=this.particles.length-1;e>=0;e--)this.particles[e].update(t)||this.particles.splice(e,1)}render(){const t=this.rapid.matrixStack;this.localSpace&&(t.save(),t.translate(this.position.x,this.position.y));for(const e of this.particles)e.render();this.localSpace&&t.restore()}getParticleCount(){return this.particles.length}isActive(){return this.emitting||this.particles.length>0}oneShot(){this.emit(this.emitRate)}}f.ArrayType=A,f.BaseTexture=F,f.BlendMode=bt,f.CanvasScaleMode=St,f.Color=d,f.CustomGlShader=J,f.DynamicArrayBuffer=W,f.GLShader=Q,f.GraphicRegion=pt,f.MaskType=wt,f.MatrixStack=ut,f.MatrixStore=ot,f.Particle=Nt,f.ParticleEmitter=at,f.ParticleShape=At,f.Rapid=Qt,f.Region=tt,f.RenderTexture=lt,f.SpriteRegion=et,f.TextTexture=dt,f.Texture=U,f.TextureFilterMode=$,f.TextureManager=ct,f.TextureWrapMode=k,f.Vec2=l,f.WebglBufferArray=z,f.drawCircle=Et,f.drawGraphic=nt,f.drawLine=Tt,f.drawMaskImage=yt,f.drawRect=Rt,f.drawSprite=vt,f.drawSpriteRaw=st,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})}));
@@ -0,0 +1,9 @@
1
+ import { SpriteRegion } from './spriteRegion';
2
+ import { Rapid } from '../render';
3
+ import { CustomGlShader } from '../webgl/glshader';
4
+ export declare class AtlasSprtieRegion extends SpriteRegion {
5
+ KEY: string;
6
+ constructor(rapid: Rapid);
7
+ createCustomShader(customShader: CustomGlShader): import('..').GLShader | null;
8
+ createDefaultShader(): import('..').GLShader;
9
+ }
@@ -0,0 +1,40 @@
1
+ import { Rapid } from '../render';
2
+ import { Region } from './region';
3
+ import { default as GLShader } from '../webgl/glshader';
4
+ import { Texture } from '../texture';
5
+ export declare class GraphicRegion extends Region {
6
+ private vertexBuffer;
7
+ private vertexCount;
8
+ matrixIndex: number;
9
+ drawMode: number;
10
+ texture?: Texture;
11
+ maskShader: GLShader;
12
+ KEY: string;
13
+ constructor(rapid: Rapid);
14
+ createBuffer(): void;
15
+ createDefaultShader(): GLShader;
16
+ createMaskShader(vs: string, fs: string): GLShader;
17
+ createShader(vs: string, fs: string): GLShader;
18
+ /**
19
+ * Begins a new polygon drawing sequence. Must be followed by addVertex() calls and endGraphic().
20
+ * @param matrixIndex The index targeting a specific transform matrix in the MatrixStore.
21
+ * @param drawMode The WebGL drawing primitive mode (e.g., gl.TRIANGLES).
22
+ * @param texture Optional texture to apply over the polygon.
23
+ */
24
+ startGraphic(matrixIndex: number, drawMode?: number, texture?: Texture): void;
25
+ /**
26
+ * Adds a vertex to the current polygon. Local coordinates and color settings.
27
+ * @param x Local X coordinate.
28
+ * @param y Local Y coordinate.
29
+ * @param u UV mapped X value (0-1, default 0).
30
+ * @param v UV mapped Y value (0-1, default 0).
31
+ * @param color Pre-multiplied hex color combined using ABGR byte order (default 0xFFFFFFFF).
32
+ */
33
+ addVertex(x: number, y: number, u?: number, v?: number, color?: number): void;
34
+ /**
35
+ * Finishes the graphic construction and dispatches the rendering call immediately.
36
+ */
37
+ endGraphic(): void;
38
+ render(): void;
39
+ hasPendingContent(): boolean;
40
+ }
@@ -0,0 +1,42 @@
1
+ import { Rapid } from '../render';
2
+ import { MatrixStore } from '../matrix-engine';
3
+ import { default as GLShader, CustomGlShader } from '../webgl/glshader';
4
+ import { WebGLContext } from '../webgl/utils';
5
+ export declare class Region {
6
+ rapid: Rapid;
7
+ defaultShader: GLShader;
8
+ currentShader: GLShader;
9
+ customShader: CustomGlShader | null;
10
+ customShaderUsedTextureNum: number;
11
+ gl: WebGLContext;
12
+ maxTextureUnits: number;
13
+ matrixStore: MatrixStore;
14
+ isDefaultShader: boolean;
15
+ KEY: string;
16
+ vs: string;
17
+ fs: string;
18
+ protected usedTextures: WebGLTexture[];
19
+ protected usedTexturePadding: number[];
20
+ constructor(rapid: Rapid);
21
+ protected createBuffer(): void;
22
+ protected createDefaultShader(): void;
23
+ get freeTextureUnitNum(): number;
24
+ getTextureUnitList(): number[];
25
+ protected findTextureUnit(texture: WebGLTexture, paddingX?: number, paddingY?: number): number;
26
+ useTexture(texture: WebGLTexture, paddingX?: number, paddingY?: number): number;
27
+ createShader(vs: string, fs: string): GLShader;
28
+ createCustomShader(customShader: CustomGlShader): GLShader | null;
29
+ getCustomShader(customShader?: GLShader | CustomGlShader): GLShader;
30
+ /**
31
+ * Checks if the given shader is the same as the currently bound shader.
32
+ * @param customShader Optional custom shader.
33
+ * @returns True if already bound, otherwise false.
34
+ */
35
+ isSameShader(customShader?: GLShader | CustomGlShader): boolean;
36
+ enter(customShader?: GLShader | CustomGlShader): void;
37
+ exit(): void;
38
+ flush(): void;
39
+ render(): void;
40
+ resetRender(): void;
41
+ hasPendingContent(): boolean;
42
+ }
@@ -0,0 +1,33 @@
1
+ import { Rapid } from '../render';
2
+ import { Region } from './region';
3
+ import { CustomGlShader } from '../webgl/glshader';
4
+ import { Texture } from '../texture';
5
+ export declare class SpriteRegion extends Region {
6
+ private instanceBuffer;
7
+ private quadBuffer;
8
+ private instanceCount;
9
+ private localSpriteMatrix;
10
+ private worldSpriteMatrix;
11
+ KEY: string;
12
+ constructor(rapid: Rapid);
13
+ createBuffer(): void;
14
+ createDefaultShader(): import('..').GLShader;
15
+ createShader(vs: string, fs: string): import('..').GLShader;
16
+ createCustomShader(customShader: CustomGlShader): import('..').GLShader | null;
17
+ /**
18
+ * Draws a textured sprite via instanced rendering to significantly improve performance.
19
+ * @param texture The WebGLTexture to map.
20
+ * @param matrixIndex The index for the transform matrix in MatrixStore.
21
+ * @param width Render width.
22
+ * @param height Render height.
23
+ * @param u0 Left UV mapped coordinate (default 0).
24
+ * @param v0 Top UV mapped coordinate (default 0).
25
+ * @param u1 Right UV mapped coordinate (default 1).
26
+ * @param v1 Bottom UV mapped coordinate (default 1).
27
+ * @param color The tint color as packed ABGR uniform uint32 (default 0xFFFFFFFF).
28
+ */
29
+ drawSprite(texture: Texture, matrixIndex: number, u0?: number, v0?: number, u1?: number, v1?: number, color?: number, paddingX?: number, paddingY?: number, flipX?: boolean, flipY?: boolean, isRotated?: boolean): void;
30
+ render(): void;
31
+ resetRender(): void;
32
+ hasPendingContent(): boolean;
33
+ }