-
Notifications
You must be signed in to change notification settings - Fork 0
/
shader-utils.js
105 lines (98 loc) · 3.56 KB
/
shader-utils.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
101
102
103
104
105
/**
* Created by Hans Dulimarta on 1/12/17.
*/
class ShaderUtils {
static getShader(gl, code, type) {
let shader = gl.createShader(type);
gl.shaderSource(shader, code);
gl.compileShader(shader);
var error = gl.getShaderInfoLog(shader);
if (error.length > 0) {
let msg = (type === gl.VERTEX_SHADER ? "vertex" : "fragment") +
" shader compile: " + error;
throw msg;
}
return shader;
}
static loadFile(name) {
return new Promise(function (resolve, reject) {
let req = new XMLHttpRequest();
let okStatus = document.location.protocol === "file:" ? 0 : 200;
req.open("GET", name, true);
req.onload = function () {
if (req.status == okStatus) {
resolve(req.response);
} else {
reject(Error(name + " " + req.statusText));
}
};
req.onerror = function () {
reject(Error("Network Error"));
};
req.send(null);
});
}
static loadFromFile(gl, vshaderName, fShaderName) {
let files = [{"name": vshaderName, "type": gl.VERTEX_SHADER},
{"name": fShaderName, "type": gl.FRAGMENT_SHADER}]
.map(obj => {
return ShaderUtils.loadFile(obj.name)
.then(result => {
return {"text": result, "type": obj.type};
});
});
return Promise.all(files)
.then(files => {
let program = gl.createProgram();
for (let f of files) {
var sh = ShaderUtils.getShader(gl, f.text, f.type);
gl.attachShader(program, sh);
}
gl.linkProgram(program);
let error = gl.getProgramInfoLog(program);
if (error.length > 0) {
var msg = "Shader program failed to link: " + error;
throw msg;
}
return program;
})
.catch(err => {
ShaderUtils.showError(gl, err);
});
}
static loadFromElement(gl, vertexId, fragmentId) {
let vertElem = document.getElementById(vertexId);
if (!vertElem) {
alert("Unable to load vertex shader " + vertexId);
return -1;
}
var vertShader = ShaderUtils.getShader(gl, vertElem.textContent, gl.VERTEX_SHADER);
let fragElem = document.getElementById(fragmentId);
if (!fragElem) {
alert("Unable to load fragment shader " + fragmentId);
return -1;
}
let fragShader = ShaderUtils.getShader(gl, fragElem.textContent, gl.FRAGMENT_SHADER);
let program = gl.createProgram();
gl.attachShader(program, vertShader);
gl.attachShader(program, fragShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
let msg = "Shader program failed to link. The error log is:"
+ "<pre>" + gl.getProgramInfoLog(program) + "</pre>";
alert(msg);
return -1;
}
return program;
}
static showError(gl, msg) {
var container = gl.canvas.parentNode;
container.innerHTML =
"<div style='background: orangered; font-family: Courier;" +
"color: white; " +
"padding: 8px; " +
"border-radius: 4px'>"
+ msg +
"</div>";
}
}