-
Notifications
You must be signed in to change notification settings - Fork 1
/
ShaderProgram.js
100 lines (91 loc) · 2.95 KB
/
ShaderProgram.js
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
var ShaderProgram = (function () {
var NULL_FUNC = function () {};
class ShaderProgram {
constructor (params) {
this._cbs = {
setup: NULL_FUNC,
update: NULL_FUNC
};
this.attrs = {};
this.unifs = {};
this.glProgram = undefined;
this.creationPromise = this._create(params);
}
_compileShader (gl, src, type) {
let info;
let shader = gl.createShader(type);
gl.shaderSource(shader, src);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
info = gl.getShaderInfoLog(shader);
console.log('Err in shader', type);
console.log(info);
shader = null;
}
return shader;
}
_getAttribLocations (gl, program, locations = []) {
let i;
let locs = {};
for (i = 0; i < locations.length; i++) {
locs[locations[i]] = gl.getAttribLocation(program, locations[i]);
}
return locs;
}
_getUniformLocations (gl, program, locations = []) {
let i;
let locs = {};
for (i = 0; i < locations.length; i++) {
locs[locations[i]] = gl.getUniformLocation(program, locations[i]);
}
return locs;
}
async _create (params) {
let gl = params.gl;
if (!params.vertPath || !params.fragPath) {
console.error('vertPath or fragPath were not detected in params object:', params);
}
let texts = [
fetch(params.vertPath).then(resp => resp.text()),
fetch(params.fragPath).then(resp => resp.text())
];
let [vertSrc, fragSrc] = await Promise.all(texts);
let info;
let program = gl.createProgram();
let vertShader = this._compileShader(gl, vertSrc, gl.VERTEX_SHADER);
let fragShader = this._compileShader(gl, fragSrc, gl.FRAGMENT_SHADER);
if (!vertShader || !fragShader) {
console.error('No suitable shaders. Shader files:', params.vertPath, params.fragPath);
return null;
}
gl.attachShader(program, vertShader);
gl.attachShader(program, fragShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
info = gl.getProgramInfoLog(program);
console.log(info);
program = null;
}
this.glProgram = program;
this.attrs = this._getAttribLocations(gl, program, params.attrs);
this.unifs = this._getUniformLocations(gl, program, params.unifs);
if (typeof params.setup === 'function') {
this._cbs.setup = params.setup;
} else {
console.log('No shader program setup func were provided, requested shaders: %s, %s', params.vertPath, params.fragPath);
}
if (typeof params.update === 'function') {
this._cbs.update = params.update;
}
return program;
}
setup (gl) {
this._cbs.setup(gl, this);
}
update (gl) {
this._cbs.update(gl, this);
}
}
return ShaderProgram;
})();
export default ShaderProgram;