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