import { Cartesian3 } from "../../Source/Cesium.js"; import { Color } from "../../Source/Cesium.js"; import { defined } from "../../Source/Cesium.js"; import { PixelFormat } from "../../Source/Cesium.js"; import { Resource } from "../../Source/Cesium.js"; import { ClearCommand } from "../../Source/Cesium.js"; import { ContextLimits } from "../../Source/Cesium.js"; import { CubeMap } from "../../Source/Cesium.js"; import { PixelDatatype } from "../../Source/Cesium.js"; import { Sampler } from "../../Source/Cesium.js"; import { Texture } from "../../Source/Cesium.js"; import { TextureMagnificationFilter } from "../../Source/Cesium.js"; import { TextureMinificationFilter } from "../../Source/Cesium.js"; import { TextureWrap } from "../../Source/Cesium.js"; import createContext from "../createContext.js"; import { when } from "../../Source/Cesium.js"; describe( "Renderer/CubeMap", function () { var context; var cubeMap; function expectCubeMapFaces(options) { var cubeMap = options.cubeMap; var expectedColors = options.expectedColors; var fs = "uniform samplerCube u_texture;" + "uniform mediump vec3 u_direction;" + "void main() { gl_FragColor = textureCube(u_texture, normalize(u_direction)); }"; var faceDirections = options.faceDirections; if (!defined(faceDirections)) { faceDirections = [ new Cartesian3(1.0, 0.0, 0.0), // +X new Cartesian3(-1.0, 0.0, 0.0), // -X new Cartesian3(0.0, 1.0, 0.0), // +Y new Cartesian3(0.0, -1.0, 0.0), // -Y new Cartesian3(0.0, 0.0, 1.0), // +Z new Cartesian3(0.0, 0.0, -1.0), // -Z ]; } var uniformMap = { direction: undefined, u_texture: function () { return cubeMap; }, u_direction: function () { return this.direction; }, }; for (var i = 0; i < 6; ++i) { uniformMap.direction = faceDirections[i]; expect({ context: context, fragmentShader: fs, uniformMap: uniformMap, epsilon: options.epsilon, }).contextToRender(expectedColors[i]); } } var greenImage; var blueImage; var blueAlphaImage; var blueOverRedImage; var red16x16Image; beforeAll(function () { context = createContext(); var promises = []; promises.push( Resource.fetchImage("./Data/Images/Green.png").then(function (result) { greenImage = result; }) ); promises.push( Resource.fetchImage("./Data/Images/Blue.png").then(function (result) { blueImage = result; }) ); promises.push( Resource.fetchImage("./Data/Images/BlueAlpha.png").then(function ( result ) { blueAlphaImage = result; }) ); promises.push( Resource.fetchImage("./Data/Images/BlueOverRed.png").then(function ( result ) { blueOverRedImage = result; }) ); promises.push( Resource.fetchImage("./Data/Images/Red16x16.png").then(function ( result ) { red16x16Image = result; }) ); return when.all(promises); }); afterAll(function () { context.destroyForSpecs(); }); afterEach(function () { cubeMap = cubeMap && cubeMap.destroy(); }); it("gets the pixel format", function () { cubeMap = new CubeMap({ context: context, width: 16, height: 16, }); expect(cubeMap.pixelFormat).toEqual(PixelFormat.RGBA); expect(cubeMap.positiveX.pixelFormat).toEqual(PixelFormat.RGBA); expect(cubeMap.negativeX.pixelFormat).toEqual(PixelFormat.RGBA); expect(cubeMap.positiveY.pixelFormat).toEqual(PixelFormat.RGBA); expect(cubeMap.negativeY.pixelFormat).toEqual(PixelFormat.RGBA); expect(cubeMap.positiveZ.pixelFormat).toEqual(PixelFormat.RGBA); expect(cubeMap.negativeZ.pixelFormat).toEqual(PixelFormat.RGBA); }); it("gets the pixel datatype", function () { cubeMap = new CubeMap({ context: context, width: 16, height: 16, }); expect(cubeMap.pixelDatatype).toEqual(PixelDatatype.UNSIGNED_BYTE); expect(cubeMap.positiveX.pixelDatatype).toEqual( PixelDatatype.UNSIGNED_BYTE ); expect(cubeMap.negativeX.pixelDatatype).toEqual( PixelDatatype.UNSIGNED_BYTE ); expect(cubeMap.positiveY.pixelDatatype).toEqual( PixelDatatype.UNSIGNED_BYTE ); expect(cubeMap.negativeY.pixelDatatype).toEqual( PixelDatatype.UNSIGNED_BYTE ); expect(cubeMap.positiveZ.pixelDatatype).toEqual( PixelDatatype.UNSIGNED_BYTE ); expect(cubeMap.negativeZ.pixelDatatype).toEqual( PixelDatatype.UNSIGNED_BYTE ); }); it("sets a sampler", function () { cubeMap = new CubeMap({ context: context, width: 16, height: 16, }); var sampler = new Sampler({ wrapS: TextureWrap.REPEAT, wrapT: TextureWrap.MIRRORED_REPEAT, minificationFilter: TextureMinificationFilter.NEAREST, magnificationFilter: TextureMagnificationFilter.NEAREST, }); cubeMap.sampler = sampler; var s = cubeMap.sampler; expect(s.wrapS).toEqual(sampler.wrapS); expect(s.wrapT).toEqual(sampler.wrapT); expect(s.minificationFilter).toEqual(sampler.minificationFilter); expect(s.magnificationFilter).toEqual(sampler.magnificationFilter); }); it("gets width and height", function () { cubeMap = new CubeMap({ context: context, width: 16, height: 16, }); expect(cubeMap.width).toEqual(16); expect(cubeMap.height).toEqual(16); }); it("gets size in bytes", function () { cubeMap = new CubeMap({ context: context, width: 16, height: 16, }); expect(cubeMap.sizeInBytes).toEqual(256 * 4 * 6); }); it("gets flip Y", function () { cubeMap = new CubeMap({ context: context, width: 16, height: 16, flipY: true, }); expect(cubeMap.flipY).toEqual(true); }); it("draws with a cube map", function () { cubeMap = new CubeMap({ context: context, source: { positiveX: blueImage, negativeX: greenImage, positiveY: blueImage, negativeY: greenImage, positiveZ: blueImage, negativeZ: greenImage, }, }); expectCubeMapFaces({ cubeMap: cubeMap, expectedColors: [ [0, 0, 255, 255], // +X is blue [0, 255, 0, 255], // -X is green [0, 0, 255, 255], // +Y is blue [0, 255, 0, 255], // -Y is green [0, 0, 255, 255], // +Z is blue [0, 255, 0, 255], // -Z is green ], }); }); it("draws with a cube map with premultiplied alpha", function () { cubeMap = new CubeMap({ context: context, source: { positiveX: blueAlphaImage, negativeX: blueAlphaImage, positiveY: blueAlphaImage, negativeY: blueAlphaImage, positiveZ: blueAlphaImage, negativeZ: blueAlphaImage, }, preMultiplyAlpha: true, }); expect(cubeMap.preMultiplyAlpha).toEqual(true); expectCubeMapFaces({ cubeMap: cubeMap, epsilon: 1, expectedColors: [ [0, 0, 127, 255], // +X [0, 0, 127, 255], // -X [0, 0, 127, 255], // +Y [0, 0, 127, 255], // -Y [0, 0, 127, 255], // +Z [0, 0, 127, 255], // -Z ], }); }); it("draws the context default cube map", function () { expectCubeMapFaces({ cubeMap: context.defaultCubeMap, expectedColors: [ [255, 255, 255, 255], // +X [255, 255, 255, 255], // -X [255, 255, 255, 255], // +Y [255, 255, 255, 255], // -Y [255, 255, 255, 255], // +Z [255, 255, 255, 255], // -Z ], }); }); it("creates a cube map with typed arrays", function () { cubeMap = new CubeMap({ context: context, source: { positiveX: { width: 1, height: 1, arrayBufferView: new Uint8Array([0, 255, 255, 255]), }, negativeX: { width: 1, height: 1, arrayBufferView: new Uint8Array([0, 0, 255, 255]), }, positiveY: { width: 1, height: 1, arrayBufferView: new Uint8Array([0, 255, 0, 255]), }, negativeY: { width: 1, height: 1, arrayBufferView: new Uint8Array([255, 0, 0, 255]), }, positiveZ: { width: 1, height: 1, arrayBufferView: new Uint8Array([255, 0, 255, 255]), }, negativeZ: { width: 1, height: 1, arrayBufferView: new Uint8Array([255, 255, 0, 255]), }, }, }); expectCubeMapFaces({ cubeMap: cubeMap, expectedColors: [ [0, 255, 255, 255], // +X [0, 0, 255, 255], // -X [0, 255, 0, 255], // +Y [255, 0, 0, 255], // -Y [255, 0, 255, 255], // +Z [255, 255, 0, 255], // -Z ], }); }); it("creates a cube map with floating-point textures", function () { if (!context.floatingPointTexture) { return; } var positiveXColor = new Color(0.0, 1.0, 1.0, 1.0); var negativeXColor = new Color(0.0, 0.0, 1.0, 1.0); var positiveYColor = new Color(0.0, 1.0, 0.0, 1.0); var negativeYColor = new Color(1.0, 0.0, 0.0, 1.0); var positiveZColor = new Color(1.0, 0.0, 1.0, 1.0); var negativeZColor = new Color(1.0, 1.0, 0.0, 1.0); cubeMap = new CubeMap({ context: context, source: { positiveX: { width: 1, height: 1, arrayBufferView: new Float32Array([ positiveXColor.red, positiveXColor.green, positiveXColor.blue, positiveXColor.alpha, ]), }, negativeX: { width: 1, height: 1, arrayBufferView: new Float32Array([ negativeXColor.red, negativeXColor.green, negativeXColor.blue, negativeXColor.alpha, ]), }, positiveY: { width: 1, height: 1, arrayBufferView: new Float32Array([ positiveYColor.red, positiveYColor.green, positiveYColor.blue, positiveYColor.alpha, ]), }, negativeY: { width: 1, height: 1, arrayBufferView: new Float32Array([ negativeYColor.red, negativeYColor.green, negativeYColor.blue, negativeYColor.alpha, ]), }, positiveZ: { width: 1, height: 1, arrayBufferView: new Float32Array([ positiveZColor.red, positiveZColor.green, positiveZColor.blue, positiveZColor.alpha, ]), }, negativeZ: { width: 1, height: 1, arrayBufferView: new Float32Array([ negativeZColor.red, negativeZColor.green, negativeZColor.blue, negativeZColor.alpha, ]), }, }, pixelDatatype: PixelDatatype.FLOAT, }); expectCubeMapFaces({ cubeMap: cubeMap, expectedColors: [ [0, 255, 255, 255], // +X [0, 0, 255, 255], // -X [0, 255, 0, 255], // +Y [255, 0, 0, 255], // -Y [255, 0, 255, 255], // +Z [255, 255, 0, 255], // -Z ], }); }); it("creates a cube map with floating-point textures and linear filtering", function () { if (!context.floatingPointTexture) { return; } var positiveXColor = new Color(0.0, 1.0, 1.0, 1.0); var negativeXColor = new Color(0.0, 0.0, 1.0, 1.0); var positiveYColor = new Color(0.0, 1.0, 0.0, 1.0); var negativeYColor = new Color(1.0, 0.0, 0.0, 1.0); var positiveZColor = new Color(1.0, 0.0, 1.0, 1.0); var negativeZColor = new Color(1.0, 1.0, 0.0, 1.0); cubeMap = new CubeMap({ context: context, source: { positiveX: { width: 1, height: 1, arrayBufferView: new Float32Array([ positiveXColor.red, positiveXColor.green, positiveXColor.blue, positiveXColor.alpha, ]), }, negativeX: { width: 1, height: 1, arrayBufferView: new Float32Array([ negativeXColor.red, negativeXColor.green, negativeXColor.blue, negativeXColor.alpha, ]), }, positiveY: { width: 1, height: 1, arrayBufferView: new Float32Array([ positiveYColor.red, positiveYColor.green, positiveYColor.blue, positiveYColor.alpha, ]), }, negativeY: { width: 1, height: 1, arrayBufferView: new Float32Array([ negativeYColor.red, negativeYColor.green, negativeYColor.blue, negativeYColor.alpha, ]), }, positiveZ: { width: 1, height: 1, arrayBufferView: new Float32Array([ positiveZColor.red, positiveZColor.green, positiveZColor.blue, positiveZColor.alpha, ]), }, negativeZ: { width: 1, height: 1, arrayBufferView: new Float32Array([ negativeZColor.red, negativeZColor.green, negativeZColor.blue, negativeZColor.alpha, ]), }, }, pixelDatatype: PixelDatatype.FLOAT, sampler: new Sampler({ wrapS: TextureWrap.CLAMP_TO_EDGE, wrapT: TextureWrap.CLAMP_TO_EDGE, minificationFilter: TextureMinificationFilter.LINEAR, magnificationFilter: TextureMagnificationFilter.LINEAR, }), }); var fs = "uniform samplerCube u_texture;" + "void main() { gl_FragColor = textureCube(u_texture, normalize(vec3(1.0, 1.0, 0.0))); }"; var uniformMap = { u_texture: function () { return cubeMap; }, }; if (!context.textureFloatLinear) { expect({ context: context, fragmentShader: fs, uniformMap: uniformMap, epsilon: 1, }).contextToRender(positiveYColor.toBytes()); } else { Color.multiplyByScalar(positiveXColor, 1.0 - 0.5, positiveXColor); Color.multiplyByScalar(positiveYColor, 0.5, positiveYColor); var color = Color.add(positiveXColor, positiveYColor, positiveXColor); expect({ context: context, fragmentShader: fs, uniformMap: uniformMap, epsilon: 1, }).contextToRender(color.toBytes()); } }); it("creates a cube map with half floating-point textures", function () { if (!context.halfFloatingPointTexture) { return; } var positiveXFloats = [12902, 13926, 14541, 15360]; var negativeXFloats = [13926, 12902, 14541, 15360]; var positiveYFloats = [14541, 13926, 12902, 15360]; var negativeYFloats = [12902, 14541, 13926, 15360]; var positiveZFloats = [13926, 14541, 12902, 15360]; var negativeZFloats = [14541, 12902, 13926, 15360]; var positiveXColor = new Color(0.2, 0.4, 0.6, 1.0); var negativeXColor = new Color(0.4, 0.2, 0.6, 1.0); var positiveYColor = new Color(0.6, 0.4, 0.2, 1.0); var negativeYColor = new Color(0.2, 0.6, 0.4, 1.0); var positiveZColor = new Color(0.4, 0.6, 0.2, 1.0); var negativeZColor = new Color(0.6, 0.2, 0.4, 1.0); cubeMap = new CubeMap({ context: context, source: { positiveX: { width: 1, height: 1, arrayBufferView: new Uint16Array(positiveXFloats), }, negativeX: { width: 1, height: 1, arrayBufferView: new Uint16Array(negativeXFloats), }, positiveY: { width: 1, height: 1, arrayBufferView: new Uint16Array(positiveYFloats), }, negativeY: { width: 1, height: 1, arrayBufferView: new Uint16Array(negativeYFloats), }, positiveZ: { width: 1, height: 1, arrayBufferView: new Uint16Array(positiveZFloats), }, negativeZ: { width: 1, height: 1, arrayBufferView: new Uint16Array(negativeZFloats), }, }, pixelDatatype: PixelDatatype.HALF_FLOAT, }); expectCubeMapFaces({ cubeMap: cubeMap, expectedColors: [ positiveXColor.toBytes(), negativeXColor.toBytes(), positiveYColor.toBytes(), negativeYColor.toBytes(), positiveZColor.toBytes(), negativeZColor.toBytes(), ], }); }); it("creates a cube map with half floating-point textures and linear filtering", function () { if (!context.halfFloatingPointTexture) { return; } var positiveXFloats = [12902, 13926, 14541, 15360]; var negativeXFloats = [13926, 12902, 14541, 15360]; var positiveYFloats = [14541, 13926, 12902, 15360]; var negativeYFloats = [12902, 14541, 13926, 15360]; var positiveZFloats = [13926, 14541, 12902, 15360]; var negativeZFloats = [14541, 12902, 13926, 15360]; var positiveXColor = new Color(0.2, 0.4, 0.6, 1.0); var positiveYColor = new Color(0.6, 0.4, 0.2, 1.0); cubeMap = new CubeMap({ context: context, source: { positiveX: { width: 1, height: 1, arrayBufferView: new Uint16Array(positiveXFloats), }, negativeX: { width: 1, height: 1, arrayBufferView: new Uint16Array(negativeXFloats), }, positiveY: { width: 1, height: 1, arrayBufferView: new Uint16Array(positiveYFloats), }, negativeY: { width: 1, height: 1, arrayBufferView: new Uint16Array(negativeYFloats), }, positiveZ: { width: 1, height: 1, arrayBufferView: new Uint16Array(positiveZFloats), }, negativeZ: { width: 1, height: 1, arrayBufferView: new Uint16Array(negativeZFloats), }, }, pixelDatatype: PixelDatatype.HALF_FLOAT, sampler: new Sampler({ wrapS: TextureWrap.CLAMP_TO_EDGE, wrapT: TextureWrap.CLAMP_TO_EDGE, minificationFilter: TextureMinificationFilter.LINEAR, magnificationFilter: TextureMagnificationFilter.LINEAR, }), }); var fs = "uniform samplerCube u_texture;" + "void main() { gl_FragColor = textureCube(u_texture, normalize(vec3(1.0, 1.0, 0.0))); }"; var uniformMap = { u_texture: function () { return cubeMap; }, }; if (!context.textureHalfFloatLinear) { expect({ context: context, fragmentShader: fs, uniformMap: uniformMap, epsilon: 1, }).contextToRender(positiveYColor.toBytes()); } else { Color.multiplyByScalar(positiveXColor, 1.0 - 0.5, positiveXColor); Color.multiplyByScalar(positiveYColor, 0.5, positiveYColor); var color = Color.add(positiveXColor, positiveYColor, positiveXColor); expect({ context: context, fragmentShader: fs, uniformMap: uniformMap, epsilon: 1, }).contextToRender(color.toBytes()); } }); it("creates a cube map with typed arrays and images", function () { cubeMap = new CubeMap({ context: context, source: { positiveX: blueImage, negativeX: greenImage, positiveY: { width: 1, height: 1, arrayBufferView: new Uint8Array([0, 255, 0, 255]), }, negativeY: { width: 1, height: 1, arrayBufferView: new Uint8Array([255, 0, 0, 255]), }, positiveZ: { width: 1, height: 1, arrayBufferView: new Uint8Array([0, 0, 255, 255]), }, negativeZ: { width: 1, height: 1, arrayBufferView: new Uint8Array([255, 255, 0, 255]), }, }, }); expectCubeMapFaces({ cubeMap: cubeMap, expectedColors: [ [0, 0, 255, 255], // +X [0, 255, 0, 255], // -X [0, 255, 0, 255], // +Y [255, 0, 0, 255], // -Y [0, 0, 255, 255], // +Z [255, 255, 0, 255], // -Z ], }); }); it("copies to a cube map", function () { cubeMap = new CubeMap({ context: context, width: 1, height: 1, }); cubeMap.positiveX.copyFrom(blueImage); cubeMap.negativeX.copyFrom(greenImage); cubeMap.positiveY.copyFrom(blueImage); cubeMap.negativeY.copyFrom(greenImage); cubeMap.positiveZ.copyFrom(blueImage); cubeMap.negativeZ.copyFrom(greenImage); expectCubeMapFaces({ cubeMap: cubeMap, expectedColors: [ [0, 0, 255, 255], // +X [0, 255, 0, 255], // -X [0, 0, 255, 255], // +Y [0, 255, 0, 255], // -Y [0, 0, 255, 255], // +Z [0, 255, 0, 255], // -Z ], }); }); it("copies from a typed array", function () { cubeMap = new CubeMap({ context: context, width: 1, height: 1, }); cubeMap.positiveX.copyFrom({ width: 1, height: 1, arrayBufferView: new Uint8Array([0, 255, 255, 255]), }); cubeMap.negativeX.copyFrom({ width: 1, height: 1, arrayBufferView: new Uint8Array([0, 0, 255, 255]), }); cubeMap.positiveY.copyFrom({ width: 1, height: 1, arrayBufferView: new Uint8Array([0, 255, 0, 255]), }); cubeMap.negativeY.copyFrom({ width: 1, height: 1, arrayBufferView: new Uint8Array([255, 0, 0, 255]), }); cubeMap.positiveZ.copyFrom({ width: 1, height: 1, arrayBufferView: new Uint8Array([255, 0, 255, 255]), }); cubeMap.negativeZ.copyFrom({ width: 1, height: 1, arrayBufferView: new Uint8Array([255, 255, 0, 255]), }); expectCubeMapFaces({ cubeMap: cubeMap, expectedColors: [ [0, 255, 255, 255], // +X [0, 0, 255, 255], // -X [0, 255, 0, 255], // +Y [255, 0, 0, 255], // -Y [255, 0, 255, 255], // +Z [255, 255, 0, 255], // -Z ], }); }); it("sub copies images to a cube map", function () { cubeMap = new CubeMap({ context: context, width: 2, height: 2, }); cubeMap.positiveX.copyFrom({ width: 1, height: 1, arrayBufferView: new Uint8Array([0, 255, 255, 255]), }); cubeMap.negativeX.copyFrom({ width: 1, height: 1, arrayBufferView: new Uint8Array([0, 0, 255, 255]), }); cubeMap.positiveY.copyFrom({ width: 1, height: 1, arrayBufferView: new Uint8Array([0, 255, 0, 255]), }); cubeMap.negativeY.copyFrom({ width: 1, height: 1, arrayBufferView: new Uint8Array([255, 0, 0, 255]), }); cubeMap.positiveZ.copyFrom({ width: 1, height: 1, arrayBufferView: new Uint8Array([255, 0, 255, 255]), }); cubeMap.negativeZ.copyFrom( { width: 1, height: 1, arrayBufferView: new Uint8Array([0, 255, 0, 255]), }, 1, 0 ); var negativeZDirection = new Cartesian3(0.25, 0.0, -1.0); Cartesian3.normalize(negativeZDirection, negativeZDirection); expectCubeMapFaces({ cubeMap: cubeMap, expectedColors: [ [0, 64, 64, 255], // +X [0, 0, 64, 255], // -X [0, 64, 0, 255], // +Y [64, 0, 0, 255], // -Y [64, 0, 64, 255], // +Z [0, 32, 0, 255], // -Z ], faceDirections: [ new Cartesian3(1.0, 0.0, 0.0), // +X new Cartesian3(-1.0, 0.0, 0.0), // -X new Cartesian3(0.0, 1.0, 0.0), // +Y new Cartesian3(0.0, -1.0, 0.0), // -Y new Cartesian3(0.0, 0.0, 1.0), // +Z negativeZDirection, // -Z ], }); }); it("sub copies array buffers to a cube map", function () { cubeMap = new CubeMap({ context: context, width: 2, height: 2, }); cubeMap.positiveX.copyFrom(blueImage); cubeMap.negativeX.copyFrom(greenImage); cubeMap.positiveY.copyFrom(blueImage); cubeMap.negativeY.copyFrom(greenImage); cubeMap.positiveZ.copyFrom(blueImage); cubeMap.negativeZ.copyFrom(greenImage, 1, 0); var negativeZDirection = new Cartesian3(0.25, 0.0, -1.0); Cartesian3.normalize(negativeZDirection, negativeZDirection); expectCubeMapFaces({ cubeMap: cubeMap, expectedColors: [ [0, 0, 64, 255], // +X [0, 64, 0, 255], // -X [0, 0, 64, 255], // +Y [0, 64, 0, 255], // -Y [0, 0, 64, 255], // +Z [0, 32, 0, 255], // -Z ], faceDirections: [ new Cartesian3(1.0, 0.0, 0.0), // +X new Cartesian3(-1.0, 0.0, 0.0), // -X new Cartesian3(0.0, 1.0, 0.0), // +Y new Cartesian3(0.0, -1.0, 0.0), // -Y new Cartesian3(0.0, 0.0, 1.0), // +Z negativeZDirection, // -Z ], }); }); it("copies from the framebuffer", function () { var cxt = createContext({ webgl: { alpha: true, // Seems to be required for copyFromFramebuffer() }, }); cubeMap = new CubeMap({ context: cxt, width: 1, height: 1, }); cubeMap.positiveX.copyFrom(blueImage); var fs = "uniform samplerCube u_cubeMap;" + "void main() { gl_FragColor = textureCube(u_cubeMap, vec3(1.0, 0.0, 0.0)); }"; var uniformMap = { u_cubeMap: function () { return cubeMap; }, }; // +X is blue expect({ context: cxt, fragmentShader: fs, uniformMap: uniformMap, }).contextToRender([0, 0, 255, 255]); // Clear framebuffer to red and copy to +X face var clearCommand = new ClearCommand({ color: new Color(1.0, 0.0, 0.0, 1.0), }); clearCommand.execute(cxt); expect(cxt).toReadPixels([255, 0, 0, 255]); cubeMap.positiveX.copyFromFramebuffer(); ClearCommand.ALL.execute(cxt); expect(cxt).toReadPixels([0, 0, 0, 0]); // +X is red now expect({ context: cxt, fragmentShader: fs, uniformMap: uniformMap, }).contextToRender([255, 0, 0, 255]); cxt.destroyForSpecs(); }); it("draws with a cube map and a texture", function () { cubeMap = new CubeMap({ context: context, source: { positiveX: greenImage, negativeX: greenImage, positiveY: greenImage, negativeY: greenImage, positiveZ: greenImage, negativeZ: greenImage, }, }); var texture = new Texture({ context: context, source: blueImage, }); var fs = "uniform samplerCube u_cubeMap;" + "uniform sampler2D u_texture;" + "void main() { gl_FragColor = textureCube(u_cubeMap, vec3(1.0, 0.0, 0.0)) + texture2D(u_texture, vec2(0.0)); }"; var uniformMap = { u_cubeMap: function () { return cubeMap; }, u_texture: function () { return texture; }, }; expect({ context: context, fragmentShader: fs, uniformMap: uniformMap, }).contextToRender([0, 255, 255, 255]); texture = texture.destroy(); }); it("generates mipmaps", function () { cubeMap = new CubeMap({ context: context, source: { positiveX: blueImage, negativeX: greenImage, positiveY: blueImage, negativeY: greenImage, positiveZ: blueImage, negativeZ: greenImage, }, }); cubeMap.generateMipmap(); cubeMap.sampler = new Sampler({ minificationFilter: TextureMinificationFilter.NEAREST_MIPMAP_LINEAR, }); var fs = "uniform samplerCube u_cubeMap;" + "void main() { gl_FragColor = textureCube(u_cubeMap, vec3(1.0, 0.0, 0.0)); }"; var uniformMap = { u_cubeMap: function () { return cubeMap; }, }; expect({ context: context, fragmentShader: fs, uniformMap: uniformMap, }).contextToRender([0, 0, 255, 255]); }); it("gets size in bytes for mipmap", function () { cubeMap = new CubeMap({ context: context, source: { positiveX: red16x16Image, negativeX: red16x16Image, positiveY: red16x16Image, negativeY: red16x16Image, positiveZ: red16x16Image, negativeZ: red16x16Image, }, }); cubeMap.generateMipmap(); // Allow for some leniency with the sizeInBytes approximation expect(cubeMap.sizeInBytes).toEqualEpsilon( (16 * 16 + 8 * 8 + 4 * 4 + 2 * 2 + 1) * 4 * 6, 10 ); }); it("destroys", function () { var c = new CubeMap({ context: context, width: 16, height: 16, }); expect(c.isDestroyed()).toEqual(false); c.destroy(); expect(c.isDestroyed()).toEqual(true); }); it("fails to create (options)", function () { expect(function () { cubeMap = new CubeMap(); }).toThrowDeveloperError(); }); it("fails to create (source)", function () { expect(function () { cubeMap = new CubeMap({ context: context, }); }).toThrowDeveloperError(); }); it("fails to create (width, no height)", function () { expect(function () { cubeMap = new CubeMap({ context: context, width: 16, }); }).toThrowDeveloperError(); }); it("fails to create (width != height)", function () { expect(function () { cubeMap = new CubeMap({ context: context, width: 16, height: 32, }); }).toThrowDeveloperError(); }); it("fails to create (small width)", function () { expect(function () { cubeMap = new CubeMap({ context: context, width: 0, height: 0, }); }).toThrowDeveloperError(); }); it("fails to create (large width)", function () { expect(function () { cubeMap = new CubeMap({ context: context, width: ContextLimits.maximumCubeMapSize + 1, height: ContextLimits.maximumCubeMapSize + 1, }); }).toThrowDeveloperError(); }); it("fails to create (PixelFormat)", function () { expect(function () { cubeMap = new CubeMap({ context: context, width: 16, height: 16, pixelFormat: "invalid PixelFormat", }); }).toThrowDeveloperError(); }); it("throws during creation if pixel format is depth or depth-stencil", function () { expect(function () { cubeMap = new CubeMap({ context: context, width: 16, height: 16, pixelFormat: PixelFormat.DEPTH_COMPONENT, }); }).toThrowDeveloperError(); }); it("throws during creation if pixelDatatype is FLOAT, and OES_texture_float is not supported", function () { if (!context.floatingPointTexture) { expect(function () { cubeMap = new CubeMap({ context: context, width: 16, height: 16, pixelDatatype: PixelDatatype.FLOAT, }); }).toThrowDeveloperError(); } }); it("throws during creation if pixelDatatype is HALF_FLOAT, and OES_texture_half_float is not supported", function () { if (!context.halfFloatingPointTexture) { expect(function () { cubeMap = new CubeMap({ context: context, width: 16, height: 16, pixelDatatype: PixelDatatype.HALF_FLOAT, }); }).toThrowDeveloperError(); } }); it("fails to create (pixelDatatype)", function () { expect(function () { cubeMap = new CubeMap({ context: context, width: 16, height: 16, pixelFormat: PixelFormat.RGBA, pixelDatatype: "invalid pixelDatatype", }); }).toThrowDeveloperError(); }); it("fails to create (source)", function () { expect(function () { cubeMap = new CubeMap({ context: context, source: {}, }); }).toThrowDeveloperError(); }); it("fails to create (source width and height)", function () { expect(function () { cubeMap = new CubeMap({ context: context, source: { positiveX: greenImage, // 1x1 negativeX: greenImage, // 1x1 positiveY: greenImage, // 1x1 negativeY: greenImage, // 1x1 positiveZ: greenImage, // 1x1 negativeZ: blueOverRedImage, // 1x2 }, }); }).toThrowDeveloperError(); }); it("fails to copy from an image (source)", function () { cubeMap = new CubeMap({ context: context, width: 16, height: 16, }); expect(function () { cubeMap.positiveX.copyFrom(); }).toThrowDeveloperError(); }); it("fails to copy from an image (xOffset)", function () { cubeMap = new CubeMap({ context: context, width: 16, height: 16, }); var image = new Image(); expect(function () { cubeMap.positiveY.copyFrom(image, -1); }).toThrowDeveloperError(); }); it("fails to copy from an image (yOffset)", function () { cubeMap = new CubeMap({ context: context, width: 16, height: 16, }); var image = new Image(); expect(function () { cubeMap.positiveZ.copyFrom(image, 0, -1); }).toThrowDeveloperError(); }); it("fails to copy from an image (width)", function () { cubeMap = new CubeMap({ context: context, width: 16, height: 16, }); var image = new Image(); image.width = 16 + 1; expect(function () { cubeMap.negativeX.copyFrom(image); }).toThrowDeveloperError(); }); it("fails to copy from an image (height)", function () { cubeMap = new CubeMap({ context: context, width: 16, height: 16, }); var image = new Image(); image.height = 16 + 1; expect(function () { cubeMap.negativeY.copyFrom(image); }).toThrowDeveloperError(); }); it("fails to copy from the framebuffer (invalid data type)", function () { if (context.floatingPointTexture) { cubeMap = new CubeMap({ context: context, width: 1, height: 1, pixelDatatype: PixelDatatype.FLOAT, }); expect(function () { cubeMap.positiveX.copyFromFramebuffer(); }).toThrowDeveloperError(); } }); it("fails to copy from the framebuffer (xOffset)", function () { cubeMap = new CubeMap({ context: context, width: 1, height: 1, }); expect(function () { cubeMap.positiveX.copyFromFramebuffer(-1); }).toThrowDeveloperError(); }); it("fails to copy from the framebuffer (yOffset)", function () { cubeMap = new CubeMap({ context: context, width: 1, height: 1, }); expect(function () { cubeMap.positiveY.copyFromFramebuffer(0, -1); }).toThrowDeveloperError(); }); it("fails to copy from the framebuffer (framebufferXOffset)", function () { cubeMap = new CubeMap({ context: context, width: 1, height: 1, }); expect(function () { cubeMap.positiveZ.copyFromFramebuffer(0, 0, -1); }).toThrowDeveloperError(); }); it("fails to copy from the framebuffer (framebufferYOffset)", function () { cubeMap = new CubeMap({ context: context, width: 1, height: 1, }); expect(function () { cubeMap.negativeX.copyFromFramebuffer(0, 0, 0, -1); }).toThrowDeveloperError(); }); it("fails to copy from the framebuffer (width)", function () { cubeMap = new CubeMap({ context: context, width: 1, height: 1, }); expect(function () { cubeMap.negativeY.copyFromFramebuffer(0, 0, 0, 0, cubeMap.width + 1); }).toThrowDeveloperError(); }); it("fails to copy from the framebuffer (height)", function () { cubeMap = new CubeMap({ context: context, width: 1, height: 1, }); expect(function () { cubeMap.negativeZ.copyFromFramebuffer( 0, 0, 0, 0, 0, cubeMap.height + 1 ); }).toThrowDeveloperError(); }); it("fails to copy from the framebuffer (FLOAT", function () { if (!context.floatingPointTexture) { return; } cubeMap = new CubeMap({ context: context, width: 1, height: 1, pixelDatatype: PixelDatatype.FLOAT, }); expect(function () { cubeMap.negativeX.copyFromFramebuffer(0, 0, 0, 0, 0, 0); }).toThrowDeveloperError(); }); it("fails to copy from the framebuffer (HALF_FLOAT", function () { if (!context.halfFloatingPointTexture) { return; } cubeMap = new CubeMap({ context: context, width: 1, height: 1, pixelDatatype: PixelDatatype.HALF_FLOAT, }); expect(function () { cubeMap.negativeX.copyFromFramebuffer(0, 0, 0, 0, 0, 0); }).toThrowDeveloperError(); }); it("fails to generate mipmaps (width)", function () { cubeMap = new CubeMap({ context: context, width: 3, height: 3, }); expect(function () { cubeMap.generateMipmap(); }).toThrowDeveloperError(); }); it("fails to generate mipmaps (hint)", function () { cubeMap = new CubeMap({ context: context, width: 16, height: 16, }); expect(function () { cubeMap.generateMipmap("invalid hint"); }).toThrowDeveloperError(); }); it("fails to destroy", function () { var c = new CubeMap({ context: context, width: 16, height: 16, }); c.destroy(); expect(function () { c.destroy(); }).toThrowDeveloperError(); }); }, "WebGL" );