• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2* Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3* Licensed under the Apache License, Version 2.0 (the "License");
4* you may not use this file except in compliance with the License.
5* You may obtain a copy of the License at
6*
7* http://www.apache.org/licenses/LICENSE-2.0
8*
9* Unless required by applicable law or agreed to in writing, software
10* distributed under the License is distributed on an "AS IS" BASIS,
11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12* See the License for the specific language governing permissions and
13* limitations under the License.
14*/
15
16import { XMat4 } from "./XMat4.js"
17import { XShader } from "./XShader.js"
18import { Scr } from "../XDefine.js"
19import { XTexture } from "./XTexture.js"
20import { gl } from "../GLFrame.js"
21import { fAngle, iDistance } from "../XTools.js"
22
23export class X2DFast {
24    static gi() {
25        if (X2DFast.px2f == null) X2DFast.px2f = new X2DFast();
26        return X2DFast.px2f;
27    }
28
29    constructor() {
30        this.localBuffer = gl.createBuffer();
31        this.texSampleIdx = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
32
33        this.vertexArray = new ArrayBuffer(1024 * 1024 * 4 * 2)
34        this.vertexFloat32 = new Float32Array(this.vertexArray)
35        this.vertexUint32 = new Uint32Array(this.vertexArray)
36        this.whiteImg = XTexture.gi().loadTextureFromImage("CUSTOM_TEXTURE_1")
37        this.whiteCut = XTexture.gi().makeCut(this.whiteImg, 0, 0, 1, 1)
38
39        XShader.gi();
40
41        this.resetMat();
42    }
43    resetMat() {
44        X2DFast.transform2D.unit()
45        X2DFast.transform2D.orthoMat(0, 0, Scr.logicw, Scr.logich);
46        let tm = X2DFast.transform2D.mat;
47        this.t2dExt = [
48            tm[0][0], tm[1][0], tm[2][0], tm[3][0],
49            tm[0][1], tm[1][1], tm[2][1], tm[3][1],
50            tm[0][2], tm[1][2], tm[2][2], tm[3][2],
51            tm[0][3], tm[1][3], tm[2][3], tm[3][3]
52        ]
53    }
54
55    swapMode2D() {
56        gl.disable(gl.DEPTH_TEST)
57
58        gl.enable(gl.BLEND)
59        gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
60    }
61
62    DrawCircle(ox, oy, rw, rh, c = 0xffffffff, lw = 1) {
63        let lx = -1
64        let ly = -1
65        let i = 0
66        let gap = Math.PI * 2 / 32
67        while (i < Math.PI * 2 + 0.00001) {
68            let dx = Math.cos(i) * rw + ox
69            let dy = Math.sin(i) * rh + oy
70            if (lx != -1) {
71                this.drawLine(lx, ly, dx, dy, c, lw)
72            }
73            lx = dx
74            ly = dy
75            i += gap
76        }
77    }
78
79    fillRect(x, y, w, h, c = 0xffffffff) {
80        this.drawCut(this.whiteCut, x, y, w, h, 0, 0, 0, c)
81    }
82
83    drawLine(x1, y1, x2, y2, c = 0xffffffff, linewidth = 1) {
84        this.drawCut(this.whiteCut, x1, y1,
85            iDistance(x1 - x2, y1 - y2), linewidth, fAngle(x2 - x1, y2 - y1), 0, 0.5, c)
86    }
87
88    drawRect(x, y, w, h, c = 0xffffffff, lw = 1) {
89        this.drawLine(x - lw / 2, y, x + w + lw / 2, y, c, lw)
90        this.drawLine(x, y, x, y + h, c, lw)
91        this.drawLine(x + w, y + h, x + w, y, c, lw)
92        this.drawLine(x + w + lw / 2, y + h, x - lw / 2, y + h, c, lw)
93    }
94
95    static testTransform(x, y, sw, sh, ra, ox, oy, realw, realh) {
96        X2DFast.tmpMat.unit()
97        if (ox == -1) ox = 0
98        if (ox == -2) ox = Math.floor(realw / 2)
99        if (ox == -3) ox = realw
100        if (oy == -1) oy = 0
101        if (oy == -2) oy = Math.floor(realh / 2)
102        if (oy == -3) oy = realh
103        if (ox != 0 || oy != 0) X2DFast.tmpMat.move(-ox, -oy, 0)
104        if (sw != 1 || sh != 1) X2DFast.tmpMat.scale(sw, sh, 1)
105        if (ra != 0) X2DFast.tmpMat.rotate(0, 0, ra)
106        if (x != 0 || y != 0) X2DFast.tmpMat.move(x, y, 0)
107    }
108    clearBuffer() {
109        this.ridDict = {}
110        this.ridPoint = 0
111        this.drawCount = 0
112    }
113    swapC(c) {
114        let r = Math.floor(((c >> 16) & 0xff) * 63 / 255)
115        let g = Math.floor(((c >> 8) & 0xff) * 63 / 255)
116        let b = Math.floor((c & 0xff) * 63 / 255)
117        let a = Math.floor(((c >> 24) & 0xff) * 63 / 255)
118        return ((a * 64 + r) * 64 + g) * 64 + b
119    }
120    drawCut_(pcut, m00, m01, m10, m11, m22, m30, m31, c = 0xffffffff) {
121        if (c == -1) c = 0xffffffff
122        c = this.swapC(c)
123        this.vertexFloat32.set([0.0, 0.0, 0.0, pcut.u0, pcut.v0, m00, m01, m10, m11, m22, m30, m31,
124            this.ridDict[pcut.rid], c,
125            pcut.w, 0.0, 0.0, pcut.u1, pcut.v1, m00, m01, m10, m11, m22, m30, m31, this.ridDict[pcut.rid], c,
126            pcut.w, pcut.h, 0.0, pcut.u2, pcut.v2, m00, m01, m10, m11, m22, m30, m31, this.ridDict[pcut.rid], c,
127            0.0, 0.0, 0.0, pcut.u0, pcut.v0, m00, m01, m10, m11, m22, m30, m31, this.ridDict[pcut.rid], c,
128            pcut.w, pcut.h, 0.0, pcut.u2, pcut.v2, m00, m01, m10, m11, m22, m30, m31, this.ridDict[pcut.rid], c,
129            0.0, pcut.h, 0.0, pcut.u3, pcut.v3, m00, m01, m10, m11, m22, m30, m31, this.ridDict[pcut.rid], c],
130            this.drawCount * 14 * 6)
131        this.drawCount += 1
132    }
133    drawCutEx(cid, tmat, c = 0xffffffff) {
134        let pcut = XTexture.pinstance_.allCuts[cid];
135        if (!(pcut.rid in this.ridDict)) {
136            this.ridDict[pcut.rid] = this.ridPoint;
137            this.ridPoint += 1;
138        }
139        tmat = tmat.mat
140        this.drawCut(pcut, tmat[0][0], tmat[0][1], tmat[1][0], tmat[1][1], tmat[2][2], tmat[3][0], tmat[3][1], c)
141    }
142    drawCut(cid, x = 0, y = 0, sw = 1, sh = 1, ra = 0, ox = 0, oy = 0, c = 0xffffffff) {
143        let pcut = XTexture.gi().allCuts[cid];
144        if (pcut == null)
145            return;
146        if (!(pcut.rid in this.ridDict)) {
147            this.ridDict[pcut.rid] = this.ridPoint;
148            this.ridPoint += 1;
149        }
150        X2DFast.testTransform(x, y, sw, sh, ra, ox, oy, pcut.w, pcut.h)
151        let tmat = X2DFast.tmpMat.mat;
152        this.drawCut_(pcut, tmat[0][0], tmat[0][1], tmat[1][0], tmat[1][1], tmat[2][2], tmat[3][0], tmat[3][1], c)
153    }
154    drawText(s, size = 18, x = 0, y = 0, sw = 1, sh = 1, ra = 0, ox = 0, oy = 0, c = 0xffffffff) {
155        if (s.length <= 0) return 0;
156        let cid = XTexture.gi().getText(s, size)
157        if (cid >= 0)
158            this.drawCut(cid, x, y, sw, sh, ra, ox, oy, c)
159        return XTexture.gi().allCuts[cid].w;
160    }
161    getTextWidth(s, size) {
162        if (s.length <= 0) return 0;
163        let cid = XTexture.gi().getText(s, size)
164        return XTexture.gi().allCuts[cid].w;
165    }
166    freshBuffer() {
167        XTexture.gi()._FreshText()
168        if (this.drawCount == 0) return
169        let ps = XShader.gi().use(XShader.ID_SHADER_FAST)
170        for (let rid in this.ridDict) {
171            gl.activeTexture(gl.TEXTURE0 + this.ridDict[rid])
172            gl.bindTexture(gl.TEXTURE_2D, XTexture.gi().ximages[rid].tex);
173
174            gl.uniform1i(ps.tex[this.ridDict[rid]], this.ridDict[rid]);
175        }
176
177        gl.uniformMatrix4fv(ps.uMat, false, this.t2dExt)
178
179        gl.bindBuffer(gl.ARRAY_BUFFER, this.localBuffer);
180        gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW)
181        gl.vertexAttribPointer(ps.position, 3, gl.FLOAT, false, 4 * 14, 0)
182        gl.enableVertexAttribArray(ps.position)
183        gl.vertexAttribPointer(ps.aTexCoord, 2, gl.FLOAT, false, 4 * 14, 4 * 3)
184        gl.enableVertexAttribArray(ps.aTexCoord)
185        gl.vertexAttribPointer(ps.ext1, 4, gl.FLOAT, false, 4 * 14, 4 * 5)
186        gl.enableVertexAttribArray(ps.ext1)
187        gl.vertexAttribPointer(ps.ext2, 4, gl.FLOAT, false, 4 * 14, 4 * 9)
188        gl.enableVertexAttribArray(ps.ext2)
189        gl.vertexAttribPointer(ps.inColor, 1, gl.FLOAT, false, 4 * 14, 4 * 13)
190        gl.enableVertexAttribArray(ps.inColor)
191
192        gl.drawArrays(gl.TRIANGLES, 0, 6 * this.drawCount);
193    }
194}
195X2DFast.tmpMat = new XMat4();
196X2DFast.transform2D = new XMat4();
197
198X2DFast.px2f = null;
199
200
201