diff --git a/src/core/Application.js b/src/core/Application.js index bc730db..ea0f058 100644 --- a/src/core/Application.js +++ b/src/core/Application.js @@ -33,6 +33,9 @@ * need to call toDataUrl on the webgl context * @param {number} [options.resolution=1] - The resolution / device pixel ratio of the renderer, retina would be 2 * @param {boolean} [noWebGL=false] - prevents selection of WebGL renderer, even if such is present + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experience unexplained flickering try setting this to true. + */ constructor(width, height, options, noWebGL) { diff --git a/src/core/Application.js b/src/core/Application.js index bc730db..ea0f058 100644 --- a/src/core/Application.js +++ b/src/core/Application.js @@ -33,6 +33,9 @@ * need to call toDataUrl on the webgl context * @param {number} [options.resolution=1] - The resolution / device pixel ratio of the renderer, retina would be 2 * @param {boolean} [noWebGL=false] - prevents selection of WebGL renderer, even if such is present + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experience unexplained flickering try setting this to true. + */ constructor(width, height, options, noWebGL) { diff --git a/src/core/display/Container.js b/src/core/display/Container.js index b3792ef..ed8cd5f 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -74,12 +74,12 @@ child.parent = this; + this.children.push(child); + // ensure a transform will be recalculated.. this.transform._parentID = -1; this._boundsID++; - this.children.push(child); - // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(this.children.length - 1); child.emit('added', this); @@ -111,6 +111,10 @@ this.children.splice(index, 0, child); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('added', this); @@ -174,6 +178,7 @@ removeItems(this.children, currentIndex, 1); // remove from old position this.children.splice(index, 0, child); // add at new position + this.onChildrenChange(index); } @@ -247,6 +252,10 @@ child.parent = null; removeItems(this.children, index, 1); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('removed', this); @@ -277,6 +286,13 @@ removed[i].parent = null; } + // ensure a transform will be recalculated.. + if (this.transform) + { + this.transform._parentID = -1; + } + this._boundsID++; + this.onChildrenChange(beginIndex); for (let i = 0; i < removed.length; ++i) diff --git a/src/core/Application.js b/src/core/Application.js index bc730db..ea0f058 100644 --- a/src/core/Application.js +++ b/src/core/Application.js @@ -33,6 +33,9 @@ * need to call toDataUrl on the webgl context * @param {number} [options.resolution=1] - The resolution / device pixel ratio of the renderer, retina would be 2 * @param {boolean} [noWebGL=false] - prevents selection of WebGL renderer, even if such is present + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experience unexplained flickering try setting this to true. + */ constructor(width, height, options, noWebGL) { diff --git a/src/core/display/Container.js b/src/core/display/Container.js index b3792ef..ed8cd5f 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -74,12 +74,12 @@ child.parent = this; + this.children.push(child); + // ensure a transform will be recalculated.. this.transform._parentID = -1; this._boundsID++; - this.children.push(child); - // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(this.children.length - 1); child.emit('added', this); @@ -111,6 +111,10 @@ this.children.splice(index, 0, child); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('added', this); @@ -174,6 +178,7 @@ removeItems(this.children, currentIndex, 1); // remove from old position this.children.splice(index, 0, child); // add at new position + this.onChildrenChange(index); } @@ -247,6 +252,10 @@ child.parent = null; removeItems(this.children, index, 1); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('removed', this); @@ -277,6 +286,13 @@ removed[i].parent = null; } + // ensure a transform will be recalculated.. + if (this.transform) + { + this.transform._parentID = -1; + } + this._boundsID++; + this.onChildrenChange(beginIndex); for (let i = 0; i < removed.length; ++i) diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index ce0e1c4..75ae9b5 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -49,11 +49,20 @@ * enable this if you need to call toDataUrl on the webgl context. * @param {boolean} [options.roundPixels=false] - If true Pixi will Math.floor() x/y values when * rendering, stopping pixel interpolation. + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experiance unexplained flickering try setting this to true. */ constructor(width, height, options = {}) { super('WebGL', width, height, options); + this.legacy = !!options.legacy; + + if (this.legacy) + { + glCore.VertexArrayObject.FORCE_NATIVE = true; + } + /** * The type of this renderer as a standardised const * diff --git a/src/core/Application.js b/src/core/Application.js index bc730db..ea0f058 100644 --- a/src/core/Application.js +++ b/src/core/Application.js @@ -33,6 +33,9 @@ * need to call toDataUrl on the webgl context * @param {number} [options.resolution=1] - The resolution / device pixel ratio of the renderer, retina would be 2 * @param {boolean} [noWebGL=false] - prevents selection of WebGL renderer, even if such is present + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experience unexplained flickering try setting this to true. + */ constructor(width, height, options, noWebGL) { diff --git a/src/core/display/Container.js b/src/core/display/Container.js index b3792ef..ed8cd5f 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -74,12 +74,12 @@ child.parent = this; + this.children.push(child); + // ensure a transform will be recalculated.. this.transform._parentID = -1; this._boundsID++; - this.children.push(child); - // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(this.children.length - 1); child.emit('added', this); @@ -111,6 +111,10 @@ this.children.splice(index, 0, child); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('added', this); @@ -174,6 +178,7 @@ removeItems(this.children, currentIndex, 1); // remove from old position this.children.splice(index, 0, child); // add at new position + this.onChildrenChange(index); } @@ -247,6 +252,10 @@ child.parent = null; removeItems(this.children, index, 1); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('removed', this); @@ -277,6 +286,13 @@ removed[i].parent = null; } + // ensure a transform will be recalculated.. + if (this.transform) + { + this.transform._parentID = -1; + } + this._boundsID++; + this.onChildrenChange(beginIndex); for (let i = 0; i < removed.length; ++i) diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index ce0e1c4..75ae9b5 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -49,11 +49,20 @@ * enable this if you need to call toDataUrl on the webgl context. * @param {boolean} [options.roundPixels=false] - If true Pixi will Math.floor() x/y values when * rendering, stopping pixel interpolation. + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experiance unexplained flickering try setting this to true. */ constructor(width, height, options = {}) { super('WebGL', width, height, options); + this.legacy = !!options.legacy; + + if (this.legacy) + { + glCore.VertexArrayObject.FORCE_NATIVE = true; + } + /** * The type of this renderer as a standardised const * diff --git a/src/core/renderers/webgl/utils/RenderTarget.js b/src/core/renderers/webgl/utils/RenderTarget.js index afe51ab..6d2467f 100644 --- a/src/core/renderers/webgl/utils/RenderTarget.js +++ b/src/core/renderers/webgl/utils/RenderTarget.js @@ -124,7 +124,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Whether this object is the root element or not diff --git a/src/core/Application.js b/src/core/Application.js index bc730db..ea0f058 100644 --- a/src/core/Application.js +++ b/src/core/Application.js @@ -33,6 +33,9 @@ * need to call toDataUrl on the webgl context * @param {number} [options.resolution=1] - The resolution / device pixel ratio of the renderer, retina would be 2 * @param {boolean} [noWebGL=false] - prevents selection of WebGL renderer, even if such is present + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experience unexplained flickering try setting this to true. + */ constructor(width, height, options, noWebGL) { diff --git a/src/core/display/Container.js b/src/core/display/Container.js index b3792ef..ed8cd5f 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -74,12 +74,12 @@ child.parent = this; + this.children.push(child); + // ensure a transform will be recalculated.. this.transform._parentID = -1; this._boundsID++; - this.children.push(child); - // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(this.children.length - 1); child.emit('added', this); @@ -111,6 +111,10 @@ this.children.splice(index, 0, child); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('added', this); @@ -174,6 +178,7 @@ removeItems(this.children, currentIndex, 1); // remove from old position this.children.splice(index, 0, child); // add at new position + this.onChildrenChange(index); } @@ -247,6 +252,10 @@ child.parent = null; removeItems(this.children, index, 1); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('removed', this); @@ -277,6 +286,13 @@ removed[i].parent = null; } + // ensure a transform will be recalculated.. + if (this.transform) + { + this.transform._parentID = -1; + } + this._boundsID++; + this.onChildrenChange(beginIndex); for (let i = 0; i < removed.length; ++i) diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index ce0e1c4..75ae9b5 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -49,11 +49,20 @@ * enable this if you need to call toDataUrl on the webgl context. * @param {boolean} [options.roundPixels=false] - If true Pixi will Math.floor() x/y values when * rendering, stopping pixel interpolation. + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experiance unexplained flickering try setting this to true. */ constructor(width, height, options = {}) { super('WebGL', width, height, options); + this.legacy = !!options.legacy; + + if (this.legacy) + { + glCore.VertexArrayObject.FORCE_NATIVE = true; + } + /** * The type of this renderer as a standardised const * diff --git a/src/core/renderers/webgl/utils/RenderTarget.js b/src/core/renderers/webgl/utils/RenderTarget.js index afe51ab..6d2467f 100644 --- a/src/core/renderers/webgl/utils/RenderTarget.js +++ b/src/core/renderers/webgl/utils/RenderTarget.js @@ -124,7 +124,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Whether this object is the root element or not diff --git a/src/core/sprites/Sprite.js b/src/core/sprites/Sprite.js index 36ea5bb..28b0b18 100644 --- a/src/core/sprites/Sprite.js +++ b/src/core/sprites/Sprite.js @@ -346,8 +346,8 @@ /** * Gets the local bounds of the sprite object. * - * @param {Rectangle} rect - The output rectangle. - * @return {Rectangle} The bounds. + * @param {PIXI.Rectangle} rect - The output rectangle. + * @return {PIXI.Rectangle} The bounds. */ getLocalBounds(rect) { @@ -440,7 +440,7 @@ * * @static * @param {number|string|PIXI.BaseTexture|HTMLCanvasElement|HTMLVideoElement} source Source to create texture from - * @return {PIXI.Texture} The newly created texture + * @return {PIXI.Sprite} The newly created texture */ static from(source) { diff --git a/src/core/Application.js b/src/core/Application.js index bc730db..ea0f058 100644 --- a/src/core/Application.js +++ b/src/core/Application.js @@ -33,6 +33,9 @@ * need to call toDataUrl on the webgl context * @param {number} [options.resolution=1] - The resolution / device pixel ratio of the renderer, retina would be 2 * @param {boolean} [noWebGL=false] - prevents selection of WebGL renderer, even if such is present + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experience unexplained flickering try setting this to true. + */ constructor(width, height, options, noWebGL) { diff --git a/src/core/display/Container.js b/src/core/display/Container.js index b3792ef..ed8cd5f 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -74,12 +74,12 @@ child.parent = this; + this.children.push(child); + // ensure a transform will be recalculated.. this.transform._parentID = -1; this._boundsID++; - this.children.push(child); - // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(this.children.length - 1); child.emit('added', this); @@ -111,6 +111,10 @@ this.children.splice(index, 0, child); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('added', this); @@ -174,6 +178,7 @@ removeItems(this.children, currentIndex, 1); // remove from old position this.children.splice(index, 0, child); // add at new position + this.onChildrenChange(index); } @@ -247,6 +252,10 @@ child.parent = null; removeItems(this.children, index, 1); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('removed', this); @@ -277,6 +286,13 @@ removed[i].parent = null; } + // ensure a transform will be recalculated.. + if (this.transform) + { + this.transform._parentID = -1; + } + this._boundsID++; + this.onChildrenChange(beginIndex); for (let i = 0; i < removed.length; ++i) diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index ce0e1c4..75ae9b5 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -49,11 +49,20 @@ * enable this if you need to call toDataUrl on the webgl context. * @param {boolean} [options.roundPixels=false] - If true Pixi will Math.floor() x/y values when * rendering, stopping pixel interpolation. + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experiance unexplained flickering try setting this to true. */ constructor(width, height, options = {}) { super('WebGL', width, height, options); + this.legacy = !!options.legacy; + + if (this.legacy) + { + glCore.VertexArrayObject.FORCE_NATIVE = true; + } + /** * The type of this renderer as a standardised const * diff --git a/src/core/renderers/webgl/utils/RenderTarget.js b/src/core/renderers/webgl/utils/RenderTarget.js index afe51ab..6d2467f 100644 --- a/src/core/renderers/webgl/utils/RenderTarget.js +++ b/src/core/renderers/webgl/utils/RenderTarget.js @@ -124,7 +124,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Whether this object is the root element or not diff --git a/src/core/sprites/Sprite.js b/src/core/sprites/Sprite.js index 36ea5bb..28b0b18 100644 --- a/src/core/sprites/Sprite.js +++ b/src/core/sprites/Sprite.js @@ -346,8 +346,8 @@ /** * Gets the local bounds of the sprite object. * - * @param {Rectangle} rect - The output rectangle. - * @return {Rectangle} The bounds. + * @param {PIXI.Rectangle} rect - The output rectangle. + * @return {PIXI.Rectangle} The bounds. */ getLocalBounds(rect) { @@ -440,7 +440,7 @@ * * @static * @param {number|string|PIXI.BaseTexture|HTMLCanvasElement|HTMLVideoElement} source Source to create texture from - * @return {PIXI.Texture} The newly created texture + * @return {PIXI.Sprite} The newly created texture */ static from(source) { diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 9b349bd..f7cc1a0 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -103,11 +103,18 @@ { const gl = this.renderer.gl; - // step 1: first check max textures the GPU can handle. - this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); + if (this.renderer.legacy) + { + this.MAX_TEXTURES = 1; + } + else + { + // step 1: first check max textures the GPU can handle. + this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); - // step 2: check the maximum number of if statements the shader can have too.. - this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + // step 2: check the maximum number of if statements the shader can have too.. + this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + } const shader = this.shader = generateMultiTextureShader(gl, this.MAX_TEXTURES); diff --git a/src/core/Application.js b/src/core/Application.js index bc730db..ea0f058 100644 --- a/src/core/Application.js +++ b/src/core/Application.js @@ -33,6 +33,9 @@ * need to call toDataUrl on the webgl context * @param {number} [options.resolution=1] - The resolution / device pixel ratio of the renderer, retina would be 2 * @param {boolean} [noWebGL=false] - prevents selection of WebGL renderer, even if such is present + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experience unexplained flickering try setting this to true. + */ constructor(width, height, options, noWebGL) { diff --git a/src/core/display/Container.js b/src/core/display/Container.js index b3792ef..ed8cd5f 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -74,12 +74,12 @@ child.parent = this; + this.children.push(child); + // ensure a transform will be recalculated.. this.transform._parentID = -1; this._boundsID++; - this.children.push(child); - // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(this.children.length - 1); child.emit('added', this); @@ -111,6 +111,10 @@ this.children.splice(index, 0, child); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('added', this); @@ -174,6 +178,7 @@ removeItems(this.children, currentIndex, 1); // remove from old position this.children.splice(index, 0, child); // add at new position + this.onChildrenChange(index); } @@ -247,6 +252,10 @@ child.parent = null; removeItems(this.children, index, 1); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('removed', this); @@ -277,6 +286,13 @@ removed[i].parent = null; } + // ensure a transform will be recalculated.. + if (this.transform) + { + this.transform._parentID = -1; + } + this._boundsID++; + this.onChildrenChange(beginIndex); for (let i = 0; i < removed.length; ++i) diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index ce0e1c4..75ae9b5 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -49,11 +49,20 @@ * enable this if you need to call toDataUrl on the webgl context. * @param {boolean} [options.roundPixels=false] - If true Pixi will Math.floor() x/y values when * rendering, stopping pixel interpolation. + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experiance unexplained flickering try setting this to true. */ constructor(width, height, options = {}) { super('WebGL', width, height, options); + this.legacy = !!options.legacy; + + if (this.legacy) + { + glCore.VertexArrayObject.FORCE_NATIVE = true; + } + /** * The type of this renderer as a standardised const * diff --git a/src/core/renderers/webgl/utils/RenderTarget.js b/src/core/renderers/webgl/utils/RenderTarget.js index afe51ab..6d2467f 100644 --- a/src/core/renderers/webgl/utils/RenderTarget.js +++ b/src/core/renderers/webgl/utils/RenderTarget.js @@ -124,7 +124,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Whether this object is the root element or not diff --git a/src/core/sprites/Sprite.js b/src/core/sprites/Sprite.js index 36ea5bb..28b0b18 100644 --- a/src/core/sprites/Sprite.js +++ b/src/core/sprites/Sprite.js @@ -346,8 +346,8 @@ /** * Gets the local bounds of the sprite object. * - * @param {Rectangle} rect - The output rectangle. - * @return {Rectangle} The bounds. + * @param {PIXI.Rectangle} rect - The output rectangle. + * @return {PIXI.Rectangle} The bounds. */ getLocalBounds(rect) { @@ -440,7 +440,7 @@ * * @static * @param {number|string|PIXI.BaseTexture|HTMLCanvasElement|HTMLVideoElement} source Source to create texture from - * @return {PIXI.Texture} The newly created texture + * @return {PIXI.Sprite} The newly created texture */ static from(source) { diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 9b349bd..f7cc1a0 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -103,11 +103,18 @@ { const gl = this.renderer.gl; - // step 1: first check max textures the GPU can handle. - this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); + if (this.renderer.legacy) + { + this.MAX_TEXTURES = 1; + } + else + { + // step 1: first check max textures the GPU can handle. + this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); - // step 2: check the maximum number of if statements the shader can have too.. - this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + // step 2: check the maximum number of if statements the shader can have too.. + this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + } const shader = this.shader = generateMultiTextureShader(gl, this.MAX_TEXTURES); diff --git a/src/core/text/Text.js b/src/core/text/Text.js index 18fb723..cec8c32 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -191,6 +191,7 @@ if (style.dropShadow) { this.context.shadowBlur = style.dropShadowBlur; + this.context.globalAlpha = style.dropShadowAlpha; if (style.dropShadowBlur > 0) { @@ -239,12 +240,13 @@ } } + // reset the shadow blur and alpha that was set by the drop shadow, for the regular text + this.context.shadowBlur = 0; + this.context.globalAlpha = 1; + // set canvas text styles this.context.fillStyle = this._generateFillStyle(style, lines); - // remove blur if set for the drop shadow - this.context.shadowBlur = 0; - // draw lines line by line for (let i = 0; i < lines.length; i++) { diff --git a/src/core/Application.js b/src/core/Application.js index bc730db..ea0f058 100644 --- a/src/core/Application.js +++ b/src/core/Application.js @@ -33,6 +33,9 @@ * need to call toDataUrl on the webgl context * @param {number} [options.resolution=1] - The resolution / device pixel ratio of the renderer, retina would be 2 * @param {boolean} [noWebGL=false] - prevents selection of WebGL renderer, even if such is present + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experience unexplained flickering try setting this to true. + */ constructor(width, height, options, noWebGL) { diff --git a/src/core/display/Container.js b/src/core/display/Container.js index b3792ef..ed8cd5f 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -74,12 +74,12 @@ child.parent = this; + this.children.push(child); + // ensure a transform will be recalculated.. this.transform._parentID = -1; this._boundsID++; - this.children.push(child); - // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(this.children.length - 1); child.emit('added', this); @@ -111,6 +111,10 @@ this.children.splice(index, 0, child); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('added', this); @@ -174,6 +178,7 @@ removeItems(this.children, currentIndex, 1); // remove from old position this.children.splice(index, 0, child); // add at new position + this.onChildrenChange(index); } @@ -247,6 +252,10 @@ child.parent = null; removeItems(this.children, index, 1); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('removed', this); @@ -277,6 +286,13 @@ removed[i].parent = null; } + // ensure a transform will be recalculated.. + if (this.transform) + { + this.transform._parentID = -1; + } + this._boundsID++; + this.onChildrenChange(beginIndex); for (let i = 0; i < removed.length; ++i) diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index ce0e1c4..75ae9b5 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -49,11 +49,20 @@ * enable this if you need to call toDataUrl on the webgl context. * @param {boolean} [options.roundPixels=false] - If true Pixi will Math.floor() x/y values when * rendering, stopping pixel interpolation. + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experiance unexplained flickering try setting this to true. */ constructor(width, height, options = {}) { super('WebGL', width, height, options); + this.legacy = !!options.legacy; + + if (this.legacy) + { + glCore.VertexArrayObject.FORCE_NATIVE = true; + } + /** * The type of this renderer as a standardised const * diff --git a/src/core/renderers/webgl/utils/RenderTarget.js b/src/core/renderers/webgl/utils/RenderTarget.js index afe51ab..6d2467f 100644 --- a/src/core/renderers/webgl/utils/RenderTarget.js +++ b/src/core/renderers/webgl/utils/RenderTarget.js @@ -124,7 +124,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Whether this object is the root element or not diff --git a/src/core/sprites/Sprite.js b/src/core/sprites/Sprite.js index 36ea5bb..28b0b18 100644 --- a/src/core/sprites/Sprite.js +++ b/src/core/sprites/Sprite.js @@ -346,8 +346,8 @@ /** * Gets the local bounds of the sprite object. * - * @param {Rectangle} rect - The output rectangle. - * @return {Rectangle} The bounds. + * @param {PIXI.Rectangle} rect - The output rectangle. + * @return {PIXI.Rectangle} The bounds. */ getLocalBounds(rect) { @@ -440,7 +440,7 @@ * * @static * @param {number|string|PIXI.BaseTexture|HTMLCanvasElement|HTMLVideoElement} source Source to create texture from - * @return {PIXI.Texture} The newly created texture + * @return {PIXI.Sprite} The newly created texture */ static from(source) { diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 9b349bd..f7cc1a0 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -103,11 +103,18 @@ { const gl = this.renderer.gl; - // step 1: first check max textures the GPU can handle. - this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); + if (this.renderer.legacy) + { + this.MAX_TEXTURES = 1; + } + else + { + // step 1: first check max textures the GPU can handle. + this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); - // step 2: check the maximum number of if statements the shader can have too.. - this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + // step 2: check the maximum number of if statements the shader can have too.. + this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + } const shader = this.shader = generateMultiTextureShader(gl, this.MAX_TEXTURES); diff --git a/src/core/text/Text.js b/src/core/text/Text.js index 18fb723..cec8c32 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -191,6 +191,7 @@ if (style.dropShadow) { this.context.shadowBlur = style.dropShadowBlur; + this.context.globalAlpha = style.dropShadowAlpha; if (style.dropShadowBlur > 0) { @@ -239,12 +240,13 @@ } } + // reset the shadow blur and alpha that was set by the drop shadow, for the regular text + this.context.shadowBlur = 0; + this.context.globalAlpha = 1; + // set canvas text styles this.context.fillStyle = this._generateFillStyle(style, lines); - // remove blur if set for the drop shadow - this.context.shadowBlur = 0; - // draw lines line by line for (let i = 0; i < lines.length; i++) { diff --git a/src/core/text/TextStyle.js b/src/core/text/TextStyle.js index eec2820..890950b 100644 --- a/src/core/text/TextStyle.js +++ b/src/core/text/TextStyle.js @@ -8,6 +8,7 @@ align: 'left', breakWords: false, dropShadow: false, + dropShadowAlpha: 1, dropShadowAngle: Math.PI / 6, dropShadowBlur: 0, dropShadowColor: '#000000', @@ -49,6 +50,7 @@ * @param {boolean} [style.breakWords=false] - Indicates if lines can be wrapped within words, it * needs wordWrap to be set to true * @param {boolean} [style.dropShadow=false] - Set a drop shadow for the text + * @param {number} [style.dropShadowAlpha=1] - Set alpha for the drop shadow * @param {number} [style.dropShadowAngle=Math.PI/6] - Set a angle of the drop shadow * @param {number} [style.dropShadowBlur=0] - Set a shadow blur radius * @param {string} [style.dropShadowColor='#000000'] - A fill style to be used on the dropshadow e.g 'red', '#00FF00' @@ -157,6 +159,19 @@ } } + get dropShadowAlpha() + { + return this._dropShadowAlpha; + } + set dropShadowAlpha(dropShadowAlpha) + { + if (this._dropShadowAlpha !== dropShadowAlpha) + { + this._dropShadowAlpha = dropShadowAlpha; + this.styleID++; + } + } + get dropShadowAngle() { return this._dropShadowAngle; @@ -511,8 +526,8 @@ * Utility function to convert hexadecimal colors to strings, and simply return the color if it's a string. * This version can also convert array of colors * - * @param {Array} array1 First array to compared - * @param {Array} array1 Second array to compare + * @param {Array} array1 First array to compare + * @param {Array} array2 Second array to compare * @return {boolean} Do the arrays contain the same values in the same order */ function areArraysEqual(array1, array2) diff --git a/src/core/Application.js b/src/core/Application.js index bc730db..ea0f058 100644 --- a/src/core/Application.js +++ b/src/core/Application.js @@ -33,6 +33,9 @@ * need to call toDataUrl on the webgl context * @param {number} [options.resolution=1] - The resolution / device pixel ratio of the renderer, retina would be 2 * @param {boolean} [noWebGL=false] - prevents selection of WebGL renderer, even if such is present + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experience unexplained flickering try setting this to true. + */ constructor(width, height, options, noWebGL) { diff --git a/src/core/display/Container.js b/src/core/display/Container.js index b3792ef..ed8cd5f 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -74,12 +74,12 @@ child.parent = this; + this.children.push(child); + // ensure a transform will be recalculated.. this.transform._parentID = -1; this._boundsID++; - this.children.push(child); - // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(this.children.length - 1); child.emit('added', this); @@ -111,6 +111,10 @@ this.children.splice(index, 0, child); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('added', this); @@ -174,6 +178,7 @@ removeItems(this.children, currentIndex, 1); // remove from old position this.children.splice(index, 0, child); // add at new position + this.onChildrenChange(index); } @@ -247,6 +252,10 @@ child.parent = null; removeItems(this.children, index, 1); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('removed', this); @@ -277,6 +286,13 @@ removed[i].parent = null; } + // ensure a transform will be recalculated.. + if (this.transform) + { + this.transform._parentID = -1; + } + this._boundsID++; + this.onChildrenChange(beginIndex); for (let i = 0; i < removed.length; ++i) diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index ce0e1c4..75ae9b5 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -49,11 +49,20 @@ * enable this if you need to call toDataUrl on the webgl context. * @param {boolean} [options.roundPixels=false] - If true Pixi will Math.floor() x/y values when * rendering, stopping pixel interpolation. + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experiance unexplained flickering try setting this to true. */ constructor(width, height, options = {}) { super('WebGL', width, height, options); + this.legacy = !!options.legacy; + + if (this.legacy) + { + glCore.VertexArrayObject.FORCE_NATIVE = true; + } + /** * The type of this renderer as a standardised const * diff --git a/src/core/renderers/webgl/utils/RenderTarget.js b/src/core/renderers/webgl/utils/RenderTarget.js index afe51ab..6d2467f 100644 --- a/src/core/renderers/webgl/utils/RenderTarget.js +++ b/src/core/renderers/webgl/utils/RenderTarget.js @@ -124,7 +124,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Whether this object is the root element or not diff --git a/src/core/sprites/Sprite.js b/src/core/sprites/Sprite.js index 36ea5bb..28b0b18 100644 --- a/src/core/sprites/Sprite.js +++ b/src/core/sprites/Sprite.js @@ -346,8 +346,8 @@ /** * Gets the local bounds of the sprite object. * - * @param {Rectangle} rect - The output rectangle. - * @return {Rectangle} The bounds. + * @param {PIXI.Rectangle} rect - The output rectangle. + * @return {PIXI.Rectangle} The bounds. */ getLocalBounds(rect) { @@ -440,7 +440,7 @@ * * @static * @param {number|string|PIXI.BaseTexture|HTMLCanvasElement|HTMLVideoElement} source Source to create texture from - * @return {PIXI.Texture} The newly created texture + * @return {PIXI.Sprite} The newly created texture */ static from(source) { diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 9b349bd..f7cc1a0 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -103,11 +103,18 @@ { const gl = this.renderer.gl; - // step 1: first check max textures the GPU can handle. - this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); + if (this.renderer.legacy) + { + this.MAX_TEXTURES = 1; + } + else + { + // step 1: first check max textures the GPU can handle. + this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); - // step 2: check the maximum number of if statements the shader can have too.. - this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + // step 2: check the maximum number of if statements the shader can have too.. + this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + } const shader = this.shader = generateMultiTextureShader(gl, this.MAX_TEXTURES); diff --git a/src/core/text/Text.js b/src/core/text/Text.js index 18fb723..cec8c32 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -191,6 +191,7 @@ if (style.dropShadow) { this.context.shadowBlur = style.dropShadowBlur; + this.context.globalAlpha = style.dropShadowAlpha; if (style.dropShadowBlur > 0) { @@ -239,12 +240,13 @@ } } + // reset the shadow blur and alpha that was set by the drop shadow, for the regular text + this.context.shadowBlur = 0; + this.context.globalAlpha = 1; + // set canvas text styles this.context.fillStyle = this._generateFillStyle(style, lines); - // remove blur if set for the drop shadow - this.context.shadowBlur = 0; - // draw lines line by line for (let i = 0; i < lines.length; i++) { diff --git a/src/core/text/TextStyle.js b/src/core/text/TextStyle.js index eec2820..890950b 100644 --- a/src/core/text/TextStyle.js +++ b/src/core/text/TextStyle.js @@ -8,6 +8,7 @@ align: 'left', breakWords: false, dropShadow: false, + dropShadowAlpha: 1, dropShadowAngle: Math.PI / 6, dropShadowBlur: 0, dropShadowColor: '#000000', @@ -49,6 +50,7 @@ * @param {boolean} [style.breakWords=false] - Indicates if lines can be wrapped within words, it * needs wordWrap to be set to true * @param {boolean} [style.dropShadow=false] - Set a drop shadow for the text + * @param {number} [style.dropShadowAlpha=1] - Set alpha for the drop shadow * @param {number} [style.dropShadowAngle=Math.PI/6] - Set a angle of the drop shadow * @param {number} [style.dropShadowBlur=0] - Set a shadow blur radius * @param {string} [style.dropShadowColor='#000000'] - A fill style to be used on the dropshadow e.g 'red', '#00FF00' @@ -157,6 +159,19 @@ } } + get dropShadowAlpha() + { + return this._dropShadowAlpha; + } + set dropShadowAlpha(dropShadowAlpha) + { + if (this._dropShadowAlpha !== dropShadowAlpha) + { + this._dropShadowAlpha = dropShadowAlpha; + this.styleID++; + } + } + get dropShadowAngle() { return this._dropShadowAngle; @@ -511,8 +526,8 @@ * Utility function to convert hexadecimal colors to strings, and simply return the color if it's a string. * This version can also convert array of colors * - * @param {Array} array1 First array to compared - * @param {Array} array1 Second array to compare + * @param {Array} array1 First array to compare + * @param {Array} array2 Second array to compare * @return {boolean} Do the arrays contain the same values in the same order */ function areArraysEqual(array1, array2) diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index 2fa08c4..aa727f0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -1,8 +1,6 @@ import BaseTexture from './BaseTexture'; import settings from '../settings'; -const { SCALE_MODE } = settings; - /** * A BaseRenderTexture is a special texture that allows any Pixi display object to be rendered to it. * @@ -62,7 +60,7 @@ this.realWidth = this.width * this.resolution; this.realHeight = this.height * this.resolution; - this.scaleMode = scaleMode || SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** diff --git a/src/core/Application.js b/src/core/Application.js index bc730db..ea0f058 100644 --- a/src/core/Application.js +++ b/src/core/Application.js @@ -33,6 +33,9 @@ * need to call toDataUrl on the webgl context * @param {number} [options.resolution=1] - The resolution / device pixel ratio of the renderer, retina would be 2 * @param {boolean} [noWebGL=false] - prevents selection of WebGL renderer, even if such is present + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experience unexplained flickering try setting this to true. + */ constructor(width, height, options, noWebGL) { diff --git a/src/core/display/Container.js b/src/core/display/Container.js index b3792ef..ed8cd5f 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -74,12 +74,12 @@ child.parent = this; + this.children.push(child); + // ensure a transform will be recalculated.. this.transform._parentID = -1; this._boundsID++; - this.children.push(child); - // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(this.children.length - 1); child.emit('added', this); @@ -111,6 +111,10 @@ this.children.splice(index, 0, child); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('added', this); @@ -174,6 +178,7 @@ removeItems(this.children, currentIndex, 1); // remove from old position this.children.splice(index, 0, child); // add at new position + this.onChildrenChange(index); } @@ -247,6 +252,10 @@ child.parent = null; removeItems(this.children, index, 1); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('removed', this); @@ -277,6 +286,13 @@ removed[i].parent = null; } + // ensure a transform will be recalculated.. + if (this.transform) + { + this.transform._parentID = -1; + } + this._boundsID++; + this.onChildrenChange(beginIndex); for (let i = 0; i < removed.length; ++i) diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index ce0e1c4..75ae9b5 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -49,11 +49,20 @@ * enable this if you need to call toDataUrl on the webgl context. * @param {boolean} [options.roundPixels=false] - If true Pixi will Math.floor() x/y values when * rendering, stopping pixel interpolation. + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experiance unexplained flickering try setting this to true. */ constructor(width, height, options = {}) { super('WebGL', width, height, options); + this.legacy = !!options.legacy; + + if (this.legacy) + { + glCore.VertexArrayObject.FORCE_NATIVE = true; + } + /** * The type of this renderer as a standardised const * diff --git a/src/core/renderers/webgl/utils/RenderTarget.js b/src/core/renderers/webgl/utils/RenderTarget.js index afe51ab..6d2467f 100644 --- a/src/core/renderers/webgl/utils/RenderTarget.js +++ b/src/core/renderers/webgl/utils/RenderTarget.js @@ -124,7 +124,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Whether this object is the root element or not diff --git a/src/core/sprites/Sprite.js b/src/core/sprites/Sprite.js index 36ea5bb..28b0b18 100644 --- a/src/core/sprites/Sprite.js +++ b/src/core/sprites/Sprite.js @@ -346,8 +346,8 @@ /** * Gets the local bounds of the sprite object. * - * @param {Rectangle} rect - The output rectangle. - * @return {Rectangle} The bounds. + * @param {PIXI.Rectangle} rect - The output rectangle. + * @return {PIXI.Rectangle} The bounds. */ getLocalBounds(rect) { @@ -440,7 +440,7 @@ * * @static * @param {number|string|PIXI.BaseTexture|HTMLCanvasElement|HTMLVideoElement} source Source to create texture from - * @return {PIXI.Texture} The newly created texture + * @return {PIXI.Sprite} The newly created texture */ static from(source) { diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 9b349bd..f7cc1a0 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -103,11 +103,18 @@ { const gl = this.renderer.gl; - // step 1: first check max textures the GPU can handle. - this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); + if (this.renderer.legacy) + { + this.MAX_TEXTURES = 1; + } + else + { + // step 1: first check max textures the GPU can handle. + this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); - // step 2: check the maximum number of if statements the shader can have too.. - this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + // step 2: check the maximum number of if statements the shader can have too.. + this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + } const shader = this.shader = generateMultiTextureShader(gl, this.MAX_TEXTURES); diff --git a/src/core/text/Text.js b/src/core/text/Text.js index 18fb723..cec8c32 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -191,6 +191,7 @@ if (style.dropShadow) { this.context.shadowBlur = style.dropShadowBlur; + this.context.globalAlpha = style.dropShadowAlpha; if (style.dropShadowBlur > 0) { @@ -239,12 +240,13 @@ } } + // reset the shadow blur and alpha that was set by the drop shadow, for the regular text + this.context.shadowBlur = 0; + this.context.globalAlpha = 1; + // set canvas text styles this.context.fillStyle = this._generateFillStyle(style, lines); - // remove blur if set for the drop shadow - this.context.shadowBlur = 0; - // draw lines line by line for (let i = 0; i < lines.length; i++) { diff --git a/src/core/text/TextStyle.js b/src/core/text/TextStyle.js index eec2820..890950b 100644 --- a/src/core/text/TextStyle.js +++ b/src/core/text/TextStyle.js @@ -8,6 +8,7 @@ align: 'left', breakWords: false, dropShadow: false, + dropShadowAlpha: 1, dropShadowAngle: Math.PI / 6, dropShadowBlur: 0, dropShadowColor: '#000000', @@ -49,6 +50,7 @@ * @param {boolean} [style.breakWords=false] - Indicates if lines can be wrapped within words, it * needs wordWrap to be set to true * @param {boolean} [style.dropShadow=false] - Set a drop shadow for the text + * @param {number} [style.dropShadowAlpha=1] - Set alpha for the drop shadow * @param {number} [style.dropShadowAngle=Math.PI/6] - Set a angle of the drop shadow * @param {number} [style.dropShadowBlur=0] - Set a shadow blur radius * @param {string} [style.dropShadowColor='#000000'] - A fill style to be used on the dropshadow e.g 'red', '#00FF00' @@ -157,6 +159,19 @@ } } + get dropShadowAlpha() + { + return this._dropShadowAlpha; + } + set dropShadowAlpha(dropShadowAlpha) + { + if (this._dropShadowAlpha !== dropShadowAlpha) + { + this._dropShadowAlpha = dropShadowAlpha; + this.styleID++; + } + } + get dropShadowAngle() { return this._dropShadowAngle; @@ -511,8 +526,8 @@ * Utility function to convert hexadecimal colors to strings, and simply return the color if it's a string. * This version can also convert array of colors * - * @param {Array} array1 First array to compared - * @param {Array} array1 Second array to compare + * @param {Array} array1 First array to compare + * @param {Array} array2 Second array to compare * @return {boolean} Do the arrays contain the same values in the same order */ function areArraysEqual(array1, array2) diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index 2fa08c4..aa727f0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -1,8 +1,6 @@ import BaseTexture from './BaseTexture'; import settings from '../settings'; -const { SCALE_MODE } = settings; - /** * A BaseRenderTexture is a special texture that allows any Pixi display object to be rendered to it. * @@ -62,7 +60,7 @@ this.realWidth = this.width * this.resolution; this.realHeight = this.height * this.resolution; - this.scaleMode = scaleMode || SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 676dca3..853de7e 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -77,7 +77,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Set to true once the base texture has successfully loaded. diff --git a/src/core/Application.js b/src/core/Application.js index bc730db..ea0f058 100644 --- a/src/core/Application.js +++ b/src/core/Application.js @@ -33,6 +33,9 @@ * need to call toDataUrl on the webgl context * @param {number} [options.resolution=1] - The resolution / device pixel ratio of the renderer, retina would be 2 * @param {boolean} [noWebGL=false] - prevents selection of WebGL renderer, even if such is present + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experience unexplained flickering try setting this to true. + */ constructor(width, height, options, noWebGL) { diff --git a/src/core/display/Container.js b/src/core/display/Container.js index b3792ef..ed8cd5f 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -74,12 +74,12 @@ child.parent = this; + this.children.push(child); + // ensure a transform will be recalculated.. this.transform._parentID = -1; this._boundsID++; - this.children.push(child); - // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(this.children.length - 1); child.emit('added', this); @@ -111,6 +111,10 @@ this.children.splice(index, 0, child); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('added', this); @@ -174,6 +178,7 @@ removeItems(this.children, currentIndex, 1); // remove from old position this.children.splice(index, 0, child); // add at new position + this.onChildrenChange(index); } @@ -247,6 +252,10 @@ child.parent = null; removeItems(this.children, index, 1); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('removed', this); @@ -277,6 +286,13 @@ removed[i].parent = null; } + // ensure a transform will be recalculated.. + if (this.transform) + { + this.transform._parentID = -1; + } + this._boundsID++; + this.onChildrenChange(beginIndex); for (let i = 0; i < removed.length; ++i) diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index ce0e1c4..75ae9b5 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -49,11 +49,20 @@ * enable this if you need to call toDataUrl on the webgl context. * @param {boolean} [options.roundPixels=false] - If true Pixi will Math.floor() x/y values when * rendering, stopping pixel interpolation. + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experiance unexplained flickering try setting this to true. */ constructor(width, height, options = {}) { super('WebGL', width, height, options); + this.legacy = !!options.legacy; + + if (this.legacy) + { + glCore.VertexArrayObject.FORCE_NATIVE = true; + } + /** * The type of this renderer as a standardised const * diff --git a/src/core/renderers/webgl/utils/RenderTarget.js b/src/core/renderers/webgl/utils/RenderTarget.js index afe51ab..6d2467f 100644 --- a/src/core/renderers/webgl/utils/RenderTarget.js +++ b/src/core/renderers/webgl/utils/RenderTarget.js @@ -124,7 +124,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Whether this object is the root element or not diff --git a/src/core/sprites/Sprite.js b/src/core/sprites/Sprite.js index 36ea5bb..28b0b18 100644 --- a/src/core/sprites/Sprite.js +++ b/src/core/sprites/Sprite.js @@ -346,8 +346,8 @@ /** * Gets the local bounds of the sprite object. * - * @param {Rectangle} rect - The output rectangle. - * @return {Rectangle} The bounds. + * @param {PIXI.Rectangle} rect - The output rectangle. + * @return {PIXI.Rectangle} The bounds. */ getLocalBounds(rect) { @@ -440,7 +440,7 @@ * * @static * @param {number|string|PIXI.BaseTexture|HTMLCanvasElement|HTMLVideoElement} source Source to create texture from - * @return {PIXI.Texture} The newly created texture + * @return {PIXI.Sprite} The newly created texture */ static from(source) { diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 9b349bd..f7cc1a0 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -103,11 +103,18 @@ { const gl = this.renderer.gl; - // step 1: first check max textures the GPU can handle. - this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); + if (this.renderer.legacy) + { + this.MAX_TEXTURES = 1; + } + else + { + // step 1: first check max textures the GPU can handle. + this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); - // step 2: check the maximum number of if statements the shader can have too.. - this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + // step 2: check the maximum number of if statements the shader can have too.. + this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + } const shader = this.shader = generateMultiTextureShader(gl, this.MAX_TEXTURES); diff --git a/src/core/text/Text.js b/src/core/text/Text.js index 18fb723..cec8c32 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -191,6 +191,7 @@ if (style.dropShadow) { this.context.shadowBlur = style.dropShadowBlur; + this.context.globalAlpha = style.dropShadowAlpha; if (style.dropShadowBlur > 0) { @@ -239,12 +240,13 @@ } } + // reset the shadow blur and alpha that was set by the drop shadow, for the regular text + this.context.shadowBlur = 0; + this.context.globalAlpha = 1; + // set canvas text styles this.context.fillStyle = this._generateFillStyle(style, lines); - // remove blur if set for the drop shadow - this.context.shadowBlur = 0; - // draw lines line by line for (let i = 0; i < lines.length; i++) { diff --git a/src/core/text/TextStyle.js b/src/core/text/TextStyle.js index eec2820..890950b 100644 --- a/src/core/text/TextStyle.js +++ b/src/core/text/TextStyle.js @@ -8,6 +8,7 @@ align: 'left', breakWords: false, dropShadow: false, + dropShadowAlpha: 1, dropShadowAngle: Math.PI / 6, dropShadowBlur: 0, dropShadowColor: '#000000', @@ -49,6 +50,7 @@ * @param {boolean} [style.breakWords=false] - Indicates if lines can be wrapped within words, it * needs wordWrap to be set to true * @param {boolean} [style.dropShadow=false] - Set a drop shadow for the text + * @param {number} [style.dropShadowAlpha=1] - Set alpha for the drop shadow * @param {number} [style.dropShadowAngle=Math.PI/6] - Set a angle of the drop shadow * @param {number} [style.dropShadowBlur=0] - Set a shadow blur radius * @param {string} [style.dropShadowColor='#000000'] - A fill style to be used on the dropshadow e.g 'red', '#00FF00' @@ -157,6 +159,19 @@ } } + get dropShadowAlpha() + { + return this._dropShadowAlpha; + } + set dropShadowAlpha(dropShadowAlpha) + { + if (this._dropShadowAlpha !== dropShadowAlpha) + { + this._dropShadowAlpha = dropShadowAlpha; + this.styleID++; + } + } + get dropShadowAngle() { return this._dropShadowAngle; @@ -511,8 +526,8 @@ * Utility function to convert hexadecimal colors to strings, and simply return the color if it's a string. * This version can also convert array of colors * - * @param {Array} array1 First array to compared - * @param {Array} array1 Second array to compare + * @param {Array} array1 First array to compare + * @param {Array} array2 Second array to compare * @return {boolean} Do the arrays contain the same values in the same order */ function areArraysEqual(array1, array2) diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index 2fa08c4..aa727f0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -1,8 +1,6 @@ import BaseTexture from './BaseTexture'; import settings from '../settings'; -const { SCALE_MODE } = settings; - /** * A BaseRenderTexture is a special texture that allows any Pixi display object to be rendered to it. * @@ -62,7 +60,7 @@ this.realWidth = this.width * this.resolution; this.realHeight = this.height * this.resolution; - this.scaleMode = scaleMode || SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 676dca3..853de7e 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -77,7 +77,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Set to true once the base texture has successfully loaded. diff --git a/src/core/textures/RenderTexture.js b/src/core/textures/RenderTexture.js index 4c5034f..b3c6297 100644 --- a/src/core/textures/RenderTexture.js +++ b/src/core/textures/RenderTexture.js @@ -54,8 +54,8 @@ /* eslint-disable prefer-rest-params, no-console */ const width = arguments[1]; const height = arguments[2]; - const scaleMode = arguments[3] || 0; - const resolution = arguments[4] || 1; + const scaleMode = arguments[3]; + const resolution = arguments[4]; // we have an old render texture.. console.warn(`Please use RenderTexture.create(${width}, ${height}) instead of the ctor directly.`); diff --git a/src/core/Application.js b/src/core/Application.js index bc730db..ea0f058 100644 --- a/src/core/Application.js +++ b/src/core/Application.js @@ -33,6 +33,9 @@ * need to call toDataUrl on the webgl context * @param {number} [options.resolution=1] - The resolution / device pixel ratio of the renderer, retina would be 2 * @param {boolean} [noWebGL=false] - prevents selection of WebGL renderer, even if such is present + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experience unexplained flickering try setting this to true. + */ constructor(width, height, options, noWebGL) { diff --git a/src/core/display/Container.js b/src/core/display/Container.js index b3792ef..ed8cd5f 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -74,12 +74,12 @@ child.parent = this; + this.children.push(child); + // ensure a transform will be recalculated.. this.transform._parentID = -1; this._boundsID++; - this.children.push(child); - // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(this.children.length - 1); child.emit('added', this); @@ -111,6 +111,10 @@ this.children.splice(index, 0, child); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('added', this); @@ -174,6 +178,7 @@ removeItems(this.children, currentIndex, 1); // remove from old position this.children.splice(index, 0, child); // add at new position + this.onChildrenChange(index); } @@ -247,6 +252,10 @@ child.parent = null; removeItems(this.children, index, 1); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('removed', this); @@ -277,6 +286,13 @@ removed[i].parent = null; } + // ensure a transform will be recalculated.. + if (this.transform) + { + this.transform._parentID = -1; + } + this._boundsID++; + this.onChildrenChange(beginIndex); for (let i = 0; i < removed.length; ++i) diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index ce0e1c4..75ae9b5 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -49,11 +49,20 @@ * enable this if you need to call toDataUrl on the webgl context. * @param {boolean} [options.roundPixels=false] - If true Pixi will Math.floor() x/y values when * rendering, stopping pixel interpolation. + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experiance unexplained flickering try setting this to true. */ constructor(width, height, options = {}) { super('WebGL', width, height, options); + this.legacy = !!options.legacy; + + if (this.legacy) + { + glCore.VertexArrayObject.FORCE_NATIVE = true; + } + /** * The type of this renderer as a standardised const * diff --git a/src/core/renderers/webgl/utils/RenderTarget.js b/src/core/renderers/webgl/utils/RenderTarget.js index afe51ab..6d2467f 100644 --- a/src/core/renderers/webgl/utils/RenderTarget.js +++ b/src/core/renderers/webgl/utils/RenderTarget.js @@ -124,7 +124,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Whether this object is the root element or not diff --git a/src/core/sprites/Sprite.js b/src/core/sprites/Sprite.js index 36ea5bb..28b0b18 100644 --- a/src/core/sprites/Sprite.js +++ b/src/core/sprites/Sprite.js @@ -346,8 +346,8 @@ /** * Gets the local bounds of the sprite object. * - * @param {Rectangle} rect - The output rectangle. - * @return {Rectangle} The bounds. + * @param {PIXI.Rectangle} rect - The output rectangle. + * @return {PIXI.Rectangle} The bounds. */ getLocalBounds(rect) { @@ -440,7 +440,7 @@ * * @static * @param {number|string|PIXI.BaseTexture|HTMLCanvasElement|HTMLVideoElement} source Source to create texture from - * @return {PIXI.Texture} The newly created texture + * @return {PIXI.Sprite} The newly created texture */ static from(source) { diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 9b349bd..f7cc1a0 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -103,11 +103,18 @@ { const gl = this.renderer.gl; - // step 1: first check max textures the GPU can handle. - this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); + if (this.renderer.legacy) + { + this.MAX_TEXTURES = 1; + } + else + { + // step 1: first check max textures the GPU can handle. + this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); - // step 2: check the maximum number of if statements the shader can have too.. - this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + // step 2: check the maximum number of if statements the shader can have too.. + this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + } const shader = this.shader = generateMultiTextureShader(gl, this.MAX_TEXTURES); diff --git a/src/core/text/Text.js b/src/core/text/Text.js index 18fb723..cec8c32 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -191,6 +191,7 @@ if (style.dropShadow) { this.context.shadowBlur = style.dropShadowBlur; + this.context.globalAlpha = style.dropShadowAlpha; if (style.dropShadowBlur > 0) { @@ -239,12 +240,13 @@ } } + // reset the shadow blur and alpha that was set by the drop shadow, for the regular text + this.context.shadowBlur = 0; + this.context.globalAlpha = 1; + // set canvas text styles this.context.fillStyle = this._generateFillStyle(style, lines); - // remove blur if set for the drop shadow - this.context.shadowBlur = 0; - // draw lines line by line for (let i = 0; i < lines.length; i++) { diff --git a/src/core/text/TextStyle.js b/src/core/text/TextStyle.js index eec2820..890950b 100644 --- a/src/core/text/TextStyle.js +++ b/src/core/text/TextStyle.js @@ -8,6 +8,7 @@ align: 'left', breakWords: false, dropShadow: false, + dropShadowAlpha: 1, dropShadowAngle: Math.PI / 6, dropShadowBlur: 0, dropShadowColor: '#000000', @@ -49,6 +50,7 @@ * @param {boolean} [style.breakWords=false] - Indicates if lines can be wrapped within words, it * needs wordWrap to be set to true * @param {boolean} [style.dropShadow=false] - Set a drop shadow for the text + * @param {number} [style.dropShadowAlpha=1] - Set alpha for the drop shadow * @param {number} [style.dropShadowAngle=Math.PI/6] - Set a angle of the drop shadow * @param {number} [style.dropShadowBlur=0] - Set a shadow blur radius * @param {string} [style.dropShadowColor='#000000'] - A fill style to be used on the dropshadow e.g 'red', '#00FF00' @@ -157,6 +159,19 @@ } } + get dropShadowAlpha() + { + return this._dropShadowAlpha; + } + set dropShadowAlpha(dropShadowAlpha) + { + if (this._dropShadowAlpha !== dropShadowAlpha) + { + this._dropShadowAlpha = dropShadowAlpha; + this.styleID++; + } + } + get dropShadowAngle() { return this._dropShadowAngle; @@ -511,8 +526,8 @@ * Utility function to convert hexadecimal colors to strings, and simply return the color if it's a string. * This version can also convert array of colors * - * @param {Array} array1 First array to compared - * @param {Array} array1 Second array to compare + * @param {Array} array1 First array to compare + * @param {Array} array2 Second array to compare * @return {boolean} Do the arrays contain the same values in the same order */ function areArraysEqual(array1, array2) diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index 2fa08c4..aa727f0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -1,8 +1,6 @@ import BaseTexture from './BaseTexture'; import settings from '../settings'; -const { SCALE_MODE } = settings; - /** * A BaseRenderTexture is a special texture that allows any Pixi display object to be rendered to it. * @@ -62,7 +60,7 @@ this.realWidth = this.width * this.resolution; this.realHeight = this.height * this.resolution; - this.scaleMode = scaleMode || SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 676dca3..853de7e 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -77,7 +77,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Set to true once the base texture has successfully loaded. diff --git a/src/core/textures/RenderTexture.js b/src/core/textures/RenderTexture.js index 4c5034f..b3c6297 100644 --- a/src/core/textures/RenderTexture.js +++ b/src/core/textures/RenderTexture.js @@ -54,8 +54,8 @@ /* eslint-disable prefer-rest-params, no-console */ const width = arguments[1]; const height = arguments[2]; - const scaleMode = arguments[3] || 0; - const resolution = arguments[4] || 1; + const scaleMode = arguments[3]; + const resolution = arguments[4]; // we have an old render texture.. console.warn(`Please use RenderTexture.create(${width}, ${height}) instead of the ctor directly.`); diff --git a/src/prepare/BasePrepare.js b/src/prepare/BasePrepare.js index a2005f5..09eb5e5 100644 --- a/src/prepare/BasePrepare.js +++ b/src/prepare/BasePrepare.js @@ -20,7 +20,7 @@ * * @abstract * @class - * @memberof PIXI + * @memberof PIXI.prepare */ export default class BasePrepare { @@ -107,9 +107,9 @@ /** * Upload all the textures and graphics to the GPU. * - * @param {Function|PIXI.DisplayObject|PIXI.Container} item - Either - * the container or display object to search for items to upload or - * the callback function, if items have been added using `prepare.add`. + * @param {Function|PIXI.DisplayObject|PIXI.Container|PIXI.BaseTexture|PIXI.Texture|PIXI.Graphics|PIXI.Text} item - + * Either the container or display object to search for items to upload, the items to upload themselves, + * or the callback function, if items have been added using `prepare.add`. * @param {Function} [done] - Optional callback when all queued uploads have completed */ upload(item, done) @@ -236,7 +236,8 @@ /** * Manually add an item to the uploading queue. * - * @param {PIXI.DisplayObject|PIXI.Container|*} item - Object to add to the queue + * @param {PIXI.DisplayObject|PIXI.Container|PIXI.BaseTexture|PIXI.Texture|PIXI.Graphics|PIXI.Text|*} item - Object to + * add to the queue * @return {PIXI.CanvasPrepare} Instance of plugin for chaining. */ add(item) diff --git a/src/core/Application.js b/src/core/Application.js index bc730db..ea0f058 100644 --- a/src/core/Application.js +++ b/src/core/Application.js @@ -33,6 +33,9 @@ * need to call toDataUrl on the webgl context * @param {number} [options.resolution=1] - The resolution / device pixel ratio of the renderer, retina would be 2 * @param {boolean} [noWebGL=false] - prevents selection of WebGL renderer, even if such is present + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experience unexplained flickering try setting this to true. + */ constructor(width, height, options, noWebGL) { diff --git a/src/core/display/Container.js b/src/core/display/Container.js index b3792ef..ed8cd5f 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -74,12 +74,12 @@ child.parent = this; + this.children.push(child); + // ensure a transform will be recalculated.. this.transform._parentID = -1; this._boundsID++; - this.children.push(child); - // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(this.children.length - 1); child.emit('added', this); @@ -111,6 +111,10 @@ this.children.splice(index, 0, child); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('added', this); @@ -174,6 +178,7 @@ removeItems(this.children, currentIndex, 1); // remove from old position this.children.splice(index, 0, child); // add at new position + this.onChildrenChange(index); } @@ -247,6 +252,10 @@ child.parent = null; removeItems(this.children, index, 1); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('removed', this); @@ -277,6 +286,13 @@ removed[i].parent = null; } + // ensure a transform will be recalculated.. + if (this.transform) + { + this.transform._parentID = -1; + } + this._boundsID++; + this.onChildrenChange(beginIndex); for (let i = 0; i < removed.length; ++i) diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index ce0e1c4..75ae9b5 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -49,11 +49,20 @@ * enable this if you need to call toDataUrl on the webgl context. * @param {boolean} [options.roundPixels=false] - If true Pixi will Math.floor() x/y values when * rendering, stopping pixel interpolation. + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experiance unexplained flickering try setting this to true. */ constructor(width, height, options = {}) { super('WebGL', width, height, options); + this.legacy = !!options.legacy; + + if (this.legacy) + { + glCore.VertexArrayObject.FORCE_NATIVE = true; + } + /** * The type of this renderer as a standardised const * diff --git a/src/core/renderers/webgl/utils/RenderTarget.js b/src/core/renderers/webgl/utils/RenderTarget.js index afe51ab..6d2467f 100644 --- a/src/core/renderers/webgl/utils/RenderTarget.js +++ b/src/core/renderers/webgl/utils/RenderTarget.js @@ -124,7 +124,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Whether this object is the root element or not diff --git a/src/core/sprites/Sprite.js b/src/core/sprites/Sprite.js index 36ea5bb..28b0b18 100644 --- a/src/core/sprites/Sprite.js +++ b/src/core/sprites/Sprite.js @@ -346,8 +346,8 @@ /** * Gets the local bounds of the sprite object. * - * @param {Rectangle} rect - The output rectangle. - * @return {Rectangle} The bounds. + * @param {PIXI.Rectangle} rect - The output rectangle. + * @return {PIXI.Rectangle} The bounds. */ getLocalBounds(rect) { @@ -440,7 +440,7 @@ * * @static * @param {number|string|PIXI.BaseTexture|HTMLCanvasElement|HTMLVideoElement} source Source to create texture from - * @return {PIXI.Texture} The newly created texture + * @return {PIXI.Sprite} The newly created texture */ static from(source) { diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 9b349bd..f7cc1a0 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -103,11 +103,18 @@ { const gl = this.renderer.gl; - // step 1: first check max textures the GPU can handle. - this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); + if (this.renderer.legacy) + { + this.MAX_TEXTURES = 1; + } + else + { + // step 1: first check max textures the GPU can handle. + this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); - // step 2: check the maximum number of if statements the shader can have too.. - this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + // step 2: check the maximum number of if statements the shader can have too.. + this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + } const shader = this.shader = generateMultiTextureShader(gl, this.MAX_TEXTURES); diff --git a/src/core/text/Text.js b/src/core/text/Text.js index 18fb723..cec8c32 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -191,6 +191,7 @@ if (style.dropShadow) { this.context.shadowBlur = style.dropShadowBlur; + this.context.globalAlpha = style.dropShadowAlpha; if (style.dropShadowBlur > 0) { @@ -239,12 +240,13 @@ } } + // reset the shadow blur and alpha that was set by the drop shadow, for the regular text + this.context.shadowBlur = 0; + this.context.globalAlpha = 1; + // set canvas text styles this.context.fillStyle = this._generateFillStyle(style, lines); - // remove blur if set for the drop shadow - this.context.shadowBlur = 0; - // draw lines line by line for (let i = 0; i < lines.length; i++) { diff --git a/src/core/text/TextStyle.js b/src/core/text/TextStyle.js index eec2820..890950b 100644 --- a/src/core/text/TextStyle.js +++ b/src/core/text/TextStyle.js @@ -8,6 +8,7 @@ align: 'left', breakWords: false, dropShadow: false, + dropShadowAlpha: 1, dropShadowAngle: Math.PI / 6, dropShadowBlur: 0, dropShadowColor: '#000000', @@ -49,6 +50,7 @@ * @param {boolean} [style.breakWords=false] - Indicates if lines can be wrapped within words, it * needs wordWrap to be set to true * @param {boolean} [style.dropShadow=false] - Set a drop shadow for the text + * @param {number} [style.dropShadowAlpha=1] - Set alpha for the drop shadow * @param {number} [style.dropShadowAngle=Math.PI/6] - Set a angle of the drop shadow * @param {number} [style.dropShadowBlur=0] - Set a shadow blur radius * @param {string} [style.dropShadowColor='#000000'] - A fill style to be used on the dropshadow e.g 'red', '#00FF00' @@ -157,6 +159,19 @@ } } + get dropShadowAlpha() + { + return this._dropShadowAlpha; + } + set dropShadowAlpha(dropShadowAlpha) + { + if (this._dropShadowAlpha !== dropShadowAlpha) + { + this._dropShadowAlpha = dropShadowAlpha; + this.styleID++; + } + } + get dropShadowAngle() { return this._dropShadowAngle; @@ -511,8 +526,8 @@ * Utility function to convert hexadecimal colors to strings, and simply return the color if it's a string. * This version can also convert array of colors * - * @param {Array} array1 First array to compared - * @param {Array} array1 Second array to compare + * @param {Array} array1 First array to compare + * @param {Array} array2 Second array to compare * @return {boolean} Do the arrays contain the same values in the same order */ function areArraysEqual(array1, array2) diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index 2fa08c4..aa727f0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -1,8 +1,6 @@ import BaseTexture from './BaseTexture'; import settings from '../settings'; -const { SCALE_MODE } = settings; - /** * A BaseRenderTexture is a special texture that allows any Pixi display object to be rendered to it. * @@ -62,7 +60,7 @@ this.realWidth = this.width * this.resolution; this.realHeight = this.height * this.resolution; - this.scaleMode = scaleMode || SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 676dca3..853de7e 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -77,7 +77,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Set to true once the base texture has successfully loaded. diff --git a/src/core/textures/RenderTexture.js b/src/core/textures/RenderTexture.js index 4c5034f..b3c6297 100644 --- a/src/core/textures/RenderTexture.js +++ b/src/core/textures/RenderTexture.js @@ -54,8 +54,8 @@ /* eslint-disable prefer-rest-params, no-console */ const width = arguments[1]; const height = arguments[2]; - const scaleMode = arguments[3] || 0; - const resolution = arguments[4] || 1; + const scaleMode = arguments[3]; + const resolution = arguments[4]; // we have an old render texture.. console.warn(`Please use RenderTexture.create(${width}, ${height}) instead of the ctor directly.`); diff --git a/src/prepare/BasePrepare.js b/src/prepare/BasePrepare.js index a2005f5..09eb5e5 100644 --- a/src/prepare/BasePrepare.js +++ b/src/prepare/BasePrepare.js @@ -20,7 +20,7 @@ * * @abstract * @class - * @memberof PIXI + * @memberof PIXI.prepare */ export default class BasePrepare { @@ -107,9 +107,9 @@ /** * Upload all the textures and graphics to the GPU. * - * @param {Function|PIXI.DisplayObject|PIXI.Container} item - Either - * the container or display object to search for items to upload or - * the callback function, if items have been added using `prepare.add`. + * @param {Function|PIXI.DisplayObject|PIXI.Container|PIXI.BaseTexture|PIXI.Texture|PIXI.Graphics|PIXI.Text} item - + * Either the container or display object to search for items to upload, the items to upload themselves, + * or the callback function, if items have been added using `prepare.add`. * @param {Function} [done] - Optional callback when all queued uploads have completed */ upload(item, done) @@ -236,7 +236,8 @@ /** * Manually add an item to the uploading queue. * - * @param {PIXI.DisplayObject|PIXI.Container|*} item - Object to add to the queue + * @param {PIXI.DisplayObject|PIXI.Container|PIXI.BaseTexture|PIXI.Texture|PIXI.Graphics|PIXI.Text|*} item - Object to + * add to the queue * @return {PIXI.CanvasPrepare} Instance of plugin for chaining. */ add(item) diff --git a/src/prepare/canvas/CanvasPrepare.js b/src/prepare/canvas/CanvasPrepare.js index 4b99d22..0224bb5 100644 --- a/src/prepare/canvas/CanvasPrepare.js +++ b/src/prepare/canvas/CanvasPrepare.js @@ -12,7 +12,8 @@ * An instance of this class is automatically created by default, and can be found at renderer.plugins.prepare * * @class - * @memberof PIXI + * @extends PIXI.prepare.BasePrepare + * @memberof PIXI.prepare */ export default class CanvasPrepare extends BasePrepare { diff --git a/src/core/Application.js b/src/core/Application.js index bc730db..ea0f058 100644 --- a/src/core/Application.js +++ b/src/core/Application.js @@ -33,6 +33,9 @@ * need to call toDataUrl on the webgl context * @param {number} [options.resolution=1] - The resolution / device pixel ratio of the renderer, retina would be 2 * @param {boolean} [noWebGL=false] - prevents selection of WebGL renderer, even if such is present + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experience unexplained flickering try setting this to true. + */ constructor(width, height, options, noWebGL) { diff --git a/src/core/display/Container.js b/src/core/display/Container.js index b3792ef..ed8cd5f 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -74,12 +74,12 @@ child.parent = this; + this.children.push(child); + // ensure a transform will be recalculated.. this.transform._parentID = -1; this._boundsID++; - this.children.push(child); - // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(this.children.length - 1); child.emit('added', this); @@ -111,6 +111,10 @@ this.children.splice(index, 0, child); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('added', this); @@ -174,6 +178,7 @@ removeItems(this.children, currentIndex, 1); // remove from old position this.children.splice(index, 0, child); // add at new position + this.onChildrenChange(index); } @@ -247,6 +252,10 @@ child.parent = null; removeItems(this.children, index, 1); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('removed', this); @@ -277,6 +286,13 @@ removed[i].parent = null; } + // ensure a transform will be recalculated.. + if (this.transform) + { + this.transform._parentID = -1; + } + this._boundsID++; + this.onChildrenChange(beginIndex); for (let i = 0; i < removed.length; ++i) diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index ce0e1c4..75ae9b5 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -49,11 +49,20 @@ * enable this if you need to call toDataUrl on the webgl context. * @param {boolean} [options.roundPixels=false] - If true Pixi will Math.floor() x/y values when * rendering, stopping pixel interpolation. + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experiance unexplained flickering try setting this to true. */ constructor(width, height, options = {}) { super('WebGL', width, height, options); + this.legacy = !!options.legacy; + + if (this.legacy) + { + glCore.VertexArrayObject.FORCE_NATIVE = true; + } + /** * The type of this renderer as a standardised const * diff --git a/src/core/renderers/webgl/utils/RenderTarget.js b/src/core/renderers/webgl/utils/RenderTarget.js index afe51ab..6d2467f 100644 --- a/src/core/renderers/webgl/utils/RenderTarget.js +++ b/src/core/renderers/webgl/utils/RenderTarget.js @@ -124,7 +124,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Whether this object is the root element or not diff --git a/src/core/sprites/Sprite.js b/src/core/sprites/Sprite.js index 36ea5bb..28b0b18 100644 --- a/src/core/sprites/Sprite.js +++ b/src/core/sprites/Sprite.js @@ -346,8 +346,8 @@ /** * Gets the local bounds of the sprite object. * - * @param {Rectangle} rect - The output rectangle. - * @return {Rectangle} The bounds. + * @param {PIXI.Rectangle} rect - The output rectangle. + * @return {PIXI.Rectangle} The bounds. */ getLocalBounds(rect) { @@ -440,7 +440,7 @@ * * @static * @param {number|string|PIXI.BaseTexture|HTMLCanvasElement|HTMLVideoElement} source Source to create texture from - * @return {PIXI.Texture} The newly created texture + * @return {PIXI.Sprite} The newly created texture */ static from(source) { diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 9b349bd..f7cc1a0 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -103,11 +103,18 @@ { const gl = this.renderer.gl; - // step 1: first check max textures the GPU can handle. - this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); + if (this.renderer.legacy) + { + this.MAX_TEXTURES = 1; + } + else + { + // step 1: first check max textures the GPU can handle. + this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); - // step 2: check the maximum number of if statements the shader can have too.. - this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + // step 2: check the maximum number of if statements the shader can have too.. + this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + } const shader = this.shader = generateMultiTextureShader(gl, this.MAX_TEXTURES); diff --git a/src/core/text/Text.js b/src/core/text/Text.js index 18fb723..cec8c32 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -191,6 +191,7 @@ if (style.dropShadow) { this.context.shadowBlur = style.dropShadowBlur; + this.context.globalAlpha = style.dropShadowAlpha; if (style.dropShadowBlur > 0) { @@ -239,12 +240,13 @@ } } + // reset the shadow blur and alpha that was set by the drop shadow, for the regular text + this.context.shadowBlur = 0; + this.context.globalAlpha = 1; + // set canvas text styles this.context.fillStyle = this._generateFillStyle(style, lines); - // remove blur if set for the drop shadow - this.context.shadowBlur = 0; - // draw lines line by line for (let i = 0; i < lines.length; i++) { diff --git a/src/core/text/TextStyle.js b/src/core/text/TextStyle.js index eec2820..890950b 100644 --- a/src/core/text/TextStyle.js +++ b/src/core/text/TextStyle.js @@ -8,6 +8,7 @@ align: 'left', breakWords: false, dropShadow: false, + dropShadowAlpha: 1, dropShadowAngle: Math.PI / 6, dropShadowBlur: 0, dropShadowColor: '#000000', @@ -49,6 +50,7 @@ * @param {boolean} [style.breakWords=false] - Indicates if lines can be wrapped within words, it * needs wordWrap to be set to true * @param {boolean} [style.dropShadow=false] - Set a drop shadow for the text + * @param {number} [style.dropShadowAlpha=1] - Set alpha for the drop shadow * @param {number} [style.dropShadowAngle=Math.PI/6] - Set a angle of the drop shadow * @param {number} [style.dropShadowBlur=0] - Set a shadow blur radius * @param {string} [style.dropShadowColor='#000000'] - A fill style to be used on the dropshadow e.g 'red', '#00FF00' @@ -157,6 +159,19 @@ } } + get dropShadowAlpha() + { + return this._dropShadowAlpha; + } + set dropShadowAlpha(dropShadowAlpha) + { + if (this._dropShadowAlpha !== dropShadowAlpha) + { + this._dropShadowAlpha = dropShadowAlpha; + this.styleID++; + } + } + get dropShadowAngle() { return this._dropShadowAngle; @@ -511,8 +526,8 @@ * Utility function to convert hexadecimal colors to strings, and simply return the color if it's a string. * This version can also convert array of colors * - * @param {Array} array1 First array to compared - * @param {Array} array1 Second array to compare + * @param {Array} array1 First array to compare + * @param {Array} array2 Second array to compare * @return {boolean} Do the arrays contain the same values in the same order */ function areArraysEqual(array1, array2) diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index 2fa08c4..aa727f0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -1,8 +1,6 @@ import BaseTexture from './BaseTexture'; import settings from '../settings'; -const { SCALE_MODE } = settings; - /** * A BaseRenderTexture is a special texture that allows any Pixi display object to be rendered to it. * @@ -62,7 +60,7 @@ this.realWidth = this.width * this.resolution; this.realHeight = this.height * this.resolution; - this.scaleMode = scaleMode || SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 676dca3..853de7e 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -77,7 +77,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Set to true once the base texture has successfully loaded. diff --git a/src/core/textures/RenderTexture.js b/src/core/textures/RenderTexture.js index 4c5034f..b3c6297 100644 --- a/src/core/textures/RenderTexture.js +++ b/src/core/textures/RenderTexture.js @@ -54,8 +54,8 @@ /* eslint-disable prefer-rest-params, no-console */ const width = arguments[1]; const height = arguments[2]; - const scaleMode = arguments[3] || 0; - const resolution = arguments[4] || 1; + const scaleMode = arguments[3]; + const resolution = arguments[4]; // we have an old render texture.. console.warn(`Please use RenderTexture.create(${width}, ${height}) instead of the ctor directly.`); diff --git a/src/prepare/BasePrepare.js b/src/prepare/BasePrepare.js index a2005f5..09eb5e5 100644 --- a/src/prepare/BasePrepare.js +++ b/src/prepare/BasePrepare.js @@ -20,7 +20,7 @@ * * @abstract * @class - * @memberof PIXI + * @memberof PIXI.prepare */ export default class BasePrepare { @@ -107,9 +107,9 @@ /** * Upload all the textures and graphics to the GPU. * - * @param {Function|PIXI.DisplayObject|PIXI.Container} item - Either - * the container or display object to search for items to upload or - * the callback function, if items have been added using `prepare.add`. + * @param {Function|PIXI.DisplayObject|PIXI.Container|PIXI.BaseTexture|PIXI.Texture|PIXI.Graphics|PIXI.Text} item - + * Either the container or display object to search for items to upload, the items to upload themselves, + * or the callback function, if items have been added using `prepare.add`. * @param {Function} [done] - Optional callback when all queued uploads have completed */ upload(item, done) @@ -236,7 +236,8 @@ /** * Manually add an item to the uploading queue. * - * @param {PIXI.DisplayObject|PIXI.Container|*} item - Object to add to the queue + * @param {PIXI.DisplayObject|PIXI.Container|PIXI.BaseTexture|PIXI.Texture|PIXI.Graphics|PIXI.Text|*} item - Object to + * add to the queue * @return {PIXI.CanvasPrepare} Instance of plugin for chaining. */ add(item) diff --git a/src/prepare/canvas/CanvasPrepare.js b/src/prepare/canvas/CanvasPrepare.js index 4b99d22..0224bb5 100644 --- a/src/prepare/canvas/CanvasPrepare.js +++ b/src/prepare/canvas/CanvasPrepare.js @@ -12,7 +12,8 @@ * An instance of this class is automatically created by default, and can be found at renderer.plugins.prepare * * @class - * @memberof PIXI + * @extends PIXI.prepare.BasePrepare + * @memberof PIXI.prepare */ export default class CanvasPrepare extends BasePrepare { diff --git a/src/prepare/webgl/WebGLPrepare.js b/src/prepare/webgl/WebGLPrepare.js index 1ef7467..eb7023f 100644 --- a/src/prepare/webgl/WebGLPrepare.js +++ b/src/prepare/webgl/WebGLPrepare.js @@ -7,7 +7,8 @@ * An instance of this class is automatically created by default, and can be found at renderer.plugins.prepare * * @class - * @memberof PIXI + * @extends PIXI.prepare.BasePrepare + * @memberof PIXI.prepare */ export default class WebGLPrepare extends BasePrepare { diff --git a/src/core/Application.js b/src/core/Application.js index bc730db..ea0f058 100644 --- a/src/core/Application.js +++ b/src/core/Application.js @@ -33,6 +33,9 @@ * need to call toDataUrl on the webgl context * @param {number} [options.resolution=1] - The resolution / device pixel ratio of the renderer, retina would be 2 * @param {boolean} [noWebGL=false] - prevents selection of WebGL renderer, even if such is present + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experience unexplained flickering try setting this to true. + */ constructor(width, height, options, noWebGL) { diff --git a/src/core/display/Container.js b/src/core/display/Container.js index b3792ef..ed8cd5f 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -74,12 +74,12 @@ child.parent = this; + this.children.push(child); + // ensure a transform will be recalculated.. this.transform._parentID = -1; this._boundsID++; - this.children.push(child); - // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(this.children.length - 1); child.emit('added', this); @@ -111,6 +111,10 @@ this.children.splice(index, 0, child); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('added', this); @@ -174,6 +178,7 @@ removeItems(this.children, currentIndex, 1); // remove from old position this.children.splice(index, 0, child); // add at new position + this.onChildrenChange(index); } @@ -247,6 +252,10 @@ child.parent = null; removeItems(this.children, index, 1); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('removed', this); @@ -277,6 +286,13 @@ removed[i].parent = null; } + // ensure a transform will be recalculated.. + if (this.transform) + { + this.transform._parentID = -1; + } + this._boundsID++; + this.onChildrenChange(beginIndex); for (let i = 0; i < removed.length; ++i) diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index ce0e1c4..75ae9b5 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -49,11 +49,20 @@ * enable this if you need to call toDataUrl on the webgl context. * @param {boolean} [options.roundPixels=false] - If true Pixi will Math.floor() x/y values when * rendering, stopping pixel interpolation. + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experiance unexplained flickering try setting this to true. */ constructor(width, height, options = {}) { super('WebGL', width, height, options); + this.legacy = !!options.legacy; + + if (this.legacy) + { + glCore.VertexArrayObject.FORCE_NATIVE = true; + } + /** * The type of this renderer as a standardised const * diff --git a/src/core/renderers/webgl/utils/RenderTarget.js b/src/core/renderers/webgl/utils/RenderTarget.js index afe51ab..6d2467f 100644 --- a/src/core/renderers/webgl/utils/RenderTarget.js +++ b/src/core/renderers/webgl/utils/RenderTarget.js @@ -124,7 +124,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Whether this object is the root element or not diff --git a/src/core/sprites/Sprite.js b/src/core/sprites/Sprite.js index 36ea5bb..28b0b18 100644 --- a/src/core/sprites/Sprite.js +++ b/src/core/sprites/Sprite.js @@ -346,8 +346,8 @@ /** * Gets the local bounds of the sprite object. * - * @param {Rectangle} rect - The output rectangle. - * @return {Rectangle} The bounds. + * @param {PIXI.Rectangle} rect - The output rectangle. + * @return {PIXI.Rectangle} The bounds. */ getLocalBounds(rect) { @@ -440,7 +440,7 @@ * * @static * @param {number|string|PIXI.BaseTexture|HTMLCanvasElement|HTMLVideoElement} source Source to create texture from - * @return {PIXI.Texture} The newly created texture + * @return {PIXI.Sprite} The newly created texture */ static from(source) { diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 9b349bd..f7cc1a0 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -103,11 +103,18 @@ { const gl = this.renderer.gl; - // step 1: first check max textures the GPU can handle. - this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); + if (this.renderer.legacy) + { + this.MAX_TEXTURES = 1; + } + else + { + // step 1: first check max textures the GPU can handle. + this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); - // step 2: check the maximum number of if statements the shader can have too.. - this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + // step 2: check the maximum number of if statements the shader can have too.. + this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + } const shader = this.shader = generateMultiTextureShader(gl, this.MAX_TEXTURES); diff --git a/src/core/text/Text.js b/src/core/text/Text.js index 18fb723..cec8c32 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -191,6 +191,7 @@ if (style.dropShadow) { this.context.shadowBlur = style.dropShadowBlur; + this.context.globalAlpha = style.dropShadowAlpha; if (style.dropShadowBlur > 0) { @@ -239,12 +240,13 @@ } } + // reset the shadow blur and alpha that was set by the drop shadow, for the regular text + this.context.shadowBlur = 0; + this.context.globalAlpha = 1; + // set canvas text styles this.context.fillStyle = this._generateFillStyle(style, lines); - // remove blur if set for the drop shadow - this.context.shadowBlur = 0; - // draw lines line by line for (let i = 0; i < lines.length; i++) { diff --git a/src/core/text/TextStyle.js b/src/core/text/TextStyle.js index eec2820..890950b 100644 --- a/src/core/text/TextStyle.js +++ b/src/core/text/TextStyle.js @@ -8,6 +8,7 @@ align: 'left', breakWords: false, dropShadow: false, + dropShadowAlpha: 1, dropShadowAngle: Math.PI / 6, dropShadowBlur: 0, dropShadowColor: '#000000', @@ -49,6 +50,7 @@ * @param {boolean} [style.breakWords=false] - Indicates if lines can be wrapped within words, it * needs wordWrap to be set to true * @param {boolean} [style.dropShadow=false] - Set a drop shadow for the text + * @param {number} [style.dropShadowAlpha=1] - Set alpha for the drop shadow * @param {number} [style.dropShadowAngle=Math.PI/6] - Set a angle of the drop shadow * @param {number} [style.dropShadowBlur=0] - Set a shadow blur radius * @param {string} [style.dropShadowColor='#000000'] - A fill style to be used on the dropshadow e.g 'red', '#00FF00' @@ -157,6 +159,19 @@ } } + get dropShadowAlpha() + { + return this._dropShadowAlpha; + } + set dropShadowAlpha(dropShadowAlpha) + { + if (this._dropShadowAlpha !== dropShadowAlpha) + { + this._dropShadowAlpha = dropShadowAlpha; + this.styleID++; + } + } + get dropShadowAngle() { return this._dropShadowAngle; @@ -511,8 +526,8 @@ * Utility function to convert hexadecimal colors to strings, and simply return the color if it's a string. * This version can also convert array of colors * - * @param {Array} array1 First array to compared - * @param {Array} array1 Second array to compare + * @param {Array} array1 First array to compare + * @param {Array} array2 Second array to compare * @return {boolean} Do the arrays contain the same values in the same order */ function areArraysEqual(array1, array2) diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index 2fa08c4..aa727f0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -1,8 +1,6 @@ import BaseTexture from './BaseTexture'; import settings from '../settings'; -const { SCALE_MODE } = settings; - /** * A BaseRenderTexture is a special texture that allows any Pixi display object to be rendered to it. * @@ -62,7 +60,7 @@ this.realWidth = this.width * this.resolution; this.realHeight = this.height * this.resolution; - this.scaleMode = scaleMode || SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 676dca3..853de7e 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -77,7 +77,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Set to true once the base texture has successfully loaded. diff --git a/src/core/textures/RenderTexture.js b/src/core/textures/RenderTexture.js index 4c5034f..b3c6297 100644 --- a/src/core/textures/RenderTexture.js +++ b/src/core/textures/RenderTexture.js @@ -54,8 +54,8 @@ /* eslint-disable prefer-rest-params, no-console */ const width = arguments[1]; const height = arguments[2]; - const scaleMode = arguments[3] || 0; - const resolution = arguments[4] || 1; + const scaleMode = arguments[3]; + const resolution = arguments[4]; // we have an old render texture.. console.warn(`Please use RenderTexture.create(${width}, ${height}) instead of the ctor directly.`); diff --git a/src/prepare/BasePrepare.js b/src/prepare/BasePrepare.js index a2005f5..09eb5e5 100644 --- a/src/prepare/BasePrepare.js +++ b/src/prepare/BasePrepare.js @@ -20,7 +20,7 @@ * * @abstract * @class - * @memberof PIXI + * @memberof PIXI.prepare */ export default class BasePrepare { @@ -107,9 +107,9 @@ /** * Upload all the textures and graphics to the GPU. * - * @param {Function|PIXI.DisplayObject|PIXI.Container} item - Either - * the container or display object to search for items to upload or - * the callback function, if items have been added using `prepare.add`. + * @param {Function|PIXI.DisplayObject|PIXI.Container|PIXI.BaseTexture|PIXI.Texture|PIXI.Graphics|PIXI.Text} item - + * Either the container or display object to search for items to upload, the items to upload themselves, + * or the callback function, if items have been added using `prepare.add`. * @param {Function} [done] - Optional callback when all queued uploads have completed */ upload(item, done) @@ -236,7 +236,8 @@ /** * Manually add an item to the uploading queue. * - * @param {PIXI.DisplayObject|PIXI.Container|*} item - Object to add to the queue + * @param {PIXI.DisplayObject|PIXI.Container|PIXI.BaseTexture|PIXI.Texture|PIXI.Graphics|PIXI.Text|*} item - Object to + * add to the queue * @return {PIXI.CanvasPrepare} Instance of plugin for chaining. */ add(item) diff --git a/src/prepare/canvas/CanvasPrepare.js b/src/prepare/canvas/CanvasPrepare.js index 4b99d22..0224bb5 100644 --- a/src/prepare/canvas/CanvasPrepare.js +++ b/src/prepare/canvas/CanvasPrepare.js @@ -12,7 +12,8 @@ * An instance of this class is automatically created by default, and can be found at renderer.plugins.prepare * * @class - * @memberof PIXI + * @extends PIXI.prepare.BasePrepare + * @memberof PIXI.prepare */ export default class CanvasPrepare extends BasePrepare { diff --git a/src/prepare/webgl/WebGLPrepare.js b/src/prepare/webgl/WebGLPrepare.js index 1ef7467..eb7023f 100644 --- a/src/prepare/webgl/WebGLPrepare.js +++ b/src/prepare/webgl/WebGLPrepare.js @@ -7,7 +7,8 @@ * An instance of this class is automatically created by default, and can be found at renderer.plugins.prepare * * @class - * @memberof PIXI + * @extends PIXI.prepare.BasePrepare + * @memberof PIXI.prepare */ export default class WebGLPrepare extends BasePrepare { diff --git a/test/core/Graphics.js b/test/core/Graphics.js index 2a64946..98c7584 100644 --- a/test/core/Graphics.js +++ b/test/core/Graphics.js @@ -127,6 +127,16 @@ expect(graphics.containsPoint(point)).to.be.false; }); + + it('should return false when no fill', function () + { + const point = new PIXI.Point(1, 1); + const graphics = new PIXI.Graphics(); + + graphics.drawRect(0, 0, 10, 10); + + expect(graphics.containsPoint(point)).to.be.false; + }); }); describe('arc', function () diff --git a/src/core/Application.js b/src/core/Application.js index bc730db..ea0f058 100644 --- a/src/core/Application.js +++ b/src/core/Application.js @@ -33,6 +33,9 @@ * need to call toDataUrl on the webgl context * @param {number} [options.resolution=1] - The resolution / device pixel ratio of the renderer, retina would be 2 * @param {boolean} [noWebGL=false] - prevents selection of WebGL renderer, even if such is present + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experience unexplained flickering try setting this to true. + */ constructor(width, height, options, noWebGL) { diff --git a/src/core/display/Container.js b/src/core/display/Container.js index b3792ef..ed8cd5f 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -74,12 +74,12 @@ child.parent = this; + this.children.push(child); + // ensure a transform will be recalculated.. this.transform._parentID = -1; this._boundsID++; - this.children.push(child); - // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(this.children.length - 1); child.emit('added', this); @@ -111,6 +111,10 @@ this.children.splice(index, 0, child); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('added', this); @@ -174,6 +178,7 @@ removeItems(this.children, currentIndex, 1); // remove from old position this.children.splice(index, 0, child); // add at new position + this.onChildrenChange(index); } @@ -247,6 +252,10 @@ child.parent = null; removeItems(this.children, index, 1); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('removed', this); @@ -277,6 +286,13 @@ removed[i].parent = null; } + // ensure a transform will be recalculated.. + if (this.transform) + { + this.transform._parentID = -1; + } + this._boundsID++; + this.onChildrenChange(beginIndex); for (let i = 0; i < removed.length; ++i) diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index ce0e1c4..75ae9b5 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -49,11 +49,20 @@ * enable this if you need to call toDataUrl on the webgl context. * @param {boolean} [options.roundPixels=false] - If true Pixi will Math.floor() x/y values when * rendering, stopping pixel interpolation. + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experiance unexplained flickering try setting this to true. */ constructor(width, height, options = {}) { super('WebGL', width, height, options); + this.legacy = !!options.legacy; + + if (this.legacy) + { + glCore.VertexArrayObject.FORCE_NATIVE = true; + } + /** * The type of this renderer as a standardised const * diff --git a/src/core/renderers/webgl/utils/RenderTarget.js b/src/core/renderers/webgl/utils/RenderTarget.js index afe51ab..6d2467f 100644 --- a/src/core/renderers/webgl/utils/RenderTarget.js +++ b/src/core/renderers/webgl/utils/RenderTarget.js @@ -124,7 +124,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Whether this object is the root element or not diff --git a/src/core/sprites/Sprite.js b/src/core/sprites/Sprite.js index 36ea5bb..28b0b18 100644 --- a/src/core/sprites/Sprite.js +++ b/src/core/sprites/Sprite.js @@ -346,8 +346,8 @@ /** * Gets the local bounds of the sprite object. * - * @param {Rectangle} rect - The output rectangle. - * @return {Rectangle} The bounds. + * @param {PIXI.Rectangle} rect - The output rectangle. + * @return {PIXI.Rectangle} The bounds. */ getLocalBounds(rect) { @@ -440,7 +440,7 @@ * * @static * @param {number|string|PIXI.BaseTexture|HTMLCanvasElement|HTMLVideoElement} source Source to create texture from - * @return {PIXI.Texture} The newly created texture + * @return {PIXI.Sprite} The newly created texture */ static from(source) { diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 9b349bd..f7cc1a0 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -103,11 +103,18 @@ { const gl = this.renderer.gl; - // step 1: first check max textures the GPU can handle. - this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); + if (this.renderer.legacy) + { + this.MAX_TEXTURES = 1; + } + else + { + // step 1: first check max textures the GPU can handle. + this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); - // step 2: check the maximum number of if statements the shader can have too.. - this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + // step 2: check the maximum number of if statements the shader can have too.. + this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + } const shader = this.shader = generateMultiTextureShader(gl, this.MAX_TEXTURES); diff --git a/src/core/text/Text.js b/src/core/text/Text.js index 18fb723..cec8c32 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -191,6 +191,7 @@ if (style.dropShadow) { this.context.shadowBlur = style.dropShadowBlur; + this.context.globalAlpha = style.dropShadowAlpha; if (style.dropShadowBlur > 0) { @@ -239,12 +240,13 @@ } } + // reset the shadow blur and alpha that was set by the drop shadow, for the regular text + this.context.shadowBlur = 0; + this.context.globalAlpha = 1; + // set canvas text styles this.context.fillStyle = this._generateFillStyle(style, lines); - // remove blur if set for the drop shadow - this.context.shadowBlur = 0; - // draw lines line by line for (let i = 0; i < lines.length; i++) { diff --git a/src/core/text/TextStyle.js b/src/core/text/TextStyle.js index eec2820..890950b 100644 --- a/src/core/text/TextStyle.js +++ b/src/core/text/TextStyle.js @@ -8,6 +8,7 @@ align: 'left', breakWords: false, dropShadow: false, + dropShadowAlpha: 1, dropShadowAngle: Math.PI / 6, dropShadowBlur: 0, dropShadowColor: '#000000', @@ -49,6 +50,7 @@ * @param {boolean} [style.breakWords=false] - Indicates if lines can be wrapped within words, it * needs wordWrap to be set to true * @param {boolean} [style.dropShadow=false] - Set a drop shadow for the text + * @param {number} [style.dropShadowAlpha=1] - Set alpha for the drop shadow * @param {number} [style.dropShadowAngle=Math.PI/6] - Set a angle of the drop shadow * @param {number} [style.dropShadowBlur=0] - Set a shadow blur radius * @param {string} [style.dropShadowColor='#000000'] - A fill style to be used on the dropshadow e.g 'red', '#00FF00' @@ -157,6 +159,19 @@ } } + get dropShadowAlpha() + { + return this._dropShadowAlpha; + } + set dropShadowAlpha(dropShadowAlpha) + { + if (this._dropShadowAlpha !== dropShadowAlpha) + { + this._dropShadowAlpha = dropShadowAlpha; + this.styleID++; + } + } + get dropShadowAngle() { return this._dropShadowAngle; @@ -511,8 +526,8 @@ * Utility function to convert hexadecimal colors to strings, and simply return the color if it's a string. * This version can also convert array of colors * - * @param {Array} array1 First array to compared - * @param {Array} array1 Second array to compare + * @param {Array} array1 First array to compare + * @param {Array} array2 Second array to compare * @return {boolean} Do the arrays contain the same values in the same order */ function areArraysEqual(array1, array2) diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index 2fa08c4..aa727f0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -1,8 +1,6 @@ import BaseTexture from './BaseTexture'; import settings from '../settings'; -const { SCALE_MODE } = settings; - /** * A BaseRenderTexture is a special texture that allows any Pixi display object to be rendered to it. * @@ -62,7 +60,7 @@ this.realWidth = this.width * this.resolution; this.realHeight = this.height * this.resolution; - this.scaleMode = scaleMode || SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 676dca3..853de7e 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -77,7 +77,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Set to true once the base texture has successfully loaded. diff --git a/src/core/textures/RenderTexture.js b/src/core/textures/RenderTexture.js index 4c5034f..b3c6297 100644 --- a/src/core/textures/RenderTexture.js +++ b/src/core/textures/RenderTexture.js @@ -54,8 +54,8 @@ /* eslint-disable prefer-rest-params, no-console */ const width = arguments[1]; const height = arguments[2]; - const scaleMode = arguments[3] || 0; - const resolution = arguments[4] || 1; + const scaleMode = arguments[3]; + const resolution = arguments[4]; // we have an old render texture.. console.warn(`Please use RenderTexture.create(${width}, ${height}) instead of the ctor directly.`); diff --git a/src/prepare/BasePrepare.js b/src/prepare/BasePrepare.js index a2005f5..09eb5e5 100644 --- a/src/prepare/BasePrepare.js +++ b/src/prepare/BasePrepare.js @@ -20,7 +20,7 @@ * * @abstract * @class - * @memberof PIXI + * @memberof PIXI.prepare */ export default class BasePrepare { @@ -107,9 +107,9 @@ /** * Upload all the textures and graphics to the GPU. * - * @param {Function|PIXI.DisplayObject|PIXI.Container} item - Either - * the container or display object to search for items to upload or - * the callback function, if items have been added using `prepare.add`. + * @param {Function|PIXI.DisplayObject|PIXI.Container|PIXI.BaseTexture|PIXI.Texture|PIXI.Graphics|PIXI.Text} item - + * Either the container or display object to search for items to upload, the items to upload themselves, + * or the callback function, if items have been added using `prepare.add`. * @param {Function} [done] - Optional callback when all queued uploads have completed */ upload(item, done) @@ -236,7 +236,8 @@ /** * Manually add an item to the uploading queue. * - * @param {PIXI.DisplayObject|PIXI.Container|*} item - Object to add to the queue + * @param {PIXI.DisplayObject|PIXI.Container|PIXI.BaseTexture|PIXI.Texture|PIXI.Graphics|PIXI.Text|*} item - Object to + * add to the queue * @return {PIXI.CanvasPrepare} Instance of plugin for chaining. */ add(item) diff --git a/src/prepare/canvas/CanvasPrepare.js b/src/prepare/canvas/CanvasPrepare.js index 4b99d22..0224bb5 100644 --- a/src/prepare/canvas/CanvasPrepare.js +++ b/src/prepare/canvas/CanvasPrepare.js @@ -12,7 +12,8 @@ * An instance of this class is automatically created by default, and can be found at renderer.plugins.prepare * * @class - * @memberof PIXI + * @extends PIXI.prepare.BasePrepare + * @memberof PIXI.prepare */ export default class CanvasPrepare extends BasePrepare { diff --git a/src/prepare/webgl/WebGLPrepare.js b/src/prepare/webgl/WebGLPrepare.js index 1ef7467..eb7023f 100644 --- a/src/prepare/webgl/WebGLPrepare.js +++ b/src/prepare/webgl/WebGLPrepare.js @@ -7,7 +7,8 @@ * An instance of this class is automatically created by default, and can be found at renderer.plugins.prepare * * @class - * @memberof PIXI + * @extends PIXI.prepare.BasePrepare + * @memberof PIXI.prepare */ export default class WebGLPrepare extends BasePrepare { diff --git a/test/core/Graphics.js b/test/core/Graphics.js index 2a64946..98c7584 100644 --- a/test/core/Graphics.js +++ b/test/core/Graphics.js @@ -127,6 +127,16 @@ expect(graphics.containsPoint(point)).to.be.false; }); + + it('should return false when no fill', function () + { + const point = new PIXI.Point(1, 1); + const graphics = new PIXI.Graphics(); + + graphics.drawRect(0, 0, 10, 10); + + expect(graphics.containsPoint(point)).to.be.false; + }); }); describe('arc', function () diff --git a/test/core/WebGLRenderer.js b/test/core/WebGLRenderer.js new file mode 100644 index 0000000..f0e9bc8 --- /dev/null +++ b/test/core/WebGLRenderer.js @@ -0,0 +1,19 @@ +'use strict'; + +function isWebGLSupported(fn) +{ + return PIXI.utils.isWebGLSupported() ? fn : function () {}; // eslint-disable-line no-empty-function +} + +describe('PIXI.WebGLRenderer', isWebGLSupported(function () +{ + it('setting option legacy should disable VAOs and set minimum SPRITE_MAX_TEXTURES to 1', function () + { + const renderer = new PIXI.WebGLRenderer(1, 1, { legacy: true }); + + expect(PIXI.glCore.VertexArrayObject.FORCE_NATIVE).to.equal(true); + expect(renderer.plugins.sprite.MAX_TEXTURES).to.equal(1); + + renderer.destroy(); + }); +})); diff --git a/src/core/Application.js b/src/core/Application.js index bc730db..ea0f058 100644 --- a/src/core/Application.js +++ b/src/core/Application.js @@ -33,6 +33,9 @@ * need to call toDataUrl on the webgl context * @param {number} [options.resolution=1] - The resolution / device pixel ratio of the renderer, retina would be 2 * @param {boolean} [noWebGL=false] - prevents selection of WebGL renderer, even if such is present + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experience unexplained flickering try setting this to true. + */ constructor(width, height, options, noWebGL) { diff --git a/src/core/display/Container.js b/src/core/display/Container.js index b3792ef..ed8cd5f 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -74,12 +74,12 @@ child.parent = this; + this.children.push(child); + // ensure a transform will be recalculated.. this.transform._parentID = -1; this._boundsID++; - this.children.push(child); - // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(this.children.length - 1); child.emit('added', this); @@ -111,6 +111,10 @@ this.children.splice(index, 0, child); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('added', this); @@ -174,6 +178,7 @@ removeItems(this.children, currentIndex, 1); // remove from old position this.children.splice(index, 0, child); // add at new position + this.onChildrenChange(index); } @@ -247,6 +252,10 @@ child.parent = null; removeItems(this.children, index, 1); + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this._boundsID++; + // TODO - lets either do all callbacks or all events.. not both! this.onChildrenChange(index); child.emit('removed', this); @@ -277,6 +286,13 @@ removed[i].parent = null; } + // ensure a transform will be recalculated.. + if (this.transform) + { + this.transform._parentID = -1; + } + this._boundsID++; + this.onChildrenChange(beginIndex); for (let i = 0; i < removed.length; ++i) diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index ce0e1c4..75ae9b5 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -49,11 +49,20 @@ * enable this if you need to call toDataUrl on the webgl context. * @param {boolean} [options.roundPixels=false] - If true Pixi will Math.floor() x/y values when * rendering, stopping pixel interpolation. + * @param {boolean} [options.legacy=false] - If true Pixi will aim to ensure compatibility + * with older / less advanced devices. If you experiance unexplained flickering try setting this to true. */ constructor(width, height, options = {}) { super('WebGL', width, height, options); + this.legacy = !!options.legacy; + + if (this.legacy) + { + glCore.VertexArrayObject.FORCE_NATIVE = true; + } + /** * The type of this renderer as a standardised const * diff --git a/src/core/renderers/webgl/utils/RenderTarget.js b/src/core/renderers/webgl/utils/RenderTarget.js index afe51ab..6d2467f 100644 --- a/src/core/renderers/webgl/utils/RenderTarget.js +++ b/src/core/renderers/webgl/utils/RenderTarget.js @@ -124,7 +124,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Whether this object is the root element or not diff --git a/src/core/sprites/Sprite.js b/src/core/sprites/Sprite.js index 36ea5bb..28b0b18 100644 --- a/src/core/sprites/Sprite.js +++ b/src/core/sprites/Sprite.js @@ -346,8 +346,8 @@ /** * Gets the local bounds of the sprite object. * - * @param {Rectangle} rect - The output rectangle. - * @return {Rectangle} The bounds. + * @param {PIXI.Rectangle} rect - The output rectangle. + * @return {PIXI.Rectangle} The bounds. */ getLocalBounds(rect) { @@ -440,7 +440,7 @@ * * @static * @param {number|string|PIXI.BaseTexture|HTMLCanvasElement|HTMLVideoElement} source Source to create texture from - * @return {PIXI.Texture} The newly created texture + * @return {PIXI.Sprite} The newly created texture */ static from(source) { diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 9b349bd..f7cc1a0 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -103,11 +103,18 @@ { const gl = this.renderer.gl; - // step 1: first check max textures the GPU can handle. - this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); + if (this.renderer.legacy) + { + this.MAX_TEXTURES = 1; + } + else + { + // step 1: first check max textures the GPU can handle. + this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); - // step 2: check the maximum number of if statements the shader can have too.. - this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + // step 2: check the maximum number of if statements the shader can have too.. + this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); + } const shader = this.shader = generateMultiTextureShader(gl, this.MAX_TEXTURES); diff --git a/src/core/text/Text.js b/src/core/text/Text.js index 18fb723..cec8c32 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -191,6 +191,7 @@ if (style.dropShadow) { this.context.shadowBlur = style.dropShadowBlur; + this.context.globalAlpha = style.dropShadowAlpha; if (style.dropShadowBlur > 0) { @@ -239,12 +240,13 @@ } } + // reset the shadow blur and alpha that was set by the drop shadow, for the regular text + this.context.shadowBlur = 0; + this.context.globalAlpha = 1; + // set canvas text styles this.context.fillStyle = this._generateFillStyle(style, lines); - // remove blur if set for the drop shadow - this.context.shadowBlur = 0; - // draw lines line by line for (let i = 0; i < lines.length; i++) { diff --git a/src/core/text/TextStyle.js b/src/core/text/TextStyle.js index eec2820..890950b 100644 --- a/src/core/text/TextStyle.js +++ b/src/core/text/TextStyle.js @@ -8,6 +8,7 @@ align: 'left', breakWords: false, dropShadow: false, + dropShadowAlpha: 1, dropShadowAngle: Math.PI / 6, dropShadowBlur: 0, dropShadowColor: '#000000', @@ -49,6 +50,7 @@ * @param {boolean} [style.breakWords=false] - Indicates if lines can be wrapped within words, it * needs wordWrap to be set to true * @param {boolean} [style.dropShadow=false] - Set a drop shadow for the text + * @param {number} [style.dropShadowAlpha=1] - Set alpha for the drop shadow * @param {number} [style.dropShadowAngle=Math.PI/6] - Set a angle of the drop shadow * @param {number} [style.dropShadowBlur=0] - Set a shadow blur radius * @param {string} [style.dropShadowColor='#000000'] - A fill style to be used on the dropshadow e.g 'red', '#00FF00' @@ -157,6 +159,19 @@ } } + get dropShadowAlpha() + { + return this._dropShadowAlpha; + } + set dropShadowAlpha(dropShadowAlpha) + { + if (this._dropShadowAlpha !== dropShadowAlpha) + { + this._dropShadowAlpha = dropShadowAlpha; + this.styleID++; + } + } + get dropShadowAngle() { return this._dropShadowAngle; @@ -511,8 +526,8 @@ * Utility function to convert hexadecimal colors to strings, and simply return the color if it's a string. * This version can also convert array of colors * - * @param {Array} array1 First array to compared - * @param {Array} array1 Second array to compare + * @param {Array} array1 First array to compare + * @param {Array} array2 Second array to compare * @return {boolean} Do the arrays contain the same values in the same order */ function areArraysEqual(array1, array2) diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index 2fa08c4..aa727f0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -1,8 +1,6 @@ import BaseTexture from './BaseTexture'; import settings from '../settings'; -const { SCALE_MODE } = settings; - /** * A BaseRenderTexture is a special texture that allows any Pixi display object to be rendered to it. * @@ -62,7 +60,7 @@ this.realWidth = this.width * this.resolution; this.realHeight = this.height * this.resolution; - this.scaleMode = scaleMode || SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 676dca3..853de7e 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -77,7 +77,7 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = scaleMode || settings.SCALE_MODE; + this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; /** * Set to true once the base texture has successfully loaded. diff --git a/src/core/textures/RenderTexture.js b/src/core/textures/RenderTexture.js index 4c5034f..b3c6297 100644 --- a/src/core/textures/RenderTexture.js +++ b/src/core/textures/RenderTexture.js @@ -54,8 +54,8 @@ /* eslint-disable prefer-rest-params, no-console */ const width = arguments[1]; const height = arguments[2]; - const scaleMode = arguments[3] || 0; - const resolution = arguments[4] || 1; + const scaleMode = arguments[3]; + const resolution = arguments[4]; // we have an old render texture.. console.warn(`Please use RenderTexture.create(${width}, ${height}) instead of the ctor directly.`); diff --git a/src/prepare/BasePrepare.js b/src/prepare/BasePrepare.js index a2005f5..09eb5e5 100644 --- a/src/prepare/BasePrepare.js +++ b/src/prepare/BasePrepare.js @@ -20,7 +20,7 @@ * * @abstract * @class - * @memberof PIXI + * @memberof PIXI.prepare */ export default class BasePrepare { @@ -107,9 +107,9 @@ /** * Upload all the textures and graphics to the GPU. * - * @param {Function|PIXI.DisplayObject|PIXI.Container} item - Either - * the container or display object to search for items to upload or - * the callback function, if items have been added using `prepare.add`. + * @param {Function|PIXI.DisplayObject|PIXI.Container|PIXI.BaseTexture|PIXI.Texture|PIXI.Graphics|PIXI.Text} item - + * Either the container or display object to search for items to upload, the items to upload themselves, + * or the callback function, if items have been added using `prepare.add`. * @param {Function} [done] - Optional callback when all queued uploads have completed */ upload(item, done) @@ -236,7 +236,8 @@ /** * Manually add an item to the uploading queue. * - * @param {PIXI.DisplayObject|PIXI.Container|*} item - Object to add to the queue + * @param {PIXI.DisplayObject|PIXI.Container|PIXI.BaseTexture|PIXI.Texture|PIXI.Graphics|PIXI.Text|*} item - Object to + * add to the queue * @return {PIXI.CanvasPrepare} Instance of plugin for chaining. */ add(item) diff --git a/src/prepare/canvas/CanvasPrepare.js b/src/prepare/canvas/CanvasPrepare.js index 4b99d22..0224bb5 100644 --- a/src/prepare/canvas/CanvasPrepare.js +++ b/src/prepare/canvas/CanvasPrepare.js @@ -12,7 +12,8 @@ * An instance of this class is automatically created by default, and can be found at renderer.plugins.prepare * * @class - * @memberof PIXI + * @extends PIXI.prepare.BasePrepare + * @memberof PIXI.prepare */ export default class CanvasPrepare extends BasePrepare { diff --git a/src/prepare/webgl/WebGLPrepare.js b/src/prepare/webgl/WebGLPrepare.js index 1ef7467..eb7023f 100644 --- a/src/prepare/webgl/WebGLPrepare.js +++ b/src/prepare/webgl/WebGLPrepare.js @@ -7,7 +7,8 @@ * An instance of this class is automatically created by default, and can be found at renderer.plugins.prepare * * @class - * @memberof PIXI + * @extends PIXI.prepare.BasePrepare + * @memberof PIXI.prepare */ export default class WebGLPrepare extends BasePrepare { diff --git a/test/core/Graphics.js b/test/core/Graphics.js index 2a64946..98c7584 100644 --- a/test/core/Graphics.js +++ b/test/core/Graphics.js @@ -127,6 +127,16 @@ expect(graphics.containsPoint(point)).to.be.false; }); + + it('should return false when no fill', function () + { + const point = new PIXI.Point(1, 1); + const graphics = new PIXI.Graphics(); + + graphics.drawRect(0, 0, 10, 10); + + expect(graphics.containsPoint(point)).to.be.false; + }); }); describe('arc', function () diff --git a/test/core/WebGLRenderer.js b/test/core/WebGLRenderer.js new file mode 100644 index 0000000..f0e9bc8 --- /dev/null +++ b/test/core/WebGLRenderer.js @@ -0,0 +1,19 @@ +'use strict'; + +function isWebGLSupported(fn) +{ + return PIXI.utils.isWebGLSupported() ? fn : function () {}; // eslint-disable-line no-empty-function +} + +describe('PIXI.WebGLRenderer', isWebGLSupported(function () +{ + it('setting option legacy should disable VAOs and set minimum SPRITE_MAX_TEXTURES to 1', function () + { + const renderer = new PIXI.WebGLRenderer(1, 1, { legacy: true }); + + expect(PIXI.glCore.VertexArrayObject.FORCE_NATIVE).to.equal(true); + expect(renderer.plugins.sprite.MAX_TEXTURES).to.equal(1); + + renderer.destroy(); + }); +})); diff --git a/test/core/index.js b/test/core/index.js index 2a056a2..63a8f21 100755 --- a/test/core/index.js +++ b/test/core/index.js @@ -23,4 +23,5 @@ require('./Circle'); require('./Graphics'); require('./SpriteRenderer'); +require('./WebGLRenderer'); require('./Ellipse');