<!DOCTYPE HTML> <title>WebGL test: Hidden depth/stencil passes without a depth/stencil buffer respectively</title> <script src='/tests/SimpleTest/SimpleTest.js'></script> <link rel='stylesheet' href='/tests/SimpleTest/test.css'> <script src='webgl-util.js'></script> <body> <script id='vs' type='x-shader/x-vertex'> void main(void) { gl_PointSize = 1.0; // Note that this is undefined if we don't write to it! gl_Position = vec4(vec3(0), 1); } </script> <script id='fs' type='x-shader/x-fragment'> precision mediump float; void main(void) { gl_FragColor = vec4(0, 1, 0, 1); } </script> <script> function ColorString(arr) { return '[' + arr[0] + ', ' + arr[1] + ', ' + arr[2] + ', ' + arr[3] + ']'; } function DrawAndCheck(gl, infoPrefix, refColorStr) { gl.viewport(0, 0, 1, 1); gl.clearColor(1, 0, 0, 1); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); gl.drawArrays(gl.POINTS, 0, 1); var pixel = new Uint8Array(4); gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel); var pixelStr = ColorString(pixel); ok(pixelStr == refColorStr, infoPrefix + pixelStr + ' should be ' + refColorStr); } function TestCurrent(gl, attribs, infoPrefix) { infoPrefix = infoPrefix + JSON.stringify(attribs) + ': '; var CLEAR_COLOR = ColorString([255, 0, 0, 255]); var DRAW_COLOR = ColorString([0, 255, 0, 255]); gl.disable(gl.DEPTH_TEST); gl.disable(gl.STENCIL_TEST); DrawAndCheck(gl, infoPrefix + 'initial: ', DRAW_COLOR); if (!attribs.depth) { gl.enable(gl.DEPTH_TEST); gl.depthFunc(gl.NEVER); gl.disable(gl.STENCIL_TEST); // Depth test is enabled, and should pass NEVER. // Since there is no depth buffer, the depth test is not run. // Stencil test is disabled. DrawAndCheck(gl, infoPrefix + 'no-depth: ', DRAW_COLOR); } if (!attribs.stencil) { gl.disable(gl.DEPTH_TEST); gl.enable(gl.STENCIL_TEST); gl.stencilFunc(gl.NEVER, 0, 0); // Depth test is disabled. // Stencil test is enabled, and should pass NEVER. // Since there is no stencil buffer, the stencil test is not run. DrawAndCheck(gl, infoPrefix + 'no-stencil: ', DRAW_COLOR); } } function TestBackbuffer(requestedAttribs) { var canvas = document.createElement('canvas'); canvas.width = 1; canvas.height = 1; var gl = canvas.getContext('experimental-webgl', requestedAttribs); if (!gl) { ok(true, 'WebGL doesn\'t work, skipping test.'); return; } ok(gl.drawingBufferWidth == 1 && gl.drawingBufferHeight == 1, 'backbuffer should be 1x1'); var prog = WebGLUtil.createProgramByIds(gl, 'vs', 'fs'); gl.useProgram(prog); var attribs = { depth: gl.getContextAttributes().depth, stencil: gl.getContextAttributes().stencil, }; TestCurrent(gl, attribs, 'Backbuffer: '); } function TestUserFB() { var canvas = document.createElement('canvas'); var gl = canvas.getContext('experimental-webgl'); if (!gl) { ok(true, 'WebGL doesn\'t work, skipping test.'); return; } var prog = WebGLUtil.createProgramByIds(gl, 'vs', 'fs'); gl.useProgram(prog); var rb = gl.createRenderbuffer(); gl.bindRenderbuffer(gl.RENDERBUFFER, rb); gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 1, 1); var fb = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, fb); gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb); var depthRB = gl.createRenderbuffer(); gl.bindRenderbuffer(gl.RENDERBUFFER, depthRB); gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 1, 1); var stencilRB = gl.createRenderbuffer(); gl.bindRenderbuffer(gl.RENDERBUFFER, stencilRB); gl.renderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, 1, 1); do { gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthRB); gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, null); var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); if (status != gl.FRAMEBUFFER_COMPLETE) { ok(true, 'Depth-only user FB is incomplete. This is allowed.'); break; } TestCurrent(gl, {depth: true, stencil: false}, 'Depth-only user FB'); } while (false); do { gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, null); gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, stencilRB); var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); if (status != gl.FRAMEBUFFER_COMPLETE) { ok(true, 'Stencil-only user FB is incomplete. This is allowed.'); break; } TestCurrent(gl, {depth: false, stencil: true}, 'Stencil-only user FB'); } while (false); } (function(){ TestBackbuffer({depth: true, stencil: false}); TestBackbuffer({depth: false, stencil: true}); TestUserFB(); })(); </script> </body>