gecko/content/canvas/test/webgl/conformance/glsl-features.html
2011-08-19 11:39:00 -04:00

235 lines
7.2 KiB
HTML
Executable File

<!--
Copyright (c) 2011 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
Note: To use this sample pass arguments through the URL.
Arguments:
feature: name of the feature being testing
res: number of subdivisions in quad. default: 2
refvs: relative url to reference vertex shader
default shaders/glsl-features/base.vert
reffs: relative url to reference fragment shader
default shaders/glsl-features/base.frag
testvs: relative url to test vertex shader
default shaders/glsl-features/base.vert
testfs: relative url to test fragment shader
default shaders/glsl-features/base.frag
Example:
glsl-feature.html?feature=abs&refvs=shader/abs-ref.vert&testvs=shader/abs-test.vert
The idea is to provide 2 shaders that should generate the same image. One shader
uses the actual feature you want to test. Another emluates that feature to
provide a reference image.
For example, a test of abs would use "abs" in the test and "v < 0 ? -v : v" in
the reference.
Both shaders are passed a unit square that covers the entire canvas and
texcoords that go from 0.0 to 1.0 over the canvas. A vColor value is also passed
from the vertex shader to the fragment shader to give the vertex shader
a chance to generate something.
-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>GLSL feature Test</title>
<link rel="stylesheet" href="../resources/js-test-style.css"/>
<script src="../resources/js-test-pre.js"></script>
<script src="resources/webgl-test.js"> </script>
<script src="resources/webgl-test-utils.js"> </script>
<style>
canvas {
background-color: white;
background-image: linear-gradient(0, rgba(200, 200, 200, .5) 50%, transparent 50%), linear-gradient(rgba(200, 200, 200, .5) 50%, transparent 50%);
background-size: 8px 8px;
}
</style>
</head>
<body>
<table>
<tr><td>ref</td><td>test</td><td>diff</td></tr>
<tr>
<td><canvas id="canvas1" width="32" height="32"></canvas></td>
<td><canvas id="canvas2" width="32" height="32"></canvas></td>
<td><canvas id="diff" width="32" height="32"></canvas></td>
</tr>
</table>
<div id="description"></div>
<div id="console"></div>
<script>
function init()
{
if (window.initNonKhronosFramework) {
window.initNonKhronosFramework(false);
}
wtu = WebGLTestUtils;
var args = wtu.getUrlArguments();
var feature = args.feature || "**unset**";
var refVS = args.refvs || "shaders/glsl-features/base.vert";
var refFS = args.reffs || "shaders/glsl-features/base.frag";
var testVS = args.testvs || "shaders/glsl-features/base.vert";
var testFS = args.testfs || "shaders/glsl-features/base.frag";
var gridRes = args.res ? parseInt(args.res) : 2;
description("Testing GLSL feature: " + feature);
debug("");
debug("using reference shaders:");
debug(" " + makeLink(refVS));
debug(" " + makeLink(refFS));
debug("");
debug("using test shaders:");
debug(" " + makeLink(testVS));
debug(" " + makeLink(testFS));
debug("");
function makeLink(url) {
return '<a target="_blank" href="' + url + '">' + url + '</a>';
}
var canvas1 = document.getElementById("canvas1");
var canvas2 = document.getElementById("canvas2");
var diff = document.getElementById("diff");
var width = canvas1.width;
var height = canvas1.height;
function draw(canvas, vsURL, fsURL) {
var gl = wtu.create3DContext(canvas);
if (!gl) {
testFailed("context does not exist");
return;
}
var program = wtu.loadProgramFromFile(gl, vsURL, fsURL);
var posLoc = gl.getAttribLocation(program, "aPosition");
var refLoc = gl.getAttribLocation(program, "aTexcoord");
setupQuad(gl, posLoc, refLoc);
gl.useProgram(program);
gl.clearColor(0, 0, 1, 1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.drawElements(gl.TRIANGLES, gridRes * gridRes * 6, gl.UNSIGNED_SHORT, 0);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no errors from draw");
var img = new Uint8Array(width * height * 4);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, img);
return img;
}
function setupQuad(gl, positionLocation, texcoordLocation) {
var objects = [];
var vertsAcross = gridRes + 1;
var numVerts = vertsAcross * vertsAcross;
var positions = new Float32Array(numVerts * 3);
var texcoords = new Float32Array(numVerts * 2);
var indices = new Uint16Array(6 * gridRes * gridRes);
var poffset = 0;
var toffset = 0;
for (var yy = 0; yy <= gridRes; ++yy) {
for (var xx = 0; xx <= gridRes; ++xx) {
positions[poffset + 0] = -1 + 2 * xx / gridRes;
positions[poffset + 1] = -1 + 2 * yy / gridRes;
positions[poffset + 2] = 0;
texcoords[toffset + 0] = xx / gridRes;
texcoords[toffset + 1] = yy / gridRes;
poffset += 3;
toffset += 2;
}
}
var tbase = 0;
for (var yy = 0; yy < gridRes; ++yy) {
var index = yy * vertsAcross;
for (var xx = 0; xx < gridRes; ++xx) {
indices[tbase + 0] = index + 0;
indices[tbase + 1] = index + 1;
indices[tbase + 2] = index + vertsAcross;
indices[tbase + 3] = index + vertsAcross;
indices[tbase + 4] = index + 1;
indices[tbase + 5] = index + vertsAcross + 1;
index += 1;
tbase += 6;
}
}
var buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
gl.enableVertexAttribArray(positionLocation);
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
objects.push(buf);
var buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, texcoords, gl.STATIC_DRAW);
gl.enableVertexAttribArray(texcoordLocation);
gl.vertexAttribPointer(texcoordLocation, 2, gl.FLOAT, false, 0, 0);
objects.push(buf);
var buf = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buf);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
objects.push(buf);
return objects;
}
var refImage = draw(canvas1, refVS, refFS);
var testImage = draw(canvas2, testVS, testFS);
var ctx = diff.getContext("2d");
var imgData = ctx.getImageData(0, 0, width, height);
var same = true;
for (var yy = 0; yy < height; ++yy) {
for (var xx = 0; xx < width; ++xx) {
var offset = (yy * width + xx) * 4;
var imgOffset = ((height - yy - 1) * width + xx) * 4;
imgData.data[imgOffset + 0] = 0;
imgData.data[imgOffset + 1] = 0;
imgData.data[imgOffset + 2] = 0;
imgData.data[imgOffset + 3] = 255;
if (refImage[offset + 0] != testImage[offset + 0] ||
refImage[offset + 1] != testImage[offset + 1] ||
refImage[offset + 2] != testImage[offset + 2] ||
refImage[offset + 3] != testImage[offset + 3]) {
imgData.data[imgOffset] = 255;
same = false;
}
}
}
if (!same) {
ctx.putImageData(imgData, 0, 0);
testFailed("images are different");
} else {
testPassed("images are the same");
}
}
init();
successfullyParsed = true;
</script>
<script src="../resources/js-test-post.js"></script>
</body>
</html>