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
16const { shaderFastVs, shaderFastFs } = require('./shaders/shader_fast');
17const { NapiLog } = require('./../../hcs/NapiLog');
18import { gl } from '../GLFrame.js';
19
20export class XShader {
21  static gi() {
22    if (XShader.pinstance_ === null) {
23      XShader.pinstance_ = new XShader();
24    }
25    return XShader.pinstance_;
26  }
27  constructor() {
28    this.pUseingShader = null;
29    this.shaders = [];
30    this.initFastShader();
31  }
32  initFastShader() {
33    let program = 'program';
34    this.shaderFast = { program: this.initShader(shaderFastVs, shaderFastFs) };
35
36    this.shaderFast.position = gl.getAttribLocation(
37      this.shaderFast[program],
38      'position'
39    );
40    this.shaderFast.aTexCoord = gl.getAttribLocation(
41      this.shaderFast[program],
42      'aTexCoord'
43    );
44    this.shaderFast.ext1 = gl.getAttribLocation(
45      this.shaderFast[program],
46      'ext1'
47    );
48    this.shaderFast.ext2 = gl.getAttribLocation(
49      this.shaderFast[program],
50      'ext2'
51    );
52    this.shaderFast.inColor = gl.getAttribLocation(
53      this.shaderFast[program],
54      'inColor'
55    );
56
57    this.shaderFast.uMat = gl.getUniformLocation(
58      this.shaderFast[program],
59      'uMat'
60    );
61
62    this.shaderFast.tex = {};
63    for (let i = 0; i < 16; i++) {
64      this.shaderFast.tex[i] = gl.getUniformLocation(
65        this.shaderFast[program],
66        'tex' + i
67      );
68    }
69
70    this.shaders[XShader.ID_SHADER_FAST] = this.shaderFast;
71    this.use(XShader.ID_SHADER_FAST);
72  }
73  use(sid) {
74    let program = 'program';
75    gl.useProgram(this.shaders[sid][program]);
76    this.pUseingShader = this.shaders[sid];
77    return this.pUseingShader;
78  }
79  initShader(vss, fss) {
80    let vs = gl.createShader(gl.VERTEX_SHADER);
81    gl.shaderSource(vs, vss);
82    gl.compileShader(vs);
83    if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {
84      NapiLog.logError(
85        'error occured compiling the shaders:' + gl.getShaderInfoLog(vs)
86      );
87      return null;
88    }
89
90    let fs = gl.createShader(gl.FRAGMENT_SHADER);
91    gl.shaderSource(fs, fss);
92    gl.compileShader(fs);
93    if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {
94      NapiLog.logError(
95        'error occured compiling the shaders:' + gl.getShaderInfoLog(fs)
96      );
97      return null;
98    }
99
100    let ret = gl.createProgram();
101
102    gl.attachShader(ret, vs);
103    gl.attachShader(ret, fs);
104    gl.linkProgram(ret);
105
106    if (!gl.getProgramParameter(ret, gl.LINK_STATUS)) {
107      NapiLog.logError('unable to initialize!');
108      return;
109    }
110
111    gl.deleteShader(vs);
112    gl.deleteShader(fs);
113    return ret;
114  }
115}
116
117XShader.ID_SHADER_FAST = 2;
118
119XShader.pinstance_ = null;
120