Index: conformance/ogles/ogles-utils.js |
=================================================================== |
--- conformance/ogles/ogles-utils.js (revision 0) |
+++ conformance/ogles/ogles-utils.js (working copy) |
@@ -0,0 +1,780 @@ |
+/* |
+** Copyright (c) 2012 The Khronos Group Inc. |
+** |
+** Permission is hereby granted, free of charge, to any person obtaining a |
+** copy of this software and/or associated documentation files (the |
+** "Materials"), to deal in the Materials without restriction, including |
+** without limitation the rights to use, copy, modify, merge, publish, |
+** distribute, sublicense, and/or sell copies of the Materials, and to |
+** permit persons to whom the Materials are furnished to do so, subject to |
+** the following conditions: |
+** |
+** The above copyright notice and this permission notice shall be included |
+** in all copies or substantial portions of the Materials. |
+** |
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. |
+*/ |
+OpenGLESTestRunner = (function(){ |
+var wtu = WebGLTestUtils; |
+var gl; |
+ |
+var HALF_GRID_MAX_SIZE = 32; |
+var KNOWN_ATTRIBS = [ |
+ "gtf_Vertex", |
+ "gtf_Color" |
+]; |
+ |
+var GTFPIXELTOLERANCE = 24; |
+var GTFACCEPTABLEFAILURECONT = 10; |
+var GTFAMDPIXELTOLERANCE = 12; |
+var GTFSCORETOLERANCE = 0.65; |
+var GTFNCCTOLARANCEZERO = 0.25; |
+var GTFKERNALSIZE = 5; |
+ |
+function log(msg) { |
+ // debug(msg); |
+} |
+ |
+function compareImages(refData, tstData, width, height, diff) { |
+ function isPixelSame(offset) { |
+ // First do simple check |
+ if (Math.abs(refData[offset + 0] - tstData[offset + 0]) <= GTFPIXELTOLERANCE && |
+ Math.abs(refData[offset + 1] - tstData[offset + 1]) <= GTFPIXELTOLERANCE && |
+ Math.abs(refData[offset + 2] - tstData[offset + 2]) <= GTFPIXELTOLERANCE) { |
+ return true; |
+ } |
+ |
+ // TODO: Implement crazy check that's used in OpenGL ES 2.0 conformance tests. |
+ // NOTE: on Desktop things seem to be working. Maybe the more complex check |
+ // is needed for embedded systems? |
+ return false; |
+ } |
+ |
+ var same = true; |
+ for (var yy = 0; yy < height; ++yy) { |
+ for (var xx = 0; xx < width; ++xx) { |
+ var offset = (yy * width + xx) * 4; |
+ var diffOffset = ((height - yy - 1) * width + xx) * 4; |
+ diff[diffOffset + 0] = 0; |
+ diff[diffOffset + 1] = 0; |
+ diff[diffOffset + 2] = 0; |
+ diff[diffOffset + 3] = 255; |
+ if (!isPixelSame(offset)) { |
+ diff[diffOffset] = 255; |
+ if (same) { |
+ same = false; |
+ testFailed("pixel @ (" + xx + ", " + yy + " was [" + |
+ tstData[offset + 0] + "," + |
+ tstData[offset + 1] + "," + |
+ tstData[offset + 2] + "," + |
+ tstData[offset + 3] + "] expected [" + |
+ refData[offset + 0] + "," + |
+ refData[offset + 1] + "," + |
+ refData[offset + 2] + "," + |
+ refData[offset + 3] + "]") |
+ } |
+ } |
+ } |
+ } |
+ return same; |
+} |
+ |
+function persp(fovy, aspect, n, f) { |
+ var dz = f - n; |
+ var rad = fovy / 2.0 * 3.14159265 / 180; |
+ |
+ var s = Math.sin(rad); |
+ if (dz == 0 || s == 0 || aspect == 0) |
+ return; |
+ |
+ var cot = Math.cos(rad) / s; |
+ |
+ return [ |
+ cot / aspect, |
+ 0.0, |
+ 0.0, |
+ 0.0, |
+ |
+ 0.0, |
+ cot, |
+ 0.0, |
+ 0.0, |
+ |
+ 0.0, |
+ 0.0, |
+ -(f + n) / dz, |
+ -1.0, |
+ |
+ 0.0, |
+ 0.0, |
+ -2.0 * f * n / dz, |
+ 0.0 |
+ ]; |
+} |
+ |
+function setAttribs(attribs, buffers) { |
+ for (var name in attribs) { |
+ var buffer = buffers[name]; |
+ if (!buffer) { |
+ testFailed("no buffer for attrib:" + name); |
+ continue; |
+ } |
+ var loc = attribs[name]; |
+ log("setup attrib: " + loc + " as " + name); |
+ var buf = gl.createBuffer(); |
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf); |
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(buffer.data), gl.STATIC_DRAW); |
+ gl.enableVertexAttribArray(loc); |
+ gl.vertexAttribPointer(loc, buffer.numComponents, gl.FLOAT, false, 0, 0); |
+ } |
+} |
+ |
+function drawSquare(attribs) { |
+ var buffers = { |
+ "gtf_Vertex": { |
+ data: [ |
+ 1.0, -1.0, -2.0, |
+ 1.0, 1.0, -2.0, |
+ -1.0, -1.0, -2.0, |
+ -1.0, 1.0, -2.0 |
+ ], |
+ numComponents: 3 |
+ }, |
+ "gtf_Color": { |
+ data: [ |
+ 0.5, 1.0, 0.0, |
+ 0.0, 1.0, 1.0, |
+ 1.0, 0.0, 0.0, |
+ 0.5, 0.0, 1.0 |
+ ], |
+ numComponents: 3, |
+ }, |
+ "gtf_SecondaryColor": { |
+ data: [ |
+ 0.5, 0.0, 1.0, |
+ 1.0, 0.0, 0.0, |
+ 0.0, 1.0, 1.0, |
+ 0.5, 1.0, 0.0 |
+ ], |
+ numComponents: 3, |
+ }, |
+ "gtf_Normal": { |
+ data: [ |
+ 0.5, 0.0, 1.0, |
+ 1.0, 0.0, 0.0, |
+ 0.0, 1.0, 1.0, |
+ 0.5, 1.0, 0.0 |
+ ], |
+ numComponents: 3, |
+ }, |
+ "gtf_MultiTexCoord0": { |
+ data: [ |
+ 1.0, 0.0, |
+ 1.0, 1.0, |
+ 0.0, 0.0, |
+ 0.0, 1.0 |
+ ], |
+ numComponents: 2, |
+ }, |
+ "gtf_FogCoord": { |
+ data: [ |
+ 0.0, |
+ 1.0, |
+ 0.0, |
+ 1.0 |
+ ], |
+ numComponents: 1, |
+ } |
+ }; |
+ setAttribs(attribs, buffers); |
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); |
+} |
+ |
+function drawFrontBackSquare(attribs) { |
+ var front = { |
+ "gtf_Vertex": { |
+ data: [ |
+ 1.0, -1.0, -2.0, |
+ 1.0, 0.0, -2.0, |
+ -1.0, -1.0, -2.0, |
+ -1.0, 0.0, -2.0 |
+ ], |
+ numComponents: 3 |
+ }, |
+ "gtf_Color": { |
+ data: [ |
+ 0.0, 1.0, 0.0, |
+ 0.0, 1.0, 0.0, |
+ 0.0, 1.0, 0.0, |
+ 0.0, 1.0, 0.0 |
+ ], |
+ numComponents: 3, |
+ }, |
+ "gtf_MultiTexCoord0": { |
+ data: [ |
+ 1.0, 0.0, |
+ 1.0, 0.5, |
+ 0.0, 0.0, |
+ 0.0, 0.5 |
+ ], |
+ numComponents: 2, |
+ } |
+ }; |
+ setAttribs(attribs, front); |
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); |
+ |
+ var back = { |
+ "gtf_Vertex": { |
+ data: [ |
+ 1.0, 1.0, -2.0, |
+ 1.0, 0.0, -2.0, |
+ -1.0, 1.0, -2.0, |
+ -1.0, 0.0, -2.0 |
+ ], |
+ numComponents: 3 |
+ }, |
+ "gtf_Color": { |
+ data: [ |
+ 1.0, 0.0, 0.0, |
+ 1.0, 0.0, 0.0, |
+ 1.0, 0.0, 0.0, |
+ 1.0, 0.0, 0.0 |
+ ], |
+ numComponents: 3, |
+ }, |
+ "gtf_MultiTexCoord0": { |
+ data: [ |
+ 1.0, 0.1, |
+ 1.0, 0.5, |
+ 0.0, 0.1, |
+ 0.0, 0.5 |
+ ], |
+ numComponents: 2, |
+ } |
+ }; |
+ setAttribs(attribs, back); |
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); |
+} |
+ |
+function drawGrid(attribs, width, height) { |
+ var n = Math.min(Math.floor(Math.max(width, height) / 4), HALF_GRID_MAX_SIZE); |
+ |
+ var numVertices = (n + n) * (n + n) * 6; |
+ |
+ var gridVertices = []; |
+ var gridColors = []; |
+ var gridSecColors = []; |
+ var gridNormals = []; |
+ var gridFogCoords = []; |
+ var gridTexCoords0 = []; |
+ |
+ var currentVertex = 0; |
+ var currentColor = 0; |
+ var currentSecColor = 0; |
+ var currentTexCoord0 = 0; |
+ var currentNormal = 0; |
+ var currentFogCoord = 0; |
+ |
+ var z = -2.0; |
+ for(var i = -n; i < n; ++i) |
+ { |
+ var x1 = i / n; |
+ var x2 = (i + 1) / n; |
+ for(var j = -n; j < n; ++j) |
+ { |
+ var y1 = j / n; |
+ var y2 = (j + 1) / n; |
+ |
+ // VERTEX 0 |
+ gridVertices[currentVertex++] = x1; |
+ gridVertices[currentVertex++] = y1; |
+ gridVertices[currentVertex++] = z; |
+ gridColors[currentColor++] = 1.0 - (x1 + y1 + 2.0) / 4.0; |
+ gridColors[currentColor++] = (x1 + 1.0) / 2.0; |
+ gridColors[currentColor++] = (y1 + 1.0) / 2.0; |
+ gridSecColors[currentSecColor++] = 1.0 - (x2 + y2 + 2.0) / 4.0; |
+ gridSecColors[currentSecColor++] = (x2 + 1.0) / 2.0; |
+ gridSecColors[currentSecColor++] = (y2 + 1.0) / 2.0; |
+ gridTexCoords0[currentTexCoord0++] = (x1 + 1.0) / 2.0; |
+ gridTexCoords0[currentTexCoord0++] = (y1 + 1.0) / 2.0; |
+ gridNormals[currentNormal++] = 1.0 - (x2 + y2 + 2.0) / 4.0; |
+ gridNormals[currentNormal++] = (x2 + 1.0) / 2.0; |
+ gridNormals[currentNormal++] = (y2 + 1.0) / 2.0; |
+ gridFogCoords[currentFogCoord++] = (y1 + 1.0) / 2.0; |
+ |
+ // VERTEX 1 |
+ gridVertices[currentVertex++] = x2; |
+ gridVertices[currentVertex++] = y1; |
+ gridVertices[currentVertex++] = z; |
+ gridColors[currentColor++] = 1.0 - (x2 + y1 + 2.0) / 4.0; |
+ gridColors[currentColor++] = (x2 + 1.0) / 2.0; |
+ gridColors[currentColor++] = (y1 + 1.0) / 2.0; |
+ gridSecColors[currentSecColor++] = 1.0 - (x1 + y2 + 2.0) / 4.0; |
+ gridSecColors[currentSecColor++] = (x1 + 1.0) / 2.0; |
+ gridSecColors[currentSecColor++] = (y2 + 1.0) / 2.0; |
+ gridTexCoords0[currentTexCoord0++] = (x2 + 1.0) / 2.0; |
+ gridTexCoords0[currentTexCoord0++] = (y1 + 1.0) / 2.0; |
+ gridNormals[currentNormal++] = 1.0 - (x1 + y2 + 2.0) / 4.0; |
+ gridNormals[currentNormal++] = (x1 + 1.0) / 2.0; |
+ gridNormals[currentNormal++] = (y2 + 1.0) / 2.0; |
+ gridFogCoords[currentFogCoord++] = (y1 + 1.0) / 2.0; |
+ |
+ // VERTEX 2 |
+ gridVertices[currentVertex++] = x2; |
+ gridVertices[currentVertex++] = y2; |
+ gridVertices[currentVertex++] = z; |
+ gridColors[currentColor++] = 1.0 - (x2 + y2 + 2.0) / 4.0; |
+ gridColors[currentColor++] = (x2 + 1.0) / 2.0; |
+ gridColors[currentColor++] = (y2 + 1.0) / 2.0; |
+ gridSecColors[currentSecColor++] = 1.0 - (x1 + y1 + 2.0) / 4.0; |
+ gridSecColors[currentSecColor++] = (x1 + 1.0) / 2.0; |
+ gridSecColors[currentSecColor++] = (y1 + 1.0) / 2.0; |
+ gridTexCoords0[currentTexCoord0++] = (x2 + 1.0) / 2.0; |
+ gridTexCoords0[currentTexCoord0++] = (y2 + 1.0) / 2.0; |
+ gridNormals[currentNormal++] = 1.0 - (x1 + y1 + 2.0) / 4.0; |
+ gridNormals[currentNormal++] = (x1 + 1.0) / 2.0; |
+ gridNormals[currentNormal++] = (y1 + 1.0) / 2.0; |
+ gridFogCoords[currentFogCoord++] = (y2 + 1.0) / 2.0; |
+ |
+ // VERTEX 2 |
+ gridVertices[currentVertex++] = x2; |
+ gridVertices[currentVertex++] = y2; |
+ gridVertices[currentVertex++] = z; |
+ gridColors[currentColor++] = 1.0 - (x2 + y2 + 2.0) / 4.0; |
+ gridColors[currentColor++] = (x2 + 1.0) / 2.0; |
+ gridColors[currentColor++] = (y2 + 1.0) / 2.0; |
+ gridSecColors[currentSecColor++] = 1.0 - (x1 + y1 + 2.0) / 4.0; |
+ gridSecColors[currentSecColor++] = (x1 + 1.0) / 2.0; |
+ gridSecColors[currentSecColor++] = (y1 + 1.0) / 2.0; |
+ gridTexCoords0[currentTexCoord0++] = (x2 + 1.0) / 2.0; |
+ gridTexCoords0[currentTexCoord0++] = (y2 + 1.0) / 2.0; |
+ gridNormals[currentNormal++] = 1.0 - (x1 + y1 + 2.0) / 4.0; |
+ gridNormals[currentNormal++] = (x1 + 1.0) / 2.0; |
+ gridNormals[currentNormal++] = (y1 + 1.0) / 2.0; |
+ gridFogCoords[currentFogCoord++] = (y2 + 1.0) / 2.0; |
+ |
+ // VERTEX 3 |
+ gridVertices[currentVertex++] = x1; |
+ gridVertices[currentVertex++] = y2; |
+ gridVertices[currentVertex++] = z; |
+ gridColors[currentColor++] = 1.0 - (x1 + y2 + 2.0) / 4.0; |
+ gridColors[currentColor++] = (x1 + 1.0) / 2.0; |
+ gridColors[currentColor++] = (y2 + 1.0) / 2.0; |
+ gridSecColors[currentSecColor++] = 1.0 - (x2 + y1 + 2.0) / 4.0; |
+ gridSecColors[currentSecColor++] = (x2 + 1.0) / 2.0; |
+ gridSecColors[currentSecColor++] = (y1 + 1.0) / 2.0; |
+ gridTexCoords0[currentTexCoord0++] = (x1 + 1.0) / 2.0; |
+ gridTexCoords0[currentTexCoord0++] = (y2 + 1.0) / 2.0; |
+ gridNormals[currentNormal++] = 1.0 - (x2 + y1 + 2.0) / 4.0; |
+ gridNormals[currentNormal++] = (x2 + 1.0) / 2.0; |
+ gridNormals[currentNormal++] = (y1 + 1.0) / 2.0; |
+ gridFogCoords[currentFogCoord++] = (y2 + 1.0) / 2.0; |
+ |
+ // VERTEX 0 |
+ gridVertices[currentVertex++] = x1; |
+ gridVertices[currentVertex++] = y1; |
+ gridVertices[currentVertex++] = z; |
+ gridColors[currentColor++] = 1.0 - (x1 + y1 + 2.0) / 4.0; |
+ gridColors[currentColor++] = (x1 + 1.0) / 2.0; |
+ gridColors[currentColor++] = (y1 + 1.0) / 2.0; |
+ gridSecColors[currentSecColor++] = 1.0 - (x2 + y2 + 2.0) / 4.0; |
+ gridSecColors[currentSecColor++] = (x2 + 1.0) / 2.0; |
+ gridSecColors[currentSecColor++] = (y2 + 1.0) / 2.0; |
+ gridTexCoords0[currentTexCoord0++] = (x1 + 1.0) / 2.0; |
+ gridTexCoords0[currentTexCoord0++] = (y1 + 1.0) / 2.0; |
+ gridNormals[currentNormal++] = 1.0 - (x2 + y2 + 2.0) / 4.0; |
+ gridNormals[currentNormal++] = (x2 + 1.0) / 2.0; |
+ gridNormals[currentNormal++] = (y2 + 1.0) / 2.0; |
+ gridFogCoords[currentFogCoord++] = (y1 + 1.0) / 2.0; |
+ } |
+ } |
+ |
+ var buffers = { |
+ "gtf_Vertex": { data: gridVertices, numComponents: 3 }, |
+ "gtf_Color": { data: gridColors, numComponents: 3 }, |
+ "gtf_SecondaryColor": { data: gridSecColors, numComponents: 3 }, |
+ "gtf_Normal": { data: gridNormals, numComponents: 3 }, |
+ "gtf_FogCoord": { data: gridFogCoords, numComponents: 1 }, |
+ "gtf_MultiTexCoord0": { data: gridTexCoords0, numComponents: 2 } |
+ }; |
+ setAttribs(attribs, buffers); |
+ gl.drawArrays(gl.TRIANGLES, 0, numVertices); |
+} |
+ |
+var MODEL_FUNCS = { |
+ square: drawSquare, |
+ frontbacksquare: drawFrontBackSquare, |
+ grid: drawGrid |
+}; |
+ |
+function drawWithProgram(program, programInfo, test) { |
+ gl.useProgram(program); |
+ var attribs = { }; |
+ |
+ var numAttribs = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); |
+ for (var ii = 0; ii < numAttribs; ++ii) { |
+ var info = gl.getActiveAttrib(program, ii); |
+ var name = info.name; |
+ var location = gl.getAttribLocation(program, name); |
+ attribs[name] = location; |
+ |
+ if (KNOWN_ATTRIBS.indexOf(name) < 0) { |
+ testFailed("unknown attrib:" + name) |
+ } |
+ } |
+ |
+ var uniforms = { }; |
+ var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); |
+ for (var ii = 0; ii < numUniforms; ++ii) { |
+ var info = gl.getActiveUniform(program, ii); |
+ var name = info.name; |
+ if (name.match(/\[0\]$/)) { |
+ name = name.substr(0, name.length - 3); |
+ } |
+ var location = gl.getUniformLocation(program, name); |
+ uniforms[name] = {location: location}; |
+ } |
+ |
+ var getUniformLocation = function(name) { |
+ var uniform = uniforms[name]; |
+ if (uniform) { |
+ uniform.used = true; |
+ return uniform.location; |
+ } |
+ return null; |
+ } |
+ |
+ // Set known uniforms |
+ var loc = getUniformLocation("gtf_ModelViewProjectionMatrix"); |
+ if (loc) { |
+ gl.uniformMatrix4fv( |
+ loc, |
+ false, |
+ persp(60, 1, 1, 30)); |
+ } |
+ var loc = getUniformLocation("viewportwidth"); |
+ if (loc) { |
+ gl.uniform1f(loc, gl.canvas.width); |
+ } |
+ var loc = getUniformLocation("viewportheight"); |
+ if (loc) { |
+ gl.uniform1f(loc, gl.canvas.height); |
+ } |
+ |
+ // Set test specific uniforms |
+ for (var name in programInfo.uniforms) { |
+ var location = getUniformLocation(name); |
+ if (!location) { |
+ continue; |
+ } |
+ var uniform = programInfo.uniforms[name]; |
+ var type = uniform.type; |
+ var value = uniform.value; |
+ var transpose = uniform.transpose; |
+ if (transpose !== undefined) { |
+ log("gl." + type + '("' + name + '", ' + transpose + ", " + value + ")"); |
+ gl[type](location, transpose, value); |
+ } else if (!type.match("v$")) { |
+ var args = [location]; |
+ for (var ii = 0; ii < value.length; ++ii) { |
+ args.push(value[ii]); |
+ } |
+ gl[type].apply(gl, args); |
+ log("gl." + type + '("' + name + '", ' + args.slice(1) + ")"); |
+ } else { |
+ log("gl." + type + '("' + name + '", ' + value + ")"); |
+ gl[type](location, value); |
+ } |
+ var err = gl.getError(); |
+ if (err != gl.NO_ERROR) { |
+ testFailed(wtu.glEnumToString(gl, err) + " generated setting uniform: " + name); |
+ } |
+ } |
+ |
+ // Check for unset uniforms |
+ for (var name in uniforms) { |
+ var uniform = uniforms[name]; |
+ if (!uniform.used) { |
+ testFailed("uniform " + name + " never set"); |
+ } |
+ } |
+ |
+ |
+ for (var state in test.state) { |
+ var fields = test.state[state]; |
+ switch (state) { |
+ case 'depthrange': |
+ gl.depthRange(fields.near, fields.far); |
+ break; |
+ default: |
+ testFailed("unknown state: " + state) |
+ } |
+ } |
+ |
+ gl.clearColor(0, 0, 0, 0); |
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); |
+ |
+ var model = test.model || "square"; |
+ var fn = MODEL_FUNCS[model]; |
+ if (!fn) { |
+ testFailed("unknown model type: " + model) |
+ } else { |
+ log("draw as: " + model) |
+ fn(attribs, gl.canvas.width, gl.canvas.height); |
+ } |
+ |
+ var pixels = new Uint8Array(gl.canvas.width * gl.canvas.height * 4); |
+ gl.readPixels(0, 0, gl.canvas.width, gl.canvas.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); |
+ return { |
+ width: gl.canvas.width, |
+ height: gl.canvas.height, |
+ pixels: pixels, |
+ img: wtu.makeImage(gl.canvas) |
+ }; |
+} |
+ |
+function runProgram(programInfo, test, label, callback) { |
+ var shaders = []; |
+ var source = []; |
+ var count = 0; |
+ |
+ function loadShader(path, type, index) { |
+ wtu.loadTextFileAsync(path, function(success, text) { |
+ addShader(success, text, type, path, index); |
+ }); |
+ } |
+ |
+ function addShader(success, text, type, path, index) { |
+ ++count; |
+ if (!success) { |
+ testFailed("could not load: " + path); |
+ } else { |
+ var shader = wtu.loadShader(gl, text, type); |
+ shaders.push(shader); |
+ source[index] = text; |
+ } |
+ if (count == 2) { |
+ var result; |
+ if (shaders.length == 2) { |
+ debug(""); |
+ var console = document.getElementById("console"); |
+ wtu.addShaderSource( |
+ console, label + " vertex shader", source[0], programInfo.vertexShader); |
+ wtu.addShaderSource( |
+ console, label + " fragment shader", source[1], programInfo.fragmentShader); |
+ var program = wtu.createProgram(gl, shaders[0], shaders[1]); |
+ result = drawWithProgram(program, programInfo, test); |
+ } |
+ callback(result); |
+ } |
+ } |
+ |
+ loadShader(programInfo.vertexShader, gl.VERTEX_SHADER, 0); |
+ loadShader(programInfo.fragmentShader, gl.FRAGMENT_SHADER, 1); |
+} |
+ |
+function compareResults(expected, actual) { |
+ var width = expected.width; |
+ var height = expected.height; |
+ var canvas = document.createElement("canvas"); |
+ canvas.width = width; |
+ canvas.height = height; |
+ var ctx = canvas.getContext("2d"); |
+ var imgData = ctx.getImageData(0, 0, width, height); |
+ var tolerance = 0; |
+ |
+ var expData = expected.pixels; |
+ var actData = actual.pixels; |
+ |
+ var same = compareImages(expData, actData, width, height, imgData.data); |
+ |
+ var console = document.getElementById("console"); |
+ var diffImg = null; |
+ if (!same) { |
+ ctx.putImageData(imgData, 0, 0); |
+ diffImg = wtu.makeImage(canvas); |
+ } |
+ |
+ var div = document.createElement("div"); |
+ div.className = "testimages"; |
+ wtu.insertImage(div, "reference", expected.img); |
+ wtu.insertImage(div, "test", actual.img); |
+ if (diffImg) { |
+ wtu.insertImage(div, "diff", diffImg); |
+ } |
+ div.appendChild(document.createElement('br')); |
+ |
+ console.appendChild(div); |
+ |
+ if (!same) { |
+ testFailed("images are different"); |
+ } else { |
+ testPassed("images are the same"); |
+ } |
+ |
+ console.appendChild(document.createElement('hr')); |
+} |
+ |
+function runCompareTest(test, callback) { |
+ debug(""); |
+ debug("test: " + test.name); |
+ var results = []; |
+ var count = 0; |
+ |
+ function storeResults(index) { |
+ return function(result) { |
+ results[index] = result; |
+ ++count; |
+ if (count == 2) { |
+ compareResults(results[0], results[1]); |
+ glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors"); |
+ callback(); |
+ } |
+ } |
+ } |
+ |
+ runProgram(test.referenceProgram, test, "reference", storeResults(0)); |
+ runProgram(test.testProgram, test, "test", storeResults(1)); |
+} |
+ |
+function runBuildTest(test, callback) { |
+ debug(""); |
+ debug("test: " + test.name); |
+ |
+ var shaders = [null, null]; |
+ var source = ["",""]; |
+ var success = [undefined, undefined]; |
+ var count = 0; |
+ |
+ function loadShader(path, type, index) { |
+ if (path == "empty") { |
+ shaders[index] = gl.createShader(); |
+ success[index] = true; |
+ source[index] = "/* empty */"; |
+ attachAndLink(); |
+ } else { |
+ wtu.loadTextFileAsync(path, function(loadSuccess, text) { |
+ if (!loadSuccess) { |
+ success[index] = false; |
+ source[index] = "/* could not load */"; |
+ testFailed("could not load:" + path); |
+ } else { |
+ source[index] = text; |
+ shaders[index] = wtu.loadShader(gl, text, type, function(index) { |
+ return function(msg) { |
+ success[index] = false |
+ } |
+ }(index)); |
+ if (success[index] === undefined) { |
+ success[index] = true; |
+ } |
+ } |
+ attachAndLink(); |
+ }); |
+ } |
+ } |
+ |
+ function attachAndLink() { |
+ ++count; |
+ if (count == 2) { |
+ debug(""); |
+ var c = document.getElementById("console"); |
+ wtu.addShaderSource( |
+ c, "vertex shader", source[0], test.testProgram.vertexShader); |
+ debug("compile: " + (success[0] ? "success" : "fail")); |
+ wtu.addShaderSource( |
+ c, "fragment shader", source[1], test.testProgram.fragmentShader); |
+ debug("compile: " + (success[1] ? "success" : "fail")); |
+ compileSuccess = (success[0] && success[1]); |
+ if (!test.compstat) { |
+ if (compileSuccess) { |
+ testFailed("expected compile failure but was successful"); |
+ } else { |
+ testPassed("expected compile failure and it failed"); |
+ } |
+ } else { |
+ if (compileSuccess) { |
+ testPassed("expected compile success and it was successful"); |
+ } else { |
+ testFailed("expected compile success but it failed"); |
+ } |
+ var linkSuccess = true; |
+ var program = wtu.createProgram(gl, shaders[0], shaders[1], function() { |
+ linkSuccess = false; |
+ }); |
+ if (linkSuccess !== test.linkstat) { |
+ testFailed("expected link to " + (test.linkstat ? "succeed" : "fail")); |
+ } else { |
+ testPassed("shaders compiled and linked as expected."); |
+ } |
+ } |
+ callback(); |
+ } |
+ } |
+ |
+ loadShader(test.testProgram.vertexShader, gl.VERTEX_SHADER, 0); |
+ loadShader(test.testProgram.fragmentShader, gl.FRAGMENT_SHADER, 1); |
+} |
+ |
+var testPatterns = { |
+ compare: runCompareTest, |
+ build: runBuildTest, |
+ |
+ dummy: null // just here to mark the end |
+}; |
+ |
+function LogGLCall(functionName, args) { |
+ console.log("gl." + functionName + "(" + |
+ WebGLDebugUtils.glFunctionArgsToString(functionName, args) + ")"); |
+} |
+ |
+// Runs the tests async since they will load shaders. |
+function run(obj) { |
+ description(); |
+ |
+ var canvas = document.getElementById("example"); |
+ gl = wtu.create3DContext(canvas); |
+ if (window.WebGLDebugUtils) { |
+ gl = WebGLDebugUtils.makeDebugContext(gl, undefined, LogGLCall); |
+ } |
+ if (!gl) { |
+ testFailed("context does not exist"); |
+ finishTest(); |
+ return; |
+ } |
+ |
+ if (gl.canvas.width != 500 || gl.canvas.height != 500) { |
+ testFailed("canvas must be 500x500 pixels: Several shaders are hard coded to this size."); |
+ } |
+ |
+ var tests = obj.tests; |
+ var ndx = 0; |
+ |
+ function runNextTest() { |
+ if (ndx < tests.length) { |
+ var test = tests[ndx++]; |
+ var fn = testPatterns[test.pattern]; |
+ if (!fn) { |
+ testFailed("test pattern: " + test.pattern + " not supoprted") |
+ runNextTest(); |
+ } else { |
+ fn(test, runNextTest); |
+ } |
+ } else { |
+ finishTest(); |
+ } |
+ } |
+ runNextTest(); |
+} |
+ |
+return { |
+ run: run, |
+}; |
+}()); |
+ |
Property changes on: conformance/ogles/ogles-utils.js |
___________________________________________________________________ |
Added: svn:eol-style |
## -0,0 +1 ## |
+LF |
\ No newline at end of property |