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