rapid-render 0.0.1 → 0.0.3

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
@@ -1,149 +1,86 @@
1
- # <center>rapid.js</center>
2
-
3
- ⚡Lightning-fast, Lightweight 2D WebGL Rendering for HTML5.
4
- gzip only 5kb ! [Why is Rapid so fast?](#Why-is-Rapid-so-fast?)
5
-
6
- 10000 Sprites 60FPS ! [Stress Test Demo](https://nightre.github.io/rapid.js/demo//stress-test/)
7
-
8
- gzip only 5kb!
9
- # Demo
10
- * [Stress Test Demo](https://nightre.github.io/rapid.js/demo//stress-test/)
11
- * [Graphics Demo](https://nightre.github.io/rapid.js/demo/graphic/)
12
- * [MartixStack Demo](https://nightre.github.io/rapid.js/demo/matrix-stack)
13
-
14
- # Quick Start
15
-
16
- Installation
17
-
18
- ```
19
- npm i rapid-render
20
- ```
21
-
22
- Or use unpkg
23
-
24
- ```html
25
- <script src="https://unpkg.com/rapid-render/dist/rapid.umd.cjs"></script>
26
- ```
27
-
28
- Import
29
-
30
- ```js
31
- import { Rapid } from "rapid-render";
32
- ```
33
-
34
- # Useage
35
- Create Rapid.js renderer
36
- ```js
37
- import { Rapid } from "../../dist/rapid";
38
- let rap = new Rapid({
39
- canvas: document.getElementById("game"),
40
- width: 600,
41
- height: 600,
42
- backgroundColor: Color.fromHex("00FFFF")
43
- })
44
- rap.start() // Call rap.start() before rendering to initialize the rendering context.
45
- // draw..
46
- rap.end() // Call rap.end() after rendering to finalize the rendering process.
47
- ```
48
-
49
- # Texture
50
-
51
- create textures
52
- load a texture from a URL using the `rap.texture.textureFromUrl` method or `Texture.fromUrl(rapid,"./cat")`. If you want to use ImageSource to create textures,use `Texture.fromImageSource(rapid,image)`
53
- ```js
54
- const catTexture = await rap.texture.textureFromUrl("../cat.png") // Load a texture from a URL.
55
- // or...
56
- // await Texture.fromUrl(rapid,"./cat")
57
- // Texture.fromImageSource(rapid,image)
58
- ```
59
- If you only want to display a portion of the texture, you can set the clip region
60
- ```js
61
- catTexture.setClipRegion(
62
- 0, // The x-coordinate of the top-left corner of the region.
63
- 0, // The y-coordinate of the top-left corner of the region.
64
- 50, // The width of the region.
65
- 50 // The height of the region.
66
- )
67
- ```
68
-
69
- # Draw Sprite
70
- Sprites are used to display textures
71
-
72
- demo : [Sprites Demo](https://nightre.github.io/rapid.js/demo/stress-test/)
73
-
74
- ```js
75
- rap.start() // Call rap.start() before rendering to initialize the rendering context.
76
-
77
- rap.drawSprite(texture, offsetX, offsetY)
78
-
79
- rap.end() // Call rap.end() after rendering to finalize the rendering process.
80
- ```
81
- # Draw Graphic
82
- Graphics can be used to draw polygons
83
-
84
- demo : [Graphics Demo](https://nightre.github.io/rapid.js/demo/graphic/)
85
- ```js
86
- rap.start() // Call rap.start() before rendering to initialize the rendering context.
87
-
88
- rap.drawShape([
89
- 0 , 0 ,
90
- 100, 0 ,
91
- 100, 50 ,
92
- // The vertex of a triangle
93
- ], Color.fromHex("00FFFF"))
94
-
95
- rap.end() // Call rap.end() after rendering to finalize the rendering process.
96
- ```
97
- # MartixStack
98
-
99
- Matrix stacking is very powerful, you can use it to implement stretching, rotation, translation, and hierarchical transformation.
100
-
101
- demo : [MartixStack Demo](https://nightre.github.io/rapid.js/demo/matrix-stack)
102
- ```js
103
- rap.save() // Save the current state of the transformation matrix.
104
- rap.drawSprite(catTexture)
105
- rap.matrix.translate(32, 32)
106
- rap.matrix.rotate(1)
107
- rap.save()
108
- rap.matrix.scale(1, 1) // or rap.matrix.scale(1)
109
- rap.restore() // Restore the transformation matrix to the previously saved state.
110
- rap.drawSprite(catTexture)
111
- rap.restore() // Restore the transformation matrix to the previously saved state.
112
- rap.drawSprite(catTexture)
113
- ```
114
-
115
- # Custom Shader
116
-
117
- ```js
118
- const shader = rap.createShader("vert shader", "frag shader")
119
- rap.drawSprite(texture, offsetX, offsetY, shader)
120
- rap.drawShape([
121
- 0 , 0 ,
122
- 100, 0 ,
123
- 100, 50 ,
124
- // The vertex of a triangle
125
- ], Color.fromHex("00FFFF"), shader)
126
- ```
127
-
128
- ## Customization
129
- If the built-in Sprite and Graphics classes don’t meet your needs, you can create your own rendering mode with direct control over WebGL. Here’s how:
130
- 1. **Create a Subtype**: Start by creating a subtype that inherits from RenderRegion. This will be your custom rendering region.
131
- ```js
132
- class YourRenderRegion extends RenderRegion {
133
- // Your custom methods and properties here
134
- }
135
- ```
136
- 2. **Register Your Region**: Once your custom rendering region is defined, register it with the renderer.
137
- ```js
138
- this.registerRegion("YourRegionName", YourRenderRegion)
139
- ```
140
- 3. **Use Your Region**: Now you can set your custom region as the current region. You can also pass a custom shader if needed.
141
- ```js
142
- this.setRegion("YourRegionName", customShader?);
143
- rap.currentRegion
144
- ```
145
-
146
- For more details, please check: [RenderRegions](./src/region)
147
-
148
- # Why is Rapid so fast?
149
- Rapid-Renderer is an efficient WebGL renderer that can process multiple sprites at once and intelligently group them based on the texture units they use and the maximum texture units supported by the GPU. This means that even if there are 1000 sprites, as long as the total texture units they use do not exceed the maximum supported by the GPU, Rapid-Renderer can group them together and render them in batches. This approach fully leverages the parallel processing capabilities of the GPU, resulting in efficient rendering. This greatly improves the rendering efficiency and allows Rapid-Renderer to maintain high rendering speed while handling a large number of sprites
1
+ # 🚀 Rapid.js
2
+
3
+ A highly efficient and lightweight WebGL renderer capable of rendering 10k sprites at 60fps.
4
+
5
+
6
+ [demo](https://nightre.github.io/Rapid.js/demo/) ( [source code](./demo/index.js) )
7
+
8
+ # Features:
9
+ * Fast rendering ( capable of rendering 10,000 sprites at 60fps )
10
+ * Multi-texture support ( Batch rendering based on the GPU's maximum texture units )
11
+ * Texture cropping
12
+ * Graphic
13
+ * Matrix stacking
14
+ * Color manipulation
15
+
16
+ # Install
17
+
18
+ ```
19
+ npm i rapid-render
20
+ ```
21
+
22
+ Or use unpkg
23
+
24
+ ```html
25
+ <script src="https://unpkg.com/rapid-render/dist/rapid.umd.cjs"></script>
26
+ ```
27
+
28
+ # Import
29
+
30
+ ```js
31
+ import { Rapid } from "rapid-render"
32
+ ```
33
+
34
+ # Useage
35
+
36
+ ```js
37
+ let rapid = new Rapid({
38
+ canvas: document.getElementById("game"),
39
+ backgroundColor: Color.fromHex("FFFFFF")
40
+ })
41
+
42
+ // Creating textures
43
+ const cat = await rapid.texture.textureFromUrl("./cat.png")
44
+ const plane = await rapid.texture.textureFromUrl("./plane.png")
45
+ // or
46
+ // Texture.fromImageSource(img)
47
+ // Texture.fromUrl(url)
48
+ // set clip
49
+ cat.setClipRegion(
50
+ 10,10 // top-left corner of the clipped region.
51
+ 50,50 // size
52
+ )
53
+ // R G B A
54
+ const color = new Color(255,255,255,255)
55
+ // or Color.fromHex
56
+ // Called before starting rendering
57
+ rapid.startRender()
58
+
59
+
60
+ rapid.save() // Save state
61
+ rapid.matrixStack.translate(0,0)
62
+ rapid.matrixStack.scale(1)
63
+ rapid.matrixStack.rotate(0)
64
+
65
+ // texture offset color
66
+ rapid.renderSprite(cat,0,0, color) // draw Sprite
67
+ rapid.restore() // back to the previous saved state
68
+
69
+ // draw graphic
70
+ // Different vertices can have different colors
71
+ rapid.startGraphicDraw()
72
+ rapid.addGraphicVertex(0, 0, color)
73
+ rapid.addGraphicVertex(100, 0, color)
74
+ rapid.addGraphicVertex(100, 100, color)
75
+ rapid.endGraphicDraw()
76
+
77
+ // Called after rendering
78
+ rapid.endRender()
79
+
80
+ // set the size
81
+ rapid.resize(100,100)
82
+ ```
83
+
84
+ # Screen Shot
85
+
86
+ ![screen](./screenshot/screen.png)
package/dist/index.d.ts CHANGED
@@ -1,9 +1,6 @@
1
- import GraphicRegion from "./region/graphic_region";
2
- import RenderRegion from "./region/region";
3
- import SpriteRegion from "./region/sprite_region";
4
- import Rapid from "./renderer";
1
+ import Rapid from "./render";
2
+ export { Rapid, };
5
3
  export * from "./math";
6
4
  export * from "./interface";
7
5
  export * from "./texture";
8
- export { RenderRegion, SpriteRegion, GraphicRegion, Rapid };
9
- export * from "./utils/webgl";
6
+ export * from "./render";
@@ -1,16 +1,9 @@
1
- import { Color } from "./math";
2
1
  export type WebGLContext = WebGL2RenderingContext | WebGLRenderingContext;
3
2
  export interface IRapiadOptions {
4
3
  canvas: HTMLCanvasElement;
5
4
  pixelDensity?: number;
6
5
  width?: number;
7
6
  height?: number;
8
- backgroundColor?: Color;
9
- }
10
- export interface IRenderRegionOptions {
11
- vs: string;
12
- fs: string;
13
- attribute: IAttribute[];
14
7
  }
15
8
  export interface IAttribute {
16
9
  name: string;
package/dist/math.d.ts CHANGED
@@ -1,11 +1,14 @@
1
1
  import { WebGLContext } from "./interface";
2
2
  type ArrayType = typeof Float32Array | typeof Uint16Array;
3
- declare class DynamicArrayBuffer {
4
- protected usedElemNum: number;
3
+ export declare class DynamicArrayBuffer {
4
+ usedElemNum: number;
5
5
  protected typedArray: Float32Array | Uint16Array;
6
6
  private arrayType;
7
- private maxElemNum;
7
+ protected maxElemNum: number;
8
8
  readonly bytePerElem: number;
9
+ private arraybuffer;
10
+ /** if typedArray is Float32Array*/
11
+ private uint32?;
9
12
  constructor(arrayType: ArrayType);
10
13
  clear(): void;
11
14
  /**
@@ -13,12 +16,14 @@ declare class DynamicArrayBuffer {
13
16
  * @param size
14
17
  * @returns
15
18
  */
16
- resize(size?: number): this | undefined;
19
+ resize(size?: number): void;
20
+ protected setMaxSize(size?: number): void;
17
21
  /**
18
22
  * push a new element
19
23
  * @param value
20
24
  */
21
25
  push(value: number): void;
26
+ pushUint(value: number): void;
22
27
  /**
23
28
  * pop a element
24
29
  * @param num
@@ -36,7 +41,27 @@ declare class DynamicArrayBuffer {
36
41
  */
37
42
  get length(): number;
38
43
  }
39
- declare class MatrixStack extends DynamicArrayBuffer {
44
+ export declare class WebglBufferArray extends DynamicArrayBuffer {
45
+ buffer: WebGLBuffer;
46
+ gl: WebGLContext;
47
+ protected dirty: boolean;
48
+ readonly type: number;
49
+ /**
50
+ * webglbuffer 中的大小
51
+ */
52
+ private webglBufferSize;
53
+ constructor(gl: WebGLContext, arrayType: ArrayType, type?: number);
54
+ push(value: number): void;
55
+ /**
56
+ * bind buffer to gpu
57
+ */
58
+ bindBuffer(): void;
59
+ /**
60
+ * array data to gpu
61
+ */
62
+ bufferData(): void;
63
+ }
64
+ export declare class MatrixStack extends DynamicArrayBuffer {
40
65
  constructor();
41
66
  /**
42
67
  * push a matrix to the stack
@@ -68,61 +93,35 @@ declare class MatrixStack extends DynamicArrayBuffer {
68
93
  */
69
94
  scale(x: number, y?: number): void;
70
95
  apply(x: number, y: number): number[];
96
+ getInverse(): Float32Array;
97
+ getTransform(): Float32Array;
98
+ setTransform(array: Float32Array | number[]): void;
71
99
  }
72
- declare class Color {
73
- r: number;
74
- g: number;
75
- b: number;
76
- a: number;
100
+ export declare class WebglElementBufferArray extends WebglBufferArray {
101
+ constructor(gl: WebGLContext, elemVertPerObj: number, vertexPerObject: number, maxBatch: number);
102
+ protected addObject(_vertex?: number): void;
103
+ }
104
+ export declare class Color {
105
+ private _r;
106
+ private _g;
107
+ private _b;
108
+ private _a;
109
+ uint32: number;
77
110
  constructor(r: number, g: number, b: number, a: number);
78
- /**
79
- * is equal to another color instance
80
- * @param color
81
- * @returns
82
- */
111
+ get r(): number;
112
+ set r(value: number);
113
+ get g(): number;
114
+ set g(value: number);
115
+ get b(): number;
116
+ set b(value: number);
117
+ get a(): number;
118
+ set a(value: number);
119
+ private updateUint;
120
+ setRGBA(r: number, g: number, b: number, a: number): void;
121
+ copy(color: Color): void;
83
122
  equals(color: Color): boolean;
84
- /**
85
- * create a new color by hex string
86
- * @param hexString
87
- * @returns
88
- */
89
123
  static fromHex(hexString: string): Color;
124
+ add(color: Color): Color;
125
+ subtract(color: Color): Color;
90
126
  }
91
- declare class BufferArray extends DynamicArrayBuffer {
92
- buffer: WebGLBuffer;
93
- gl: WebGLContext;
94
- readonly type: number;
95
- private bufferSize;
96
- constructor(gl: WebGLContext, arrayType: ArrayType, type?: number);
97
- /**
98
- * bind buffer to gpu
99
- */
100
- bindBuffer(): void;
101
- /**
102
- * array data to gpu
103
- */
104
- bufferData(): void;
105
- /**
106
- * clear
107
- */
108
- clear(): void;
109
- }
110
- declare class ElementArray extends BufferArray {
111
- readonly elemVertPerObj: number;
112
- private objects;
113
- readonly vertexPerObject: number;
114
- private dirty;
115
- constructor(gl: WebGLContext, elemVertPerObj: number, vertexPerObject: number);
116
- protected addObject(_vertex?: number): void;
117
- /**
118
- * set number of objects
119
- * @param obj
120
- */
121
- setObjects(obj: number): void;
122
- /**
123
- * array data to gpu
124
- */
125
- bufferData(): void;
126
- clear(): void;
127
- }
128
- export { MatrixStack, DynamicArrayBuffer, Color, ElementArray, BufferArray };
127
+ export {};
@@ -0,0 +1 @@
1
+ var rapid=function(e){"use strict";class t{constructor(e){Object.defineProperty(this,"usedElemNum",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"typedArray",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"arrayType",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"maxElemNum",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"bytePerElem",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"arraybuffer",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"uint32",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.usedElemNum=0,this.maxElemNum=512,this.bytePerElem=e.BYTES_PER_ELEMENT,this.arrayType=e,this.arraybuffer=new ArrayBuffer(this.maxElemNum*this.bytePerElem),this.typedArray=new e(this.arraybuffer),e==Float32Array&&(this.uint32=new Uint32Array(this.arraybuffer))}clear(){this.usedElemNum=0}resize(e=0){if((e+=this.usedElemNum)>this.maxElemNum){for(;e>this.maxElemNum;)this.maxElemNum<<=1;this.setMaxSize(this.maxElemNum)}}setMaxSize(e=this.maxElemNum){const t=this.typedArray;this.maxElemNum=e,this.arraybuffer=new ArrayBuffer(e*this.bytePerElem),this.typedArray=new this.arrayType(this.arraybuffer),this.uint32&&(this.uint32=new Uint32Array(this.arraybuffer)),this.typedArray.set(t)}push(e){this.typedArray[this.usedElemNum++]=e}pushUint(e){this.uint32[this.usedElemNum++]=e}pop(e){this.usedElemNum-=e}getArray(e=0,t){return null==t?this.typedArray:this.typedArray.subarray(e,t)}get length(){return this.typedArray.length}}class r extends t{constructor(e,t,r=e.ARRAY_BUFFER){super(t),Object.defineProperty(this,"buffer",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"gl",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"dirty",{enumerable:!0,configurable:!0,writable:!0,value:!0}),Object.defineProperty(this,"type",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"webglBufferSize",{enumerable:!0,configurable:!0,writable:!0,value:0}),this.gl=e,this.buffer=e.createBuffer(),this.type=r}push(e){super.push(e),this.dirty=!0}bindBuffer(){this.gl.bindBuffer(this.type,this.buffer)}bufferData(){if(this.dirty){const e=this.gl;this.maxElemNum>this.webglBufferSize?(e.bufferData(this.type,this.getArray(),e.STATIC_DRAW),this.webglBufferSize=this.maxElemNum):e.bufferSubData(this.type,0,this.getArray(0,this.usedElemNum)),this.dirty=!1}}}class i extends t{constructor(){super(Float32Array)}pushMat(){const e=this.usedElemNum-6,t=this.typedArray;this.resize(6),this.push(t[e+0]),this.push(t[e+1]),this.push(t[e+2]),this.push(t[e+3]),this.push(t[e+4]),this.push(t[e+5])}popMat(){this.pop(6)}pushIdentity(){this.resize(6),this.push(1),this.push(0),this.push(0),this.push(1),this.push(0),this.push(0)}translate(e,t){const r=this.usedElemNum-6,i=this.typedArray;i[r+4]=i[r+0]*e+i[r+2]*t+i[r+4],i[r+5]=i[r+1]*e+i[r+3]*t+i[r+5]}rotate(e){const t=this.usedElemNum-6,r=this.typedArray,i=Math.cos(e),a=Math.sin(e),s=r[t+0],n=r[t+1],u=r[t+2],o=r[t+3];r[t+0]=s*i-n*a,r[t+1]=s*a+n*i,r[t+2]=u*i-o*a,r[t+3]=u*a+o*i}scale(e,t=e){const r=this.usedElemNum-6,i=this.typedArray;i[r+0]=i[r+0]*e,i[r+1]=i[r+1]*e,i[r+2]=i[r+2]*t,i[r+3]=i[r+3]*t}apply(e,t){const r=this.usedElemNum-6,i=this.typedArray;return[i[r+0]*e+i[r+2]*t+i[r+4],i[r+1]*e+i[r+3]*t+i[r+5]]}getInverse(){const e=this.usedElemNum-6,t=this.typedArray,r=t[e+0],i=t[e+1],a=t[e+2],s=t[e+3],n=t[e+4],u=t[e+5],o=r*s-i*a;return new Float32Array([s/o,-i/o,-a/o,r/o,(a*u-s*n)/o,(i*n-r*u)/o])}getTransform(){const e=this.usedElemNum-6,t=this.typedArray;return new Float32Array([t[e+0],t[e+1],t[e+2],t[e+3],t[e+4],t[e+5]])}setTransform(e){const t=this.usedElemNum-6,r=this.typedArray;r[t+0]=e[0],r[t+1]=e[1],r[t+2]=e[2],r[t+3]=e[3],r[t+4]=e[4],r[t+5]=e[5]}}class a extends r{constructor(e,t,r,i){super(e,Uint16Array,e.ELEMENT_ARRAY_BUFFER),this.setMaxSize(t*i);for(let e=0;e<i;e++)this.addObject(e*r);this.bindBuffer(),this.bufferData()}addObject(e){}}class s{constructor(e,t,r,i){Object.defineProperty(this,"_r",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_g",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_b",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_a",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"uint32",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this._r=e,this._g=t,this._b=r,this._a=i,this.updateUint()}get r(){return this._r}set r(e){this._r=e,this.updateUint()}get g(){return this._g}set g(e){this._g=e,this.updateUint()}get b(){return this._b}set b(e){this._b=e,this.updateUint()}get a(){return this._a}set a(e){this._a=e,this.updateUint()}updateUint(){this.uint32=(this._a<<24|this._b<<16|this._g<<8|this._r)>>>0}setRGBA(e,t,r,i){this.r=e,this.g=t,this.b=r,this.a=i,this.updateUint()}copy(e){this.setRGBA(e.r,e.g,e.b,e.a)}equals(e){return e.r==this.r&&e.g==this.g&&e.b==this.b&&e.a==this.a}static fromHex(e){e.startsWith("#")&&(e=e.slice(1));const t=parseInt(e.slice(0,2),16),r=parseInt(e.slice(2,4),16),i=parseInt(e.slice(4,6),16);let a=255;return e.length>=8&&(a=parseInt(e.slice(6,8),16)),new s(t,r,i,a)}add(e){return new s(Math.min(this.r+e.r,255),Math.min(this.g+e.g,255),Math.min(this.b+e.b,255),Math.min(this.a+e.a,255))}subtract(e){return new s(Math.max(this.r-e.r,0),Math.max(this.g-e.g,0),Math.max(this.b-e.b,0),Math.max(this.a-e.a,0))}}const n=(e,t,r)=>{const i=e.createShader(r);if(!i)throw new Error("Unable to create webgl shader");e.shaderSource(i,t),e.compileShader(i);if(!e.getShaderParameter(i,e.COMPILE_STATUS)){const r=e.getShaderInfoLog(i);throw console.error("Shader compilation failed:",r),new Error("Unable to compile shader: "+r+t)}return i};class u{constructor(e,t,r){Object.defineProperty(this,"attributeLoc",{enumerable:!0,configurable:!0,writable:!0,value:{}}),Object.defineProperty(this,"unifromLoc",{enumerable:!0,configurable:!0,writable:!0,value:{}}),Object.defineProperty(this,"program",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"gl",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.program=((e,t,r)=>{var i=e.createProgram(),a=n(e,t,35633),s=n(e,r,35632);if(!i)throw new Error("Unable to create program shader");return e.attachShader(i,a),e.attachShader(i,s),e.linkProgram(i),i})(e.gl,t,r),this.gl=e.gl,this.parseShader(t),this.parseShader(r)}use(){this.gl.useProgram(this.program)}parseShader(e){const t=this.gl,r=e.match(/attribute\s+\w+\s+(\w+)/g);if(r)for(const e of r){const r=e.split(" ")[2];this.attributeLoc[r]=t.getAttribLocation(this.program,r)}const i=e.match(/uniform\s+\w+\s+(\w+)/g);if(i)for(const e of i){const r=e.split(" ")[2];this.unifromLoc[r]=t.getUniformLocation(this.program,r)}}setAttribute(e){const t=this.gl;t.vertexAttribPointer(this.attributeLoc[e.name],e.size,e.type,e.normalized||!1,e.stride,e.offset||0),t.enableVertexAttribArray(this.attributeLoc[e.name])}}class o{constructor(e,t){Object.defineProperty(this,"currentShader",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"defaultShader",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"attribute",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"webglArrayBuffer",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"rapid",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"gl",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"usedTextures",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"TEXTURE_UNITS_ARRAY",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.attribute=t,this.rapid=e,this.gl=e.gl,this.webglArrayBuffer=new r(e.gl,Float32Array,e.gl.ARRAY_BUFFER),this.TEXTURE_UNITS_ARRAY=Array.from({length:e.MAX_TEXTURE_UNITS},((e,t)=>t))}addVertex(e,t,...r){const[i,a]=this.rapid.transformPoint(e,t);this.webglArrayBuffer.push(i),this.webglArrayBuffer.push(a)}useTexture(e){let t=this.usedTextures.indexOf(e);return-1===t&&(this.usedTextures.length>=this.rapid.MAX_TEXTURE_UNITS&&this.render(),this.usedTextures.push(e),t=this.usedTextures.length-1),t}enterRegion(e){this.currentShader=e??this.defaultShader,this.currentShader.use(),this.initializeForNextRender(),this.webglArrayBuffer.bindBuffer(),this.attribute.forEach((e=>{this.currentShader?.setAttribute(e)})),this.gl.uniformMatrix4fv(this.currentShader.unifromLoc.uProjectionMatrix,!1,this.rapid.projection)}exitRegion(){}initDefaultShader(e,t){this.webglArrayBuffer.bindBuffer(),this.defaultShader=new u(this.rapid,e,t)}render(){this.executeRender(),this.initializeForNextRender()}executeRender(){this.webglArrayBuffer.bufferData();const e=this.gl;for(let t=0;t<this.usedTextures.length;t++)e.activeTexture(e.TEXTURE0+t),e.bindTexture(e.TEXTURE_2D,this.usedTextures[t])}initializeForNextRender(){this.webglArrayBuffer.clear(),this.usedTextures=[]}}class h extends o{constructor(e){const t=e.gl;super(e,[{name:"aPosition",size:2,type:t.FLOAT,stride:12},{name:"aColor",size:4,type:t.UNSIGNED_BYTE,stride:12,offset:2*Float32Array.BYTES_PER_ELEMENT,normalized:!0}]),Object.defineProperty(this,"vertex",{enumerable:!0,configurable:!0,writable:!0,value:0}),this.initDefaultShader("precision mediump float;\r\n\r\nattribute vec2 aPosition;\r\nattribute vec4 aColor;\r\nvarying vec4 vColor;\r\nuniform mat4 uProjectionMatrix;\r\nuniform vec4 uColor;\r\n\r\nvoid main(void) {\r\n gl_Position = uProjectionMatrix * vec4(aPosition, 0.0, 1.0);\r\n vColor = aColor;\r\n}\r\n","precision mediump float;\r\n\r\nvarying vec4 vColor;\r\nvoid main(void) {\r\n gl_FragColor = vColor;//vColor;\r\n}\r\n")}startRender(){this.vertex=0,this.webglArrayBuffer.clear()}addVertex(e,t,r){this.webglArrayBuffer.resize(3),super.addVertex(e,t),this.webglArrayBuffer.pushUint(r),this.vertex+=1}executeRender(){super.executeRender();const e=this.gl;e.drawArrays(e.TRIANGLE_FAN,0,this.vertex),this.vertex=0}}class l extends a{constructor(e,t){super(e,6,4,t)}addObject(e){super.addObject(),this.push(e),this.push(e+3),this.push(e+2),this.push(e),this.push(e+1),this.push(e+2)}}class c extends o{constructor(e){const t=e.gl;super(e,[{name:"aPosition",size:2,type:t.FLOAT,stride:24},{name:"aRegion",size:2,type:t.FLOAT,stride:24,offset:2*Float32Array.BYTES_PER_ELEMENT},{name:"aTextureId",size:1,type:t.FLOAT,stride:24,offset:4*Float32Array.BYTES_PER_ELEMENT},{name:"aColor",size:4,type:t.UNSIGNED_BYTE,stride:24,offset:5*Float32Array.BYTES_PER_ELEMENT,normalized:!0}]),Object.defineProperty(this,"batchSprite",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"indexBuffer",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"MAX_BATCH",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.initDefaultShader("precision mediump float;\r\n\r\nattribute vec2 aPosition;\r\nattribute vec2 aRegion;\r\nattribute float aTextureId;\r\nattribute vec4 aColor;\r\n\r\nuniform mat4 uProjectionMatrix;\r\n\r\nvarying vec2 vRegion;\r\nvarying float vTextureId;\r\nvarying vec4 vColor;\r\n\r\nvoid main(void) {\r\n vRegion = aRegion;\r\n vTextureId = aTextureId;\r\n vColor = aColor;\r\n gl_Position = uProjectionMatrix * vec4(aPosition, 0.0, 1.0);\r\n}",this.generateFragShader("precision mediump float;\r\nuniform sampler2D uTextures[%TEXTURE_NUM%];\r\n\r\nvarying vec2 vRegion;\r\nvarying float vTextureId;\r\nvarying vec4 vColor;\r\n\r\nvoid main(void) {\r\n vec4 color;\r\n %GET_COLOR%\r\n\r\n gl_FragColor = color*vColor;\r\n}",e.MAX_TEXTURE_UNITS)),this.MAX_BATCH=Math.floor(16384),this.indexBuffer=new l(t,this.MAX_BATCH)}addVertex(e,t,r,i,a,s){super.addVertex(e,t),this.webglArrayBuffer.push(r),this.webglArrayBuffer.push(i),this.webglArrayBuffer.push(a),this.webglArrayBuffer.pushUint(s)}renderSprite(e,t,r,i,a,s,n,u,o,h){this.batchSprite>=this.MAX_BATCH&&this.render(),this.batchSprite++,this.webglArrayBuffer.resize(24);const l=this.useTexture(e),c=u+t,b=o+r,d=i+s,f=a+n;this.addVertex(u,o,i,a,l,h),this.addVertex(c,o,d,a,l,h),this.addVertex(c,b,d,f,l,h),this.addVertex(u,b,i,f,l,h)}executeRender(){super.executeRender();const e=this.gl;this.indexBuffer.bufferData(),e.drawElements(e.TRIANGLES,6*this.batchSprite,e.UNSIGNED_SHORT,0)}enterRegion(e){super.enterRegion(e),this.indexBuffer.bindBuffer(),this.gl.uniform1iv(this.currentShader.unifromLoc.uTextures,this.TEXTURE_UNITS_ARRAY)}initializeForNextRender(){super.initializeForNextRender(),this.batchSprite=0}generateFragShader(e,t){let r="";e=e.replace("%TEXTURE_NUM%",t.toString());for(let e=0;e<t;e++)r+=0==e?`if(vTextureId == ${e}.0)`:e==t-1?"else":`else if(vTextureId == ${e}.0)`,r+=`{color = texture2D(uTextures[${e}], vRegion);}`;return e=e.replace("%GET_COLOR%",r)}}class b{constructor(e){Object.defineProperty(this,"render",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"cache",{enumerable:!0,configurable:!0,writable:!0,value:new Map}),this.render=e}async textureFromUrl(e,t=!1){let r=this.cache.get(e);if(!r){const i=await this.loadImage(e);r=d.fromImageSource(this.render,i,t),this.cache.set(e,r)}return new f(r)}async loadImage(e){return new Promise((t=>{const r=new Image;r.onload=()=>{t(r)},r.src=e}))}}class d{constructor(e,t,r){Object.defineProperty(this,"texture",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"width",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"height",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.texture=e,this.width=t,this.height=r}static fromImageSource(e,t,r=!1){return new d(function(e,t,r){const i=e.createTexture();if(e.bindTexture(e.TEXTURE_2D,i),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,r?e.LINEAR:e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,r?e.LINEAR:e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,t),!i)throw new Error("unable to create texture");return i}(e.gl,t,r),t.width,t.height)}}class f{constructor(e){Object.defineProperty(this,"base",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"clipX",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"clipY",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"clipW",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"clipH",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"width",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"height",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.base=e,this.setClipRegion(0,0,e.width,e.height)}setClipRegion(e,t,r,i){this.clipX=e/this.base.width,this.clipY=t/this.base.width,this.clipW=this.clipX+r/this.base.width,this.clipH=this.clipY+i/this.base.width,this.width=r,this.height=i}static fromImageSource(e,t,r=!1){return new f(d.fromImageSource(e,t,r))}static fromUrl(e,t){return e.texture.textureFromUrl(t)}}return e.BaseTexture=d,e.Color=s,e.DynamicArrayBuffer=t,e.MatrixStack=i,e.Rapid=class{constructor(e){Object.defineProperty(this,"gl",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"canvas",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"projection",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"matrixStack",{enumerable:!0,configurable:!0,writable:!0,value:new i}),Object.defineProperty(this,"texture",{enumerable:!0,configurable:!0,writable:!0,value:new b(this)}),Object.defineProperty(this,"currentRegion",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"currentRegionName",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"regions",{enumerable:!0,configurable:!0,writable:!0,value:new Map}),Object.defineProperty(this,"MAX_TEXTURE_UNITS",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"defaultColor",{enumerable:!0,configurable:!0,writable:!0,value:new s(255,255,255,255)});const t=(e=>{const t=e.getContext("webgl2")||e.getContext("webgl");if(!t)throw new Error("TODO");return t})(e.canvas);this.gl=t,this.canvas=e.canvas,this.MAX_TEXTURE_UNITS=t.getParameter(this.gl.MAX_TEXTURE_IMAGE_UNITS),this.projection=this.createOrthMatrix(0,this.canvas.width,this.canvas.height,0),this.registerBuildInRegion(),t.enable(t.BLEND),t.disable(t.DEPTH_TEST),t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA)}registerBuildInRegion(){this.registerRegion("sprite",c),this.registerRegion("graphic",h)}registerRegion(e,t){this.regions.set(e,new t(this))}setRegion(e,t){if(e!=this.currentRegionName||t&&t!==this.currentRegion.currentShader){const r=this.regions.get(e);this.currentRegion&&(this.currentRegion.render(),this.currentRegion.exitRegion()),this.currentRegion=r,this.currentRegionName=e,r.enterRegion(t)}}save(){this.matrixStack.pushMat()}restore(){this.matrixStack.popMat()}startRender(e=!0){e&&this.matrixStack.clear(),this.matrixStack.pushIdentity(),this.currentRegion=void 0,this.currentRegionName=void 0}endRender(){this.currentRegion?.render()}renderSprite(e,t=0,r=0,i=this.defaultColor,a){this.setRegion("sprite",a),this.currentRegion.renderSprite(e.base.texture,e.width,e.height,e.clipX,e.clipY,e.clipW,e.clipH,t,r,i.uint32)}startGraphicDraw(e){this.setRegion("graphic",e),this.currentRegion.startRender()}addGraphicVertex(e,t,r){this.currentRegion.addVertex(e,t,r.uint32)}endGraphicDraw(){this.currentRegion.render()}clear(){const e=this.gl;e.clearColor(.2,.2,.2,1),e.clear(e.COLOR_BUFFER_BIT)}createOrthMatrix(e,t,r,i){return new Float32Array([2/(t-e),0,0,0,0,2/(i-r),0,0,0,0,-1,0,-(t+e)/(t-e),-(i+r)/(i-r),0,1])}transformPoint(e,t){return this.matrixStack.apply(e,t)}},e.Texture=f,e.TextureCache=b,e.WebglBufferArray=r,e.WebglElementBufferArray=a,e}({});