868 lines
32 KiB
JavaScript
868 lines
32 KiB
JavaScript
define([
|
|
'./equals',
|
|
'Core/Cartesian2',
|
|
'Core/defaultValue',
|
|
'Core/defined',
|
|
'Core/DeveloperError',
|
|
'Core/FeatureDetection',
|
|
'Core/Math',
|
|
'Core/PrimitiveType',
|
|
'Core/RuntimeError',
|
|
'Renderer/Buffer',
|
|
'Renderer/BufferUsage',
|
|
'Renderer/ClearCommand',
|
|
'Renderer/DrawCommand',
|
|
'Renderer/ShaderProgram',
|
|
'Renderer/VertexArray'
|
|
], function(
|
|
equals,
|
|
Cartesian2,
|
|
defaultValue,
|
|
defined,
|
|
DeveloperError,
|
|
FeatureDetection,
|
|
CesiumMath,
|
|
PrimitiveType,
|
|
RuntimeError,
|
|
Buffer,
|
|
BufferUsage,
|
|
ClearCommand,
|
|
DrawCommand,
|
|
ShaderProgram,
|
|
VertexArray) {
|
|
'use strict';
|
|
|
|
function createMissingFunctionMessageFunction(item, actualPrototype, expectedInterfacePrototype) {
|
|
return function() {
|
|
return 'Expected function \'' + item + '\' to exist on ' + actualPrototype.constructor.name + ' because it should implement interface ' + expectedInterfacePrototype.constructor.name + '.';
|
|
};
|
|
}
|
|
|
|
function makeThrowFunction(debug, Type, name) {
|
|
if (debug) {
|
|
return function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected) {
|
|
// based on the built-in Jasmine toThrow matcher
|
|
var result = false;
|
|
var exception;
|
|
|
|
if (typeof actual !== 'function') {
|
|
throw new Error('Actual is not a function');
|
|
}
|
|
|
|
try {
|
|
actual();
|
|
} catch (e) {
|
|
exception = e;
|
|
}
|
|
|
|
if (exception) {
|
|
result = exception instanceof Type;
|
|
}
|
|
|
|
var message;
|
|
if (result) {
|
|
message = ['Expected function not to throw ' + name + ' , but it threw', exception.message || exception].join(' ');
|
|
} else {
|
|
message = 'Expected function to throw ' + name + '.';
|
|
}
|
|
|
|
return {
|
|
pass : result,
|
|
message : message
|
|
};
|
|
}
|
|
};
|
|
};
|
|
}
|
|
|
|
return function() {
|
|
return {
|
|
compare : function(actual, expected) {
|
|
return { pass : true };
|
|
},
|
|
negativeCompare : function(actual, expected) {
|
|
return { pass : true };
|
|
}
|
|
};
|
|
};
|
|
}
|
|
|
|
function createDefaultMatchers(debug) {
|
|
return {
|
|
toBeGreaterThanOrEqualTo : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected) {
|
|
return { pass : actual >= expected };
|
|
}
|
|
};
|
|
},
|
|
|
|
toBeLessThanOrEqualTo : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected) {
|
|
return { pass : actual <= expected };
|
|
}
|
|
};
|
|
},
|
|
|
|
toBeBetween : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, lower, upper) {
|
|
if (lower > upper) {
|
|
var tmp = upper;
|
|
upper = lower;
|
|
lower = tmp;
|
|
}
|
|
return { pass : actual >= lower && actual <= upper };
|
|
}
|
|
};
|
|
},
|
|
|
|
toStartWith : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected) {
|
|
return { pass : actual.slice(0, expected.length) === expected };
|
|
}
|
|
};
|
|
},
|
|
|
|
toEndWith : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected) {
|
|
return { pass : actual.slice(-expected.length) === expected };
|
|
}
|
|
};
|
|
},
|
|
|
|
toEqual : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected) {
|
|
return { pass : equals(util, customEqualityTesters, actual, expected) };
|
|
}
|
|
};
|
|
},
|
|
|
|
toEqualEpsilon : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected, epsilon) {
|
|
function equalityTester(a, b) {
|
|
if (Array.isArray(a) && Array.isArray(b)) {
|
|
if (a.length !== b.length) {
|
|
return false;
|
|
}
|
|
|
|
for (var i = 0; i < a.length; ++i) {
|
|
if (!equalityTester(a[i], b[i])) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
var to_run;
|
|
if (defined(a)) {
|
|
if (typeof a.equalsEpsilon === 'function') {
|
|
return a.equalsEpsilon(b, epsilon);
|
|
} else if (a instanceof Object) {
|
|
// Check if the current object has a static function named 'equalsEpsilon'
|
|
to_run = Object.getPrototypeOf(a).constructor.equalsEpsilon;
|
|
if (typeof to_run === 'function') {
|
|
return to_run(a, b, epsilon);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (defined(b)) {
|
|
if (typeof b.equalsEpsilon === 'function') {
|
|
return b.equalsEpsilon(a, epsilon);
|
|
} else if (b instanceof Object) {
|
|
// Check if the current object has a static function named 'equalsEpsilon'
|
|
to_run = Object.getPrototypeOf(b).constructor.equalsEpsilon;
|
|
if (typeof to_run === 'function') {
|
|
return to_run(b, a, epsilon);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (typeof a === 'number' || typeof b === 'number') {
|
|
return Math.abs(a - b) <= epsilon;
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
var result = equals(util, [equalityTester], actual, expected);
|
|
|
|
return { pass : result };
|
|
}
|
|
};
|
|
},
|
|
|
|
toConformToInterface : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expectedInterface) {
|
|
// All function properties on the prototype should also exist on the actual's prototype.
|
|
var actualPrototype = actual.prototype;
|
|
var expectedInterfacePrototype = expectedInterface.prototype;
|
|
|
|
for ( var item in expectedInterfacePrototype) {
|
|
if (expectedInterfacePrototype.hasOwnProperty(item) && typeof expectedInterfacePrototype[item] === 'function' && !actualPrototype.hasOwnProperty(item)) {
|
|
return { pass : false, message : createMissingFunctionMessageFunction(item, actualPrototype, expectedInterfacePrototype) };
|
|
}
|
|
}
|
|
|
|
return { pass : true };
|
|
}
|
|
};
|
|
},
|
|
|
|
toBeInstanceOf : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expectedConstructor) {
|
|
return { pass : actual instanceof expectedConstructor };
|
|
}
|
|
};
|
|
},
|
|
|
|
toRender : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected) {
|
|
return renderEquals(util, customEqualityTesters, actual, expected, true);
|
|
}
|
|
};
|
|
},
|
|
|
|
notToRender : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected) {
|
|
return renderEquals(util, customEqualityTesters, actual, expected, false);
|
|
}
|
|
};
|
|
},
|
|
|
|
toRenderAndCall : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected) {
|
|
var actualRgba = renderAndReadPixels(actual);
|
|
|
|
var webglStub = !!window.webglStub;
|
|
if (!webglStub) {
|
|
// The callback may have expectations that fail, which still makes the
|
|
// spec fail, as we desired, even though this matcher sets pass to true.
|
|
var callback = expected;
|
|
callback(actualRgba);
|
|
}
|
|
|
|
return {
|
|
pass : true
|
|
};
|
|
}
|
|
};
|
|
},
|
|
|
|
toRenderPixelCountAndCall : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected) {
|
|
var actualRgba = renderAndReadPixels(actual);
|
|
|
|
var webglStub = !!window.webglStub;
|
|
if (!webglStub) {
|
|
// The callback may have expectations that fail, which still makes the
|
|
// spec fail, as we desired, even though this matcher sets pass to true.
|
|
var callback = expected;
|
|
callback(countRenderedPixels(actualRgba));
|
|
}
|
|
|
|
return {
|
|
pass : true
|
|
};
|
|
}
|
|
};
|
|
},
|
|
|
|
toPickPrimitive : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected, x, y, width, height) {
|
|
return pickPrimitiveEquals(actual, expected, x, y, width, height);
|
|
}
|
|
};
|
|
},
|
|
|
|
notToPick : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, x, y, width, height) {
|
|
return pickPrimitiveEquals(actual, undefined, x, y, width, height);
|
|
}
|
|
};
|
|
},
|
|
|
|
toDrillPickPrimitive : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected, x, y, width, height) {
|
|
return drillPickPrimitiveEquals(actual, 1, x, y, width, height);
|
|
}
|
|
};
|
|
},
|
|
|
|
notToDrillPick : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, x, y, width, height) {
|
|
return drillPickPrimitiveEquals(actual, 0, x, y, width, height);
|
|
}
|
|
};
|
|
},
|
|
|
|
toPickAndCall : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected) {
|
|
var scene = actual;
|
|
var result = scene.pick(new Cartesian2(0, 0));
|
|
|
|
var webglStub = !!window.webglStub;
|
|
if (!webglStub) {
|
|
// The callback may have expectations that fail, which still makes the
|
|
// spec fail, as we desired, even though this matcher sets pass to true.
|
|
var callback = expected;
|
|
callback(result);
|
|
}
|
|
|
|
return {
|
|
pass : true
|
|
};
|
|
}
|
|
};
|
|
},
|
|
|
|
toDrillPickAndCall : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected, limit) {
|
|
var scene = actual;
|
|
var pickedObjects = scene.drillPick(new Cartesian2(0, 0), limit);
|
|
|
|
var webglStub = !!window.webglStub;
|
|
if (!webglStub) {
|
|
// The callback may have expectations that fail, which still makes the
|
|
// spec fail, as we desired, even though this matcher sets pass to true.
|
|
var callback = expected;
|
|
callback(pickedObjects);
|
|
}
|
|
|
|
return {
|
|
pass : true
|
|
};
|
|
}
|
|
};
|
|
},
|
|
|
|
toPickFromRayAndCall : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected, ray, objectsToExclude) {
|
|
var scene = actual;
|
|
var result = scene.pickFromRay(ray, objectsToExclude);
|
|
|
|
var webglStub = !!window.webglStub;
|
|
if (!webglStub) {
|
|
// The callback may have expectations that fail, which still makes the
|
|
// spec fail, as we desired, even though this matcher sets pass to true.
|
|
var callback = expected;
|
|
callback(result);
|
|
}
|
|
|
|
return {
|
|
pass : true
|
|
};
|
|
}
|
|
};
|
|
},
|
|
|
|
toDrillPickFromRayAndCall : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected, ray, limit, objectsToExclude) {
|
|
var scene = actual;
|
|
var results = scene.drillPickFromRay(ray, limit, objectsToExclude);
|
|
|
|
var webglStub = !!window.webglStub;
|
|
if (!webglStub) {
|
|
// The callback may have expectations that fail, which still makes the
|
|
// spec fail, as we desired, even though this matcher sets pass to true.
|
|
var callback = expected;
|
|
callback(results);
|
|
}
|
|
|
|
return {
|
|
pass : true
|
|
};
|
|
}
|
|
};
|
|
},
|
|
|
|
toSampleHeightAndCall : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected, position, objectsToExclude) {
|
|
var scene = actual;
|
|
var results = scene.sampleHeight(position, objectsToExclude);
|
|
|
|
var webglStub = !!window.webglStub;
|
|
if (!webglStub) {
|
|
// The callback may have expectations that fail, which still makes the
|
|
// spec fail, as we desired, even though this matcher sets pass to true.
|
|
var callback = expected;
|
|
callback(results);
|
|
}
|
|
|
|
return {
|
|
pass : true
|
|
};
|
|
}
|
|
};
|
|
},
|
|
|
|
toClampToHeightAndCall : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected, cartesian, objectsToExclude) {
|
|
var scene = actual;
|
|
var results = scene.clampToHeight(cartesian, objectsToExclude);
|
|
|
|
var webglStub = !!window.webglStub;
|
|
if (!webglStub) {
|
|
// The callback may have expectations that fail, which still makes the
|
|
// spec fail, as we desired, even though this matcher sets pass to true.
|
|
var callback = expected;
|
|
callback(results);
|
|
}
|
|
|
|
return {
|
|
pass : true
|
|
};
|
|
}
|
|
};
|
|
},
|
|
|
|
toPickPositionAndCall : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected, x, y) {
|
|
var scene = actual;
|
|
var canvas = scene.canvas;
|
|
x = defaultValue(x, canvas.clientWidth / 2);
|
|
y = defaultValue(y, canvas.clientHeight / 2);
|
|
var result = scene.pickPosition(new Cartesian2(x, y));
|
|
|
|
var webglStub = !!window.webglStub;
|
|
if (!webglStub) {
|
|
// The callback may have expectations that fail, which still makes the
|
|
// spec fail, as we desired, even though this matcher sets pass to true.
|
|
var callback = expected;
|
|
callback(result);
|
|
}
|
|
|
|
return {
|
|
pass : true
|
|
};
|
|
}
|
|
};
|
|
},
|
|
|
|
toReadPixels : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected) {
|
|
var context;
|
|
var framebuffer;
|
|
var epsilon = 0;
|
|
|
|
var options = actual;
|
|
if (defined(options.context)) {
|
|
// options were passed to to a framebuffer
|
|
context = options.context;
|
|
framebuffer = options.framebuffer;
|
|
epsilon = defaultValue(options.epsilon, epsilon);
|
|
} else {
|
|
context = options;
|
|
}
|
|
|
|
var rgba = context.readPixels({
|
|
framebuffer : framebuffer
|
|
});
|
|
|
|
var pass = true;
|
|
var message;
|
|
|
|
var webglStub = !!window.webglStub;
|
|
if (!webglStub) {
|
|
if (!CesiumMath.equalsEpsilon(rgba[0], expected[0], 0, epsilon) ||
|
|
!CesiumMath.equalsEpsilon(rgba[1], expected[1], 0, epsilon) ||
|
|
!CesiumMath.equalsEpsilon(rgba[2], expected[2], 0, epsilon) ||
|
|
!CesiumMath.equalsEpsilon(rgba[3], expected[3], 0, epsilon)) {
|
|
pass = false;
|
|
if (epsilon === 0) {
|
|
message = 'Expected context to render ' + expected + ', but rendered: ' + rgba;
|
|
} else {
|
|
message = 'Expected context to render ' + expected + ' with epsilon = ' + epsilon + ', but rendered: ' + rgba;
|
|
}
|
|
}
|
|
}
|
|
|
|
return {
|
|
pass : pass,
|
|
message : message
|
|
};
|
|
}
|
|
};
|
|
},
|
|
|
|
notToReadPixels : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected) {
|
|
var context = actual;
|
|
var rgba = context.readPixels();
|
|
|
|
var pass = true;
|
|
var message;
|
|
|
|
var webglStub = !!window.webglStub;
|
|
if (!webglStub) {
|
|
if ((rgba[0] === expected[0]) &&
|
|
(rgba[1] === expected[1]) &&
|
|
(rgba[2] === expected[2]) &&
|
|
(rgba[3] === expected[3])) {
|
|
pass = false;
|
|
message = 'Expected context not to render ' + expected + ', but rendered: ' + rgba;
|
|
}
|
|
}
|
|
|
|
return {
|
|
pass : pass,
|
|
message : message
|
|
};
|
|
}
|
|
};
|
|
},
|
|
|
|
contextToRenderAndCall : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected) {
|
|
var actualRgba = contextRenderAndReadPixels(actual).color;
|
|
|
|
var webglStub = !!window.webglStub;
|
|
if (!webglStub) {
|
|
// The callback may have expectations that fail, which still makes the
|
|
// spec fail, as we desired, even though this matcher sets pass to true.
|
|
var callback = expected;
|
|
callback(actualRgba);
|
|
}
|
|
|
|
return {
|
|
pass : true
|
|
};
|
|
}
|
|
};
|
|
},
|
|
|
|
contextToRender : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected) {
|
|
return expectContextToRender(actual, expected, true);
|
|
}
|
|
};
|
|
},
|
|
|
|
notContextToRender : function(util, customEqualityTesters) {
|
|
return {
|
|
compare : function(actual, expected) {
|
|
return expectContextToRender(actual, expected, false);
|
|
}
|
|
};
|
|
},
|
|
|
|
toThrowDeveloperError : makeThrowFunction(debug, DeveloperError, 'DeveloperError'),
|
|
|
|
toThrowRuntimeError : makeThrowFunction(true, RuntimeError, 'RuntimeError'),
|
|
|
|
toThrowSyntaxError : makeThrowFunction(true, SyntaxError, 'SyntaxError')
|
|
};
|
|
}
|
|
|
|
function countRenderedPixels(rgba) {
|
|
var pixelCount = rgba.length / 4;
|
|
var count = 0;
|
|
for (var i = 0; i < pixelCount; i++) {
|
|
var index = i * 4;
|
|
if (rgba[index] !== 0 ||
|
|
rgba[index + 1] !== 0 ||
|
|
rgba[index + 2] !== 0 ||
|
|
rgba[index + 3] !== 255) {
|
|
count++;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
function renderAndReadPixels(options) {
|
|
var scene;
|
|
|
|
if (defined(options.scene)) {
|
|
// options were passed to render the scene at a given time or prime shadow map
|
|
scene = options.scene;
|
|
var time = options.time;
|
|
|
|
scene.initializeFrame();
|
|
if (defined(options.primeShadowMap)) {
|
|
scene.render(time); // Computes shadow near/far for next frame
|
|
}
|
|
scene.render(time);
|
|
} else {
|
|
scene = options;
|
|
scene.initializeFrame();
|
|
scene.render();
|
|
}
|
|
|
|
return scene.context.readPixels();
|
|
}
|
|
|
|
function isTypedArray(o) {
|
|
return FeatureDetection.typedArrayTypes.some(function(type) {
|
|
return o instanceof type;
|
|
});
|
|
}
|
|
|
|
function typedArrayToArray(array) {
|
|
if (isTypedArray(array)) {
|
|
return Array.prototype.slice.call(array, 0);
|
|
}
|
|
return array;
|
|
}
|
|
|
|
function renderEquals(util, customEqualityTesters, actual, expected, expectEqual) {
|
|
var actualRgba = renderAndReadPixels(actual);
|
|
|
|
// When the WebGL stub is used, all WebGL function calls are noops so
|
|
// the expectation is not verified. This allows running all the WebGL
|
|
// tests, to exercise as much Cesium code as possible, even if the system
|
|
// doesn't have a WebGL implementation or a reliable one.
|
|
if (!!window.webglStub) {
|
|
return {
|
|
pass : true
|
|
};
|
|
}
|
|
|
|
var eq = equals(util, customEqualityTesters, actualRgba, expected);
|
|
var pass = expectEqual ? eq : !eq;
|
|
|
|
var message;
|
|
if (!pass) {
|
|
message = 'Expected ' + (expectEqual ? '' : 'not ') + 'to render [' + typedArrayToArray(expected) + '], but actually rendered [' + typedArrayToArray(actualRgba) + '].';
|
|
}
|
|
|
|
return {
|
|
pass : pass,
|
|
message : message
|
|
};
|
|
}
|
|
|
|
function pickPrimitiveEquals(actual, expected, x, y, width, height) {
|
|
var scene = actual;
|
|
var windowPosition = new Cartesian2(x, y);
|
|
var result = scene.pick(windowPosition, width, height);
|
|
|
|
if (!!window.webglStub) {
|
|
return {
|
|
pass : true
|
|
};
|
|
}
|
|
|
|
var pass = true;
|
|
var message;
|
|
|
|
if (defined(expected)) {
|
|
pass = (result.primitive === expected);
|
|
} else {
|
|
pass = !defined(result);
|
|
}
|
|
|
|
if (!pass) {
|
|
message = 'Expected to pick ' + expected + ', but picked: ' + result;
|
|
}
|
|
|
|
return {
|
|
pass : pass,
|
|
message : message
|
|
};
|
|
}
|
|
|
|
function drillPickPrimitiveEquals(actual, expected, x, y, width, height) {
|
|
var scene = actual;
|
|
var windowPosition = new Cartesian2(x, y);
|
|
var result = scene.drillPick(windowPosition, undefined, width, height);
|
|
|
|
if (!!window.webglStub) {
|
|
return {
|
|
pass : true
|
|
};
|
|
}
|
|
|
|
var pass = true;
|
|
var message;
|
|
|
|
if (defined(expected)) {
|
|
pass = (result.length === expected);
|
|
} else {
|
|
pass = !defined(result);
|
|
}
|
|
|
|
if (!pass) {
|
|
message = 'Expected to pick ' + expected + ', but picked: ' + result;
|
|
}
|
|
|
|
return {
|
|
pass : pass,
|
|
message : message
|
|
};
|
|
}
|
|
|
|
function contextRenderAndReadPixels(options) {
|
|
var context = options.context;
|
|
var vs = options.vertexShader;
|
|
var fs = options.fragmentShader;
|
|
var sp = options.shaderProgram;
|
|
var uniformMap = options.uniformMap;
|
|
var modelMatrix = options.modelMatrix;
|
|
var depth = defaultValue(options.depth, 0.0);
|
|
var clear = defaultValue(options.clear, true);
|
|
var clearColor;
|
|
|
|
if (!defined(context)) {
|
|
throw new DeveloperError('options.context is required.');
|
|
}
|
|
|
|
if (!defined(fs) && !defined(sp)) {
|
|
throw new DeveloperError('options.fragmentShader or options.shaderProgram is required.');
|
|
}
|
|
|
|
if (defined(fs) && defined(sp)) {
|
|
throw new DeveloperError('Both options.fragmentShader and options.shaderProgram can not be used at the same time.');
|
|
}
|
|
|
|
if (defined(vs) && defined(sp)) {
|
|
throw new DeveloperError('Both options.vertexShader and options.shaderProgram can not be used at the same time.');
|
|
}
|
|
|
|
if (!defined(sp)) {
|
|
if (!defined(vs)) {
|
|
vs = 'attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }';
|
|
}
|
|
sp = ShaderProgram.fromCache({
|
|
context : context,
|
|
vertexShaderSource : vs,
|
|
fragmentShaderSource : fs,
|
|
attributeLocations: {
|
|
position: 0
|
|
}
|
|
});
|
|
}
|
|
|
|
var va = new VertexArray({
|
|
context : context,
|
|
attributes : [{
|
|
index : 0,
|
|
vertexBuffer : Buffer.createVertexBuffer({
|
|
context : context,
|
|
typedArray : new Float32Array([0.0, 0.0, depth, 1.0]),
|
|
usage : BufferUsage.STATIC_DRAW
|
|
}),
|
|
componentsPerAttribute : 4
|
|
}]
|
|
});
|
|
|
|
if (clear) {
|
|
ClearCommand.ALL.execute(context);
|
|
clearColor = context.readPixels();
|
|
}
|
|
|
|
var command = new DrawCommand({
|
|
primitiveType : PrimitiveType.POINTS,
|
|
shaderProgram : sp,
|
|
vertexArray : va,
|
|
uniformMap : uniformMap,
|
|
modelMatrix : modelMatrix
|
|
});
|
|
|
|
command.execute(context);
|
|
var rgba = context.readPixels();
|
|
|
|
sp = sp.destroy();
|
|
va = va.destroy();
|
|
|
|
return {
|
|
color : rgba,
|
|
clearColor : clearColor
|
|
};
|
|
}
|
|
|
|
function expectContextToRender(actual, expected, expectEqual) {
|
|
var options = actual;
|
|
var context = options.context;
|
|
var clear = defaultValue(options.clear, true);
|
|
var epsilon = defaultValue(options.epsilon, 0);
|
|
|
|
if (!defined(expected)) {
|
|
expected = [255, 255, 255, 255];
|
|
}
|
|
|
|
var webglStub = !!window.webglStub;
|
|
|
|
var output = contextRenderAndReadPixels(options);
|
|
|
|
if (clear) {
|
|
var clearedRgba = output.clearColor;
|
|
if (!webglStub) {
|
|
var expectedAlpha = context.options.webgl.alpha ? 0 : 255;
|
|
if ((clearedRgba[0] !== 0) ||
|
|
(clearedRgba[1] !== 0) ||
|
|
(clearedRgba[2] !== 0) ||
|
|
(clearedRgba[3] !== expectedAlpha)) {
|
|
return {
|
|
pass : false,
|
|
message : 'After clearing the framebuffer, expected context to render [0, 0, 0, ' + expectedAlpha + '], but rendered: ' + clearedRgba
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
var rgba = output.color;
|
|
|
|
if (!webglStub) {
|
|
if (expectEqual) {
|
|
if (!CesiumMath.equalsEpsilon(rgba[0], expected[0], 0, epsilon) ||
|
|
!CesiumMath.equalsEpsilon(rgba[1], expected[1], 0, epsilon) ||
|
|
!CesiumMath.equalsEpsilon(rgba[2], expected[2], 0, epsilon) ||
|
|
!CesiumMath.equalsEpsilon(rgba[3], expected[3], 0, epsilon)) {
|
|
return {
|
|
pass : false,
|
|
message : 'Expected context to render ' + expected + ', but rendered: ' + rgba
|
|
};
|
|
}
|
|
} else if (CesiumMath.equalsEpsilon(rgba[0], expected[0], 0, epsilon) &&
|
|
CesiumMath.equalsEpsilon(rgba[1], expected[1], 0, epsilon) &&
|
|
CesiumMath.equalsEpsilon(rgba[2], expected[2], 0, epsilon) &&
|
|
CesiumMath.equalsEpsilon(rgba[3], expected[3], 0, epsilon)) {
|
|
return {
|
|
pass : false,
|
|
message : 'Expected context not to render ' + expected + ', but rendered: ' + rgba
|
|
};
|
|
}
|
|
}
|
|
|
|
return {
|
|
pass : true
|
|
};
|
|
}
|
|
|
|
return function(debug) {
|
|
return function() {
|
|
this.addMatchers(createDefaultMatchers(debug));
|
|
};
|
|
};
|
|
});
|