|
169 | 169 | surface = { centerX: 0, centerY: 0, width: 1, height: 1, isPanning: false, isZooming: false, lastX: 0, lastY: 0 },
|
170 | 170 | frontTarget, backTarget, screenProgram, getWebGL, resizer = {}, compileOnChangeCode = true;
|
171 | 171 |
|
| 172 | + var customTextures, textureCache = {}, loadCustomTexture = function ( url ) { |
| 173 | + if (!textureCache[ url ]) { |
| 174 | + |
| 175 | + var tex = gl.createTexture(); |
| 176 | + var img = new Image(); |
| 177 | + |
| 178 | + // assume cross-domain image |
| 179 | + img.crossOrigin = 'anonymous'; |
| 180 | + |
| 181 | + img.onload = function () { |
| 182 | + gl.bindTexture(gl.TEXTURE_2D, tex); |
| 183 | + |
| 184 | + // assume NPOT texture |
| 185 | + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); |
| 186 | + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); |
| 187 | + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); |
| 188 | + |
| 189 | + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img); |
| 190 | + |
| 191 | + gl.bindTexture(gl.TEXTURE_2D, null); |
| 192 | + }; |
| 193 | + |
| 194 | + img.src = url; |
| 195 | + |
| 196 | + textureCache[ url ] = tex; |
| 197 | + } |
| 198 | + |
| 199 | + return textureCache[ url ]; |
| 200 | + }; |
| 201 | + |
172 | 202 | init();
|
173 | 203 | if (gl) { animate(); }
|
174 | 204 |
|
|
621 | 651 | cacheUniformLocation( program, 'backbuffer' );
|
622 | 652 | cacheUniformLocation( program, 'surfaceSize' );
|
623 | 653 |
|
| 654 | + // Custom textures |
| 655 | + |
| 656 | + customTextures = {}; |
| 657 | + |
| 658 | + var matches, regexp = /sampler2D\s+(\w+)\s*;\s*\/\/\s*([^\s]+)/g; |
| 659 | + while (matches = regexp.exec (fragment)) { |
| 660 | + var name = matches[ 1 ]; |
| 661 | + cacheUniformLocation( program, name ); |
| 662 | + customTextures[ name ] = matches[ 2 ]; |
| 663 | + } |
| 664 | + |
624 | 665 | // Load program into GPU
|
625 | 666 |
|
626 | 667 | gl.useProgram( currentProgram );
|
|
893 | 934 | gl.activeTexture( gl.TEXTURE0 );
|
894 | 935 | gl.bindTexture( gl.TEXTURE_2D, backTarget.texture );
|
895 | 936 |
|
| 937 | + // Load custom textures |
| 938 | + |
| 939 | + var sampler = 1; |
| 940 | + for (var samplerName in customTextures) { |
| 941 | + gl.uniform1i( currentProgram.uniformsCache[ samplerName ], sampler ); |
| 942 | + |
| 943 | + gl.activeTexture( gl[ 'TEXTURE' + sampler ] ); |
| 944 | + gl.bindTexture( gl.TEXTURE_2D, loadCustomTexture( customTextures[ samplerName ] ) ); |
| 945 | + |
| 946 | + sampler++; |
| 947 | + } |
| 948 | + |
896 | 949 | // Render custom shader to front buffer
|
897 | 950 |
|
898 | 951 | gl.bindFramebuffer( gl.FRAMEBUFFER, frontTarget.framebuffer );
|
|
0 commit comments