OLD | NEW |
(Empty) | |
| 1 <!DOCTYPE html> |
| 2 <html><head> |
| 3 <meta charset="utf-8"> |
| 4 <!-- |
| 5 Tests for the OpenGL ES 2.0 HTML Canvas context |
| 6 |
| 7 Copyright (C) 2011 Ilmari Heikkinen <ilmari.heikkinen@gmail.com> |
| 8 |
| 9 Permission is hereby granted, free of charge, to any person |
| 10 obtaining a copy of this software and associated documentation |
| 11 files (the "Software"), to deal in the Software without |
| 12 restriction, including without limitation the rights to use, |
| 13 copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 14 copies of the Software, and to permit persons to whom the |
| 15 Software is furnished to do so, subject to the following |
| 16 conditions: |
| 17 |
| 18 The above copyright notice and this permission notice shall be |
| 19 included in all copies or substantial portions of the Software. |
| 20 |
| 21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| 22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
| 23 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| 24 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
| 25 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| 26 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| 27 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| 28 OTHER DEALINGS IN THE SOFTWARE. |
| 29 |
| 30 --> |
| 31 <link rel="stylesheet" type="text/css" href="../unit.css" /> |
| 32 <script type="application/x-javascript" src="../unit.js"></script> |
| 33 <script type="application/x-javascript" src="../util.js"></script> |
| 34 <script type="application/x-javascript"> |
| 35 |
| 36 Tests.startUnit = function () { |
| 37 var canvas = document.getElementById('gl'); |
| 38 var gl = wrapGLContext(canvas.getContext(GL_CONTEXT_ID)); |
| 39 gl.viewport(0,0,canvas.width,canvas.height); |
| 40 gl.clearColor(0,0,1,1); |
| 41 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); |
| 42 gl.disable(gl.DEPTH_TEST); |
| 43 return [gl]; |
| 44 } |
| 45 |
| 46 Tests.setup = function(gl) { |
| 47 var tex = gl.createTexture(); |
| 48 gl.bindTexture(gl.TEXTURE_2D, tex); |
| 49 var texCubeMap = gl.createTexture(); |
| 50 gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap); |
| 51 return [gl] |
| 52 } |
| 53 |
| 54 Tests.teardown = function(gl, tex, texCubeMap) { |
| 55 gl.bindTexture(gl.TEXTURE_2D, null); |
| 56 gl.deleteTexture(tex); |
| 57 gl.bindTexture(gl.TEXTURE_CUBE_MAP, null); |
| 58 gl.deleteTexture(texCubeMap); |
| 59 } |
| 60 |
| 61 Tests.testTexImage2D = function(gl) { |
| 62 gl.enable(gl.BLEND); |
| 63 var img = document.getElementById('i'); |
| 64 var c = document.getElementById('c'); |
| 65 var ctx = c.getContext('2d'); |
| 66 ctx.drawImage(img,0,0); |
| 67 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img); |
| 68 gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, img); |
| 69 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); |
| 70 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); |
| 71 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); |
| 72 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); |
| 73 var f = new Filter(gl, 'identity-flip-vert', 'identity-frag'); |
| 74 gl.blendFunc(gl.ONE, gl.ZERO); |
| 75 f.apply(); |
| 76 f.destroy(); |
| 77 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c); |
| 78 gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, c); |
| 79 f = new Filter(gl, 'identity-hflip-vert', 'identity-frag'); |
| 80 gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); |
| 81 f.apply(); |
| 82 f.destroy(); |
| 83 var valid_targets = [ |
| 84 gl.TEXTURE_2D, |
| 85 gl.TEXTURE_CUBE_MAP_POSITIVE_X, |
| 86 gl.TEXTURE_CUBE_MAP_NEGATIVE_X, |
| 87 gl.TEXTURE_CUBE_MAP_POSITIVE_Y, |
| 88 gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, |
| 89 gl.TEXTURE_CUBE_MAP_POSITIVE_Z, |
| 90 gl.TEXTURE_CUBE_MAP_NEGATIVE_Z |
| 91 ]; |
| 92 valid_targets.forEach(function(t) { |
| 93 assertOk(function(){ |
| 94 gl.texImage2D(t, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c); |
| 95 gl.texSubImage2D(t, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, c); |
| 96 }); |
| 97 assertOk(function(){ |
| 98 gl.texImage2D(t, 1, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c); |
| 99 gl.texSubImage2D(t, 1, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, c); |
| 100 }); |
| 101 }); |
| 102 } |
| 103 |
| 104 Tests.testTexImage2DNonSOP = function(gl) { |
| 105 var img = document.getElementById('i2'); |
| 106 while (!img.complete) {} |
| 107 var c = document.getElementById('c'); |
| 108 var ctx = c.getContext('2d'); |
| 109 ctx.drawImage(img,0,0); |
| 110 assertThrowNoGLError(gl, "texImage2D with cross-origin image should throw ex
ception.", |
| 111 function(){gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_B
YTE, img);}); |
| 112 assertThrowNoGLError(gl, "texSubImage2D with cross-origin image should throw
exception.", |
| 113 function(){gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, gl.RGBA, gl.UNSIGNED_BY
TE, img);}); |
| 114 assertThrowNoGLError(gl, "texImage2D with dirty origin canvas should throw e
xception.", |
| 115 function(){gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_B
YTE, c);}); |
| 116 assertThrowNoGLError(gl, "texSubImage2D with dirty origin canvas should thro
w exception.", |
| 117 function(){gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, gl.RGBA, gl.UNSIGNED_BY
TE, c);}); |
| 118 } |
| 119 |
| 120 Tests.endUnit = function(gl) { |
| 121 } |
| 122 |
| 123 </script> |
| 124 <script id="identity-flip-vert" type="x-shader/x-vertex"> |
| 125 attribute vec3 Vertex; |
| 126 attribute vec2 Tex; |
| 127 |
| 128 varying vec4 texCoord0; |
| 129 void main() |
| 130 { |
| 131 texCoord0 = vec4(Tex.s, 1.0-Tex.t, 0.0, 0.0); |
| 132 gl_Position = vec4(Vertex, 1.0); |
| 133 } |
| 134 </script> |
| 135 <script id="identity-hflip-vert" type="x-shader/x-vertex"> |
| 136 attribute vec3 Vertex; |
| 137 attribute vec2 Tex; |
| 138 |
| 139 varying vec4 texCoord0; |
| 140 void main() |
| 141 { |
| 142 texCoord0 = vec4(1.0-Tex.s, Tex.t, 0.0, 0.0); |
| 143 gl_Position = vec4(Vertex, 1.0); |
| 144 } |
| 145 </script> |
| 146 <script id="identity-frag" type="x-shader/x-fragment"> |
| 147 precision mediump float; |
| 148 |
| 149 uniform sampler2D Texture; |
| 150 |
| 151 varying vec4 texCoord0; |
| 152 void main() |
| 153 { |
| 154 vec4 c = texture2D(Texture, texCoord0.st); |
| 155 gl_FragColor = c; |
| 156 } |
| 157 </script> |
| 158 </head><body> |
| 159 <canvas id="gl" width="256" height="256"></canvas> |
| 160 <canvas id="c" width="256" height="256"></canvas> |
| 161 <img id="i" width="256" height="256" src="data:image/png;base64,iVBORw0KGgoAAAA
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
vmQAAAABJRU5ErkJggg=="> |
| 162 <img id="i2" src="http://mashable.com/wp-content/uploads/2008/08/thunderbird-log
o-64x64.png"> |
| 163 |
| 164 </body></html> |
OLD | NEW |