Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

<!doctype html>
<meta charset="utf-8">
<title>stencilMaskSeparate with FRONT_AND_BACK sets both stencil writemasks</title>
<link rel="author" title="mxmgorin" href="mailto:102797145+mxmgorin@users.noreply.github.com">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
function createContext() {
// No stencil on the default framebuffer, so the only stencil is the FBO's.
var gl = document.createElement("canvas").getContext("webgl", { stencil: false });
var 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, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
var renderbuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, 4, 4);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT,
gl.RENDERBUFFER, renderbuffer);
assert_equals(gl.checkFramebufferStatus(gl.FRAMEBUFFER), gl.FRAMEBUFFER_COMPLETE);
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, "attribute vec2 p; void main() { gl_Position = vec4(p, 0, 1); }");
gl.compileShader(vertexShader);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, "void main() { gl_FragColor = vec4(1, 0, 0, 1); }");
gl.compileShader(fragmentShader);
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
// One front-facing triangle covering the whole viewport.
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 3, -1, -1, 3]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
return gl;
}
function readPixel(gl) {
var pixel = new Uint8Array(4);
gl.readPixels(1, 1, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
return Array.from(pixel);
}
test(function() {
var gl = document.createElement("canvas").getContext("webgl");
gl.stencilMask(0x0f);
gl.stencilMaskSeparate(gl.FRONT_AND_BACK, 0xf0);
assert_equals(gl.getParameter(gl.STENCIL_WRITEMASK), 0xf0, "front");
assert_equals(gl.getParameter(gl.STENCIL_BACK_WRITEMASK), 0xf0, "back");
assert_equals(gl.getError(), gl.NO_ERROR);
}, "FRONT_AND_BACK updates both writemasks");
test(function() {
var gl = createContext();
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
gl.enable(gl.STENCIL_TEST);
// With the front writemask zero, this front-facing draw must leave the stencil at 0.
gl.stencilMaskSeparate(gl.FRONT_AND_BACK, 0);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
gl.stencilFunc(gl.ALWAYS, 5, 0xff);
gl.drawArrays(gl.TRIANGLES, 0, 3);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
gl.stencilFunc(gl.EQUAL, 5, 0xff);
gl.drawArrays(gl.TRIANGLES, 0, 3);
assert_array_equals(readPixel(gl), [0, 0, 0, 255]);
assert_equals(gl.getError(), gl.NO_ERROR);
}, "FRONT_AND_BACK with a zero mask blocks front-facing stencil writes");
</script>