|
1 WebGLUtil = (function() { |
|
2 // --------------------------------------------------------------------------- |
|
3 // Error handling (for obvious failures, such as invalid element ids) |
|
4 |
|
5 function defaultErrorFunc(str) { |
|
6 console.log('Error: ' + str); |
|
7 } |
|
8 |
|
9 var gErrorFunc = defaultErrorFunc; |
|
10 function setErrorFunc(func) { |
|
11 gErrorFunc = func; |
|
12 } |
|
13 |
|
14 function error(str) { |
|
15 gErrorFunc(str); |
|
16 } |
|
17 |
|
18 // --------------------------------------------------------------------------- |
|
19 // Warning handling (for failures that may be intentional) |
|
20 |
|
21 function defaultWarningFunc(str) { |
|
22 console.log('Warning: ' + str); |
|
23 } |
|
24 |
|
25 var gWarningFunc = defaultWarningFunc; |
|
26 function setWarningFunc(func) { |
|
27 gWarningFunc = func; |
|
28 } |
|
29 |
|
30 function warning(str) { |
|
31 gWarningFunc(str); |
|
32 } |
|
33 |
|
34 // --------------------------------------------------------------------------- |
|
35 // WebGL helpers |
|
36 |
|
37 function getWebGL(canvasId, requireConformant) { |
|
38 // `requireConformant` will default to falsey if it is not supplied. |
|
39 |
|
40 var canvas = document.getElementById(canvasId); |
|
41 |
|
42 var gl = null; |
|
43 try { |
|
44 gl = canvas.getContext('webgl'); |
|
45 } catch(e) {} |
|
46 |
|
47 if (!gl && !requireConformant) { |
|
48 try { |
|
49 gl = canvas.getContext('experimental-webgl'); |
|
50 } catch(e) {} |
|
51 } |
|
52 |
|
53 if (!gl) { |
|
54 error('WebGL context could not be retrieved from \'' + canvasId + '\'.'); |
|
55 return null; |
|
56 } |
|
57 |
|
58 return gl; |
|
59 } |
|
60 |
|
61 function getContentFromElem(elem) { |
|
62 var str = ""; |
|
63 var k = elem.firstChild; |
|
64 while (k) { |
|
65 if (k.nodeType == 3) |
|
66 str += k.textContent; |
|
67 |
|
68 k = k.nextSibling; |
|
69 } |
|
70 |
|
71 return str; |
|
72 } |
|
73 |
|
74 // Returns a valid shader, or null on errors. |
|
75 function createShaderById(gl, id) { |
|
76 var elem = document.getElementById(id); |
|
77 if (!elem) { |
|
78 error('Failed to create shader from non-existent id \'' + id + '\'.'); |
|
79 return null; |
|
80 } |
|
81 |
|
82 var src = getContentFromElem(elem); |
|
83 |
|
84 var shader; |
|
85 if (elem.type == "x-shader/x-fragment") { |
|
86 shader = gl.createShader(gl.FRAGMENT_SHADER); |
|
87 } else if (elem.type == "x-shader/x-vertex") { |
|
88 shader = gl.createShader(gl.VERTEX_SHADER); |
|
89 } else { |
|
90 error('Bad MIME type for shader \'' + id + '\': ' + elem.type + '.'); |
|
91 return null; |
|
92 } |
|
93 |
|
94 gl.shaderSource(shader, src); |
|
95 gl.compileShader(shader); |
|
96 |
|
97 return shader; |
|
98 } |
|
99 |
|
100 function createProgramByIds(gl, vsId, fsId) { |
|
101 var vs = createShaderById(gl, vsId); |
|
102 var fs = createShaderById(gl, fsId); |
|
103 if (!vs || !fs) |
|
104 return null; |
|
105 |
|
106 var prog = gl.createProgram(); |
|
107 gl.attachShader(prog, vs); |
|
108 gl.attachShader(prog, fs); |
|
109 gl.linkProgram(prog); |
|
110 |
|
111 if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) { |
|
112 var str = "Shader program linking failed:"; |
|
113 str += "\nShader program info log:\n" + gl.getProgramInfoLog(prog); |
|
114 str += "\n\nVert shader log:\n" + gl.getShaderInfoLog(vs); |
|
115 str += "\n\nFrag shader log:\n" + gl.getShaderInfoLog(fs); |
|
116 warning(str); |
|
117 return null; |
|
118 } |
|
119 |
|
120 return prog; |
|
121 } |
|
122 |
|
123 return { |
|
124 setErrorFunc: setErrorFunc, |
|
125 setWarningFunc: setWarningFunc, |
|
126 |
|
127 getWebGL: getWebGL, |
|
128 createShaderById: createShaderById, |
|
129 createProgramByIds: createProgramByIds, |
|
130 }; |
|
131 })(); |