OLD | NEW |
(Empty) | |
| 1 <!-- |
| 2 |
| 3 /* |
| 4 ** Copyright (c) 2012 The Khronos Group Inc. |
| 5 ** |
| 6 ** Permission is hereby granted, free of charge, to any person obtaining a |
| 7 ** copy of this software and/or associated documentation files (the |
| 8 ** "Materials"), to deal in the Materials without restriction, including |
| 9 ** without limitation the rights to use, copy, modify, merge, publish, |
| 10 ** distribute, sublicense, and/or sell copies of the Materials, and to |
| 11 ** permit persons to whom the Materials are furnished to do so, subject to |
| 12 ** the following conditions: |
| 13 ** |
| 14 ** The above copyright notice and this permission notice shall be included |
| 15 ** in all copies or substantial portions of the Materials. |
| 16 ** |
| 17 ** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| 18 ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| 19 ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| 20 ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
| 21 ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| 22 ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
| 23 ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. |
| 24 */ |
| 25 |
| 26 --> |
| 27 <!DOCTYPE html> |
| 28 <html> |
| 29 <head> |
| 30 <meta charset="utf-8"> |
| 31 <link rel="stylesheet" href="../../resources/js-test-style.css"/> |
| 32 <script src="../../resources/js-test-pre.js"></script> |
| 33 <script src="../resources/webgl-test.js"></script> |
| 34 <script src="../resources/webgl-test-utils.js"></script> |
| 35 <title>WebGL WEBGL_depth_texture Conformance Tests</title> |
| 36 </head> |
| 37 <body> |
| 38 <script id="vshader" type="x-shader/x-vertex"> |
| 39 attribute vec4 a_position; |
| 40 void main() |
| 41 { |
| 42 gl_Position = a_position; |
| 43 } |
| 44 </script> |
| 45 |
| 46 <script id="fshader" type="x-shader/x-fragment"> |
| 47 precision mediump float; |
| 48 uniform sampler2D u_texture; |
| 49 uniform vec2 u_resolution; |
| 50 void main() |
| 51 { |
| 52 vec2 texcoord = gl_FragCoord.xy / u_resolution; |
| 53 gl_FragColor = texture2D(u_texture, texcoord); |
| 54 } |
| 55 </script> |
| 56 <div id="description"></div> |
| 57 <div id="console"></div> |
| 58 <canvas id="canvas" width="8" height="8" style="width: 8px; height: 8px;"></canv
as> |
| 59 <script> |
| 60 "use strict"; |
| 61 description("This test verifies the functionality of the WEBGL_depth_texture ext
ension, if it is available."); |
| 62 |
| 63 debug(""); |
| 64 |
| 65 var wtu = WebGLTestUtils; |
| 66 var canvas = document.getElementById("canvas"); |
| 67 var gl = wtu.create3DContext(canvas, {antialias: false}); |
| 68 var program = wtu.setupTexturedQuad(gl); |
| 69 var ext = null; |
| 70 var vao = null; |
| 71 var tex; |
| 72 var name; |
| 73 var supportedFormats; |
| 74 var canvas2; |
| 75 |
| 76 if (!gl) { |
| 77 testFailed("WebGL context does not exist"); |
| 78 } else { |
| 79 testPassed("WebGL context exists"); |
| 80 |
| 81 // Run tests with extension disabled |
| 82 runTestDisabled(); |
| 83 |
| 84 // Query the extension and store globally so shouldBe can access it |
| 85 ext = wtu.getExtensionWithKnownPrefixes(gl, "WEBGL_depth_texture"); |
| 86 if (!ext) { |
| 87 testPassed("No WEBGL_depth_texture support -- this is legal"); |
| 88 runSupportedTest(false); |
| 89 } else { |
| 90 testPassed("Successfully enabled WEBGL_depth_texture extension"); |
| 91 |
| 92 runSupportedTest(true); |
| 93 runTestExtension(); |
| 94 } |
| 95 } |
| 96 |
| 97 function runSupportedTest(extensionEnabled) { |
| 98 var name = wtu.getSupportedExtensionWithKnownPrefixes(gl, "WEBGL_depth_textu
re"); |
| 99 if (name !== undefined) { |
| 100 if (extensionEnabled) { |
| 101 testPassed("WEBGL_depth_texture listed as supported and getExtension
succeeded"); |
| 102 } else { |
| 103 testFailed("WEBGL_depth_texture listed as supported but getExtension
failed"); |
| 104 } |
| 105 } else { |
| 106 if (extensionEnabled) { |
| 107 testFailed("WEBGL_depth_texture not listed as supported but getExten
sion succeeded"); |
| 108 } else { |
| 109 testPassed("WEBGL_depth_texture not listed as supported and getExten
sion failed -- this is legal"); |
| 110 } |
| 111 } |
| 112 } |
| 113 |
| 114 |
| 115 function runTestDisabled() { |
| 116 debug("Testing binding enum with extension disabled"); |
| 117 |
| 118 var tex = gl.createTexture(); |
| 119 gl.bindTexture(gl.TEXTURE_2D, tex); |
| 120 shouldGenerateGLError(gl, gl.INVALID_ENUM, 'gl.texImage2D(gl.TEXTURE_2D, 0,
gl.DEPTH_COMPONENT, 1, 1, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null)'); |
| 121 shouldGenerateGLError(gl, gl.INVALID_ENUM, 'gl.texImage2D(gl.TEXTURE_2D, 0,
gl.DEPTH_COMPONENT, 1, 1, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, null)'); |
| 122 } |
| 123 |
| 124 |
| 125 function dumpIt(gl, res, msg) { |
| 126 return; // comment out to debug |
| 127 debug(msg); |
| 128 var actualPixels = new Uint8Array(res * res * 4); |
| 129 gl.readPixels(0, 0, res, res, gl.RGBA, gl.UNSIGNED_BYTE, actualPixels); |
| 130 |
| 131 for (var yy = 0; yy < res; ++yy) { |
| 132 var strs = []; |
| 133 for (var xx = 0; xx < res; ++xx) { |
| 134 var actual = (yy * res + xx) * 4; |
| 135 strs.push("(" + actualPixels[actual] + "," + actualPixels[actual+1] + ","
+ actualPixels[actual + 2] + "," + actualPixels[actual + 3] + ")"); |
| 136 } |
| 137 debug(strs.join(" ")); |
| 138 } |
| 139 } |
| 140 function runTestExtension() { |
| 141 debug("Testing WEBGL_depth_texture"); |
| 142 |
| 143 var res = 8; |
| 144 |
| 145 // make canvas for testing. |
| 146 canvas2 = document.createElement("canvas"); |
| 147 canvas2.width = res; |
| 148 canvas2.height = res; |
| 149 var ctx = canvas2.getContext("2d"); |
| 150 ctx.fillStyle = "blue"; |
| 151 ctx.fillRect(0, 0, canvas2.width, canvas2.height); |
| 152 |
| 153 var program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['a_position']); |
| 154 gl.useProgram(program); |
| 155 gl.uniform2f(gl.getUniformLocation(program, "u_resolution"), res, res); |
| 156 |
| 157 var buffer = gl.createBuffer(); |
| 158 gl.bindBuffer(gl.ARRAY_BUFFER, buffer); |
| 159 gl.bufferData( |
| 160 gl.ARRAY_BUFFER, |
| 161 new Float32Array( |
| 162 [ 1, 1, 1, |
| 163 -1, 1, 0, |
| 164 -1, -1, -1, |
| 165 1, 1, 1, |
| 166 -1, -1, -1, |
| 167 1, -1, 0, |
| 168 ]), |
| 169 gl.STATIC_DRAW); |
| 170 gl.enableVertexAttribArray(0); |
| 171 gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); |
| 172 |
| 173 var types = [ |
| 174 {obj: 'gl', attachment: 'DEPTH_ATTACHMENT', format: 'DEPTH_COMP
ONENT', type: 'UNSIGNED_SHORT', data: 'new Uint16Array(1)' }, |
| 175 {obj: 'gl', attachment: 'DEPTH_ATTACHMENT', format: 'DEPTH_COMP
ONENT', type: 'UNSIGNED_INT', data: 'new Uint32Array(1)' }, |
| 176 {obj: 'ext', attachment: 'DEPTH_STENCIL_ATTACHMENT', format: 'DEPTH_STEN
CIL', type: 'UNSIGNED_INT_24_8_WEBGL', data: 'new Uint32Array(1)' } |
| 177 ]; |
| 178 |
| 179 for (var ii = 0; ii < types.length; ++ii) { |
| 180 var typeInfo = types[ii]; |
| 181 var type = typeInfo.type; |
| 182 var typeStr = typeInfo.obj + '.' + type; |
| 183 |
| 184 debug(""); |
| 185 debug("testing: " + type); |
| 186 |
| 187 // check that cubemaps are not allowed. |
| 188 var cubeTex = gl.createTexture(); |
| 189 gl.bindTexture(gl.TEXTURE_CUBE_MAP, cubeTex); |
| 190 var targets = [ |
| 191 'TEXTURE_CUBE_MAP_POSITIVE_X', |
| 192 'TEXTURE_CUBE_MAP_NEGATIVE_X', |
| 193 'TEXTURE_CUBE_MAP_POSITIVE_Y', |
| 194 'TEXTURE_CUBE_MAP_NEGATIVE_Y', |
| 195 'TEXTURE_CUBE_MAP_POSITIVE_Z', |
| 196 'TEXTURE_CUBE_MAP_NEGATIVE_Z' |
| 197 ]; |
| 198 for (var tt = 0; tt < targets.length; ++tt) { |
| 199 shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.texImage2D(gl.'
+ targets[ii] + ', 1, gl.' + typeInfo.format + ', 1, 1, 0, gl.' + typeInfo.forma
t + ', ' + typeStr + ', null)'); |
| 200 } |
| 201 |
| 202 // check 2d textures. |
| 203 tex = gl.createTexture(); |
| 204 gl.bindTexture(gl.TEXTURE_2D, tex); |
| 205 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); |
| 206 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); |
| 207 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); |
| 208 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); |
| 209 |
| 210 // test level > 0 |
| 211 shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.texImage2D(gl.TEXTUR
E_2D, 1, gl.' + typeInfo.format + ', 1, 1, 0, gl.' + typeInfo.format + ', ' + ty
peStr + ', null)'); |
| 212 |
| 213 // test with data |
| 214 shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.texImage2D(gl.TEXTUR
E_2D, 0, gl.' + typeInfo.format + ', 1, 1, 0, gl.' + typeInfo.format + ', ' + ty
peStr + ', ' + typeInfo.data + ')'); |
| 215 |
| 216 // test with canvas |
| 217 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)'); |
| 218 |
| 219 // test copyTexImage2D |
| 220 shouldGenerateGLError(gl, [gl.INVALID_ENUM, gl.INVALID_OPERATION], 'gl.c
opyTexImage2D(gl.TEXTURE_2D, 0, gl.' + typeInfo.format + ', 0, 0, 1, 1, 0)'); |
| 221 |
| 222 // test real thing |
| 223 shouldGenerateGLError(gl, gl.NO_ERROR, 'gl.texImage2D(gl.TEXTURE_2D, 0,
gl.' + typeInfo.format + ', ' + res + ', ' + res + ', 0, gl.' + typeInfo.format
+ ', ' + typeStr + ', null)'); |
| 224 |
| 225 // test texSubImage2D |
| 226 shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.texSubImage2D(gl.TEX
TURE_2D, 0, 0, 0, 1, 1, gl.' + typeInfo.format + ', ' + typeStr + ', ' + typeIn
fo.data + ')'); |
| 227 |
| 228 // test copyTexSubImage2D |
| 229 shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.copyTexSubImage2D(gl
.TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1)'); |
| 230 |
| 231 // test generateMipmap |
| 232 shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.generateMipmap(gl.TE
XTURE_2D)'); |
| 233 |
| 234 var fbo = gl.createFramebuffer(); |
| 235 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); |
| 236 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl[typeInfo.attachment], gl.TEXT
URE_2D, tex, 0); |
| 237 // TODO: remove this check if the spec is updated to require these combi
nations to work. |
| 238 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE
) |
| 239 { |
| 240 // try adding a color buffer. |
| 241 var colorTex = gl.createTexture(); |
| 242 gl.bindTexture(gl.TEXTURE_2D, colorTex); |
| 243 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
; |
| 244 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
; |
| 245 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); |
| 246 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); |
| 247 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, res, res, 0, gl.RGBA, gl.UN
SIGNED_BYTE, null); |
| 248 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEX
TURE_2D, colorTex, 0); |
| 249 } |
| 250 |
| 251 shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_CO
MPLETE'); |
| 252 |
| 253 // use the default texture to render with while we return to the depth t
exture. |
| 254 gl.bindTexture(gl.TEXTURE_2D, null); |
| 255 |
| 256 // render the z-quad |
| 257 gl.enable(gl.DEPTH_TEST); |
| 258 gl.clearColor(1, 0, 0, 1); |
| 259 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); |
| 260 gl.drawArrays(gl.TRIANGLES, 0, 6); |
| 261 |
| 262 dumpIt(gl, res, "--first--"); |
| 263 |
| 264 // render the depth texture. |
| 265 gl.bindFramebuffer(gl.FRAMEBUFFER, null); |
| 266 gl.bindTexture(gl.TEXTURE_2D, tex); |
| 267 gl.clearColor(0, 0, 1, 1); |
| 268 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); |
| 269 gl.drawArrays(gl.TRIANGLES, 0, 6); |
| 270 |
| 271 var actualPixels = new Uint8Array(res * res * 4); |
| 272 gl.readPixels(0, 0, res, res, gl.RGBA, gl.UNSIGNED_BYTE, actualPixels); |
| 273 |
| 274 dumpIt(gl, res, "--depth--"); |
| 275 |
| 276 // Check that each pixel's R value is less than that of the previous pix
el |
| 277 // in either direction. Basically verify we have a gradient. |
| 278 var success = true; |
| 279 for (var yy = 0; yy < res; ++yy) { |
| 280 for (var xx = 0; xx < res; ++xx) { |
| 281 var actual = (yy * res + xx) * 4; |
| 282 var left = actual - 4; |
| 283 var down = actual - res * 4; |
| 284 |
| 285 if (xx > 0) { |
| 286 if (actualPixels[actual] <= actualPixels[left]) { |
| 287 testFailed("actual(" + actualPixels[actual] + ") < left(" + ac
tualPixels[left] + ")"); |
| 288 success = false; |
| 289 } |
| 290 } |
| 291 if (yy > 0) { |
| 292 if (actualPixels[actual] <= actualPixels[down]) { |
| 293 testFailed("actual(" + actualPixels[actual] + ") < down(" +
actualPixels[down] + ")"); |
| 294 success = false; |
| 295 } |
| 296 } |
| 297 } |
| 298 } |
| 299 |
| 300 // Check that bottom left corner is vastly different thatn top right. |
| 301 if (actualPixels[(res * res - 1) * 4] - actualPixels[0] < 0xC0) { |
| 302 testFailed("corners are not different enough"); |
| 303 success = false; |
| 304 } |
| 305 |
| 306 if (success) { |
| 307 testPassed("depth texture rendered correctly."); |
| 308 } |
| 309 |
| 310 // check limitations |
| 311 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); |
| 312 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl[typeInfo.attachment], gl.TEXT
URE_2D, null, 0); |
| 313 var badAttachment = typeInfo.attachment == 'DEPTH_ATTACHMENT' ? 'DEPTH_S
TENCIL_ATTACHMENT' : 'DEPTH_ATTACHMENT'; |
| 314 shouldGenerateGLError(gl, gl.NO_ERROR, 'gl.framebufferTexture2D(gl.FRAME
BUFFER, gl.' + badAttachment + ', gl.TEXTURE_2D, tex, 0)'); |
| 315 shouldNotBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER
_COMPLETE'); |
| 316 shouldGenerateGLError(gl, gl.INVALID_FRAMEBUFFER_OPERATION, 'gl.clear(gl
.DEPTH_BUFFER_BIT)'); |
| 317 gl.bindFramebuffer(gl.FRAMEBUFFER, null); |
| 318 shouldBe('gl.getError()', 'gl.NO_ERROR'); |
| 319 } |
| 320 } |
| 321 |
| 322 debug(""); |
| 323 var successfullyParsed = true; |
| 324 </script> |
| 325 <script src="../../resources/js-test-post.js"></script> |
| 326 </body> |
| 327 </html> |
OLD | NEW |