1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/canvas/test/webgl-conformance/conformance/extensions/webgl-depth-texture.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,343 @@ 1.4 +<!-- 1.5 + 1.6 +/* 1.7 +** Copyright (c) 2012 The Khronos Group Inc. 1.8 +** 1.9 +** Permission is hereby granted, free of charge, to any person obtaining a 1.10 +** copy of this software and/or associated documentation files (the 1.11 +** "Materials"), to deal in the Materials without restriction, including 1.12 +** without limitation the rights to use, copy, modify, merge, publish, 1.13 +** distribute, sublicense, and/or sell copies of the Materials, and to 1.14 +** permit persons to whom the Materials are furnished to do so, subject to 1.15 +** the following conditions: 1.16 +** 1.17 +** The above copyright notice and this permission notice shall be included 1.18 +** in all copies or substantial portions of the Materials. 1.19 +** 1.20 +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1.21 +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1.22 +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 1.23 +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 1.24 +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 1.25 +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 1.26 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. 1.27 +*/ 1.28 + 1.29 +--> 1.30 +<!DOCTYPE html> 1.31 +<html> 1.32 +<head> 1.33 +<meta charset="utf-8"> 1.34 +<link rel="stylesheet" href="../../resources/js-test-style.css"/> 1.35 +<script src="../../resources/js-test-pre.js"></script> 1.36 +<script src="../resources/webgl-test.js"></script> 1.37 +<script src="../resources/webgl-test-utils.js"></script> 1.38 +<title>WebGL WEBGL_depth_texture Conformance Tests</title> 1.39 +</head> 1.40 +<body> 1.41 +<script id="vshader" type="x-shader/x-vertex"> 1.42 +attribute vec4 a_position; 1.43 +void main() 1.44 +{ 1.45 + gl_Position = a_position; 1.46 +} 1.47 +</script> 1.48 + 1.49 +<script id="fshader" type="x-shader/x-fragment"> 1.50 +precision mediump float; 1.51 +uniform sampler2D u_texture; 1.52 +uniform vec2 u_resolution; 1.53 +void main() 1.54 +{ 1.55 + vec2 texcoord = gl_FragCoord.xy / u_resolution; 1.56 + gl_FragColor = texture2D(u_texture, texcoord); 1.57 +} 1.58 +</script> 1.59 +<div id="description"></div> 1.60 +<div id="console"></div> 1.61 +<canvas id="canvas" width="8" height="8" style="width: 8px; height: 8px;"></canvas> 1.62 +<script> 1.63 +if (window.initNonKhronosFramework) { 1.64 + window.initNonKhronosFramework(false); 1.65 +} 1.66 +description("This test verifies the functionality of the WEBGL_depth_texture extension, if it is available."); 1.67 + 1.68 +debug(""); 1.69 + 1.70 +var wtu = WebGLTestUtils; 1.71 +var canvas = document.getElementById("canvas"); 1.72 +var gl = wtu.create3DContext(canvas, {antialias: false}); 1.73 +var program = wtu.setupTexturedQuad(gl); 1.74 +var ext = null; 1.75 +var vao = null; 1.76 +var tex; 1.77 +var name; 1.78 +var supportedFormats; 1.79 + 1.80 +if (!gl) { 1.81 + testFailed("WebGL context does not exist"); 1.82 +} else { 1.83 + testPassed("WebGL context exists"); 1.84 + 1.85 + // Run tests with extension disabled 1.86 + runTestDisabled(); 1.87 + 1.88 + // Query the extension and store globally so shouldBe can access it 1.89 + ext = wtu.getExtensionWithKnownPrefixes(gl, "WEBGL_depth_texture"); 1.90 + if (!ext) { 1.91 + testPassed("No WEBGL_depth_texture support -- this is legal"); 1.92 + runSupportedTest(false); 1.93 + } else { 1.94 + testPassed("Successfully enabled WEBGL_depth_texture extension"); 1.95 + 1.96 + runSupportedTest(true); 1.97 + runTestExtension(); 1.98 + } 1.99 +} 1.100 + 1.101 +function runSupportedTest(extensionEnabled) { 1.102 + var name = wtu.getSupportedExtensionWithKnownPrefixes(gl, "WEBGL_depth_texture"); 1.103 + if (name !== undefined) { 1.104 + if (extensionEnabled) { 1.105 + testPassed("WEBGL_depth_texture listed as supported and getExtension succeeded"); 1.106 + } else { 1.107 + testFailed("WEBGL_depth_texture listed as supported but getExtension failed"); 1.108 + } 1.109 + } else { 1.110 + if (extensionEnabled) { 1.111 + testFailed("WEBGL_depth_texture not listed as supported but getExtension succeeded"); 1.112 + } else { 1.113 + testPassed("WEBGL_depth_texture not listed as supported and getExtension failed -- this is legal"); 1.114 + } 1.115 + } 1.116 +} 1.117 + 1.118 + 1.119 +function runTestDisabled() { 1.120 + debug("Testing binding enum with extension disabled"); 1.121 + 1.122 + var tex = gl.createTexture(); 1.123 + gl.bindTexture(gl.TEXTURE_2D, tex); 1.124 + shouldGenerateGLError(gl, gl.INVALID_ENUM, 'gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, 1, 1, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null)'); 1.125 + shouldGenerateGLError(gl, gl.INVALID_ENUM, 'gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, 1, 1, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, null)'); 1.126 +} 1.127 + 1.128 + 1.129 +function dumpIt(gl, res, msg) { 1.130 + return; // comment out to debug 1.131 + debug(msg); 1.132 + var actualPixels = new Uint8Array(res * res * 4); 1.133 + gl.readPixels(0, 0, res, res, gl.RGBA, gl.UNSIGNED_BYTE, actualPixels); 1.134 + 1.135 + for (var yy = 0; yy < res; ++yy) { 1.136 + var strs = []; 1.137 + for (var xx = 0; xx < res; ++xx) { 1.138 + var actual = (yy * res + xx) * 4; 1.139 + strs.push("(" + actualPixels[actual] + "," + actualPixels[actual+1] + "," + actualPixels[actual + 2] + "," + actualPixels[actual + 3] + ")"); 1.140 + } 1.141 + debug(strs.join(" ")); 1.142 + } 1.143 +} 1.144 +function runTestExtension() { 1.145 + debug("Testing WEBGL_depth_texture"); 1.146 + 1.147 + var res = 8; 1.148 + 1.149 + // make canvas for testing. 1.150 + canvas2 = document.createElement("canvas"); 1.151 + canvas2.width = res; 1.152 + canvas2.height = res; 1.153 + var ctx = canvas2.getContext("2d"); 1.154 + ctx.fillStyle = "blue"; 1.155 + ctx.fillRect(0, 0, canvas2.width, canvas2.height); 1.156 + 1.157 + var program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['a_position']); 1.158 + gl.useProgram(program); 1.159 + gl.uniform2f(gl.getUniformLocation(program, "u_resolution"), res, res); 1.160 + 1.161 + var buffer = gl.createBuffer(); 1.162 + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 1.163 + gl.bufferData( 1.164 + gl.ARRAY_BUFFER, 1.165 + new Float32Array( 1.166 + [ 1, 1, 1, 1.167 + -1, 1, 0, 1.168 + -1, -1, -1, 1.169 + 1, 1, 1, 1.170 + -1, -1, -1, 1.171 + 1, -1, 0, 1.172 + ]), 1.173 + gl.STATIC_DRAW); 1.174 + gl.enableVertexAttribArray(0); 1.175 + gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); 1.176 + 1.177 + var types = [ 1.178 + {obj: 'gl', attachment: 'DEPTH_ATTACHMENT', format: 'DEPTH_COMPONENT', type: 'UNSIGNED_SHORT', data: 'new Uint16Array(1)' }, 1.179 + {obj: 'gl', attachment: 'DEPTH_ATTACHMENT', format: 'DEPTH_COMPONENT', type: 'UNSIGNED_INT', data: 'new Uint32Array(1)' }, 1.180 + {obj: 'ext', attachment: 'DEPTH_STENCIL_ATTACHMENT', format: 'DEPTH_STENCIL', type: 'UNSIGNED_INT_24_8_WEBGL', data: 'new Uint32Array(1)' } 1.181 + ]; 1.182 + 1.183 + for (var ii = 0; ii < types.length; ++ii) { 1.184 + var typeInfo = types[ii]; 1.185 + var type = typeInfo.type; 1.186 + var typeStr = typeInfo.obj + '.' + type; 1.187 + 1.188 + debug(""); 1.189 + debug("testing: " + type); 1.190 + 1.191 + // check that cubemaps are not allowed. 1.192 + var cubeTex = gl.createTexture(); 1.193 + gl.bindTexture(gl.TEXTURE_CUBE_MAP, cubeTex); 1.194 + var targets = [ 1.195 + 'TEXTURE_CUBE_MAP_POSITIVE_X', 1.196 + 'TEXTURE_CUBE_MAP_NEGATIVE_X', 1.197 + 'TEXTURE_CUBE_MAP_POSITIVE_Y', 1.198 + 'TEXTURE_CUBE_MAP_NEGATIVE_Y', 1.199 + 'TEXTURE_CUBE_MAP_POSITIVE_Z', 1.200 + 'TEXTURE_CUBE_MAP_NEGATIVE_Z' 1.201 + ]; 1.202 + for (var tt = 0; tt < targets.length; ++tt) { 1.203 + shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.texImage2D(gl.' + targets[ii] + ', 1, gl.' + typeInfo.format + ', 1, 1, 0, gl.' + typeInfo.format + ', ' + typeStr + ', null)'); 1.204 + } 1.205 + 1.206 + // check 2d textures. 1.207 + tex = gl.createTexture(); 1.208 + gl.bindTexture(gl.TEXTURE_2D, tex); 1.209 + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 1.210 + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 1.211 + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 1.212 + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 1.213 + 1.214 + // test level > 0 1.215 + shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.texImage2D(gl.TEXTURE_2D, 1, gl.' + typeInfo.format + ', 1, 1, 0, gl.' + typeInfo.format + ', ' + typeStr + ', null)'); 1.216 + 1.217 + // test with data 1.218 + shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.texImage2D(gl.TEXTURE_2D, 0, gl.' + typeInfo.format + ', 1, 1, 0, gl.' + typeInfo.format + ', ' + typeStr + ', ' + typeInfo.data + ')'); 1.219 + 1.220 + // test with canvas 1.221 + shouldGenerateGLError(gl, [gl.INVALID_VALUE, gl.INVALID_ENUM, gl.INVALID_OPERATION], 'gl.texImage2D(gl.TEXTURE_2D, 0, gl.' + typeInfo.format + ', gl.' + typeInfo.format + ', ' + typeStr + ', canvas2)'); 1.222 + 1.223 + // test copyTexImage2D 1.224 + shouldGenerateGLError(gl, [gl.INVALID_ENUM, gl.INVALID_OPERATION], 'gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.' + typeInfo.format + ', 0, 0, 1, 1, 0)'); 1.225 + 1.226 + // test real thing 1.227 + shouldGenerateGLError(gl, gl.NO_ERROR, 'gl.texImage2D(gl.TEXTURE_2D, 0, gl.' + typeInfo.format + ', ' + res + ', ' + res + ', 0, gl.' + typeInfo.format + ', ' + typeStr + ', null)'); 1.228 + 1.229 + // test texSubImage2D 1.230 + shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 1, 1, gl.' + typeInfo.format + ', ' + typeStr + ', ' + typeInfo.data + ')'); 1.231 + 1.232 + // test copyTexSubImage2D 1.233 + shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1)'); 1.234 + 1.235 + // test generateMipmap 1.236 + shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.generateMipmap(gl.TEXTURE_2D)'); 1.237 + 1.238 + var fbo = gl.createFramebuffer(); 1.239 + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); 1.240 + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl[typeInfo.attachment], gl.TEXTURE_2D, tex, 0); 1.241 + // TODO: remove this check if the spec is updated to require these combinations to work. 1.242 + if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) 1.243 + { 1.244 + // try adding a color buffer. 1.245 + var colorTex = gl.createTexture(); 1.246 + gl.bindTexture(gl.TEXTURE_2D, colorTex); 1.247 + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 1.248 + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 1.249 + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 1.250 + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 1.251 + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, res, res, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 1.252 + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTex, 0); 1.253 + shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE'); 1.254 + } 1.255 + 1.256 + // use the default texture to render with while we return to the depth texture. 1.257 + gl.bindTexture(gl.TEXTURE_2D, null); 1.258 + 1.259 + // render the z-quad 1.260 + gl.enable(gl.DEPTH_TEST); 1.261 + gl.clearColor(1, 0, 0, 1); 1.262 + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 1.263 + gl.drawArrays(gl.TRIANGLES, 0, 6); 1.264 + 1.265 + dumpIt(gl, res, "--first--"); 1.266 + 1.267 + // render the depth texture. 1.268 + gl.bindFramebuffer(gl.FRAMEBUFFER, null); 1.269 + gl.bindTexture(gl.TEXTURE_2D, tex); 1.270 + gl.clearColor(0, 0, 1, 1); 1.271 + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 1.272 + gl.drawArrays(gl.TRIANGLES, 0, 6); 1.273 + 1.274 + var actualPixels = new Uint8Array(res * res * 4); 1.275 + gl.readPixels(0, 0, res, res, gl.RGBA, gl.UNSIGNED_BYTE, actualPixels); 1.276 + 1.277 + dumpIt(gl, res, "--depth--"); 1.278 + 1.279 + // Check that each pixel's RGB are the same and that it's value is less 1.280 + // than the previous pixel in either direction. Basically verify we have a 1.281 + // gradient. 1.282 + var success = true; 1.283 + for (var yy = 0; yy < res; ++yy) { 1.284 + for (var xx = 0; xx < res; ++xx) { 1.285 + var actual = (yy * res + xx) * 4; 1.286 + var left = actual - 4; 1.287 + var down = actual - res * 4; 1.288 + 1.289 + if (actualPixels[actual + 0] != actualPixels[actual + 1]) { 1.290 + testFailed('R != G'); 1.291 + success = false; 1.292 + } 1.293 + if (actualPixels[actual + 0] != actualPixels[actual + 2]) { 1.294 + testFailed('R != B'); 1.295 + success = false; 1.296 + } 1.297 + // ALPHA is implementation dependent 1.298 + if (actualPixels[actual + 3] != 0xFF && actualPixels[actual + 3] != actualPixels[actual + 0]) { 1.299 + testFailed('A != 255 && A != R'); 1.300 + success = false; 1.301 + } 1.302 + 1.303 + if (xx > 0) { 1.304 + if (actualPixels[actual] <= actualPixels[left]) { 1.305 + testFailed("actual(" + actualPixels[actual] + ") < left(" + actualPixels[left] + ")"); 1.306 + success = false; 1.307 + } 1.308 + } 1.309 + if (yy > 0) { 1.310 + if (actualPixels[actual] <= actualPixels[down]) { 1.311 + testFailed("actual(" + actualPixels[actual] + ") < down(" + actualPixels[down] + ")"); 1.312 + success = false; 1.313 + } 1.314 + } 1.315 + } 1.316 + } 1.317 + 1.318 + // Check that bottom left corner is vastly different thatn top right. 1.319 + if (actualPixels[(res * res - 1) * 4] - actualPixels[0] < 0xC0) { 1.320 + testFailed("corners are not different enough"); 1.321 + success = false; 1.322 + } 1.323 + 1.324 + if (success) { 1.325 + testPassed("depth texture rendered correctly."); 1.326 + } 1.327 + 1.328 + // check limitations 1.329 + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); 1.330 + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl[typeInfo.attachment], gl.TEXTURE_2D, null, 0); 1.331 + var badAttachment = typeInfo.attachment == 'DEPTH_ATTACHMENT' ? 'DEPTH_STENCIL_ATTACHMENT' : 'DEPTH_ATTACHMENT'; 1.332 + shouldGenerateGLError(gl, gl.NO_ERROR, 'gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.' + badAttachment + ', gl.TEXTURE_2D, tex, 0)'); 1.333 + shouldNotBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE'); 1.334 + shouldGenerateGLError(gl, gl.INVALID_FRAMEBUFFER_OPERATION, 'gl.clear(gl.DEPTH_BUFFER_BIT)'); 1.335 + gl.bindFramebuffer(gl.FRAMEBUFFER, null); 1.336 + shouldBe('gl.getError()', 'gl.NO_ERROR'); 1.337 + } 1.338 +} 1.339 + 1.340 +debug(""); 1.341 +successfullyParsed = true; 1.342 +</script> 1.343 +<script src="../../resources/js-test-post.js"></script> 1.344 +</body> 1.345 +</html> 1.346 +