rapid-render 0.0.1 → 0.0.2
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 +70 -149
- package/dist/index.d.ts +3 -6
- package/dist/interface.d.ts +0 -7
- package/dist/math.d.ts +57 -58
- package/dist/rapid.global.js +1 -0
- package/dist/rapid.js +1 -784
- package/dist/rapid.umd.cjs +1 -42
- package/dist/regions/graphic_region.d.ts +10 -0
- package/dist/regions/region.d.ts +24 -0
- package/dist/regions/sprite_region.d.ts +16 -0
- package/dist/render.d.ts +33 -0
- package/dist/texture.d.ts +1 -1
- package/dist/webgl/glshader.d.ts +13 -0
- package/package.json +10 -21
- package/dist/consts.d.ts +0 -5
- package/dist/region/graphic_region.d.ts +0 -41
- package/dist/region/region.d.ts +0 -44
- package/dist/region/sprite_region.d.ts +0 -47
- package/dist/renderer.d.ts +0 -109
- /package/dist/{utils/webgl.d.ts → webgl/utils.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,149 +1,70 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
+
⚠️ This project is under development and will be completed soon ⚠️
|
|
4
|
+
|
|
5
|
+
A highly efficient and lightweight WebGL renderer capable of rendering 10k sprites at 60fps.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
[Demo](https://nightre.github.io/Rapid.js/demo/)
|
|
9
|
+
|
|
10
|
+
# Features:
|
|
11
|
+
* Fast rendering ( capable of rendering 10,000 sprites at 60fps )
|
|
12
|
+
* Multi-texture support ( Batch rendering based on the GPU's maximum texture units )
|
|
13
|
+
* Texture cropping
|
|
14
|
+
* Graphic
|
|
15
|
+
* Matrix stacking
|
|
16
|
+
* Color manipulation
|
|
17
|
+
|
|
18
|
+
# Useage
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
let rapid = new Rapid({
|
|
22
|
+
canvas: document.getElementById("game"),
|
|
23
|
+
backgroundColor: Color.fromHex("FFFFFF")
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
// Creating textures
|
|
27
|
+
const cat = await rapid.texture.textureFromUrl("./cat.png")
|
|
28
|
+
const plane = await rapid.texture.textureFromUrl("./plane.png")
|
|
29
|
+
// or
|
|
30
|
+
// Texture.fromImageSource(img)
|
|
31
|
+
// Texture.fromUrl(url)
|
|
32
|
+
// set clip
|
|
33
|
+
cat.setClipRegion(
|
|
34
|
+
10,10 // top-left corner of the clipped region.
|
|
35
|
+
50,50 // size
|
|
36
|
+
)
|
|
37
|
+
// R G B A
|
|
38
|
+
const color = new Color(255,255,255,255)
|
|
39
|
+
// or Color.fromHex
|
|
40
|
+
// Called before starting rendering
|
|
41
|
+
rapid.startRender()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
rapid.save() // Save state
|
|
45
|
+
rapid.matrixStack.translate(0,0)
|
|
46
|
+
rapid.matrixStack.scale(1)
|
|
47
|
+
rapid.matrixStack.rotate(0)
|
|
48
|
+
|
|
49
|
+
// texture offset color
|
|
50
|
+
rapid.renderSprite(cat,0,0, color) // draw Sprite
|
|
51
|
+
rapid.restore() // back to the previous saved state
|
|
52
|
+
|
|
53
|
+
// draw graphic
|
|
54
|
+
// Different vertices can have different colors
|
|
55
|
+
rapid.startGraphicDraw()
|
|
56
|
+
rapid.addGraphicVertex(0, 0, color)
|
|
57
|
+
rapid.addGraphicVertex(100, 0, color)
|
|
58
|
+
rapid.addGraphicVertex(100, 100, color)
|
|
59
|
+
rapid.endGraphicDraw()
|
|
60
|
+
|
|
61
|
+
// Called after rendering
|
|
62
|
+
rapid.endRender()
|
|
63
|
+
|
|
64
|
+
// set the size
|
|
65
|
+
rapid.resize(100,100)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
# Screen Shot
|
|
69
|
+
|
|
70
|
+

|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
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
|
|
9
|
-
export * from "./utils/webgl";
|
|
6
|
+
export * from "./render";
|
package/dist/interface.d.ts
CHANGED
|
@@ -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
|
-
|
|
3
|
+
export declare class DynamicArrayBuffer {
|
|
4
|
+
usedElemNum: number;
|
|
5
5
|
protected typedArray: Float32Array | Uint16Array;
|
|
6
6
|
private arrayType;
|
|
7
|
-
|
|
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):
|
|
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
|
|
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
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
|
|
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}({});
|