Source code
Revision control
Copy as Markdown
Other Tools
<!--
Copyright (c) 2019 The Khronos Group Inc.
Use of this source code is governed by an MIT-style license that can be
found in the LICENSE.txt file.
-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test clearBuffer with drawing</title>
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script>
</head>
<body onload="runTest()">
<div id="description"></div>
<div id="console"></div>
<canvas id="canvas" width="64" height="64" style="position:fixed;left:0;top:0"> </canvas>
<script>
"use strict";
description("This tests the operation of clearBuffer followed by a draw call.");
debug("Verifies that these combined with preserveDrawingBuffer's implicit clears work properly together.");
var wtu = WebGLTestUtils;
var canvas = document.getElementById("canvas");
var gl;
var testIndex = 0;
var iterations = 0;
var maxIterations = 10;
var prog;
var tests;
var stage = 0;
var blackUint8 = [0, 0, 0, 255];
var redFloat = [1.0, 0.0, 0.0, 0.0];
var redUint8 = [255, 0, 0, 255];
var greenFloat = [0.0, 1.0, 0.0, 0.0];
var greenUint8 = [0, 255, 0, 255];
function verifyOnePixel(kind, x, y, readFormat, readType, arrayType, expectedColor) {
var buffer = new arrayType(4);
gl.readPixels(Math.floor(x), Math.floor(y), 1, 1, readFormat, readType, buffer);
if (buffer[0] == expectedColor[0] &&
buffer[1] == expectedColor[1] &&
buffer[2] == expectedColor[2] &&
buffer[3] == expectedColor[3]) {
testPassed(kind + " succeeded");
} else {
testFailed(kind + " failed. Expected: " + expectedColor + ", got: " + buffer);
}
}
function testClearBufferAndDraw(test) {
gl.stencilFunc(gl.EQUAL, 0, 0xFF);
test['clear']();
wtu.setFloatDrawColor(gl, greenFloat);
wtu.drawUnitQuad(gl);
// Back buffer has no alpha channel.
let readFormat = gl.RGBA;
let readType = gl.UNSIGNED_BYTE;
if (stage == 2) {
verifyOnePixel("Clearing outside scissor",63, 63, readFormat, readType, Uint8Array, blackUint8);
verifyOnePixel("Drawing outside scissor", 40, 40, readFormat, readType, Uint8Array, blackUint8);
}
verifyOnePixel("Clearing", 0, 0, readFormat, readType, Uint8Array, test['bgColor']);
verifyOnePixel("Drawing", 32, 32, readFormat, readType, Uint8Array, test['drawColor']);
}
function runNextTest() {
if (testIndex >= tests.length) {
// Restore after the last clearBufferiv test
gl.enable(gl.DEPTH_TEST);
if (stage == 0) {
debug('');
debug('Enabling full-canvas scissor');
gl.enable(gl.SCISSOR_TEST);
} else if (stage == 1) {
debug('');
debug('Limiting scissor rect');
gl.scissor(0, 0, 33, 33);
} else if (stage == 2) {
finishTest();
return;
}
testIndex = 0;
stage++;
}
let test = tests[testIndex];
if (iterations == 0) {
debug('');
debug('Testing: ' + test['desc'])
}
testClearBufferAndDraw(test);
if (++iterations == maxIterations) {
iterations = 0;
++testIndex;
// Clear to yellow between the tests to ensure that
// subsequent tests do not rely on past results.
gl.clearColor(1.0, 1.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
}
wtu.waitForComposite(runNextTest);
}
function runTest() {
gl = wtu.create3DContext(canvas, { alpha: false, stencil: true }, 2);
if (!gl) {
testFailed("context does not exist");
return;
} else {
testPassed("context exists");
}
prog = wtu.setupColorQuad(gl, 0, { scale: 0.5 });
tests = [
{
desc: 'Implicit clear',
clear: function() {},
bgColor: blackUint8,
// The implicit clear clears depth to 1.0, and since the quad is
// drawn at a depth of 0.0, it's always discarded.
drawColor: blackUint8,
},
{
desc: 'clearBufferfi only',
clear: function() {
gl.clearBufferfi(gl.DEPTH_STENCIL, 0, 0.0, 1);
gl.stencilFunc(gl.EQUAL, 1, 0xFF);
},
bgColor: blackUint8,
drawColor: greenUint8,
},
{
desc: 'clearBufferfv only',
clear: function() {
gl.clearBufferfv(gl.DEPTH, 0, [0.0]);
},
bgColor: blackUint8,
drawColor: greenUint8,
},
{
desc: 'clearBufferfv and clear',
clear: function() {
gl.clearBufferfv(gl.COLOR, 0, redFloat);
gl.clearDepth(0.0);
gl.clear(gl.DEPTH_BUFFER_BIT);
},
bgColor: redUint8,
drawColor: greenUint8,
},
{
desc: 'clearBufferfv (no-op) and clear',
clear: function() {
gl.clearBufferfv(gl.COLOR, 1, greenFloat);
gl.clearDepth(0.0);
gl.clear(gl.DEPTH_BUFFER_BIT);
},
bgColor: blackUint8,
drawColor: greenUint8,
},
{
desc: 'clearBuffer{fv} and {fi}',
clear: function() {
gl.clearBufferfv(gl.COLOR, 0, redFloat);
gl.clearBufferfi(gl.DEPTH_STENCIL, 0, 0.0, 2);
gl.stencilFunc(gl.EQUAL, 2, 0xFF);
},
bgColor: redUint8,
drawColor: greenUint8,
},
{
desc: 'clearBufferiv only',
clear: function() {
gl.disable(gl.DEPTH_TEST);
gl.clearBufferiv(gl.STENCIL, 0, [3]);
gl.stencilFunc(gl.EQUAL, 3, 0xFF);
},
bgColor: blackUint8,
drawColor: greenUint8,
},
];
// Clear canvas to something other than black to start.
gl.clearColor(0.0, 0.0, 1.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.enable(gl.DEPTH_TEST);
// Unreal Engine's depth test is reversed from the
// default. Including the clear of the depth buffer in this test
// case highlights the rendering error more clearly, since neither
// the background nor any rendered object show up.
gl.depthFunc(gl.GEQUAL);
gl.enable(gl.STENCIL_TEST);
// Must run in a requestAnimationFrame loop to provoke implicit
// clears of the canvas.
wtu.waitForComposite(runNextTest);
}
debug("");
var successfullyParsed = true;
</script>
</body>
</html>