diff --git a/CHANGES.md b/CHANGES.md index 1ed8b8576067..e52ca3f0ec38 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -46,6 +46,7 @@ Change Log * Fixed an issue causing the Bing Maps key to be sent unnecessarily with every tile request. [#6250](https://github.com/AnalyticalGraphicsInc/cesium/pull/6250) * Fixed bug with zooming to dynamic geometry. [#6269](https://github.com/AnalyticalGraphicsInc/cesium/issues/6269) * Fixed documentation issue for the `Cesium.Math` class. [#6233](https://github.com/AnalyticalGraphicsInc/cesium/issues/6233) +* Fix Firefox WebGL console warnings. [#5912](https://github.com/AnalyticalGraphicsInc/cesium/issues/5912) ### 1.42.1 - 2018-02-01 _This is an npm-only release to fix an issue with using Cesium in Node.js.__ diff --git a/Source/Core/PixelFormat.js b/Source/Core/PixelFormat.js index 5c01b6999909..6654608f5b21 100644 --- a/Source/Core/PixelFormat.js +++ b/Source/Core/PixelFormat.js @@ -281,6 +281,26 @@ define([ componentsLength = 1; } return componentsLength * PixelDatatype.sizeInBytes(pixelDatatype) * width * height; + }, + + /** + * @private + */ + createTypedArray : function(pixelFormat, pixelDatatype, width, height) { + var constructor; + var sizeInBytes = PixelDatatype.sizeInBytes(pixelDatatype); + if (sizeInBytes === Uint8Array.BYTES_PER_ELEMENT) { + constructor = Uint8Array; + } else if (sizeInBytes === Uint16Array.BYTES_PER_ELEMENT) { + constructor = Uint16Array; + } else if (sizeInBytes === Float32Array.BYTES_PER_ELEMENT && pixelDatatype === PixelDatatype.FLOAT) { + constructor = Float32Array; + } else { + constructor = Uint32Array; + } + + var size = PixelFormat.componentsLength(pixelFormat) * width * height; + return new constructor(size); } }; diff --git a/Source/Renderer/CubeMap.js b/Source/Renderer/CubeMap.js index e08eccd1c718..00a3fe450861 100644 --- a/Source/Renderer/CubeMap.js +++ b/Source/Renderer/CubeMap.js @@ -33,7 +33,6 @@ define([ 'use strict'; function CubeMap(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); //>>includeStart('debug', pragmas.debug); @@ -121,25 +120,29 @@ define([ gl.activeTexture(gl.TEXTURE0); gl.bindTexture(textureTarget, texture); - function createFace(target, sourceFace) { + function createFace(target, sourceFace, preMultiplyAlpha, flipY) { + // TODO: gl.pixelStorei(gl._UNPACK_ALIGNMENT, 4); if (sourceFace.arrayBufferView) { + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); gl.texImage2D(target, 0, pixelFormat, size, size, 0, pixelFormat, pixelDatatype, sourceFace.arrayBufferView); } else { + // Only valid for DOM-Element uploads + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, preMultiplyAlpha); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY); + + // Source: ImageData, HTMLImageElement, HTMLCanvasElement, or HTMLVideoElement gl.texImage2D(target, 0, pixelFormat, pixelFormat, pixelDatatype, sourceFace); } } if (defined(source)) { - // TODO: _gl.pixelStorei(_gl._UNPACK_ALIGNMENT, 4); - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, preMultiplyAlpha); - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY); - - createFace(gl.TEXTURE_CUBE_MAP_POSITIVE_X, source.positiveX); - createFace(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, source.negativeX); - createFace(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, source.positiveY); - createFace(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, source.negativeY); - createFace(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, source.positiveZ); - createFace(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, source.negativeZ); + createFace(gl.TEXTURE_CUBE_MAP_POSITIVE_X, source.positiveX, preMultiplyAlpha, flipY); + createFace(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, source.negativeX, preMultiplyAlpha, flipY); + createFace(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, source.positiveY, preMultiplyAlpha, flipY); + createFace(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, source.negativeY, preMultiplyAlpha, flipY); + createFace(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, source.positiveZ, preMultiplyAlpha, flipY); + createFace(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, source.negativeZ, preMultiplyAlpha, flipY); } else { gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, pixelFormat, size, size, 0, pixelFormat, pixelDatatype, null); gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, pixelFormat, size, size, 0, pixelFormat, pixelDatatype, null); @@ -163,12 +166,13 @@ define([ this._flipY = flipY; this._sampler = undefined; - this._positiveX = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_POSITIVE_X, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY); - this._negativeX = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_NEGATIVE_X, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY); - this._positiveY = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_POSITIVE_Y, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY); - this._negativeY = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY); - this._positiveZ = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_POSITIVE_Z, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY); - this._negativeZ = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY); + var initialized = defined(source); + this._positiveX = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_POSITIVE_X, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY, initialized); + this._negativeX = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_NEGATIVE_X, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY, initialized); + this._positiveY = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_POSITIVE_Y, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY, initialized); + this._negativeY = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY, initialized); + this._positiveZ = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_POSITIVE_Z, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY, initialized); + this._negativeZ = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY, initialized); this.sampler = defined(options.sampler) ? options.sampler : new Sampler(); } diff --git a/Source/Renderer/CubeMapFace.js b/Source/Renderer/CubeMapFace.js index 83e9a165cd73..152cb59c9dfa 100644 --- a/Source/Renderer/CubeMapFace.js +++ b/Source/Renderer/CubeMapFace.js @@ -1,21 +1,25 @@ define([ '../Core/Check', '../Core/defaultValue', + '../Core/defined', '../Core/defineProperties', '../Core/DeveloperError', + '../Core/PixelFormat', './PixelDatatype' ], function( Check, defaultValue, + defined, defineProperties, DeveloperError, + PixelFormat, PixelDatatype) { 'use strict'; /** * @private */ - function CubeMapFace(gl, texture, textureTarget, targetFace, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY) { + function CubeMapFace(gl, texture, textureTarget, targetFace, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY, initialized) { this._gl = gl; this._texture = texture; this._textureTarget = textureTarget; @@ -25,6 +29,7 @@ define([ this._size = size; this._preMultiplyAlpha = preMultiplyAlpha; this._flipY = flipY; + this._initialized = initialized; } defineProperties(CubeMapFace.prototype, { @@ -91,15 +96,52 @@ define([ var target = this._textureTarget; // TODO: gl.pixelStorei(gl._UNPACK_ALIGNMENT, 4); - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this._preMultiplyAlpha); - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this._flipY); + gl.activeTexture(gl.TEXTURE0); gl.bindTexture(target, this._texture); - if (source.arrayBufferView) { - gl.texSubImage2D(this._targetFace, 0, xOffset, yOffset, source.width, source.height, this._pixelFormat, this._pixelDatatype, source.arrayBufferView); - } else { - gl.texSubImage2D(this._targetFace, 0, xOffset, yOffset, this._pixelFormat, this._pixelDatatype, source); + var uploaded = false; + if (!this._initialized) { + if (xOffset === 0 && yOffset === 0 && source.width === this._size && source.height === this._size) { + // initialize the entire texture + if (defined(source.arrayBufferView)) { + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + + gl.texImage2D(this._targetFace, 0, this._pixelFormat, this._size, this._size, 0, this._pixelFormat, this._pixelDatatype, source.arrayBufferView); + } else { + // Only valid for DOM-Element uploads + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this._preMultiplyAlpha); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this._flipY); + + gl.texImage2D(this._targetFace, 0, this._pixelFormat, this._pixelFormat, this._pixelDatatype, source); + } + uploaded = true; + } else { + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + + // initialize the entire texture to zero + var bufferView = PixelFormat.createTypedArray(this._pixelFormat, this._pixelDatatype, this._size, this._size); + gl.texImage2D(this._targetFace, 0, this._pixelFormat, this._size, this._size, 0, this._pixelFormat, this._pixelDatatype, bufferView); + } + this._initialized = true; + } + + if (!uploaded) { + if (source.arrayBufferView) { + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + + gl.texSubImage2D(this._targetFace, 0, xOffset, yOffset, source.width, source.height, this._pixelFormat, this._pixelDatatype, source.arrayBufferView); + } else { + // Only valid for DOM-Element uploads + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this._preMultiplyAlpha); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this._flipY); + + // Source: ImageData, HTMLImageElement, HTMLCanvasElement, or HTMLVideoElement + gl.texSubImage2D(this._targetFace, 0, xOffset, yOffset, this._pixelFormat, this._pixelDatatype, source); + } } gl.bindTexture(target, null); @@ -160,6 +202,7 @@ define([ gl.bindTexture(target, this._texture); gl.copyTexSubImage2D(this._targetFace, 0, xOffset, yOffset, framebufferXOffset, framebufferYOffset, width, height); gl.bindTexture(target, null); + this._initialized = true; }; return CubeMapFace; diff --git a/Source/Renderer/Texture.js b/Source/Renderer/Texture.js index 2ba7284e05c7..9d7387962a41 100644 --- a/Source/Renderer/Texture.js +++ b/Source/Renderer/Texture.js @@ -164,19 +164,22 @@ define([ var preMultiplyAlpha = options.preMultiplyAlpha || pixelFormat === PixelFormat.RGB || pixelFormat === PixelFormat.LUMINANCE; var flipY = defaultValue(options.flipY, true); + var initialized = true; + var gl = context._gl; var textureTarget = gl.TEXTURE_2D; var texture = gl.createTexture(); + // TODO: gl.pixelStorei(gl._UNPACK_ALIGNMENT, 4); + gl.activeTexture(gl.TEXTURE0); gl.bindTexture(textureTarget, texture); if (defined(source)) { - // TODO: _gl.pixelStorei(_gl._UNPACK_ALIGNMENT, 4); - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, preMultiplyAlpha); - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY); - if (defined(source.arrayBufferView)) { + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + // Source: typed array if (isCompressed) { gl.compressedTexImage2D(textureTarget, 0, internalFormat, width, height, 0, source.arrayBufferView); @@ -184,6 +187,9 @@ define([ gl.texImage2D(textureTarget, 0, internalFormat, width, height, 0, pixelFormat, pixelDatatype, source.arrayBufferView); } } else if (defined(source.framebuffer)) { + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + // Source: framebuffer if (source.framebuffer !== context.defaultFramebuffer) { source.framebuffer._bind(); @@ -195,11 +201,16 @@ define([ source.framebuffer._unBind(); } } else { + // Only valid for DOM-Element uploads + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, preMultiplyAlpha); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY); + // Source: ImageData, HTMLImageElement, HTMLCanvasElement, or HTMLVideoElement gl.texImage2D(textureTarget, 0, internalFormat, pixelFormat, pixelDatatype, source); } } else { gl.texImage2D(textureTarget, 0, internalFormat, width, height, 0, pixelFormat, pixelDatatype, null); + initialized = false; } gl.bindTexture(textureTarget, null); @@ -224,6 +235,7 @@ define([ this._sizeInBytes = sizeInBytes; this._preMultiplyAlpha = preMultiplyAlpha; this._flipY = flipY; + this._initialized = initialized; this._sampler = undefined; this.sampler = defined(options.sampler) ? options.sampler : new Sampler(); @@ -469,15 +481,50 @@ define([ var target = this._textureTarget; // TODO: gl.pixelStorei(gl._UNPACK_ALIGNMENT, 4); - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this._preMultiplyAlpha); - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this._flipY); + gl.activeTexture(gl.TEXTURE0); gl.bindTexture(target, this._texture); - if (source.arrayBufferView) { - gl.texSubImage2D(target, 0, xOffset, yOffset, source.width, source.height, this._pixelFormat, this._pixelDatatype, source.arrayBufferView); - } else { - gl.texSubImage2D(target, 0, xOffset, yOffset, this._pixelFormat, this._pixelDatatype, source); + var uploaded = false; + if (!this._initialized) { + if (xOffset === 0 && yOffset === 0 && source.width === this._width && source.height === this._height) { + // initialize the entire texture + if (defined(source.arrayBufferView)) { + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + gl.texImage2D(target, 0, this._pixelFormat, this._width, this._height, 0, this._pixelFormat, this._pixelDatatype, source.arrayBufferView); + } else { + // Only valid for DOM-Element uploads + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this._preMultiplyAlpha); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this._flipY); + + gl.texImage2D(target, 0, this._pixelFormat, this._pixelFormat, this._pixelDatatype, source); + } + uploaded = true; + } else { + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + + // initialize the entire texture to zero + var bufferView = PixelFormat.createTypedArray(this._pixelFormat, this._pixelDatatype, this._width, this._height); + gl.texImage2D(target, 0, this._pixelFormat, this._width, this._height, 0, this._pixelFormat, this._pixelDatatype, bufferView); + } + this._initialized = true; + } + + if (!uploaded) { + if (source.arrayBufferView) { + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + + gl.texSubImage2D(target, 0, xOffset, yOffset, source.width, source.height, this._pixelFormat, this._pixelDatatype, source.arrayBufferView); + } else { + // Only valid for DOM-Element uploads + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this._preMultiplyAlpha); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this._flipY); + + gl.texSubImage2D(target, 0, xOffset, yOffset, this._pixelFormat, this._pixelDatatype, source); + } } gl.bindTexture(target, null); @@ -536,6 +583,7 @@ define([ gl.bindTexture(target, this._texture); gl.copyTexSubImage2D(target, 0, xOffset, yOffset, framebufferXOffset, framebufferYOffset, width, height); gl.bindTexture(target, null); + this._initialized = true; }; /**