| |
| <!DOCTYPE html> |
| <html> |
| <head> |
| <meta charset="utf-8"> |
| <script src="../../../resources/js-test.js"></script> |
| <script src="resources/webgl-test.js"></script> |
| <script id="vshader" type="x-shader/x-vertex"> |
| attribute vec3 pos; |
| attribute vec4 colorIn; |
| varying vec4 color; |
| |
| void main() |
| { |
| color = colorIn; |
| gl_Position = vec4(pos.xyz, 1.0); |
| } |
| </script> |
| |
| <script id="fshader" type="x-shader/x-fragment"> |
| precision mediump float; |
| |
| varying vec4 color; |
| |
| void main() |
| { |
| gl_FragColor = color; |
| } |
| </script> |
| |
| <script> |
| var successfullyParsed = false; |
| |
| // These four declarations need to be global for "shouldBe" to see them |
| var gl; |
| var contextAttribs = null; |
| var pixel = [0, 0, 0, 1]; |
| var correctColor = null; |
| var framebuffer; |
| var fbHasColor; |
| var fbHasDepth; |
| var fbHasStencil; |
| |
| function init() |
| { |
| if (window.initNonKhronosFramework) { |
| window.initNonKhronosFramework(true); |
| } |
| |
| if (window.internals) |
| window.internals.settings.setWebGLErrorsToConsoleEnabled(false); |
| |
| description('Verify WebGLContextAttributes are working as specified, including alpha, depth, stencil, antialias, but not premultipliedAlpha'); |
| |
| runTest(); |
| } |
| |
| function getWebGL(canvasWidth, canvasHeight, contextAttribs, clearColor, clearDepth, clearStencil) |
| { |
| var canvas = document.createElement("canvas"); |
| if (!canvas) |
| return null; |
| canvas.width = canvasWidth; |
| canvas.height = canvasHeight; |
| |
| gl = create3DContext(canvas, contextAttribs); |
| if (!gl) |
| return null; |
| |
| var program = createProgram(gl, "vshader", "fshader", ["pos", "colorIn"]); |
| if (!program) |
| return null; |
| |
| gl.useProgram(program); |
| |
| gl.enable(gl.DEPTH_TEST); |
| gl.enable(gl.STENCIL_TEST); |
| gl.disable(gl.BLEND); |
| |
| gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); |
| gl.clearDepth(clearDepth); |
| gl.clearStencil(clearStencil); |
| gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); |
| |
| framebuffer = gl.createFramebuffer(); |
| gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); |
| var texture = gl.createTexture(); |
| gl.bindTexture(gl.TEXTURE_2D, texture); |
| gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.canvas.width, gl.canvas.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); |
| gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); |
| fbHasStencil = false; |
| fbHasDepth = false; |
| fbHasColor = gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE; |
| if (fbHasColor) { |
| var depthStencil = gl.createRenderbuffer(); |
| gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencil); |
| gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, gl.canvas.width, gl.canvas.height); |
| gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencil); |
| fbHasDepth = gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE; |
| if (!fbHasDepth) { |
| gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, null); |
| shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE'); |
| } else { |
| fbHasStencil = true; |
| } |
| } |
| gl.bindFramebuffer(gl.FRAMEBUFFER, null); |
| glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors"); |
| |
| return gl; |
| } |
| |
| function drawAndReadPixel(gl, vertices, colors, x, y) |
| { |
| var colorOffset = vertices.byteLength; |
| |
| var vbo = gl.createBuffer(); |
| gl.bindBuffer(gl.ARRAY_BUFFER, vbo); |
| gl.bufferData(gl.ARRAY_BUFFER, colorOffset + colors.byteLength, gl.STATIC_DRAW); |
| gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices); |
| gl.bufferSubData(gl.ARRAY_BUFFER, colorOffset, colors); |
| |
| gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); |
| gl.enableVertexAttribArray(0); |
| gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, true, 0, colorOffset); |
| gl.enableVertexAttribArray(1); |
| |
| gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 3); |
| |
| var buf = new Uint8Array(1 * 1 * 4); |
| gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf); |
| return buf; |
| } |
| |
| function testAlpha(alpha, is_default_test) |
| { |
| if (is_default_test) { |
| debug("Testing default alpha = true"); |
| alpha = true; |
| |
| shouldBeNonNull("gl = getWebGL(1, 1, { depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 0 ], 1, 0)"); |
| shouldBeTrue("gl.getParameter(gl.ALPHA_BITS) >= 8"); |
| } else { |
| debug("Testing alpha = " + alpha); |
| |
| if (alpha) { |
| shouldBeNonNull("gl = getWebGL(1, 1, { alpha: true, depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 0 ], 1, 0)"); |
| shouldBeTrue("gl.getParameter(gl.ALPHA_BITS) >= 8"); |
| } else { |
| shouldBeNonNull("gl = getWebGL(1, 1, { alpha: false, depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 0 ], 1, 0)"); |
| shouldBeTrue("gl.getParameter(gl.ALPHA_BITS) == 0"); |
| } |
| } |
| |
| shouldBeTrue("gl.getParameter(gl.RED_BITS) >= 8"); |
| shouldBeTrue("gl.getParameter(gl.GREEN_BITS) >= 8"); |
| shouldBeTrue("gl.getParameter(gl.BLUE_BITS) >= 8"); |
| shouldBeTrue("gl.getParameter(gl.DEPTH_BITS) == 0"); |
| shouldBeTrue("gl.getParameter(gl.STENCIL_BITS) == 0"); |
| |
| shouldBeNonNull("contextAttribs = gl.getContextAttributes()"); |
| shouldBeTrue("contextAttribs.alpha == " + alpha); |
| |
| var buf = new Uint8Array(1 * 1 * 4); |
| gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf); |
| pixel[0] = buf[0]; |
| pixel[1] = buf[1]; |
| pixel[2] = buf[2]; |
| pixel[3] = buf[3]; |
| correctColor = (contextAttribs.alpha ? [0, 0, 0, 0] : [0, 0, 0, 255]); |
| shouldBe("pixel", "correctColor"); |
| |
| if (fbHasColor) { |
| gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); |
| gl.clearColor(0.5, 0.5, 0.5, 0.5); |
| gl.clear(gl.COLOR_BUFFER_BIT); |
| gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf); |
| pixel[0] = buf[0]; |
| pixel[1] = buf[1]; |
| pixel[2] = buf[2]; |
| pixel[3] = buf[3]; |
| shouldBeTrue("Math.abs(pixel[0] - 127) <= 1 && Math.abs(pixel[1] - 127) <= 1 && Math.abs(pixel[2] - 127) <= 1 && Math.abs(pixel[3] - 127) <= 1"); |
| gl.bindFramebuffer(gl.FRAMEBUFFER, null); |
| } |
| } |
| |
| function testDepth(depth, is_default_test) |
| { |
| if (is_default_test) { |
| debug("Testing default depth = true"); |
| depth = true; |
| shouldBeNonNull("gl = getWebGL(1, 1, { stencil: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)"); |
| shouldBeTrue("gl.getParameter(gl.DEPTH_BITS) >= 16"); |
| } else { |
| debug("Testing depth = " + depth); |
| if (depth) { |
| shouldBeNonNull("gl = getWebGL(1, 1, { depth: true, stencil: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)"); |
| shouldBeTrue("gl.getParameter(gl.DEPTH_BITS) >= 16"); |
| } else { |
| shouldBeNonNull("gl = getWebGL(1, 1, { depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)"); |
| shouldBeTrue("gl.getParameter(gl.DEPTH_BITS) == 0"); |
| } |
| } |
| shouldBeTrue("gl.getParameter(gl.RED_BITS) >= 8"); |
| shouldBeTrue("gl.getParameter(gl.GREEN_BITS) >= 8"); |
| shouldBeTrue("gl.getParameter(gl.BLUE_BITS) >= 8"); |
| shouldBeTrue("gl.getParameter(gl.ALPHA_BITS) >= 8"); |
| |
| shouldBeNonNull("contextAttribs = gl.getContextAttributes()"); |
| |
| gl.depthFunc(gl.NEVER); |
| |
| var vertices = new Float32Array([ |
| 1.0, 1.0, 0.0, |
| -1.0, 1.0, 0.0, |
| -1.0, -1.0, 0.0, |
| 1.0, 1.0, 0.0, |
| -1.0, -1.0, 0.0, |
| 1.0, -1.0, 0.0]); |
| var colors = new Uint8Array([ |
| 255, 0, 0, 255, |
| 255, 0, 0, 255, |
| 255, 0, 0, 255, |
| 255, 0, 0, 255, |
| 255, 0, 0, 255, |
| 255, 0, 0, 255]); |
| |
| var buf = drawAndReadPixel(gl, vertices, colors, 0, 0); |
| pixel[0] = buf[0]; |
| pixel[1] = buf[1]; |
| pixel[2] = buf[2]; |
| pixel[3] = buf[3]; |
| correctColor = (contextAttribs.depth ? [0, 0, 0, 255] : [255, 0, 0, 255]); |
| shouldBe("pixel", "correctColor"); |
| |
| if (fbHasDepth) { |
| gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); |
| gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); |
| var buf = drawAndReadPixel(gl, vertices, colors, 0, 0); |
| pixel[0] = buf[0]; |
| pixel[1] = buf[1]; |
| pixel[2] = buf[2]; |
| pixel[3] = buf[3]; |
| shouldBe("pixel", "[0, 0, 0, 255]"); |
| gl.bindFramebuffer(gl.FRAMEBUFFER, null); |
| } |
| } |
| |
| function testStencilAndDepth(stencil, depth, is_default_test) |
| { |
| if (is_default_test) { |
| debug("Testing default stencil = false and default depth = true"); |
| stencil = false; |
| depth = true; |
| var creationString = |
| "gl = getWebGL(1, 1, { antialias: false }, [ 0, 0, 0, 1 ], 1, 0)"; |
| shouldBeNonNull(creationString); |
| } else { |
| debug("Testing stencil = " + stencil + ", depth = " + depth); |
| var creationString = |
| "gl = getWebGL(1, 1, { depth: " + depth + ", stencil: " + stencil + ", antialias: false }, [ 0, 0, 0, 1 ], 1, 0)"; |
| shouldBeNonNull(creationString); |
| } |
| |
| shouldBeTrue("gl.getParameter(gl.RED_BITS) >= 8"); |
| shouldBeTrue("gl.getParameter(gl.GREEN_BITS) >= 8"); |
| shouldBeTrue("gl.getParameter(gl.BLUE_BITS) >= 8"); |
| shouldBeTrue("gl.getParameter(gl.ALPHA_BITS) >= 8"); |
| if (depth) |
| shouldBeTrue("gl.getParameter(gl.DEPTH_BITS) >= 16"); |
| else |
| shouldBeTrue("gl.getParameter(gl.DEPTH_BITS) == 0"); |
| |
| if (stencil) |
| shouldBeTrue("gl.getParameter(gl.STENCIL_BITS) >= 8"); |
| else |
| shouldBeTrue("gl.getParameter(gl.STENCIL_BITS) == 0"); |
| |
| shouldBeNonNull("contextAttribs = gl.getContextAttributes()"); |
| if (!depth && contextAttribs.depth) { |
| testFailed("WebGL implementation provided a depth buffer when it should not have"); |
| } |
| if (!contextAttribs.depth) |
| depth = false; |
| if (!stencil && contextAttribs.stencil) { |
| testFailed("WebGL implementation provided a stencil buffer when it should not have"); |
| } |
| if (!contextAttribs.stencil) |
| stencil = false; |
| |
| gl.depthFunc(gl.ALWAYS); |
| |
| gl.stencilFunc(gl.NEVER, 1, 1); |
| gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP); |
| |
| var vertices = new Float32Array([ |
| 1.0, 1.0, 0.0, |
| -1.0, 1.0, 0.0, |
| -1.0, -1.0, 0.0, |
| 1.0, 1.0, 0.0, |
| -1.0, -1.0, 0.0, |
| 1.0, -1.0, 0.0]); |
| var colors = new Uint8Array([ |
| 255, 0, 0, 255, |
| 255, 0, 0, 255, |
| 255, 0, 0, 255, |
| 255, 0, 0, 255, |
| 255, 0, 0, 255, |
| 255, 0, 0, 255]); |
| |
| var buf = drawAndReadPixel(gl, vertices, colors, 0, 0); |
| pixel[0] = buf[0]; |
| pixel[1] = buf[1]; |
| pixel[2] = buf[2]; |
| pixel[3] = buf[3]; |
| correctColor = (stencil ? [0, 0, 0, 255] : [255, 0, 0, 255]); |
| shouldBe("pixel", "correctColor"); |
| |
| if (fbHasStencil) { |
| gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); |
| gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); |
| var buf = drawAndReadPixel(gl, vertices, colors, 0, 0); |
| pixel[0] = buf[0]; |
| pixel[1] = buf[1]; |
| pixel[2] = buf[2]; |
| pixel[3] = buf[3]; |
| shouldBe("pixel", "[0, 0, 0, 255]"); |
| gl.bindFramebuffer(gl.FRAMEBUFFER, null); |
| } |
| } |
| |
| function testAntialias(antialias, is_default_test) |
| { |
| if (is_default_test) { |
| debug("Testing default antialias = true"); |
| antialias = true; |
| shouldBeNonNull("gl = getWebGL(2, 2, { depth: false, stencil: false, alpha: false }, [ 0, 0, 0, 1 ], 1, 0)"); |
| } else { |
| debug("Testing antialias = " + antialias); |
| if (antialias) |
| shouldBeNonNull("gl = getWebGL(2, 2, { depth: false, stencil: false, alpha: false, antialias: true }, [ 0, 0, 0, 1 ], 1, 0)"); |
| else |
| shouldBeNonNull("gl = getWebGL(2, 2, { depth: false, stencil: false, alpha: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)"); |
| } |
| shouldBeNonNull("contextAttribs = gl.getContextAttributes()"); |
| |
| var vertices = new Float32Array([ |
| 1.0, 1.0, 0.0, |
| -1.0, 1.0, 0.0, |
| -1.0, -1.0, 0.0]); |
| var colors = new Uint8Array([ |
| 255, 0, 0, 255, |
| 255, 0, 0, 255, |
| 255, 0, 0, 255]); |
| var buf = drawAndReadPixel(gl, vertices, colors, 0, 0); |
| pixel[0] = buf[0]; |
| shouldBe("pixel[0] != 255 && pixel[0] != 0", "contextAttribs.antialias"); |
| } |
| |
| function runDefaultTests(run_default_tests) |
| { |
| if (run_default_tests) { |
| debug("Testing default values for attributes"); |
| testAlpha(true, run_default_tests); |
| testDepth(true, run_default_tests); |
| testStencilAndDepth(true, true, run_default_tests); |
| testAntialias(true, run_default_tests); |
| } else { |
| testAlpha(true, run_default_tests); |
| testAlpha(false, run_default_tests); |
| testDepth(true, run_default_tests); |
| testDepth(false, run_default_tests); |
| testStencilAndDepth(true, false, run_default_tests); |
| testStencilAndDepth(false, false, run_default_tests); |
| testStencilAndDepth(true, true, run_default_tests); |
| testStencilAndDepth(false, true, run_default_tests); |
| testAntialias(true, run_default_tests); |
| testAntialias(false, run_default_tests); |
| } |
| } |
| |
| function runTest() |
| { |
| runDefaultTests(false); |
| runDefaultTests(true); |
| finishTest(); |
| } |
| |
| </script> |
| </head> |
| <body onload="init()"> |
| <div id="description"></div> |
| <div id="console"></div> |
| </body> |
| </html> |