• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022-2023 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    XShader.gi();
39
40    this.resetMat();
41  }
42  resetMat() {
43    X2DFast.transform2D.unit();
44    X2DFast.transform2D.orthoMat(0, 0, Scr.logicw, Scr.logich);
45    let tm = X2DFast.transform2D.mat;
46    this.t2dExt = [
47      tm[0][0],
48      tm[1][0],
49      tm[2][0],
50      tm[3][0],
51      tm[0][1],
52      tm[1][1],
53      tm[2][1],
54      tm[3][1],
55      tm[0][2],
56      tm[1][2],
57      tm[2][2],
58      tm[3][2],
59      tm[0][3],
60      tm[1][3],
61      tm[2][3],
62      tm[3][3],
63    ];
64  }
65
66  swapMode2D() {
67    gl.disable(gl.DEPTH_TEST);
68
69    gl.enable(gl.BLEND);
70    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);// ONE_MINUS_SRC_ALPHA
71    // GL_FUNC_ADD、GL_FUNC_SUBTRACT、GL_FUNC_REVERSE_SUBTRACT、GL_MIN、GL_MAX和GL_LOGIC_OP
72  }
73
74  DrawCircle(ox, oy, rw, rh, c = 0xffffffff, lw = 1) {
75    let lx = -1;
76    let ly = -1;
77    let i = 0;
78    let gap = (Math.PI * 2) / 32;
79    while (i < Math.PI * 2 + 0.00001) {
80      let dx = Math.cos(i) * rw + ox;
81      let dy = Math.sin(i) * rh + oy;
82      if (lx !== -1) {
83        this.drawLine(lx, ly, dx, dy, c, lw);
84      }
85      lx = dx;
86      ly = dy;
87      i += gap;
88    }
89  }
90
91  fillRect(x, y, w, h, c = 0xffffffff) {
92    this.drawCut(this.whiteCut, x, y, w, h, 0, 0, 0, c);
93  }
94
95  drawLine(x1, y1, x2, y2, c = 0xffffffff, linewidth = 1) {
96    x1 = parseInt(x1);
97    y1 = parseInt(y1);
98    x2 = parseInt(x2);
99    y2 = parseInt(y2);
100    this.drawCut(
101      this.whiteCut,
102      x1,
103      y1,
104      iDistance(x1 - x2, y1 - y2),
105      linewidth,
106      fAngle(x2 - x1, y2 - y1),
107      0,
108      0,// +0.5
109      c
110    );
111  }
112
113  drawRect(x, y, w, h, c = 0xffffffff, lw = 1) {
114    this.drawLine(x - lw / 2, y, x + w + lw / 2, y, c, lw);
115    this.drawLine(x, y, x, y + h, c, lw);
116    this.drawLine(x + w, y + h, x + w, y, c, lw);
117    this.drawLine(x + w + lw / 2, y + h, x - lw / 2, y + h, c, lw);
118  }
119
120  static testTransform(x, y, sw, sh, ra, ox, oy, realw, realh) {
121    X2DFast.tmpMat.unit();
122    if (ox === -1) ox = 0;
123    if (ox === -2) ox = Math.floor(realw / 2);
124    if (ox === -3) ox = realw;
125    if (oy === -1) oy = 0;
126    if (oy === -2) oy = Math.floor(realh / 2);
127    if (oy === -3) oy = realh;
128    if (ox !== 0 || oy !== 0) X2DFast.tmpMat.move(-ox, -oy, 0);
129    if (sw !== 1 || sh !== 1) X2DFast.tmpMat.scale(sw, sh, 1);
130    if (ra !== 0) X2DFast.tmpMat.rotate(0, 0, ra);
131    if (x !== 0 || y !== 0) X2DFast.tmpMat.move(x, y, 0);
132  }
133  clearBuffer() {
134    this.ridDict = {};
135    this.ridPoint = 0;
136    this.drawCount = 0;
137  }
138  swapC(c) {
139    let r, g, b, a;
140    if (isNaN(c)) {
141      r = Math.floor(c[0] * 63 / 255);
142      g = Math.floor(c[1] * 63 / 255);
143      b = Math.floor(c[2] * 63 / 255);
144      a = Math.floor(c[3] * 63 / 255);
145    }
146    else {
147      if (c === -1) c = 0xffffffff;
148      r = Math.floor((((c >> 16) & 0xff) * 63) / 255);
149      g = Math.floor((((c >> 8) & 0xff) * 63) / 255);
150      b = Math.floor(((c & 0xff) * 63) / 255);
151      a = Math.floor((((c >> 24) & 0xff) * 63) / 255);
152    }
153    return ((a * 64 + r) * 64 + g) * 64 + b + 0.1;
154  }
155  drawCut_(pcut, m00, m01, m10, m11, m22, m30, m31, c = 0xffffffff) {
156    c = this.swapC(c);
157    this.vertexFloat32.set([0.0, 0.0, 0.0, pcut.u0, pcut.v0, m00, m01, m10, m11, m22, m30, m31,
158      this.ridDict[pcut.rid], c,
159      pcut.w, 0.0, 0.0, pcut.u1, pcut.v1, m00, m01, m10, m11, m22, m30, m31, this.ridDict[pcut.rid], c,
160      pcut.w, pcut.h, 0.0, pcut.u2, pcut.v2, m00, m01, m10, m11, m22, m30, m31, this.ridDict[pcut.rid], c,
161      0.0, 0.0, 0.0, pcut.u0, pcut.v0, m00, m01, m10, m11, m22, m30, m31, this.ridDict[pcut.rid], c,
162      pcut.w, pcut.h, 0.0, pcut.u2, pcut.v2, m00, m01, m10, m11, m22, m30, m31, this.ridDict[pcut.rid], c,
163      0.0, pcut.h, 0.0, pcut.u3, pcut.v3, m00, m01, m10, m11, m22, m30, m31, this.ridDict[pcut.rid], c,],
164      this.drawCount * 14 * 6);
165    this.drawCount += 1;
166  }
167  drawCutEx(cid, tmat, c = 0xffffffff) {
168    let pcut = XTexture.pinstance_.allCuts[cid];
169    if (!(pcut.rid in this.ridDict)) {
170      this.ridDict[pcut.rid] = this.ridPoint;
171      this.ridPoint += 1;
172    }
173    tmat = tmat.mat;
174    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);
175  }
176  drawCut(cid, x = 0, y = 0, sw = 1, sh = 1, ra = 0, ox = 0, oy = 0, c = 0xffffffff) {
177    let intX = parseInt(x);
178    let intY = parseInt(y);
179    let pcut = XTexture.gi().allCuts[cid];
180    if (pcut == null) return;
181    if (!(pcut.rid in this.ridDict)) {
182      if (this.ridPoint >= 16) {
183        this.freshBuffer();
184        this.clearBuffer();
185      }
186      this.ridDict[pcut.rid] = this.ridPoint;
187      this.ridPoint += 1;
188    }
189    X2DFast.testTransform(intX, intY, sw, sh, ra, ox, oy, pcut.w, pcut.h);
190    let tmat = X2DFast.tmpMat.mat;
191    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);
192  }
193  drawText(s, size = 14, x = 0, y = 0, sw = 1, sh = 1, ra = 0, ox = 0, oy = 0, c = 0xffffffff) {
194    if (s.length <= 0) return 0;
195    let cid = XTexture.gi().getText(s, size);
196    if (cid >= 0) this.drawCut(cid, x, y, sw, sh, ra, ox, oy, c);
197    return XTexture.gi().allCuts[cid].w;
198  }
199  getTextWidth(s, size) {
200    if (s.length <= 0) return 0;
201    let cid = XTexture.gi().getText(s, size);
202    return XTexture.gi().allCuts[cid].w;
203  }
204  freshBuffer() {
205    XTexture.gi()._FreshText();
206    if (this.drawCount === 0) return;
207    let ps = XShader.gi().use(XShader.ID_SHADER_FAST);
208    for (let rid in this.ridDict) {
209      gl.activeTexture(gl.TEXTURE0 + this.ridDict[rid]);
210      gl.bindTexture(gl.TEXTURE_2D, XTexture.gi().ximages[rid].tex);
211
212      gl.uniform1i(ps.tex[this.ridDict[rid]], this.ridDict[rid]);
213    }
214
215    gl.uniformMatrix4fv(ps.uMat, false, this.t2dExt);
216
217    gl.bindBuffer(gl.ARRAY_BUFFER, this.localBuffer);
218    gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW);
219    gl.vertexAttribPointer(ps.position, 3, gl.FLOAT, false, 4 * 14, 0);
220    gl.enableVertexAttribArray(ps.position);
221    gl.vertexAttribPointer(ps.aTexCoord, 2, gl.FLOAT, false, 4 * 14, 4 * 3);
222    gl.enableVertexAttribArray(ps.aTexCoord);
223    gl.vertexAttribPointer(ps.ext1, 4, gl.FLOAT, false, 4 * 14, 4 * 5);
224    gl.enableVertexAttribArray(ps.ext1);
225    gl.vertexAttribPointer(ps.ext2, 4, gl.FLOAT, false, 4 * 14, 4 * 9);
226    gl.enableVertexAttribArray(ps.ext2);
227    gl.vertexAttribPointer(ps.inColor, 1, gl.FLOAT, false, 4 * 14, 4 * 13);
228    gl.enableVertexAttribArray(ps.inColor);
229
230    gl.drawArrays(gl.TRIANGLES, 0, 6 * this.drawCount);
231  }
232}
233X2DFast.tmpMat = new XMat4();
234X2DFast.transform2D = new XMat4();
235
236X2DFast.px2f = null;
237