1 define([ ], function () {
2 var WIDTH
= 512, HEIGHT
= 512;
4 function makeShaderFactory(vertexLines
, fragmentLines
, callback
) {
5 return function makeShader(gl
) {
6 var prog
= createProgram(
8 vertexLines
.join('\n'),
9 fragmentLines
.join('\n')
11 return callback(gl
, prog
);
16 sprite
: makeShaderFactory([
17 '#define WIDTH ' + WIDTH
.toFixed(1),
18 '#define HEIGHT ' + HEIGHT
.toFixed(1),
20 'attribute vec2 aCoord;',
22 'uniform vec2 uSize;',
23 'uniform mat3 uMatrix;',
25 'varying vec2 vTextureCoord;',
27 'mat4 projection = mat4(',
28 '2.0 / WIDTH, 0.0, 0.0, -1.0,',
29 '0.0, -2.0 / HEIGHT, 0.0, 1.0,',
30 '0.0, 0.0,-2.0,-0.0,',
34 // TODO Turn * mul + translate into one matrix multiply.
36 'uMatrix[0][0], uMatrix[1][0],',
37 'uMatrix[0][1], uMatrix[1][1]',
40 'vec2 translate = vec2(uMatrix[0][2], uMatrix[1][2]);',
43 'vec4 p = vec4(aCoord * uSize * mul + translate, 0.0, 1.0);',
44 'gl_Position = p * projection;',
45 'vTextureCoord = aCoord;',
48 'varying vec2 vTextureCoord;',
50 'uniform sampler2D uSampler;',
53 'gl_FragColor = texture2D(uSampler, vTextureCoord.st);',
55 ], function (gl
, prog
) {
57 coord
: gl
.getAttribLocation(prog
, 'aCoord')
60 sampler
: gl
.getUniformLocation(prog
, 'uSampler'),
61 size
: gl
.getUniformLocation(prog
, 'uSize'),
62 matrix
: gl
.getUniformLocation(prog
, 'uMatrix')
67 batchSprite
: makeShaderFactory([
68 '#define WIDTH ' + WIDTH
.toFixed(1),
69 '#define HEIGHT ' + HEIGHT
.toFixed(1),
71 'attribute vec2 aCoord;',
72 'attribute vec2 aTexCoord;',
74 'varying vec2 vTextureCoord;',
76 'mat4 projection = mat4(',
77 '2.0 / WIDTH, 0.0, 0.0, -1.0,',
78 '0.0, -2.0 / HEIGHT, 0.0, 1.0,',
79 '0.0, 0.0,-2.0,-0.0,',
84 'vec4 p = vec4(aCoord, 0.0, 1.0);',
85 'gl_Position = p * projection;',
86 'vTextureCoord = aTexCoord;',
89 'varying vec2 vTextureCoord;',
91 'uniform sampler2D uSampler;',
94 'gl_FragColor = texture2D(uSampler, vTextureCoord.st);',
96 ], function (gl
, prog
) {
98 coord
: gl
.getAttribLocation(prog
, 'aCoord'),
99 texCoord
: gl
.getAttribLocation(prog
, 'aTexCoord')
102 sampler
: gl
.getUniformLocation(prog
, 'uSampler')
108 function reportGLError(gl
, error
) {
109 // Find the error name
110 for (var key
in gl
) {
111 // Include properties of prototype
112 if (gl
[key
] === error
) {
113 throw new Error("GL error " + key
+ " (code " + error
+ ")");
117 // Couldn't find it; whatever
118 throw new Error("GL error code " + error
);
121 function checkGLError(gl
) {
122 var error
= gl
.getError();
124 reportGLError(gl
, error
);
128 function wrapGL(gl
) {
139 var ret
= gl
[key
].apply(gl
, arguments
);
145 for (var key
in gl
) {
146 // Include properties of prototype
147 if (typeof gl
[key
] === 'function') {
148 wrapped
[key
] = wrap(key
);
150 wrapped
[key
] = gl
[key
];
157 function makeTexture(gl
, image
) {
158 var texture
= gl
.createTexture();
160 gl
.bindTexture(gl
.TEXTURE_2D
, texture
);
161 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.RGBA
, gl
.RGBA
, gl
.UNSIGNED_BYTE
, image
);
162 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_MAG_FILTER
, gl
.LINEAR
);
163 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_MIN_FILTER
, gl
.LINEAR
);
164 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_WRAP_S
, gl
.CLAMP_TO_EDGE
);
165 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_WRAP_T
, gl
.CLAMP_TO_EDGE
);
167 gl
.bindTexture(gl
.TEXTURE_2D
, null);
174 /*jshint white: false, eqeqeq: false, eqnull: true */
177 // https://github.com/strager/owp/
179 // which took from webgl-boilerplate
180 // https://github.com/jaredwilli/webgl-boilerplate/
182 function createShader( gl
, src
, type
) {
184 var shader
= gl
.createShader( type
);
186 gl
.shaderSource( shader
, src
);
187 gl
.compileShader( shader
);
189 if ( !gl
.getShaderParameter( shader
, gl
.COMPILE_STATUS
) ) {
191 throw new Error( ( type
== gl
.VERTEX_SHADER
? "VERTEX" : "FRAGMENT" ) + " SHADER:\n" + gl
.getShaderInfoLog( shader
) + "\nSOURCE:\n" + src
);
199 createProgram
= function createProgram( gl
, vertex
, fragment
) {
201 var program
= gl
.createProgram();
203 var vs
= createShader( gl
, vertex
, gl
.VERTEX_SHADER
);
204 var fs
= createShader( gl
, '#version 100\n#ifdef GL_ES\nprecision highp float;\n#endif\n\n' + fragment
, gl
.FRAGMENT_SHADER
);
206 if ( vs
== null || fs
== null ) return null;
208 gl
.attachShader( program
, vs
);
209 gl
.attachShader( program
, fs
);
211 gl
.deleteShader( vs
);
212 gl
.deleteShader( fs
);
214 gl
.linkProgram( program
);
216 if ( !gl
.getProgramParameter( program
, gl
.LINK_STATUS
) ) {
218 throw new Error( "ERROR:\n" +
219 "VALIDATE_STATUS: " + gl
.getProgramParameter( program
, gl
.VALIDATE_STATUS
) + "\n" +
220 "ERROR: " + gl
.getError() + "\n\n" +
221 "- Vertex Shader -\n" + vertex
+ "\n\n" +
222 "- Fragment Shader -\n" + fragment
);
231 function getContext(canvas
, options
) {
234 context
= canvas
.getContext('webgl', options
);
240 context
= canvas
.getContext('experimental-webgl', options
);
245 throw new Error("WebGL not supported");
249 if (false) { // DEBUG
250 context
= wrapGL(context
);
259 makeTexture
: makeTexture
,
260 createProgram
: createProgram
,
261 getContext
: getContext