diff --git a/package-lock.json b/package-lock.json index eb731c3..a16c04b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2868,7 +2868,7 @@ }, "yargs": { "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { @@ -9992,14 +9992,28 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" + }, + "dependencies": { + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + } } }, "temp-dir": { diff --git a/package-lock.json b/package-lock.json index eb731c3..a16c04b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2868,7 +2868,7 @@ }, "yargs": { "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { @@ -9992,14 +9992,28 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" + }, + "dependencies": { + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + } } }, "temp-dir": { diff --git a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js index fde693f..b7b7a7e 100644 --- a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js +++ b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js @@ -82,6 +82,8 @@ const holes = data.holes; let outerArea; let innerArea; + let px; + let py; context.moveTo(points[0], points[1]); @@ -98,19 +100,30 @@ if (holes.length > 0) { outerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + outerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } for (let k = 0; k < holes.length; k++) { - points = holes[k].points; + points = holes[k].shape.points; + + if (!points) + { + continue; + } innerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + innerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } if (innerArea * outerArea < 0) diff --git a/package-lock.json b/package-lock.json index eb731c3..a16c04b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2868,7 +2868,7 @@ }, "yargs": { "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { @@ -9992,14 +9992,28 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" + }, + "dependencies": { + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + } } }, "temp-dir": { diff --git a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js index fde693f..b7b7a7e 100644 --- a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js +++ b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js @@ -82,6 +82,8 @@ const holes = data.holes; let outerArea; let innerArea; + let px; + let py; context.moveTo(points[0], points[1]); @@ -98,19 +100,30 @@ if (holes.length > 0) { outerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + outerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } for (let k = 0; k < holes.length; k++) { - points = holes[k].points; + points = holes[k].shape.points; + + if (!points) + { + continue; + } innerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + innerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } if (innerArea * outerArea < 0) diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js index 8f4e0e4..4eac1d7 100644 --- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js +++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js @@ -29,7 +29,7 @@ const modY = ((this.tilePosition.y / this.tileScale.y) % texture._frame.height) * baseTextureResolution; // create a nice shiny pattern! - if (this._textureID !== this._texture._updateID || this.cachedTint !== this.tint) + if (this._textureID !== this._texture._updateID || this._cachedTint !== this.tint) { this._textureID = this._texture._updateID; // cut an object from a spritesheet.. @@ -48,7 +48,7 @@ tempCanvas.context.drawImage(source, -texture._frame.x * baseTextureResolution, -texture._frame.y * baseTextureResolution); } - this.cachedTint = this.tint; + this._cachedTint = this.tint; this._canvasPattern = tempCanvas.context.createPattern(tempCanvas.canvas, 'repeat'); } diff --git a/package-lock.json b/package-lock.json index eb731c3..a16c04b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2868,7 +2868,7 @@ }, "yargs": { "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { @@ -9992,14 +9992,28 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" + }, + "dependencies": { + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + } } }, "temp-dir": { diff --git a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js index fde693f..b7b7a7e 100644 --- a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js +++ b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js @@ -82,6 +82,8 @@ const holes = data.holes; let outerArea; let innerArea; + let px; + let py; context.moveTo(points[0], points[1]); @@ -98,19 +100,30 @@ if (holes.length > 0) { outerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + outerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } for (let k = 0; k < holes.length; k++) { - points = holes[k].points; + points = holes[k].shape.points; + + if (!points) + { + continue; + } innerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + innerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } if (innerArea * outerArea < 0) diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js index 8f4e0e4..4eac1d7 100644 --- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js +++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js @@ -29,7 +29,7 @@ const modY = ((this.tilePosition.y / this.tileScale.y) % texture._frame.height) * baseTextureResolution; // create a nice shiny pattern! - if (this._textureID !== this._texture._updateID || this.cachedTint !== this.tint) + if (this._textureID !== this._texture._updateID || this._cachedTint !== this.tint) { this._textureID = this._texture._updateID; // cut an object from a spritesheet.. @@ -48,7 +48,7 @@ tempCanvas.context.drawImage(source, -texture._frame.x * baseTextureResolution, -texture._frame.y * baseTextureResolution); } - this.cachedTint = this.tint; + this._cachedTint = this.tint; this._canvasPattern = tempCanvas.context.createPattern(tempCanvas.canvas, 'repeat'); } diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js index 297cb75..225beb0 100644 --- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js +++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js @@ -159,7 +159,7 @@ } context.drawImage( - source, + sprite._tintedCanvas, 0, 0, width * resolution, diff --git a/package-lock.json b/package-lock.json index eb731c3..a16c04b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2868,7 +2868,7 @@ }, "yargs": { "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { @@ -9992,14 +9992,28 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" + }, + "dependencies": { + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + } } }, "temp-dir": { diff --git a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js index fde693f..b7b7a7e 100644 --- a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js +++ b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js @@ -82,6 +82,8 @@ const holes = data.holes; let outerArea; let innerArea; + let px; + let py; context.moveTo(points[0], points[1]); @@ -98,19 +100,30 @@ if (holes.length > 0) { outerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + outerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } for (let k = 0; k < holes.length; k++) { - points = holes[k].points; + points = holes[k].shape.points; + + if (!points) + { + continue; + } innerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + innerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } if (innerArea * outerArea < 0) diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js index 8f4e0e4..4eac1d7 100644 --- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js +++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js @@ -29,7 +29,7 @@ const modY = ((this.tilePosition.y / this.tileScale.y) % texture._frame.height) * baseTextureResolution; // create a nice shiny pattern! - if (this._textureID !== this._texture._updateID || this.cachedTint !== this.tint) + if (this._textureID !== this._texture._updateID || this._cachedTint !== this.tint) { this._textureID = this._texture._updateID; // cut an object from a spritesheet.. @@ -48,7 +48,7 @@ tempCanvas.context.drawImage(source, -texture._frame.x * baseTextureResolution, -texture._frame.y * baseTextureResolution); } - this.cachedTint = this.tint; + this._cachedTint = this.tint; this._canvasPattern = tempCanvas.context.createPattern(tempCanvas.canvas, 'repeat'); } diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js index 297cb75..225beb0 100644 --- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js +++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js @@ -159,7 +159,7 @@ } context.drawImage( - source, + sprite._tintedCanvas, 0, 0, width * resolution, diff --git a/packages/canvas/canvas-sprite/src/Sprite.js b/packages/canvas/canvas-sprite/src/Sprite.js index 4bef51d..d94950f 100644 --- a/packages/canvas/canvas-sprite/src/Sprite.js +++ b/packages/canvas/canvas-sprite/src/Sprite.js @@ -9,14 +9,6 @@ Sprite.prototype._tintedCanvas = null; /** - * Cached tint value so we can tell when the tint is changed. - * @memberof PIXI.Sprite# - * @member {number} _cachedTint - * @protected - */ -Sprite.prototype._cachedTint = 0xFFFFFF; - -/** * Renders the object using the Canvas renderer * * @private diff --git a/package-lock.json b/package-lock.json index eb731c3..a16c04b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2868,7 +2868,7 @@ }, "yargs": { "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { @@ -9992,14 +9992,28 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" + }, + "dependencies": { + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + } } }, "temp-dir": { diff --git a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js index fde693f..b7b7a7e 100644 --- a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js +++ b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js @@ -82,6 +82,8 @@ const holes = data.holes; let outerArea; let innerArea; + let px; + let py; context.moveTo(points[0], points[1]); @@ -98,19 +100,30 @@ if (holes.length > 0) { outerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + outerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } for (let k = 0; k < holes.length; k++) { - points = holes[k].points; + points = holes[k].shape.points; + + if (!points) + { + continue; + } innerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + innerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } if (innerArea * outerArea < 0) diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js index 8f4e0e4..4eac1d7 100644 --- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js +++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js @@ -29,7 +29,7 @@ const modY = ((this.tilePosition.y / this.tileScale.y) % texture._frame.height) * baseTextureResolution; // create a nice shiny pattern! - if (this._textureID !== this._texture._updateID || this.cachedTint !== this.tint) + if (this._textureID !== this._texture._updateID || this._cachedTint !== this.tint) { this._textureID = this._texture._updateID; // cut an object from a spritesheet.. @@ -48,7 +48,7 @@ tempCanvas.context.drawImage(source, -texture._frame.x * baseTextureResolution, -texture._frame.y * baseTextureResolution); } - this.cachedTint = this.tint; + this._cachedTint = this.tint; this._canvasPattern = tempCanvas.context.createPattern(tempCanvas.canvas, 'repeat'); } diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js index 297cb75..225beb0 100644 --- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js +++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js @@ -159,7 +159,7 @@ } context.drawImage( - source, + sprite._tintedCanvas, 0, 0, width * resolution, diff --git a/packages/canvas/canvas-sprite/src/Sprite.js b/packages/canvas/canvas-sprite/src/Sprite.js index 4bef51d..d94950f 100644 --- a/packages/canvas/canvas-sprite/src/Sprite.js +++ b/packages/canvas/canvas-sprite/src/Sprite.js @@ -9,14 +9,6 @@ Sprite.prototype._tintedCanvas = null; /** - * Cached tint value so we can tell when the tint is changed. - * @memberof PIXI.Sprite# - * @member {number} _cachedTint - * @protected - */ -Sprite.prototype._cachedTint = 0xFFFFFF; - -/** * Renders the object using the Canvas renderer * * @private diff --git a/packages/core/src/context/ContextSystem.js b/packages/core/src/context/ContextSystem.js index dc6243d..6487683 100644 --- a/packages/core/src/context/ContextSystem.js +++ b/packages/core/src/context/ContextSystem.js @@ -163,6 +163,7 @@ vertexArrayObject: gl.getExtension('OES_vertex_array_object') || gl.getExtension('MOZ_OES_vertex_array_object') || gl.getExtension('WEBKIT_OES_vertex_array_object'), + uint32ElementIndex: gl.getExtension('OES_element_index_uint'), }); } diff --git a/package-lock.json b/package-lock.json index eb731c3..a16c04b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2868,7 +2868,7 @@ }, "yargs": { "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { @@ -9992,14 +9992,28 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" + }, + "dependencies": { + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + } } }, "temp-dir": { diff --git a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js index fde693f..b7b7a7e 100644 --- a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js +++ b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js @@ -82,6 +82,8 @@ const holes = data.holes; let outerArea; let innerArea; + let px; + let py; context.moveTo(points[0], points[1]); @@ -98,19 +100,30 @@ if (holes.length > 0) { outerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + outerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } for (let k = 0; k < holes.length; k++) { - points = holes[k].points; + points = holes[k].shape.points; + + if (!points) + { + continue; + } innerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + innerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } if (innerArea * outerArea < 0) diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js index 8f4e0e4..4eac1d7 100644 --- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js +++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js @@ -29,7 +29,7 @@ const modY = ((this.tilePosition.y / this.tileScale.y) % texture._frame.height) * baseTextureResolution; // create a nice shiny pattern! - if (this._textureID !== this._texture._updateID || this.cachedTint !== this.tint) + if (this._textureID !== this._texture._updateID || this._cachedTint !== this.tint) { this._textureID = this._texture._updateID; // cut an object from a spritesheet.. @@ -48,7 +48,7 @@ tempCanvas.context.drawImage(source, -texture._frame.x * baseTextureResolution, -texture._frame.y * baseTextureResolution); } - this.cachedTint = this.tint; + this._cachedTint = this.tint; this._canvasPattern = tempCanvas.context.createPattern(tempCanvas.canvas, 'repeat'); } diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js index 297cb75..225beb0 100644 --- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js +++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js @@ -159,7 +159,7 @@ } context.drawImage( - source, + sprite._tintedCanvas, 0, 0, width * resolution, diff --git a/packages/canvas/canvas-sprite/src/Sprite.js b/packages/canvas/canvas-sprite/src/Sprite.js index 4bef51d..d94950f 100644 --- a/packages/canvas/canvas-sprite/src/Sprite.js +++ b/packages/canvas/canvas-sprite/src/Sprite.js @@ -9,14 +9,6 @@ Sprite.prototype._tintedCanvas = null; /** - * Cached tint value so we can tell when the tint is changed. - * @memberof PIXI.Sprite# - * @member {number} _cachedTint - * @protected - */ -Sprite.prototype._cachedTint = 0xFFFFFF; - -/** * Renders the object using the Canvas renderer * * @private diff --git a/packages/core/src/context/ContextSystem.js b/packages/core/src/context/ContextSystem.js index dc6243d..6487683 100644 --- a/packages/core/src/context/ContextSystem.js +++ b/packages/core/src/context/ContextSystem.js @@ -163,6 +163,7 @@ vertexArrayObject: gl.getExtension('OES_vertex_array_object') || gl.getExtension('MOZ_OES_vertex_array_object') || gl.getExtension('WEBKIT_OES_vertex_array_object'), + uint32ElementIndex: gl.getExtension('OES_element_index_uint'), }); } diff --git a/packages/core/src/filters/FilterSystem.js b/packages/core/src/filters/FilterSystem.js index a2ae32f..e4edd02 100644 --- a/packages/core/src/filters/FilterSystem.js +++ b/packages/core/src/filters/FilterSystem.js @@ -451,12 +451,9 @@ if (!renderTexture) { - // temporary bypass cache.. - // internally - this will cause a texture to be bound.. renderTexture = RenderTexture.create({ - width: minWidth / resolution, - height: minHeight / resolution, - resolution, + width: minWidth, + height: minHeight, }); } diff --git a/package-lock.json b/package-lock.json index eb731c3..a16c04b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2868,7 +2868,7 @@ }, "yargs": { "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { @@ -9992,14 +9992,28 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" + }, + "dependencies": { + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + } } }, "temp-dir": { diff --git a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js index fde693f..b7b7a7e 100644 --- a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js +++ b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js @@ -82,6 +82,8 @@ const holes = data.holes; let outerArea; let innerArea; + let px; + let py; context.moveTo(points[0], points[1]); @@ -98,19 +100,30 @@ if (holes.length > 0) { outerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + outerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } for (let k = 0; k < holes.length; k++) { - points = holes[k].points; + points = holes[k].shape.points; + + if (!points) + { + continue; + } innerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + innerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } if (innerArea * outerArea < 0) diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js index 8f4e0e4..4eac1d7 100644 --- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js +++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js @@ -29,7 +29,7 @@ const modY = ((this.tilePosition.y / this.tileScale.y) % texture._frame.height) * baseTextureResolution; // create a nice shiny pattern! - if (this._textureID !== this._texture._updateID || this.cachedTint !== this.tint) + if (this._textureID !== this._texture._updateID || this._cachedTint !== this.tint) { this._textureID = this._texture._updateID; // cut an object from a spritesheet.. @@ -48,7 +48,7 @@ tempCanvas.context.drawImage(source, -texture._frame.x * baseTextureResolution, -texture._frame.y * baseTextureResolution); } - this.cachedTint = this.tint; + this._cachedTint = this.tint; this._canvasPattern = tempCanvas.context.createPattern(tempCanvas.canvas, 'repeat'); } diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js index 297cb75..225beb0 100644 --- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js +++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js @@ -159,7 +159,7 @@ } context.drawImage( - source, + sprite._tintedCanvas, 0, 0, width * resolution, diff --git a/packages/canvas/canvas-sprite/src/Sprite.js b/packages/canvas/canvas-sprite/src/Sprite.js index 4bef51d..d94950f 100644 --- a/packages/canvas/canvas-sprite/src/Sprite.js +++ b/packages/canvas/canvas-sprite/src/Sprite.js @@ -9,14 +9,6 @@ Sprite.prototype._tintedCanvas = null; /** - * Cached tint value so we can tell when the tint is changed. - * @memberof PIXI.Sprite# - * @member {number} _cachedTint - * @protected - */ -Sprite.prototype._cachedTint = 0xFFFFFF; - -/** * Renders the object using the Canvas renderer * * @private diff --git a/packages/core/src/context/ContextSystem.js b/packages/core/src/context/ContextSystem.js index dc6243d..6487683 100644 --- a/packages/core/src/context/ContextSystem.js +++ b/packages/core/src/context/ContextSystem.js @@ -163,6 +163,7 @@ vertexArrayObject: gl.getExtension('OES_vertex_array_object') || gl.getExtension('MOZ_OES_vertex_array_object') || gl.getExtension('WEBKIT_OES_vertex_array_object'), + uint32ElementIndex: gl.getExtension('OES_element_index_uint'), }); } diff --git a/packages/core/src/filters/FilterSystem.js b/packages/core/src/filters/FilterSystem.js index a2ae32f..e4edd02 100644 --- a/packages/core/src/filters/FilterSystem.js +++ b/packages/core/src/filters/FilterSystem.js @@ -451,12 +451,9 @@ if (!renderTexture) { - // temporary bypass cache.. - // internally - this will cause a texture to be bound.. renderTexture = RenderTexture.create({ - width: minWidth / resolution, - height: minHeight / resolution, - resolution, + width: minWidth, + height: minHeight, }); } diff --git a/packages/core/src/geometry/GeometrySystem.js b/packages/core/src/geometry/GeometrySystem.js index 3b83a89..3c56989 100644 --- a/packages/core/src/geometry/GeometrySystem.js +++ b/packages/core/src/geometry/GeometrySystem.js @@ -39,6 +39,13 @@ this.hasInstance = true; /** + * `true` if support `gl.UNSIGNED_INT` in `gl.drawElements` or `gl.drawElementsInstanced` + * @member {boolean} + * @readonly + */ + this.canUseUInt32ElementIndex = false; + + /** * A cache of currently bound buffer, * contains only two members with keys ARRAY_BUFFER and ELEMENT_ARRAY_BUFFER * @member {Object.} @@ -69,6 +76,7 @@ this.disposeAll(true); const gl = this.gl = this.renderer.gl; + const context = this.renderer.context; this.CONTEXT_UID = this.renderer.CONTEXT_UID; @@ -134,6 +142,8 @@ this.hasInstance = false; } } + + this.canUseUInt32ElementIndex = context.webGLVersion === 2 || !!context.extensions.uint32ElementIndex; } /** @@ -593,15 +603,27 @@ if (geometry.indexBuffer) { - if (geometry.instanced) + const byteSize = geometry.indexBuffer.data.BYTES_PER_ELEMENT; + const glType = byteSize === 2 ? gl.UNSIGNED_SHORT : gl.UNSIGNED_INT; + + if (byteSize === 2 || (byteSize === 4 && this.canUseUInt32ElementIndex)) { - /* eslint-disable max-len */ - gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2, instanceCount || 1); - /* eslint-enable max-len */ + if (geometry.instanced) + { + /* eslint-disable max-len */ + gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize, instanceCount || 1); + /* eslint-enable max-len */ + } + else + { + /* eslint-disable max-len */ + gl.drawElements(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize); + /* eslint-enable max-len */ + } } else { - gl.drawElements(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2); + console.warn('unsupported index buffer type: uint32'); } } else if (geometry.instanced) diff --git a/package-lock.json b/package-lock.json index eb731c3..a16c04b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2868,7 +2868,7 @@ }, "yargs": { "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { @@ -9992,14 +9992,28 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" + }, + "dependencies": { + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + } } }, "temp-dir": { diff --git a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js index fde693f..b7b7a7e 100644 --- a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js +++ b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js @@ -82,6 +82,8 @@ const holes = data.holes; let outerArea; let innerArea; + let px; + let py; context.moveTo(points[0], points[1]); @@ -98,19 +100,30 @@ if (holes.length > 0) { outerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + outerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } for (let k = 0; k < holes.length; k++) { - points = holes[k].points; + points = holes[k].shape.points; + + if (!points) + { + continue; + } innerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + innerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } if (innerArea * outerArea < 0) diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js index 8f4e0e4..4eac1d7 100644 --- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js +++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js @@ -29,7 +29,7 @@ const modY = ((this.tilePosition.y / this.tileScale.y) % texture._frame.height) * baseTextureResolution; // create a nice shiny pattern! - if (this._textureID !== this._texture._updateID || this.cachedTint !== this.tint) + if (this._textureID !== this._texture._updateID || this._cachedTint !== this.tint) { this._textureID = this._texture._updateID; // cut an object from a spritesheet.. @@ -48,7 +48,7 @@ tempCanvas.context.drawImage(source, -texture._frame.x * baseTextureResolution, -texture._frame.y * baseTextureResolution); } - this.cachedTint = this.tint; + this._cachedTint = this.tint; this._canvasPattern = tempCanvas.context.createPattern(tempCanvas.canvas, 'repeat'); } diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js index 297cb75..225beb0 100644 --- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js +++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js @@ -159,7 +159,7 @@ } context.drawImage( - source, + sprite._tintedCanvas, 0, 0, width * resolution, diff --git a/packages/canvas/canvas-sprite/src/Sprite.js b/packages/canvas/canvas-sprite/src/Sprite.js index 4bef51d..d94950f 100644 --- a/packages/canvas/canvas-sprite/src/Sprite.js +++ b/packages/canvas/canvas-sprite/src/Sprite.js @@ -9,14 +9,6 @@ Sprite.prototype._tintedCanvas = null; /** - * Cached tint value so we can tell when the tint is changed. - * @memberof PIXI.Sprite# - * @member {number} _cachedTint - * @protected - */ -Sprite.prototype._cachedTint = 0xFFFFFF; - -/** * Renders the object using the Canvas renderer * * @private diff --git a/packages/core/src/context/ContextSystem.js b/packages/core/src/context/ContextSystem.js index dc6243d..6487683 100644 --- a/packages/core/src/context/ContextSystem.js +++ b/packages/core/src/context/ContextSystem.js @@ -163,6 +163,7 @@ vertexArrayObject: gl.getExtension('OES_vertex_array_object') || gl.getExtension('MOZ_OES_vertex_array_object') || gl.getExtension('WEBKIT_OES_vertex_array_object'), + uint32ElementIndex: gl.getExtension('OES_element_index_uint'), }); } diff --git a/packages/core/src/filters/FilterSystem.js b/packages/core/src/filters/FilterSystem.js index a2ae32f..e4edd02 100644 --- a/packages/core/src/filters/FilterSystem.js +++ b/packages/core/src/filters/FilterSystem.js @@ -451,12 +451,9 @@ if (!renderTexture) { - // temporary bypass cache.. - // internally - this will cause a texture to be bound.. renderTexture = RenderTexture.create({ - width: minWidth / resolution, - height: minHeight / resolution, - resolution, + width: minWidth, + height: minHeight, }); } diff --git a/packages/core/src/geometry/GeometrySystem.js b/packages/core/src/geometry/GeometrySystem.js index 3b83a89..3c56989 100644 --- a/packages/core/src/geometry/GeometrySystem.js +++ b/packages/core/src/geometry/GeometrySystem.js @@ -39,6 +39,13 @@ this.hasInstance = true; /** + * `true` if support `gl.UNSIGNED_INT` in `gl.drawElements` or `gl.drawElementsInstanced` + * @member {boolean} + * @readonly + */ + this.canUseUInt32ElementIndex = false; + + /** * A cache of currently bound buffer, * contains only two members with keys ARRAY_BUFFER and ELEMENT_ARRAY_BUFFER * @member {Object.} @@ -69,6 +76,7 @@ this.disposeAll(true); const gl = this.gl = this.renderer.gl; + const context = this.renderer.context; this.CONTEXT_UID = this.renderer.CONTEXT_UID; @@ -134,6 +142,8 @@ this.hasInstance = false; } } + + this.canUseUInt32ElementIndex = context.webGLVersion === 2 || !!context.extensions.uint32ElementIndex; } /** @@ -593,15 +603,27 @@ if (geometry.indexBuffer) { - if (geometry.instanced) + const byteSize = geometry.indexBuffer.data.BYTES_PER_ELEMENT; + const glType = byteSize === 2 ? gl.UNSIGNED_SHORT : gl.UNSIGNED_INT; + + if (byteSize === 2 || (byteSize === 4 && this.canUseUInt32ElementIndex)) { - /* eslint-disable max-len */ - gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2, instanceCount || 1); - /* eslint-enable max-len */ + if (geometry.instanced) + { + /* eslint-disable max-len */ + gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize, instanceCount || 1); + /* eslint-enable max-len */ + } + else + { + /* eslint-disable max-len */ + gl.drawElements(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize); + /* eslint-enable max-len */ + } } else { - gl.drawElements(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2); + console.warn('unsupported index buffer type: uint32'); } } else if (geometry.instanced) diff --git a/packages/core/src/renderTexture/RenderTexture.js b/packages/core/src/renderTexture/RenderTexture.js index f9c4f18..ecf5080 100644 --- a/packages/core/src/renderTexture/RenderTexture.js +++ b/packages/core/src/renderTexture/RenderTexture.js @@ -7,6 +7,9 @@ * __Hint__: All DisplayObjects (i.e. Sprites) that render to a RenderTexture should be preloaded * otherwise black rectangles will be drawn instead. * + * __Hint-2__: The actual memory allocation will happen on first render. + * You shouldn't create renderTextures each frame just to delete them after, try to reuse them. + * * A RenderTexture takes a snapshot of any Display Object given to its render method. For example: * * ```js diff --git a/package-lock.json b/package-lock.json index eb731c3..a16c04b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2868,7 +2868,7 @@ }, "yargs": { "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { @@ -9992,14 +9992,28 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" + }, + "dependencies": { + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + } } }, "temp-dir": { diff --git a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js index fde693f..b7b7a7e 100644 --- a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js +++ b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js @@ -82,6 +82,8 @@ const holes = data.holes; let outerArea; let innerArea; + let px; + let py; context.moveTo(points[0], points[1]); @@ -98,19 +100,30 @@ if (holes.length > 0) { outerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + outerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } for (let k = 0; k < holes.length; k++) { - points = holes[k].points; + points = holes[k].shape.points; + + if (!points) + { + continue; + } innerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + innerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } if (innerArea * outerArea < 0) diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js index 8f4e0e4..4eac1d7 100644 --- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js +++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js @@ -29,7 +29,7 @@ const modY = ((this.tilePosition.y / this.tileScale.y) % texture._frame.height) * baseTextureResolution; // create a nice shiny pattern! - if (this._textureID !== this._texture._updateID || this.cachedTint !== this.tint) + if (this._textureID !== this._texture._updateID || this._cachedTint !== this.tint) { this._textureID = this._texture._updateID; // cut an object from a spritesheet.. @@ -48,7 +48,7 @@ tempCanvas.context.drawImage(source, -texture._frame.x * baseTextureResolution, -texture._frame.y * baseTextureResolution); } - this.cachedTint = this.tint; + this._cachedTint = this.tint; this._canvasPattern = tempCanvas.context.createPattern(tempCanvas.canvas, 'repeat'); } diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js index 297cb75..225beb0 100644 --- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js +++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js @@ -159,7 +159,7 @@ } context.drawImage( - source, + sprite._tintedCanvas, 0, 0, width * resolution, diff --git a/packages/canvas/canvas-sprite/src/Sprite.js b/packages/canvas/canvas-sprite/src/Sprite.js index 4bef51d..d94950f 100644 --- a/packages/canvas/canvas-sprite/src/Sprite.js +++ b/packages/canvas/canvas-sprite/src/Sprite.js @@ -9,14 +9,6 @@ Sprite.prototype._tintedCanvas = null; /** - * Cached tint value so we can tell when the tint is changed. - * @memberof PIXI.Sprite# - * @member {number} _cachedTint - * @protected - */ -Sprite.prototype._cachedTint = 0xFFFFFF; - -/** * Renders the object using the Canvas renderer * * @private diff --git a/packages/core/src/context/ContextSystem.js b/packages/core/src/context/ContextSystem.js index dc6243d..6487683 100644 --- a/packages/core/src/context/ContextSystem.js +++ b/packages/core/src/context/ContextSystem.js @@ -163,6 +163,7 @@ vertexArrayObject: gl.getExtension('OES_vertex_array_object') || gl.getExtension('MOZ_OES_vertex_array_object') || gl.getExtension('WEBKIT_OES_vertex_array_object'), + uint32ElementIndex: gl.getExtension('OES_element_index_uint'), }); } diff --git a/packages/core/src/filters/FilterSystem.js b/packages/core/src/filters/FilterSystem.js index a2ae32f..e4edd02 100644 --- a/packages/core/src/filters/FilterSystem.js +++ b/packages/core/src/filters/FilterSystem.js @@ -451,12 +451,9 @@ if (!renderTexture) { - // temporary bypass cache.. - // internally - this will cause a texture to be bound.. renderTexture = RenderTexture.create({ - width: minWidth / resolution, - height: minHeight / resolution, - resolution, + width: minWidth, + height: minHeight, }); } diff --git a/packages/core/src/geometry/GeometrySystem.js b/packages/core/src/geometry/GeometrySystem.js index 3b83a89..3c56989 100644 --- a/packages/core/src/geometry/GeometrySystem.js +++ b/packages/core/src/geometry/GeometrySystem.js @@ -39,6 +39,13 @@ this.hasInstance = true; /** + * `true` if support `gl.UNSIGNED_INT` in `gl.drawElements` or `gl.drawElementsInstanced` + * @member {boolean} + * @readonly + */ + this.canUseUInt32ElementIndex = false; + + /** * A cache of currently bound buffer, * contains only two members with keys ARRAY_BUFFER and ELEMENT_ARRAY_BUFFER * @member {Object.} @@ -69,6 +76,7 @@ this.disposeAll(true); const gl = this.gl = this.renderer.gl; + const context = this.renderer.context; this.CONTEXT_UID = this.renderer.CONTEXT_UID; @@ -134,6 +142,8 @@ this.hasInstance = false; } } + + this.canUseUInt32ElementIndex = context.webGLVersion === 2 || !!context.extensions.uint32ElementIndex; } /** @@ -593,15 +603,27 @@ if (geometry.indexBuffer) { - if (geometry.instanced) + const byteSize = geometry.indexBuffer.data.BYTES_PER_ELEMENT; + const glType = byteSize === 2 ? gl.UNSIGNED_SHORT : gl.UNSIGNED_INT; + + if (byteSize === 2 || (byteSize === 4 && this.canUseUInt32ElementIndex)) { - /* eslint-disable max-len */ - gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2, instanceCount || 1); - /* eslint-enable max-len */ + if (geometry.instanced) + { + /* eslint-disable max-len */ + gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize, instanceCount || 1); + /* eslint-enable max-len */ + } + else + { + /* eslint-disable max-len */ + gl.drawElements(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize); + /* eslint-enable max-len */ + } } else { - gl.drawElements(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2); + console.warn('unsupported index buffer type: uint32'); } } else if (geometry.instanced) diff --git a/packages/core/src/renderTexture/RenderTexture.js b/packages/core/src/renderTexture/RenderTexture.js index f9c4f18..ecf5080 100644 --- a/packages/core/src/renderTexture/RenderTexture.js +++ b/packages/core/src/renderTexture/RenderTexture.js @@ -7,6 +7,9 @@ * __Hint__: All DisplayObjects (i.e. Sprites) that render to a RenderTexture should be preloaded * otherwise black rectangles will be drawn instead. * + * __Hint-2__: The actual memory allocation will happen on first render. + * You shouldn't create renderTextures each frame just to delete them after, try to reuse them. + * * A RenderTexture takes a snapshot of any Display Object given to its render method. For example: * * ```js diff --git a/packages/core/src/renderTexture/RenderTextureSystem.js b/packages/core/src/renderTexture/RenderTextureSystem.js index 7e29532..57c2fcc 100644 --- a/packages/core/src/renderTexture/RenderTextureSystem.js +++ b/packages/core/src/renderTexture/RenderTextureSystem.js @@ -61,9 +61,9 @@ /** * Bind the current render texture - * @param {PIXI.RenderTexture} renderTexture - * @param {PIXI.Rectangle} sourceFrame - * @param {PIXI.Rectangle} destinationFrame + * @param {PIXI.RenderTexture} [renderTexture] - RenderTexture to bind, by default its `null`, the screen + * @param {PIXI.Rectangle} [sourceFrame] - part of screen that is mapped to the renderTexture + * @param {PIXI.Rectangle} [destinationFrame] - part of renderTexture, by default it has the same size as sourceFrame */ bind(renderTexture = null, sourceFrame, destinationFrame) { diff --git a/package-lock.json b/package-lock.json index eb731c3..a16c04b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2868,7 +2868,7 @@ }, "yargs": { "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { @@ -9992,14 +9992,28 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" + }, + "dependencies": { + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + } } }, "temp-dir": { diff --git a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js index fde693f..b7b7a7e 100644 --- a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js +++ b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js @@ -82,6 +82,8 @@ const holes = data.holes; let outerArea; let innerArea; + let px; + let py; context.moveTo(points[0], points[1]); @@ -98,19 +100,30 @@ if (holes.length > 0) { outerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + outerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } for (let k = 0; k < holes.length; k++) { - points = holes[k].points; + points = holes[k].shape.points; + + if (!points) + { + continue; + } innerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + innerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } if (innerArea * outerArea < 0) diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js index 8f4e0e4..4eac1d7 100644 --- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js +++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js @@ -29,7 +29,7 @@ const modY = ((this.tilePosition.y / this.tileScale.y) % texture._frame.height) * baseTextureResolution; // create a nice shiny pattern! - if (this._textureID !== this._texture._updateID || this.cachedTint !== this.tint) + if (this._textureID !== this._texture._updateID || this._cachedTint !== this.tint) { this._textureID = this._texture._updateID; // cut an object from a spritesheet.. @@ -48,7 +48,7 @@ tempCanvas.context.drawImage(source, -texture._frame.x * baseTextureResolution, -texture._frame.y * baseTextureResolution); } - this.cachedTint = this.tint; + this._cachedTint = this.tint; this._canvasPattern = tempCanvas.context.createPattern(tempCanvas.canvas, 'repeat'); } diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js index 297cb75..225beb0 100644 --- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js +++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js @@ -159,7 +159,7 @@ } context.drawImage( - source, + sprite._tintedCanvas, 0, 0, width * resolution, diff --git a/packages/canvas/canvas-sprite/src/Sprite.js b/packages/canvas/canvas-sprite/src/Sprite.js index 4bef51d..d94950f 100644 --- a/packages/canvas/canvas-sprite/src/Sprite.js +++ b/packages/canvas/canvas-sprite/src/Sprite.js @@ -9,14 +9,6 @@ Sprite.prototype._tintedCanvas = null; /** - * Cached tint value so we can tell when the tint is changed. - * @memberof PIXI.Sprite# - * @member {number} _cachedTint - * @protected - */ -Sprite.prototype._cachedTint = 0xFFFFFF; - -/** * Renders the object using the Canvas renderer * * @private diff --git a/packages/core/src/context/ContextSystem.js b/packages/core/src/context/ContextSystem.js index dc6243d..6487683 100644 --- a/packages/core/src/context/ContextSystem.js +++ b/packages/core/src/context/ContextSystem.js @@ -163,6 +163,7 @@ vertexArrayObject: gl.getExtension('OES_vertex_array_object') || gl.getExtension('MOZ_OES_vertex_array_object') || gl.getExtension('WEBKIT_OES_vertex_array_object'), + uint32ElementIndex: gl.getExtension('OES_element_index_uint'), }); } diff --git a/packages/core/src/filters/FilterSystem.js b/packages/core/src/filters/FilterSystem.js index a2ae32f..e4edd02 100644 --- a/packages/core/src/filters/FilterSystem.js +++ b/packages/core/src/filters/FilterSystem.js @@ -451,12 +451,9 @@ if (!renderTexture) { - // temporary bypass cache.. - // internally - this will cause a texture to be bound.. renderTexture = RenderTexture.create({ - width: minWidth / resolution, - height: minHeight / resolution, - resolution, + width: minWidth, + height: minHeight, }); } diff --git a/packages/core/src/geometry/GeometrySystem.js b/packages/core/src/geometry/GeometrySystem.js index 3b83a89..3c56989 100644 --- a/packages/core/src/geometry/GeometrySystem.js +++ b/packages/core/src/geometry/GeometrySystem.js @@ -39,6 +39,13 @@ this.hasInstance = true; /** + * `true` if support `gl.UNSIGNED_INT` in `gl.drawElements` or `gl.drawElementsInstanced` + * @member {boolean} + * @readonly + */ + this.canUseUInt32ElementIndex = false; + + /** * A cache of currently bound buffer, * contains only two members with keys ARRAY_BUFFER and ELEMENT_ARRAY_BUFFER * @member {Object.} @@ -69,6 +76,7 @@ this.disposeAll(true); const gl = this.gl = this.renderer.gl; + const context = this.renderer.context; this.CONTEXT_UID = this.renderer.CONTEXT_UID; @@ -134,6 +142,8 @@ this.hasInstance = false; } } + + this.canUseUInt32ElementIndex = context.webGLVersion === 2 || !!context.extensions.uint32ElementIndex; } /** @@ -593,15 +603,27 @@ if (geometry.indexBuffer) { - if (geometry.instanced) + const byteSize = geometry.indexBuffer.data.BYTES_PER_ELEMENT; + const glType = byteSize === 2 ? gl.UNSIGNED_SHORT : gl.UNSIGNED_INT; + + if (byteSize === 2 || (byteSize === 4 && this.canUseUInt32ElementIndex)) { - /* eslint-disable max-len */ - gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2, instanceCount || 1); - /* eslint-enable max-len */ + if (geometry.instanced) + { + /* eslint-disable max-len */ + gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize, instanceCount || 1); + /* eslint-enable max-len */ + } + else + { + /* eslint-disable max-len */ + gl.drawElements(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize); + /* eslint-enable max-len */ + } } else { - gl.drawElements(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2); + console.warn('unsupported index buffer type: uint32'); } } else if (geometry.instanced) diff --git a/packages/core/src/renderTexture/RenderTexture.js b/packages/core/src/renderTexture/RenderTexture.js index f9c4f18..ecf5080 100644 --- a/packages/core/src/renderTexture/RenderTexture.js +++ b/packages/core/src/renderTexture/RenderTexture.js @@ -7,6 +7,9 @@ * __Hint__: All DisplayObjects (i.e. Sprites) that render to a RenderTexture should be preloaded * otherwise black rectangles will be drawn instead. * + * __Hint-2__: The actual memory allocation will happen on first render. + * You shouldn't create renderTextures each frame just to delete them after, try to reuse them. + * * A RenderTexture takes a snapshot of any Display Object given to its render method. For example: * * ```js diff --git a/packages/core/src/renderTexture/RenderTextureSystem.js b/packages/core/src/renderTexture/RenderTextureSystem.js index 7e29532..57c2fcc 100644 --- a/packages/core/src/renderTexture/RenderTextureSystem.js +++ b/packages/core/src/renderTexture/RenderTextureSystem.js @@ -61,9 +61,9 @@ /** * Bind the current render texture - * @param {PIXI.RenderTexture} renderTexture - * @param {PIXI.Rectangle} sourceFrame - * @param {PIXI.Rectangle} destinationFrame + * @param {PIXI.RenderTexture} [renderTexture] - RenderTexture to bind, by default its `null`, the screen + * @param {PIXI.Rectangle} [sourceFrame] - part of screen that is mapped to the renderTexture + * @param {PIXI.Rectangle} [destinationFrame] - part of renderTexture, by default it has the same size as sourceFrame */ bind(renderTexture = null, sourceFrame, destinationFrame) { diff --git a/packages/core/src/state/State.js b/packages/core/src/state/State.js index c87e268..9ef36dc 100644 --- a/packages/core/src/state/State.js +++ b/packages/core/src/state/State.js @@ -127,7 +127,7 @@ * The blend mode to be applied when this state is set. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode. * Setting this mode to anything other than NO_BLEND will automatically switch blending on. * - * @member {boolean} + * @member {number} * @default PIXI.BLEND_MODES.NORMAL * @see PIXI.BLEND_MODES */ diff --git a/package-lock.json b/package-lock.json index eb731c3..a16c04b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2868,7 +2868,7 @@ }, "yargs": { "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { @@ -9992,14 +9992,28 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" + }, + "dependencies": { + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + } } }, "temp-dir": { diff --git a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js index fde693f..b7b7a7e 100644 --- a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js +++ b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js @@ -82,6 +82,8 @@ const holes = data.holes; let outerArea; let innerArea; + let px; + let py; context.moveTo(points[0], points[1]); @@ -98,19 +100,30 @@ if (holes.length > 0) { outerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + outerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } for (let k = 0; k < holes.length; k++) { - points = holes[k].points; + points = holes[k].shape.points; + + if (!points) + { + continue; + } innerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + innerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } if (innerArea * outerArea < 0) diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js index 8f4e0e4..4eac1d7 100644 --- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js +++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js @@ -29,7 +29,7 @@ const modY = ((this.tilePosition.y / this.tileScale.y) % texture._frame.height) * baseTextureResolution; // create a nice shiny pattern! - if (this._textureID !== this._texture._updateID || this.cachedTint !== this.tint) + if (this._textureID !== this._texture._updateID || this._cachedTint !== this.tint) { this._textureID = this._texture._updateID; // cut an object from a spritesheet.. @@ -48,7 +48,7 @@ tempCanvas.context.drawImage(source, -texture._frame.x * baseTextureResolution, -texture._frame.y * baseTextureResolution); } - this.cachedTint = this.tint; + this._cachedTint = this.tint; this._canvasPattern = tempCanvas.context.createPattern(tempCanvas.canvas, 'repeat'); } diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js index 297cb75..225beb0 100644 --- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js +++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js @@ -159,7 +159,7 @@ } context.drawImage( - source, + sprite._tintedCanvas, 0, 0, width * resolution, diff --git a/packages/canvas/canvas-sprite/src/Sprite.js b/packages/canvas/canvas-sprite/src/Sprite.js index 4bef51d..d94950f 100644 --- a/packages/canvas/canvas-sprite/src/Sprite.js +++ b/packages/canvas/canvas-sprite/src/Sprite.js @@ -9,14 +9,6 @@ Sprite.prototype._tintedCanvas = null; /** - * Cached tint value so we can tell when the tint is changed. - * @memberof PIXI.Sprite# - * @member {number} _cachedTint - * @protected - */ -Sprite.prototype._cachedTint = 0xFFFFFF; - -/** * Renders the object using the Canvas renderer * * @private diff --git a/packages/core/src/context/ContextSystem.js b/packages/core/src/context/ContextSystem.js index dc6243d..6487683 100644 --- a/packages/core/src/context/ContextSystem.js +++ b/packages/core/src/context/ContextSystem.js @@ -163,6 +163,7 @@ vertexArrayObject: gl.getExtension('OES_vertex_array_object') || gl.getExtension('MOZ_OES_vertex_array_object') || gl.getExtension('WEBKIT_OES_vertex_array_object'), + uint32ElementIndex: gl.getExtension('OES_element_index_uint'), }); } diff --git a/packages/core/src/filters/FilterSystem.js b/packages/core/src/filters/FilterSystem.js index a2ae32f..e4edd02 100644 --- a/packages/core/src/filters/FilterSystem.js +++ b/packages/core/src/filters/FilterSystem.js @@ -451,12 +451,9 @@ if (!renderTexture) { - // temporary bypass cache.. - // internally - this will cause a texture to be bound.. renderTexture = RenderTexture.create({ - width: minWidth / resolution, - height: minHeight / resolution, - resolution, + width: minWidth, + height: minHeight, }); } diff --git a/packages/core/src/geometry/GeometrySystem.js b/packages/core/src/geometry/GeometrySystem.js index 3b83a89..3c56989 100644 --- a/packages/core/src/geometry/GeometrySystem.js +++ b/packages/core/src/geometry/GeometrySystem.js @@ -39,6 +39,13 @@ this.hasInstance = true; /** + * `true` if support `gl.UNSIGNED_INT` in `gl.drawElements` or `gl.drawElementsInstanced` + * @member {boolean} + * @readonly + */ + this.canUseUInt32ElementIndex = false; + + /** * A cache of currently bound buffer, * contains only two members with keys ARRAY_BUFFER and ELEMENT_ARRAY_BUFFER * @member {Object.} @@ -69,6 +76,7 @@ this.disposeAll(true); const gl = this.gl = this.renderer.gl; + const context = this.renderer.context; this.CONTEXT_UID = this.renderer.CONTEXT_UID; @@ -134,6 +142,8 @@ this.hasInstance = false; } } + + this.canUseUInt32ElementIndex = context.webGLVersion === 2 || !!context.extensions.uint32ElementIndex; } /** @@ -593,15 +603,27 @@ if (geometry.indexBuffer) { - if (geometry.instanced) + const byteSize = geometry.indexBuffer.data.BYTES_PER_ELEMENT; + const glType = byteSize === 2 ? gl.UNSIGNED_SHORT : gl.UNSIGNED_INT; + + if (byteSize === 2 || (byteSize === 4 && this.canUseUInt32ElementIndex)) { - /* eslint-disable max-len */ - gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2, instanceCount || 1); - /* eslint-enable max-len */ + if (geometry.instanced) + { + /* eslint-disable max-len */ + gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize, instanceCount || 1); + /* eslint-enable max-len */ + } + else + { + /* eslint-disable max-len */ + gl.drawElements(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize); + /* eslint-enable max-len */ + } } else { - gl.drawElements(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2); + console.warn('unsupported index buffer type: uint32'); } } else if (geometry.instanced) diff --git a/packages/core/src/renderTexture/RenderTexture.js b/packages/core/src/renderTexture/RenderTexture.js index f9c4f18..ecf5080 100644 --- a/packages/core/src/renderTexture/RenderTexture.js +++ b/packages/core/src/renderTexture/RenderTexture.js @@ -7,6 +7,9 @@ * __Hint__: All DisplayObjects (i.e. Sprites) that render to a RenderTexture should be preloaded * otherwise black rectangles will be drawn instead. * + * __Hint-2__: The actual memory allocation will happen on first render. + * You shouldn't create renderTextures each frame just to delete them after, try to reuse them. + * * A RenderTexture takes a snapshot of any Display Object given to its render method. For example: * * ```js diff --git a/packages/core/src/renderTexture/RenderTextureSystem.js b/packages/core/src/renderTexture/RenderTextureSystem.js index 7e29532..57c2fcc 100644 --- a/packages/core/src/renderTexture/RenderTextureSystem.js +++ b/packages/core/src/renderTexture/RenderTextureSystem.js @@ -61,9 +61,9 @@ /** * Bind the current render texture - * @param {PIXI.RenderTexture} renderTexture - * @param {PIXI.Rectangle} sourceFrame - * @param {PIXI.Rectangle} destinationFrame + * @param {PIXI.RenderTexture} [renderTexture] - RenderTexture to bind, by default its `null`, the screen + * @param {PIXI.Rectangle} [sourceFrame] - part of screen that is mapped to the renderTexture + * @param {PIXI.Rectangle} [destinationFrame] - part of renderTexture, by default it has the same size as sourceFrame */ bind(renderTexture = null, sourceFrame, destinationFrame) { diff --git a/packages/core/src/state/State.js b/packages/core/src/state/State.js index c87e268..9ef36dc 100644 --- a/packages/core/src/state/State.js +++ b/packages/core/src/state/State.js @@ -127,7 +127,7 @@ * The blend mode to be applied when this state is set. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode. * Setting this mode to anything other than NO_BLEND will automatically switch blending on. * - * @member {boolean} + * @member {number} * @default PIXI.BLEND_MODES.NORMAL * @see PIXI.BLEND_MODES */ diff --git a/packages/core/src/state/StateSystem.js b/packages/core/src/state/StateSystem.js index c7e35d2..f3be34e 100755 --- a/packages/core/src/state/StateSystem.js +++ b/packages/core/src/state/StateSystem.js @@ -182,6 +182,8 @@ */ setOffset(value) { + this.updateCheck(StateSystem.checkPolygonOffset, value); + this.gl[value ? 'enable' : 'disable'](this.gl.POLYGON_OFFSET_FILL); } @@ -314,5 +316,16 @@ system.setBlendMode(state.blendMode); } - // TODO - add polygon offset? + /** + * A private little wrapper function that we call to check the polygon offset. + * + * @static + * @private + * @param {PIXI.StateSystem} System the System to perform the state check on + * @param {PIXI.State} state the state that the blendMode will pulled from + */ + static checkPolygonOffset(system, state) + { + system.setPolygonOffset(state.polygonOffset, 0); + } } diff --git a/package-lock.json b/package-lock.json index eb731c3..a16c04b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2868,7 +2868,7 @@ }, "yargs": { "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { @@ -9992,14 +9992,28 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" + }, + "dependencies": { + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + } } }, "temp-dir": { diff --git a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js index fde693f..b7b7a7e 100644 --- a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js +++ b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js @@ -82,6 +82,8 @@ const holes = data.holes; let outerArea; let innerArea; + let px; + let py; context.moveTo(points[0], points[1]); @@ -98,19 +100,30 @@ if (holes.length > 0) { outerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + outerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } for (let k = 0; k < holes.length; k++) { - points = holes[k].points; + points = holes[k].shape.points; + + if (!points) + { + continue; + } innerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + innerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } if (innerArea * outerArea < 0) diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js index 8f4e0e4..4eac1d7 100644 --- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js +++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js @@ -29,7 +29,7 @@ const modY = ((this.tilePosition.y / this.tileScale.y) % texture._frame.height) * baseTextureResolution; // create a nice shiny pattern! - if (this._textureID !== this._texture._updateID || this.cachedTint !== this.tint) + if (this._textureID !== this._texture._updateID || this._cachedTint !== this.tint) { this._textureID = this._texture._updateID; // cut an object from a spritesheet.. @@ -48,7 +48,7 @@ tempCanvas.context.drawImage(source, -texture._frame.x * baseTextureResolution, -texture._frame.y * baseTextureResolution); } - this.cachedTint = this.tint; + this._cachedTint = this.tint; this._canvasPattern = tempCanvas.context.createPattern(tempCanvas.canvas, 'repeat'); } diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js index 297cb75..225beb0 100644 --- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js +++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js @@ -159,7 +159,7 @@ } context.drawImage( - source, + sprite._tintedCanvas, 0, 0, width * resolution, diff --git a/packages/canvas/canvas-sprite/src/Sprite.js b/packages/canvas/canvas-sprite/src/Sprite.js index 4bef51d..d94950f 100644 --- a/packages/canvas/canvas-sprite/src/Sprite.js +++ b/packages/canvas/canvas-sprite/src/Sprite.js @@ -9,14 +9,6 @@ Sprite.prototype._tintedCanvas = null; /** - * Cached tint value so we can tell when the tint is changed. - * @memberof PIXI.Sprite# - * @member {number} _cachedTint - * @protected - */ -Sprite.prototype._cachedTint = 0xFFFFFF; - -/** * Renders the object using the Canvas renderer * * @private diff --git a/packages/core/src/context/ContextSystem.js b/packages/core/src/context/ContextSystem.js index dc6243d..6487683 100644 --- a/packages/core/src/context/ContextSystem.js +++ b/packages/core/src/context/ContextSystem.js @@ -163,6 +163,7 @@ vertexArrayObject: gl.getExtension('OES_vertex_array_object') || gl.getExtension('MOZ_OES_vertex_array_object') || gl.getExtension('WEBKIT_OES_vertex_array_object'), + uint32ElementIndex: gl.getExtension('OES_element_index_uint'), }); } diff --git a/packages/core/src/filters/FilterSystem.js b/packages/core/src/filters/FilterSystem.js index a2ae32f..e4edd02 100644 --- a/packages/core/src/filters/FilterSystem.js +++ b/packages/core/src/filters/FilterSystem.js @@ -451,12 +451,9 @@ if (!renderTexture) { - // temporary bypass cache.. - // internally - this will cause a texture to be bound.. renderTexture = RenderTexture.create({ - width: minWidth / resolution, - height: minHeight / resolution, - resolution, + width: minWidth, + height: minHeight, }); } diff --git a/packages/core/src/geometry/GeometrySystem.js b/packages/core/src/geometry/GeometrySystem.js index 3b83a89..3c56989 100644 --- a/packages/core/src/geometry/GeometrySystem.js +++ b/packages/core/src/geometry/GeometrySystem.js @@ -39,6 +39,13 @@ this.hasInstance = true; /** + * `true` if support `gl.UNSIGNED_INT` in `gl.drawElements` or `gl.drawElementsInstanced` + * @member {boolean} + * @readonly + */ + this.canUseUInt32ElementIndex = false; + + /** * A cache of currently bound buffer, * contains only two members with keys ARRAY_BUFFER and ELEMENT_ARRAY_BUFFER * @member {Object.} @@ -69,6 +76,7 @@ this.disposeAll(true); const gl = this.gl = this.renderer.gl; + const context = this.renderer.context; this.CONTEXT_UID = this.renderer.CONTEXT_UID; @@ -134,6 +142,8 @@ this.hasInstance = false; } } + + this.canUseUInt32ElementIndex = context.webGLVersion === 2 || !!context.extensions.uint32ElementIndex; } /** @@ -593,15 +603,27 @@ if (geometry.indexBuffer) { - if (geometry.instanced) + const byteSize = geometry.indexBuffer.data.BYTES_PER_ELEMENT; + const glType = byteSize === 2 ? gl.UNSIGNED_SHORT : gl.UNSIGNED_INT; + + if (byteSize === 2 || (byteSize === 4 && this.canUseUInt32ElementIndex)) { - /* eslint-disable max-len */ - gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2, instanceCount || 1); - /* eslint-enable max-len */ + if (geometry.instanced) + { + /* eslint-disable max-len */ + gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize, instanceCount || 1); + /* eslint-enable max-len */ + } + else + { + /* eslint-disable max-len */ + gl.drawElements(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize); + /* eslint-enable max-len */ + } } else { - gl.drawElements(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2); + console.warn('unsupported index buffer type: uint32'); } } else if (geometry.instanced) diff --git a/packages/core/src/renderTexture/RenderTexture.js b/packages/core/src/renderTexture/RenderTexture.js index f9c4f18..ecf5080 100644 --- a/packages/core/src/renderTexture/RenderTexture.js +++ b/packages/core/src/renderTexture/RenderTexture.js @@ -7,6 +7,9 @@ * __Hint__: All DisplayObjects (i.e. Sprites) that render to a RenderTexture should be preloaded * otherwise black rectangles will be drawn instead. * + * __Hint-2__: The actual memory allocation will happen on first render. + * You shouldn't create renderTextures each frame just to delete them after, try to reuse them. + * * A RenderTexture takes a snapshot of any Display Object given to its render method. For example: * * ```js diff --git a/packages/core/src/renderTexture/RenderTextureSystem.js b/packages/core/src/renderTexture/RenderTextureSystem.js index 7e29532..57c2fcc 100644 --- a/packages/core/src/renderTexture/RenderTextureSystem.js +++ b/packages/core/src/renderTexture/RenderTextureSystem.js @@ -61,9 +61,9 @@ /** * Bind the current render texture - * @param {PIXI.RenderTexture} renderTexture - * @param {PIXI.Rectangle} sourceFrame - * @param {PIXI.Rectangle} destinationFrame + * @param {PIXI.RenderTexture} [renderTexture] - RenderTexture to bind, by default its `null`, the screen + * @param {PIXI.Rectangle} [sourceFrame] - part of screen that is mapped to the renderTexture + * @param {PIXI.Rectangle} [destinationFrame] - part of renderTexture, by default it has the same size as sourceFrame */ bind(renderTexture = null, sourceFrame, destinationFrame) { diff --git a/packages/core/src/state/State.js b/packages/core/src/state/State.js index c87e268..9ef36dc 100644 --- a/packages/core/src/state/State.js +++ b/packages/core/src/state/State.js @@ -127,7 +127,7 @@ * The blend mode to be applied when this state is set. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode. * Setting this mode to anything other than NO_BLEND will automatically switch blending on. * - * @member {boolean} + * @member {number} * @default PIXI.BLEND_MODES.NORMAL * @see PIXI.BLEND_MODES */ diff --git a/packages/core/src/state/StateSystem.js b/packages/core/src/state/StateSystem.js index c7e35d2..f3be34e 100755 --- a/packages/core/src/state/StateSystem.js +++ b/packages/core/src/state/StateSystem.js @@ -182,6 +182,8 @@ */ setOffset(value) { + this.updateCheck(StateSystem.checkPolygonOffset, value); + this.gl[value ? 'enable' : 'disable'](this.gl.POLYGON_OFFSET_FILL); } @@ -314,5 +316,16 @@ system.setBlendMode(state.blendMode); } - // TODO - add polygon offset? + /** + * A private little wrapper function that we call to check the polygon offset. + * + * @static + * @private + * @param {PIXI.StateSystem} System the System to perform the state check on + * @param {PIXI.State} state the state that the blendMode will pulled from + */ + static checkPolygonOffset(system, state) + { + system.setPolygonOffset(state.polygonOffset, 0); + } } diff --git a/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js b/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js index fdebdc9..e53a723 100644 --- a/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js +++ b/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js @@ -15,7 +15,7 @@ // TODO - premultiply alpha would be different. // add a boolean for that! array[BLEND_MODES.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - array[BLEND_MODES.ADD] = [gl.ONE, gl.DST_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + array[BLEND_MODES.ADD] = [gl.ONE, gl.ONE]; array[BLEND_MODES.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; array[BLEND_MODES.SCREEN] = [gl.ONE, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; array[BLEND_MODES.OVERLAY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; @@ -35,7 +35,7 @@ // not-premultiplied blend modes array[BLEND_MODES.NORMAL_NPM] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - array[BLEND_MODES.ADD_NPM] = [gl.SRC_ALPHA, gl.DST_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + array[BLEND_MODES.ADD_NPM] = [gl.SRC_ALPHA, gl.ONE, gl.ONE, gl.ONE]; array[BLEND_MODES.SCREEN_NPM] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; // composite operations diff --git a/package-lock.json b/package-lock.json index eb731c3..a16c04b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2868,7 +2868,7 @@ }, "yargs": { "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { @@ -9992,14 +9992,28 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" + }, + "dependencies": { + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + } } }, "temp-dir": { diff --git a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js index fde693f..b7b7a7e 100644 --- a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js +++ b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js @@ -82,6 +82,8 @@ const holes = data.holes; let outerArea; let innerArea; + let px; + let py; context.moveTo(points[0], points[1]); @@ -98,19 +100,30 @@ if (holes.length > 0) { outerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + outerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } for (let k = 0; k < holes.length; k++) { - points = holes[k].points; + points = holes[k].shape.points; + + if (!points) + { + continue; + } innerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + innerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } if (innerArea * outerArea < 0) diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js index 8f4e0e4..4eac1d7 100644 --- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js +++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js @@ -29,7 +29,7 @@ const modY = ((this.tilePosition.y / this.tileScale.y) % texture._frame.height) * baseTextureResolution; // create a nice shiny pattern! - if (this._textureID !== this._texture._updateID || this.cachedTint !== this.tint) + if (this._textureID !== this._texture._updateID || this._cachedTint !== this.tint) { this._textureID = this._texture._updateID; // cut an object from a spritesheet.. @@ -48,7 +48,7 @@ tempCanvas.context.drawImage(source, -texture._frame.x * baseTextureResolution, -texture._frame.y * baseTextureResolution); } - this.cachedTint = this.tint; + this._cachedTint = this.tint; this._canvasPattern = tempCanvas.context.createPattern(tempCanvas.canvas, 'repeat'); } diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js index 297cb75..225beb0 100644 --- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js +++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js @@ -159,7 +159,7 @@ } context.drawImage( - source, + sprite._tintedCanvas, 0, 0, width * resolution, diff --git a/packages/canvas/canvas-sprite/src/Sprite.js b/packages/canvas/canvas-sprite/src/Sprite.js index 4bef51d..d94950f 100644 --- a/packages/canvas/canvas-sprite/src/Sprite.js +++ b/packages/canvas/canvas-sprite/src/Sprite.js @@ -9,14 +9,6 @@ Sprite.prototype._tintedCanvas = null; /** - * Cached tint value so we can tell when the tint is changed. - * @memberof PIXI.Sprite# - * @member {number} _cachedTint - * @protected - */ -Sprite.prototype._cachedTint = 0xFFFFFF; - -/** * Renders the object using the Canvas renderer * * @private diff --git a/packages/core/src/context/ContextSystem.js b/packages/core/src/context/ContextSystem.js index dc6243d..6487683 100644 --- a/packages/core/src/context/ContextSystem.js +++ b/packages/core/src/context/ContextSystem.js @@ -163,6 +163,7 @@ vertexArrayObject: gl.getExtension('OES_vertex_array_object') || gl.getExtension('MOZ_OES_vertex_array_object') || gl.getExtension('WEBKIT_OES_vertex_array_object'), + uint32ElementIndex: gl.getExtension('OES_element_index_uint'), }); } diff --git a/packages/core/src/filters/FilterSystem.js b/packages/core/src/filters/FilterSystem.js index a2ae32f..e4edd02 100644 --- a/packages/core/src/filters/FilterSystem.js +++ b/packages/core/src/filters/FilterSystem.js @@ -451,12 +451,9 @@ if (!renderTexture) { - // temporary bypass cache.. - // internally - this will cause a texture to be bound.. renderTexture = RenderTexture.create({ - width: minWidth / resolution, - height: minHeight / resolution, - resolution, + width: minWidth, + height: minHeight, }); } diff --git a/packages/core/src/geometry/GeometrySystem.js b/packages/core/src/geometry/GeometrySystem.js index 3b83a89..3c56989 100644 --- a/packages/core/src/geometry/GeometrySystem.js +++ b/packages/core/src/geometry/GeometrySystem.js @@ -39,6 +39,13 @@ this.hasInstance = true; /** + * `true` if support `gl.UNSIGNED_INT` in `gl.drawElements` or `gl.drawElementsInstanced` + * @member {boolean} + * @readonly + */ + this.canUseUInt32ElementIndex = false; + + /** * A cache of currently bound buffer, * contains only two members with keys ARRAY_BUFFER and ELEMENT_ARRAY_BUFFER * @member {Object.} @@ -69,6 +76,7 @@ this.disposeAll(true); const gl = this.gl = this.renderer.gl; + const context = this.renderer.context; this.CONTEXT_UID = this.renderer.CONTEXT_UID; @@ -134,6 +142,8 @@ this.hasInstance = false; } } + + this.canUseUInt32ElementIndex = context.webGLVersion === 2 || !!context.extensions.uint32ElementIndex; } /** @@ -593,15 +603,27 @@ if (geometry.indexBuffer) { - if (geometry.instanced) + const byteSize = geometry.indexBuffer.data.BYTES_PER_ELEMENT; + const glType = byteSize === 2 ? gl.UNSIGNED_SHORT : gl.UNSIGNED_INT; + + if (byteSize === 2 || (byteSize === 4 && this.canUseUInt32ElementIndex)) { - /* eslint-disable max-len */ - gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2, instanceCount || 1); - /* eslint-enable max-len */ + if (geometry.instanced) + { + /* eslint-disable max-len */ + gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize, instanceCount || 1); + /* eslint-enable max-len */ + } + else + { + /* eslint-disable max-len */ + gl.drawElements(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize); + /* eslint-enable max-len */ + } } else { - gl.drawElements(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2); + console.warn('unsupported index buffer type: uint32'); } } else if (geometry.instanced) diff --git a/packages/core/src/renderTexture/RenderTexture.js b/packages/core/src/renderTexture/RenderTexture.js index f9c4f18..ecf5080 100644 --- a/packages/core/src/renderTexture/RenderTexture.js +++ b/packages/core/src/renderTexture/RenderTexture.js @@ -7,6 +7,9 @@ * __Hint__: All DisplayObjects (i.e. Sprites) that render to a RenderTexture should be preloaded * otherwise black rectangles will be drawn instead. * + * __Hint-2__: The actual memory allocation will happen on first render. + * You shouldn't create renderTextures each frame just to delete them after, try to reuse them. + * * A RenderTexture takes a snapshot of any Display Object given to its render method. For example: * * ```js diff --git a/packages/core/src/renderTexture/RenderTextureSystem.js b/packages/core/src/renderTexture/RenderTextureSystem.js index 7e29532..57c2fcc 100644 --- a/packages/core/src/renderTexture/RenderTextureSystem.js +++ b/packages/core/src/renderTexture/RenderTextureSystem.js @@ -61,9 +61,9 @@ /** * Bind the current render texture - * @param {PIXI.RenderTexture} renderTexture - * @param {PIXI.Rectangle} sourceFrame - * @param {PIXI.Rectangle} destinationFrame + * @param {PIXI.RenderTexture} [renderTexture] - RenderTexture to bind, by default its `null`, the screen + * @param {PIXI.Rectangle} [sourceFrame] - part of screen that is mapped to the renderTexture + * @param {PIXI.Rectangle} [destinationFrame] - part of renderTexture, by default it has the same size as sourceFrame */ bind(renderTexture = null, sourceFrame, destinationFrame) { diff --git a/packages/core/src/state/State.js b/packages/core/src/state/State.js index c87e268..9ef36dc 100644 --- a/packages/core/src/state/State.js +++ b/packages/core/src/state/State.js @@ -127,7 +127,7 @@ * The blend mode to be applied when this state is set. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode. * Setting this mode to anything other than NO_BLEND will automatically switch blending on. * - * @member {boolean} + * @member {number} * @default PIXI.BLEND_MODES.NORMAL * @see PIXI.BLEND_MODES */ diff --git a/packages/core/src/state/StateSystem.js b/packages/core/src/state/StateSystem.js index c7e35d2..f3be34e 100755 --- a/packages/core/src/state/StateSystem.js +++ b/packages/core/src/state/StateSystem.js @@ -182,6 +182,8 @@ */ setOffset(value) { + this.updateCheck(StateSystem.checkPolygonOffset, value); + this.gl[value ? 'enable' : 'disable'](this.gl.POLYGON_OFFSET_FILL); } @@ -314,5 +316,16 @@ system.setBlendMode(state.blendMode); } - // TODO - add polygon offset? + /** + * A private little wrapper function that we call to check the polygon offset. + * + * @static + * @private + * @param {PIXI.StateSystem} System the System to perform the state check on + * @param {PIXI.State} state the state that the blendMode will pulled from + */ + static checkPolygonOffset(system, state) + { + system.setPolygonOffset(state.polygonOffset, 0); + } } diff --git a/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js b/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js index fdebdc9..e53a723 100644 --- a/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js +++ b/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js @@ -15,7 +15,7 @@ // TODO - premultiply alpha would be different. // add a boolean for that! array[BLEND_MODES.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - array[BLEND_MODES.ADD] = [gl.ONE, gl.DST_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + array[BLEND_MODES.ADD] = [gl.ONE, gl.ONE]; array[BLEND_MODES.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; array[BLEND_MODES.SCREEN] = [gl.ONE, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; array[BLEND_MODES.OVERLAY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; @@ -35,7 +35,7 @@ // not-premultiplied blend modes array[BLEND_MODES.NORMAL_NPM] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - array[BLEND_MODES.ADD_NPM] = [gl.SRC_ALPHA, gl.DST_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + array[BLEND_MODES.ADD_NPM] = [gl.SRC_ALPHA, gl.ONE, gl.ONE, gl.ONE]; array[BLEND_MODES.SCREEN_NPM] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; // composite operations diff --git a/packages/core/src/textures/resources/SVGResource.js b/packages/core/src/textures/resources/SVGResource.js index 04eb33d..a87a355 100644 --- a/packages/core/src/textures/resources/SVGResource.js +++ b/packages/core/src/textures/resources/SVGResource.js @@ -1,4 +1,4 @@ -import { decomposeDataUri, uid } from '@pixi/utils'; +import { uid } from '@pixi/utils'; import BaseImageResource from './BaseImageResource'; /** @@ -41,6 +41,13 @@ this._resolve = null; /** + * Cross origin value to use + * @private + * @member {boolean|string} + */ + this._crossorigin = options.crossorigin; + + /** * Promise when loading * @member {Promise} * @private @@ -73,112 +80,35 @@ // Convert SVG inline string to data-uri if ((/^\ - { - if (svgXhr.readyState !== svgXhr.DONE || svgXhr.status !== 200) - { - throw new Error('Failed to load SVG using XHR.'); - } - - this._loadString(svgXhr.response); - }; - - // svgXhr.onerror = () => this.emit('error', this); - - svgXhr.open('GET', this.svg, true); - svgXhr.send(); - } - - /** - * Loads texture using an SVG string. The original SVG Image is stored as `origSource` and the - * created canvas is the new `source`. The SVG is scaled using `sourceScale`. Called by - * `_loadXhr` or `_loadDataUri`. - * - * @private - * @param {string} svgString SVG source as string - * - * @fires loaded - */ - _loadString(svgString) - { - const svgSize = SVGResource.getSize(svgString); - const tempImage = new Image(); - tempImage.src = `data:image/svg+xml,${svgString}`; - - tempImage.onerror = () => - { - throw new Error(`Unable to load image from: ${tempImage.src}`); - }; + BaseImageResource.crossOrigin(tempImage, this.svg, this._crossorigin); + tempImage.src = this.svg; tempImage.onload = () => { - const svgWidth = svgSize.width; - const svgHeight = svgSize.height; + const svgWidth = tempImage.width; + const svgHeight = tempImage.height; if (!svgWidth || !svgHeight) { @@ -244,6 +174,7 @@ { super.dispose(); this._resolve = null; + this._crossorigin = null; } /** @@ -258,7 +189,9 @@ // url file extension is SVG return extension === 'svg' // source is SVG data-uri - || (typeof source === 'string' && source.indexOf('data:image/svg+xml') === 0); + || (typeof source === 'string' && source.indexOf('data:image/svg+xml;base64') === 0) + // source is SVG inline + || (typeof source === 'string' && source.indexOf('=0.5 0", + "rimraf": "2" + } + } } }, "temp-dir": { diff --git a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js index fde693f..b7b7a7e 100644 --- a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js +++ b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js @@ -82,6 +82,8 @@ const holes = data.holes; let outerArea; let innerArea; + let px; + let py; context.moveTo(points[0], points[1]); @@ -98,19 +100,30 @@ if (holes.length > 0) { outerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + outerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } for (let k = 0; k < holes.length; k++) { - points = holes[k].points; + points = holes[k].shape.points; + + if (!points) + { + continue; + } innerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + innerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } if (innerArea * outerArea < 0) diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js index 8f4e0e4..4eac1d7 100644 --- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js +++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js @@ -29,7 +29,7 @@ const modY = ((this.tilePosition.y / this.tileScale.y) % texture._frame.height) * baseTextureResolution; // create a nice shiny pattern! - if (this._textureID !== this._texture._updateID || this.cachedTint !== this.tint) + if (this._textureID !== this._texture._updateID || this._cachedTint !== this.tint) { this._textureID = this._texture._updateID; // cut an object from a spritesheet.. @@ -48,7 +48,7 @@ tempCanvas.context.drawImage(source, -texture._frame.x * baseTextureResolution, -texture._frame.y * baseTextureResolution); } - this.cachedTint = this.tint; + this._cachedTint = this.tint; this._canvasPattern = tempCanvas.context.createPattern(tempCanvas.canvas, 'repeat'); } diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js index 297cb75..225beb0 100644 --- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js +++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js @@ -159,7 +159,7 @@ } context.drawImage( - source, + sprite._tintedCanvas, 0, 0, width * resolution, diff --git a/packages/canvas/canvas-sprite/src/Sprite.js b/packages/canvas/canvas-sprite/src/Sprite.js index 4bef51d..d94950f 100644 --- a/packages/canvas/canvas-sprite/src/Sprite.js +++ b/packages/canvas/canvas-sprite/src/Sprite.js @@ -9,14 +9,6 @@ Sprite.prototype._tintedCanvas = null; /** - * Cached tint value so we can tell when the tint is changed. - * @memberof PIXI.Sprite# - * @member {number} _cachedTint - * @protected - */ -Sprite.prototype._cachedTint = 0xFFFFFF; - -/** * Renders the object using the Canvas renderer * * @private diff --git a/packages/core/src/context/ContextSystem.js b/packages/core/src/context/ContextSystem.js index dc6243d..6487683 100644 --- a/packages/core/src/context/ContextSystem.js +++ b/packages/core/src/context/ContextSystem.js @@ -163,6 +163,7 @@ vertexArrayObject: gl.getExtension('OES_vertex_array_object') || gl.getExtension('MOZ_OES_vertex_array_object') || gl.getExtension('WEBKIT_OES_vertex_array_object'), + uint32ElementIndex: gl.getExtension('OES_element_index_uint'), }); } diff --git a/packages/core/src/filters/FilterSystem.js b/packages/core/src/filters/FilterSystem.js index a2ae32f..e4edd02 100644 --- a/packages/core/src/filters/FilterSystem.js +++ b/packages/core/src/filters/FilterSystem.js @@ -451,12 +451,9 @@ if (!renderTexture) { - // temporary bypass cache.. - // internally - this will cause a texture to be bound.. renderTexture = RenderTexture.create({ - width: minWidth / resolution, - height: minHeight / resolution, - resolution, + width: minWidth, + height: minHeight, }); } diff --git a/packages/core/src/geometry/GeometrySystem.js b/packages/core/src/geometry/GeometrySystem.js index 3b83a89..3c56989 100644 --- a/packages/core/src/geometry/GeometrySystem.js +++ b/packages/core/src/geometry/GeometrySystem.js @@ -39,6 +39,13 @@ this.hasInstance = true; /** + * `true` if support `gl.UNSIGNED_INT` in `gl.drawElements` or `gl.drawElementsInstanced` + * @member {boolean} + * @readonly + */ + this.canUseUInt32ElementIndex = false; + + /** * A cache of currently bound buffer, * contains only two members with keys ARRAY_BUFFER and ELEMENT_ARRAY_BUFFER * @member {Object.} @@ -69,6 +76,7 @@ this.disposeAll(true); const gl = this.gl = this.renderer.gl; + const context = this.renderer.context; this.CONTEXT_UID = this.renderer.CONTEXT_UID; @@ -134,6 +142,8 @@ this.hasInstance = false; } } + + this.canUseUInt32ElementIndex = context.webGLVersion === 2 || !!context.extensions.uint32ElementIndex; } /** @@ -593,15 +603,27 @@ if (geometry.indexBuffer) { - if (geometry.instanced) + const byteSize = geometry.indexBuffer.data.BYTES_PER_ELEMENT; + const glType = byteSize === 2 ? gl.UNSIGNED_SHORT : gl.UNSIGNED_INT; + + if (byteSize === 2 || (byteSize === 4 && this.canUseUInt32ElementIndex)) { - /* eslint-disable max-len */ - gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2, instanceCount || 1); - /* eslint-enable max-len */ + if (geometry.instanced) + { + /* eslint-disable max-len */ + gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize, instanceCount || 1); + /* eslint-enable max-len */ + } + else + { + /* eslint-disable max-len */ + gl.drawElements(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize); + /* eslint-enable max-len */ + } } else { - gl.drawElements(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2); + console.warn('unsupported index buffer type: uint32'); } } else if (geometry.instanced) diff --git a/packages/core/src/renderTexture/RenderTexture.js b/packages/core/src/renderTexture/RenderTexture.js index f9c4f18..ecf5080 100644 --- a/packages/core/src/renderTexture/RenderTexture.js +++ b/packages/core/src/renderTexture/RenderTexture.js @@ -7,6 +7,9 @@ * __Hint__: All DisplayObjects (i.e. Sprites) that render to a RenderTexture should be preloaded * otherwise black rectangles will be drawn instead. * + * __Hint-2__: The actual memory allocation will happen on first render. + * You shouldn't create renderTextures each frame just to delete them after, try to reuse them. + * * A RenderTexture takes a snapshot of any Display Object given to its render method. For example: * * ```js diff --git a/packages/core/src/renderTexture/RenderTextureSystem.js b/packages/core/src/renderTexture/RenderTextureSystem.js index 7e29532..57c2fcc 100644 --- a/packages/core/src/renderTexture/RenderTextureSystem.js +++ b/packages/core/src/renderTexture/RenderTextureSystem.js @@ -61,9 +61,9 @@ /** * Bind the current render texture - * @param {PIXI.RenderTexture} renderTexture - * @param {PIXI.Rectangle} sourceFrame - * @param {PIXI.Rectangle} destinationFrame + * @param {PIXI.RenderTexture} [renderTexture] - RenderTexture to bind, by default its `null`, the screen + * @param {PIXI.Rectangle} [sourceFrame] - part of screen that is mapped to the renderTexture + * @param {PIXI.Rectangle} [destinationFrame] - part of renderTexture, by default it has the same size as sourceFrame */ bind(renderTexture = null, sourceFrame, destinationFrame) { diff --git a/packages/core/src/state/State.js b/packages/core/src/state/State.js index c87e268..9ef36dc 100644 --- a/packages/core/src/state/State.js +++ b/packages/core/src/state/State.js @@ -127,7 +127,7 @@ * The blend mode to be applied when this state is set. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode. * Setting this mode to anything other than NO_BLEND will automatically switch blending on. * - * @member {boolean} + * @member {number} * @default PIXI.BLEND_MODES.NORMAL * @see PIXI.BLEND_MODES */ diff --git a/packages/core/src/state/StateSystem.js b/packages/core/src/state/StateSystem.js index c7e35d2..f3be34e 100755 --- a/packages/core/src/state/StateSystem.js +++ b/packages/core/src/state/StateSystem.js @@ -182,6 +182,8 @@ */ setOffset(value) { + this.updateCheck(StateSystem.checkPolygonOffset, value); + this.gl[value ? 'enable' : 'disable'](this.gl.POLYGON_OFFSET_FILL); } @@ -314,5 +316,16 @@ system.setBlendMode(state.blendMode); } - // TODO - add polygon offset? + /** + * A private little wrapper function that we call to check the polygon offset. + * + * @static + * @private + * @param {PIXI.StateSystem} System the System to perform the state check on + * @param {PIXI.State} state the state that the blendMode will pulled from + */ + static checkPolygonOffset(system, state) + { + system.setPolygonOffset(state.polygonOffset, 0); + } } diff --git a/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js b/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js index fdebdc9..e53a723 100644 --- a/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js +++ b/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js @@ -15,7 +15,7 @@ // TODO - premultiply alpha would be different. // add a boolean for that! array[BLEND_MODES.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - array[BLEND_MODES.ADD] = [gl.ONE, gl.DST_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + array[BLEND_MODES.ADD] = [gl.ONE, gl.ONE]; array[BLEND_MODES.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; array[BLEND_MODES.SCREEN] = [gl.ONE, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; array[BLEND_MODES.OVERLAY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; @@ -35,7 +35,7 @@ // not-premultiplied blend modes array[BLEND_MODES.NORMAL_NPM] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - array[BLEND_MODES.ADD_NPM] = [gl.SRC_ALPHA, gl.DST_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + array[BLEND_MODES.ADD_NPM] = [gl.SRC_ALPHA, gl.ONE, gl.ONE, gl.ONE]; array[BLEND_MODES.SCREEN_NPM] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; // composite operations diff --git a/packages/core/src/textures/resources/SVGResource.js b/packages/core/src/textures/resources/SVGResource.js index 04eb33d..a87a355 100644 --- a/packages/core/src/textures/resources/SVGResource.js +++ b/packages/core/src/textures/resources/SVGResource.js @@ -1,4 +1,4 @@ -import { decomposeDataUri, uid } from '@pixi/utils'; +import { uid } from '@pixi/utils'; import BaseImageResource from './BaseImageResource'; /** @@ -41,6 +41,13 @@ this._resolve = null; /** + * Cross origin value to use + * @private + * @member {boolean|string} + */ + this._crossorigin = options.crossorigin; + + /** * Promise when loading * @member {Promise} * @private @@ -73,112 +80,35 @@ // Convert SVG inline string to data-uri if ((/^\ - { - if (svgXhr.readyState !== svgXhr.DONE || svgXhr.status !== 200) - { - throw new Error('Failed to load SVG using XHR.'); - } - - this._loadString(svgXhr.response); - }; - - // svgXhr.onerror = () => this.emit('error', this); - - svgXhr.open('GET', this.svg, true); - svgXhr.send(); - } - - /** - * Loads texture using an SVG string. The original SVG Image is stored as `origSource` and the - * created canvas is the new `source`. The SVG is scaled using `sourceScale`. Called by - * `_loadXhr` or `_loadDataUri`. - * - * @private - * @param {string} svgString SVG source as string - * - * @fires loaded - */ - _loadString(svgString) - { - const svgSize = SVGResource.getSize(svgString); - const tempImage = new Image(); - tempImage.src = `data:image/svg+xml,${svgString}`; - - tempImage.onerror = () => - { - throw new Error(`Unable to load image from: ${tempImage.src}`); - }; + BaseImageResource.crossOrigin(tempImage, this.svg, this._crossorigin); + tempImage.src = this.svg; tempImage.onload = () => { - const svgWidth = svgSize.width; - const svgHeight = svgSize.height; + const svgWidth = tempImage.width; + const svgHeight = tempImage.height; if (!svgWidth || !svgHeight) { @@ -244,6 +174,7 @@ { super.dispose(); this._resolve = null; + this._crossorigin = null; } /** @@ -258,7 +189,9 @@ // url file extension is SVG return extension === 'svg' // source is SVG data-uri - || (typeof source === 'string' && source.indexOf('data:image/svg+xml') === 0); + || (typeof source === 'string' && source.indexOf('data:image/svg+xml;base64') === 0) + // source is SVG inline + || (typeof source === 'string' && source.indexOf(' maxSize) - { - batchSize = maxSize; - } - /** * Set properties to be dynamic (true) / static (false) * diff --git a/package-lock.json b/package-lock.json index eb731c3..a16c04b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2868,7 +2868,7 @@ }, "yargs": { "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { @@ -9992,14 +9992,28 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" + }, + "dependencies": { + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + } } }, "temp-dir": { diff --git a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js index fde693f..b7b7a7e 100644 --- a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js +++ b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js @@ -82,6 +82,8 @@ const holes = data.holes; let outerArea; let innerArea; + let px; + let py; context.moveTo(points[0], points[1]); @@ -98,19 +100,30 @@ if (holes.length > 0) { outerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + outerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } for (let k = 0; k < holes.length; k++) { - points = holes[k].points; + points = holes[k].shape.points; + + if (!points) + { + continue; + } innerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + innerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } if (innerArea * outerArea < 0) diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js index 8f4e0e4..4eac1d7 100644 --- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js +++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js @@ -29,7 +29,7 @@ const modY = ((this.tilePosition.y / this.tileScale.y) % texture._frame.height) * baseTextureResolution; // create a nice shiny pattern! - if (this._textureID !== this._texture._updateID || this.cachedTint !== this.tint) + if (this._textureID !== this._texture._updateID || this._cachedTint !== this.tint) { this._textureID = this._texture._updateID; // cut an object from a spritesheet.. @@ -48,7 +48,7 @@ tempCanvas.context.drawImage(source, -texture._frame.x * baseTextureResolution, -texture._frame.y * baseTextureResolution); } - this.cachedTint = this.tint; + this._cachedTint = this.tint; this._canvasPattern = tempCanvas.context.createPattern(tempCanvas.canvas, 'repeat'); } diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js index 297cb75..225beb0 100644 --- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js +++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js @@ -159,7 +159,7 @@ } context.drawImage( - source, + sprite._tintedCanvas, 0, 0, width * resolution, diff --git a/packages/canvas/canvas-sprite/src/Sprite.js b/packages/canvas/canvas-sprite/src/Sprite.js index 4bef51d..d94950f 100644 --- a/packages/canvas/canvas-sprite/src/Sprite.js +++ b/packages/canvas/canvas-sprite/src/Sprite.js @@ -9,14 +9,6 @@ Sprite.prototype._tintedCanvas = null; /** - * Cached tint value so we can tell when the tint is changed. - * @memberof PIXI.Sprite# - * @member {number} _cachedTint - * @protected - */ -Sprite.prototype._cachedTint = 0xFFFFFF; - -/** * Renders the object using the Canvas renderer * * @private diff --git a/packages/core/src/context/ContextSystem.js b/packages/core/src/context/ContextSystem.js index dc6243d..6487683 100644 --- a/packages/core/src/context/ContextSystem.js +++ b/packages/core/src/context/ContextSystem.js @@ -163,6 +163,7 @@ vertexArrayObject: gl.getExtension('OES_vertex_array_object') || gl.getExtension('MOZ_OES_vertex_array_object') || gl.getExtension('WEBKIT_OES_vertex_array_object'), + uint32ElementIndex: gl.getExtension('OES_element_index_uint'), }); } diff --git a/packages/core/src/filters/FilterSystem.js b/packages/core/src/filters/FilterSystem.js index a2ae32f..e4edd02 100644 --- a/packages/core/src/filters/FilterSystem.js +++ b/packages/core/src/filters/FilterSystem.js @@ -451,12 +451,9 @@ if (!renderTexture) { - // temporary bypass cache.. - // internally - this will cause a texture to be bound.. renderTexture = RenderTexture.create({ - width: minWidth / resolution, - height: minHeight / resolution, - resolution, + width: minWidth, + height: minHeight, }); } diff --git a/packages/core/src/geometry/GeometrySystem.js b/packages/core/src/geometry/GeometrySystem.js index 3b83a89..3c56989 100644 --- a/packages/core/src/geometry/GeometrySystem.js +++ b/packages/core/src/geometry/GeometrySystem.js @@ -39,6 +39,13 @@ this.hasInstance = true; /** + * `true` if support `gl.UNSIGNED_INT` in `gl.drawElements` or `gl.drawElementsInstanced` + * @member {boolean} + * @readonly + */ + this.canUseUInt32ElementIndex = false; + + /** * A cache of currently bound buffer, * contains only two members with keys ARRAY_BUFFER and ELEMENT_ARRAY_BUFFER * @member {Object.} @@ -69,6 +76,7 @@ this.disposeAll(true); const gl = this.gl = this.renderer.gl; + const context = this.renderer.context; this.CONTEXT_UID = this.renderer.CONTEXT_UID; @@ -134,6 +142,8 @@ this.hasInstance = false; } } + + this.canUseUInt32ElementIndex = context.webGLVersion === 2 || !!context.extensions.uint32ElementIndex; } /** @@ -593,15 +603,27 @@ if (geometry.indexBuffer) { - if (geometry.instanced) + const byteSize = geometry.indexBuffer.data.BYTES_PER_ELEMENT; + const glType = byteSize === 2 ? gl.UNSIGNED_SHORT : gl.UNSIGNED_INT; + + if (byteSize === 2 || (byteSize === 4 && this.canUseUInt32ElementIndex)) { - /* eslint-disable max-len */ - gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2, instanceCount || 1); - /* eslint-enable max-len */ + if (geometry.instanced) + { + /* eslint-disable max-len */ + gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize, instanceCount || 1); + /* eslint-enable max-len */ + } + else + { + /* eslint-disable max-len */ + gl.drawElements(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize); + /* eslint-enable max-len */ + } } else { - gl.drawElements(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2); + console.warn('unsupported index buffer type: uint32'); } } else if (geometry.instanced) diff --git a/packages/core/src/renderTexture/RenderTexture.js b/packages/core/src/renderTexture/RenderTexture.js index f9c4f18..ecf5080 100644 --- a/packages/core/src/renderTexture/RenderTexture.js +++ b/packages/core/src/renderTexture/RenderTexture.js @@ -7,6 +7,9 @@ * __Hint__: All DisplayObjects (i.e. Sprites) that render to a RenderTexture should be preloaded * otherwise black rectangles will be drawn instead. * + * __Hint-2__: The actual memory allocation will happen on first render. + * You shouldn't create renderTextures each frame just to delete them after, try to reuse them. + * * A RenderTexture takes a snapshot of any Display Object given to its render method. For example: * * ```js diff --git a/packages/core/src/renderTexture/RenderTextureSystem.js b/packages/core/src/renderTexture/RenderTextureSystem.js index 7e29532..57c2fcc 100644 --- a/packages/core/src/renderTexture/RenderTextureSystem.js +++ b/packages/core/src/renderTexture/RenderTextureSystem.js @@ -61,9 +61,9 @@ /** * Bind the current render texture - * @param {PIXI.RenderTexture} renderTexture - * @param {PIXI.Rectangle} sourceFrame - * @param {PIXI.Rectangle} destinationFrame + * @param {PIXI.RenderTexture} [renderTexture] - RenderTexture to bind, by default its `null`, the screen + * @param {PIXI.Rectangle} [sourceFrame] - part of screen that is mapped to the renderTexture + * @param {PIXI.Rectangle} [destinationFrame] - part of renderTexture, by default it has the same size as sourceFrame */ bind(renderTexture = null, sourceFrame, destinationFrame) { diff --git a/packages/core/src/state/State.js b/packages/core/src/state/State.js index c87e268..9ef36dc 100644 --- a/packages/core/src/state/State.js +++ b/packages/core/src/state/State.js @@ -127,7 +127,7 @@ * The blend mode to be applied when this state is set. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode. * Setting this mode to anything other than NO_BLEND will automatically switch blending on. * - * @member {boolean} + * @member {number} * @default PIXI.BLEND_MODES.NORMAL * @see PIXI.BLEND_MODES */ diff --git a/packages/core/src/state/StateSystem.js b/packages/core/src/state/StateSystem.js index c7e35d2..f3be34e 100755 --- a/packages/core/src/state/StateSystem.js +++ b/packages/core/src/state/StateSystem.js @@ -182,6 +182,8 @@ */ setOffset(value) { + this.updateCheck(StateSystem.checkPolygonOffset, value); + this.gl[value ? 'enable' : 'disable'](this.gl.POLYGON_OFFSET_FILL); } @@ -314,5 +316,16 @@ system.setBlendMode(state.blendMode); } - // TODO - add polygon offset? + /** + * A private little wrapper function that we call to check the polygon offset. + * + * @static + * @private + * @param {PIXI.StateSystem} System the System to perform the state check on + * @param {PIXI.State} state the state that the blendMode will pulled from + */ + static checkPolygonOffset(system, state) + { + system.setPolygonOffset(state.polygonOffset, 0); + } } diff --git a/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js b/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js index fdebdc9..e53a723 100644 --- a/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js +++ b/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js @@ -15,7 +15,7 @@ // TODO - premultiply alpha would be different. // add a boolean for that! array[BLEND_MODES.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - array[BLEND_MODES.ADD] = [gl.ONE, gl.DST_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + array[BLEND_MODES.ADD] = [gl.ONE, gl.ONE]; array[BLEND_MODES.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; array[BLEND_MODES.SCREEN] = [gl.ONE, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; array[BLEND_MODES.OVERLAY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; @@ -35,7 +35,7 @@ // not-premultiplied blend modes array[BLEND_MODES.NORMAL_NPM] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - array[BLEND_MODES.ADD_NPM] = [gl.SRC_ALPHA, gl.DST_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + array[BLEND_MODES.ADD_NPM] = [gl.SRC_ALPHA, gl.ONE, gl.ONE, gl.ONE]; array[BLEND_MODES.SCREEN_NPM] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; // composite operations diff --git a/packages/core/src/textures/resources/SVGResource.js b/packages/core/src/textures/resources/SVGResource.js index 04eb33d..a87a355 100644 --- a/packages/core/src/textures/resources/SVGResource.js +++ b/packages/core/src/textures/resources/SVGResource.js @@ -1,4 +1,4 @@ -import { decomposeDataUri, uid } from '@pixi/utils'; +import { uid } from '@pixi/utils'; import BaseImageResource from './BaseImageResource'; /** @@ -41,6 +41,13 @@ this._resolve = null; /** + * Cross origin value to use + * @private + * @member {boolean|string} + */ + this._crossorigin = options.crossorigin; + + /** * Promise when loading * @member {Promise} * @private @@ -73,112 +80,35 @@ // Convert SVG inline string to data-uri if ((/^\ - { - if (svgXhr.readyState !== svgXhr.DONE || svgXhr.status !== 200) - { - throw new Error('Failed to load SVG using XHR.'); - } - - this._loadString(svgXhr.response); - }; - - // svgXhr.onerror = () => this.emit('error', this); - - svgXhr.open('GET', this.svg, true); - svgXhr.send(); - } - - /** - * Loads texture using an SVG string. The original SVG Image is stored as `origSource` and the - * created canvas is the new `source`. The SVG is scaled using `sourceScale`. Called by - * `_loadXhr` or `_loadDataUri`. - * - * @private - * @param {string} svgString SVG source as string - * - * @fires loaded - */ - _loadString(svgString) - { - const svgSize = SVGResource.getSize(svgString); - const tempImage = new Image(); - tempImage.src = `data:image/svg+xml,${svgString}`; - - tempImage.onerror = () => - { - throw new Error(`Unable to load image from: ${tempImage.src}`); - }; + BaseImageResource.crossOrigin(tempImage, this.svg, this._crossorigin); + tempImage.src = this.svg; tempImage.onload = () => { - const svgWidth = svgSize.width; - const svgHeight = svgSize.height; + const svgWidth = tempImage.width; + const svgHeight = tempImage.height; if (!svgWidth || !svgHeight) { @@ -244,6 +174,7 @@ { super.dispose(); this._resolve = null; + this._crossorigin = null; } /** @@ -258,7 +189,9 @@ // url file extension is SVG return extension === 'svg' // source is SVG data-uri - || (typeof source === 'string' && source.indexOf('data:image/svg+xml') === 0); + || (typeof source === 'string' && source.indexOf('data:image/svg+xml;base64') === 0) + // source is SVG inline + || (typeof source === 'string' && source.indexOf(' maxSize) - { - batchSize = maxSize; - } - /** * Set properties to be dynamic (true) / static (false) * diff --git a/packages/particles/src/ParticleRenderer.js b/packages/particles/src/ParticleRenderer.js index 253b0ed..d5e4c03 100644 --- a/packages/particles/src/ParticleRenderer.js +++ b/packages/particles/src/ParticleRenderer.js @@ -109,7 +109,7 @@ { return; } - else if (totalChildren > maxSize) + else if (totalChildren > maxSize && !container.autoResize) { totalChildren = maxSize; } @@ -155,10 +155,6 @@ if (j >= buffers.length) { - if (!container.autoResize) - { - break; - } buffers.push(this._generateOneMoreBuffer(container)); } diff --git a/package-lock.json b/package-lock.json index eb731c3..a16c04b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2868,7 +2868,7 @@ }, "yargs": { "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { @@ -9992,14 +9992,28 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" + }, + "dependencies": { + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + } } }, "temp-dir": { diff --git a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js index fde693f..b7b7a7e 100644 --- a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js +++ b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js @@ -82,6 +82,8 @@ const holes = data.holes; let outerArea; let innerArea; + let px; + let py; context.moveTo(points[0], points[1]); @@ -98,19 +100,30 @@ if (holes.length > 0) { outerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + outerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } for (let k = 0; k < holes.length; k++) { - points = holes[k].points; + points = holes[k].shape.points; + + if (!points) + { + continue; + } innerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + innerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } if (innerArea * outerArea < 0) diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js index 8f4e0e4..4eac1d7 100644 --- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js +++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js @@ -29,7 +29,7 @@ const modY = ((this.tilePosition.y / this.tileScale.y) % texture._frame.height) * baseTextureResolution; // create a nice shiny pattern! - if (this._textureID !== this._texture._updateID || this.cachedTint !== this.tint) + if (this._textureID !== this._texture._updateID || this._cachedTint !== this.tint) { this._textureID = this._texture._updateID; // cut an object from a spritesheet.. @@ -48,7 +48,7 @@ tempCanvas.context.drawImage(source, -texture._frame.x * baseTextureResolution, -texture._frame.y * baseTextureResolution); } - this.cachedTint = this.tint; + this._cachedTint = this.tint; this._canvasPattern = tempCanvas.context.createPattern(tempCanvas.canvas, 'repeat'); } diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js index 297cb75..225beb0 100644 --- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js +++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js @@ -159,7 +159,7 @@ } context.drawImage( - source, + sprite._tintedCanvas, 0, 0, width * resolution, diff --git a/packages/canvas/canvas-sprite/src/Sprite.js b/packages/canvas/canvas-sprite/src/Sprite.js index 4bef51d..d94950f 100644 --- a/packages/canvas/canvas-sprite/src/Sprite.js +++ b/packages/canvas/canvas-sprite/src/Sprite.js @@ -9,14 +9,6 @@ Sprite.prototype._tintedCanvas = null; /** - * Cached tint value so we can tell when the tint is changed. - * @memberof PIXI.Sprite# - * @member {number} _cachedTint - * @protected - */ -Sprite.prototype._cachedTint = 0xFFFFFF; - -/** * Renders the object using the Canvas renderer * * @private diff --git a/packages/core/src/context/ContextSystem.js b/packages/core/src/context/ContextSystem.js index dc6243d..6487683 100644 --- a/packages/core/src/context/ContextSystem.js +++ b/packages/core/src/context/ContextSystem.js @@ -163,6 +163,7 @@ vertexArrayObject: gl.getExtension('OES_vertex_array_object') || gl.getExtension('MOZ_OES_vertex_array_object') || gl.getExtension('WEBKIT_OES_vertex_array_object'), + uint32ElementIndex: gl.getExtension('OES_element_index_uint'), }); } diff --git a/packages/core/src/filters/FilterSystem.js b/packages/core/src/filters/FilterSystem.js index a2ae32f..e4edd02 100644 --- a/packages/core/src/filters/FilterSystem.js +++ b/packages/core/src/filters/FilterSystem.js @@ -451,12 +451,9 @@ if (!renderTexture) { - // temporary bypass cache.. - // internally - this will cause a texture to be bound.. renderTexture = RenderTexture.create({ - width: minWidth / resolution, - height: minHeight / resolution, - resolution, + width: minWidth, + height: minHeight, }); } diff --git a/packages/core/src/geometry/GeometrySystem.js b/packages/core/src/geometry/GeometrySystem.js index 3b83a89..3c56989 100644 --- a/packages/core/src/geometry/GeometrySystem.js +++ b/packages/core/src/geometry/GeometrySystem.js @@ -39,6 +39,13 @@ this.hasInstance = true; /** + * `true` if support `gl.UNSIGNED_INT` in `gl.drawElements` or `gl.drawElementsInstanced` + * @member {boolean} + * @readonly + */ + this.canUseUInt32ElementIndex = false; + + /** * A cache of currently bound buffer, * contains only two members with keys ARRAY_BUFFER and ELEMENT_ARRAY_BUFFER * @member {Object.} @@ -69,6 +76,7 @@ this.disposeAll(true); const gl = this.gl = this.renderer.gl; + const context = this.renderer.context; this.CONTEXT_UID = this.renderer.CONTEXT_UID; @@ -134,6 +142,8 @@ this.hasInstance = false; } } + + this.canUseUInt32ElementIndex = context.webGLVersion === 2 || !!context.extensions.uint32ElementIndex; } /** @@ -593,15 +603,27 @@ if (geometry.indexBuffer) { - if (geometry.instanced) + const byteSize = geometry.indexBuffer.data.BYTES_PER_ELEMENT; + const glType = byteSize === 2 ? gl.UNSIGNED_SHORT : gl.UNSIGNED_INT; + + if (byteSize === 2 || (byteSize === 4 && this.canUseUInt32ElementIndex)) { - /* eslint-disable max-len */ - gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2, instanceCount || 1); - /* eslint-enable max-len */ + if (geometry.instanced) + { + /* eslint-disable max-len */ + gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize, instanceCount || 1); + /* eslint-enable max-len */ + } + else + { + /* eslint-disable max-len */ + gl.drawElements(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize); + /* eslint-enable max-len */ + } } else { - gl.drawElements(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2); + console.warn('unsupported index buffer type: uint32'); } } else if (geometry.instanced) diff --git a/packages/core/src/renderTexture/RenderTexture.js b/packages/core/src/renderTexture/RenderTexture.js index f9c4f18..ecf5080 100644 --- a/packages/core/src/renderTexture/RenderTexture.js +++ b/packages/core/src/renderTexture/RenderTexture.js @@ -7,6 +7,9 @@ * __Hint__: All DisplayObjects (i.e. Sprites) that render to a RenderTexture should be preloaded * otherwise black rectangles will be drawn instead. * + * __Hint-2__: The actual memory allocation will happen on first render. + * You shouldn't create renderTextures each frame just to delete them after, try to reuse them. + * * A RenderTexture takes a snapshot of any Display Object given to its render method. For example: * * ```js diff --git a/packages/core/src/renderTexture/RenderTextureSystem.js b/packages/core/src/renderTexture/RenderTextureSystem.js index 7e29532..57c2fcc 100644 --- a/packages/core/src/renderTexture/RenderTextureSystem.js +++ b/packages/core/src/renderTexture/RenderTextureSystem.js @@ -61,9 +61,9 @@ /** * Bind the current render texture - * @param {PIXI.RenderTexture} renderTexture - * @param {PIXI.Rectangle} sourceFrame - * @param {PIXI.Rectangle} destinationFrame + * @param {PIXI.RenderTexture} [renderTexture] - RenderTexture to bind, by default its `null`, the screen + * @param {PIXI.Rectangle} [sourceFrame] - part of screen that is mapped to the renderTexture + * @param {PIXI.Rectangle} [destinationFrame] - part of renderTexture, by default it has the same size as sourceFrame */ bind(renderTexture = null, sourceFrame, destinationFrame) { diff --git a/packages/core/src/state/State.js b/packages/core/src/state/State.js index c87e268..9ef36dc 100644 --- a/packages/core/src/state/State.js +++ b/packages/core/src/state/State.js @@ -127,7 +127,7 @@ * The blend mode to be applied when this state is set. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode. * Setting this mode to anything other than NO_BLEND will automatically switch blending on. * - * @member {boolean} + * @member {number} * @default PIXI.BLEND_MODES.NORMAL * @see PIXI.BLEND_MODES */ diff --git a/packages/core/src/state/StateSystem.js b/packages/core/src/state/StateSystem.js index c7e35d2..f3be34e 100755 --- a/packages/core/src/state/StateSystem.js +++ b/packages/core/src/state/StateSystem.js @@ -182,6 +182,8 @@ */ setOffset(value) { + this.updateCheck(StateSystem.checkPolygonOffset, value); + this.gl[value ? 'enable' : 'disable'](this.gl.POLYGON_OFFSET_FILL); } @@ -314,5 +316,16 @@ system.setBlendMode(state.blendMode); } - // TODO - add polygon offset? + /** + * A private little wrapper function that we call to check the polygon offset. + * + * @static + * @private + * @param {PIXI.StateSystem} System the System to perform the state check on + * @param {PIXI.State} state the state that the blendMode will pulled from + */ + static checkPolygonOffset(system, state) + { + system.setPolygonOffset(state.polygonOffset, 0); + } } diff --git a/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js b/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js index fdebdc9..e53a723 100644 --- a/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js +++ b/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js @@ -15,7 +15,7 @@ // TODO - premultiply alpha would be different. // add a boolean for that! array[BLEND_MODES.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - array[BLEND_MODES.ADD] = [gl.ONE, gl.DST_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + array[BLEND_MODES.ADD] = [gl.ONE, gl.ONE]; array[BLEND_MODES.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; array[BLEND_MODES.SCREEN] = [gl.ONE, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; array[BLEND_MODES.OVERLAY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; @@ -35,7 +35,7 @@ // not-premultiplied blend modes array[BLEND_MODES.NORMAL_NPM] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - array[BLEND_MODES.ADD_NPM] = [gl.SRC_ALPHA, gl.DST_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + array[BLEND_MODES.ADD_NPM] = [gl.SRC_ALPHA, gl.ONE, gl.ONE, gl.ONE]; array[BLEND_MODES.SCREEN_NPM] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; // composite operations diff --git a/packages/core/src/textures/resources/SVGResource.js b/packages/core/src/textures/resources/SVGResource.js index 04eb33d..a87a355 100644 --- a/packages/core/src/textures/resources/SVGResource.js +++ b/packages/core/src/textures/resources/SVGResource.js @@ -1,4 +1,4 @@ -import { decomposeDataUri, uid } from '@pixi/utils'; +import { uid } from '@pixi/utils'; import BaseImageResource from './BaseImageResource'; /** @@ -41,6 +41,13 @@ this._resolve = null; /** + * Cross origin value to use + * @private + * @member {boolean|string} + */ + this._crossorigin = options.crossorigin; + + /** * Promise when loading * @member {Promise} * @private @@ -73,112 +80,35 @@ // Convert SVG inline string to data-uri if ((/^\ - { - if (svgXhr.readyState !== svgXhr.DONE || svgXhr.status !== 200) - { - throw new Error('Failed to load SVG using XHR.'); - } - - this._loadString(svgXhr.response); - }; - - // svgXhr.onerror = () => this.emit('error', this); - - svgXhr.open('GET', this.svg, true); - svgXhr.send(); - } - - /** - * Loads texture using an SVG string. The original SVG Image is stored as `origSource` and the - * created canvas is the new `source`. The SVG is scaled using `sourceScale`. Called by - * `_loadXhr` or `_loadDataUri`. - * - * @private - * @param {string} svgString SVG source as string - * - * @fires loaded - */ - _loadString(svgString) - { - const svgSize = SVGResource.getSize(svgString); - const tempImage = new Image(); - tempImage.src = `data:image/svg+xml,${svgString}`; - - tempImage.onerror = () => - { - throw new Error(`Unable to load image from: ${tempImage.src}`); - }; + BaseImageResource.crossOrigin(tempImage, this.svg, this._crossorigin); + tempImage.src = this.svg; tempImage.onload = () => { - const svgWidth = svgSize.width; - const svgHeight = svgSize.height; + const svgWidth = tempImage.width; + const svgHeight = tempImage.height; if (!svgWidth || !svgHeight) { @@ -244,6 +174,7 @@ { super.dispose(); this._resolve = null; + this._crossorigin = null; } /** @@ -258,7 +189,9 @@ // url file extension is SVG return extension === 'svg' // source is SVG data-uri - || (typeof source === 'string' && source.indexOf('data:image/svg+xml') === 0); + || (typeof source === 'string' && source.indexOf('data:image/svg+xml;base64') === 0) + // source is SVG inline + || (typeof source === 'string' && source.indexOf(' maxSize) - { - batchSize = maxSize; - } - /** * Set properties to be dynamic (true) / static (false) * diff --git a/packages/particles/src/ParticleRenderer.js b/packages/particles/src/ParticleRenderer.js index 253b0ed..d5e4c03 100644 --- a/packages/particles/src/ParticleRenderer.js +++ b/packages/particles/src/ParticleRenderer.js @@ -109,7 +109,7 @@ { return; } - else if (totalChildren > maxSize) + else if (totalChildren > maxSize && !container.autoResize) { totalChildren = maxSize; } @@ -155,10 +155,6 @@ if (j >= buffers.length) { - if (!container.autoResize) - { - break; - } buffers.push(this._generateOneMoreBuffer(container)); } diff --git a/packages/sprite-animated/src/AnimatedSprite.js b/packages/sprite-animated/src/AnimatedSprite.js index 5adaba2..5b63574 100644 --- a/packages/sprite-animated/src/AnimatedSprite.js +++ b/packages/sprite-animated/src/AnimatedSprite.js @@ -296,7 +296,7 @@ this._texture = this._textures[this.currentFrame]; this._textureID = -1; this._textureTrimmedID = -1; - this.cachedTint = 0xFFFFFF; + this._cachedTint = 0xFFFFFF; this.uvs = this._texture._uvs.uvsFloat32; if (this.updateAnchor) diff --git a/package-lock.json b/package-lock.json index eb731c3..a16c04b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2868,7 +2868,7 @@ }, "yargs": { "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { @@ -9992,14 +9992,28 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" + }, + "dependencies": { + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + } } }, "temp-dir": { diff --git a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js index fde693f..b7b7a7e 100644 --- a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js +++ b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js @@ -82,6 +82,8 @@ const holes = data.holes; let outerArea; let innerArea; + let px; + let py; context.moveTo(points[0], points[1]); @@ -98,19 +100,30 @@ if (holes.length > 0) { outerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + outerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } for (let k = 0; k < holes.length; k++) { - points = holes[k].points; + points = holes[k].shape.points; + + if (!points) + { + continue; + } innerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + innerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } if (innerArea * outerArea < 0) diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js index 8f4e0e4..4eac1d7 100644 --- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js +++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js @@ -29,7 +29,7 @@ const modY = ((this.tilePosition.y / this.tileScale.y) % texture._frame.height) * baseTextureResolution; // create a nice shiny pattern! - if (this._textureID !== this._texture._updateID || this.cachedTint !== this.tint) + if (this._textureID !== this._texture._updateID || this._cachedTint !== this.tint) { this._textureID = this._texture._updateID; // cut an object from a spritesheet.. @@ -48,7 +48,7 @@ tempCanvas.context.drawImage(source, -texture._frame.x * baseTextureResolution, -texture._frame.y * baseTextureResolution); } - this.cachedTint = this.tint; + this._cachedTint = this.tint; this._canvasPattern = tempCanvas.context.createPattern(tempCanvas.canvas, 'repeat'); } diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js index 297cb75..225beb0 100644 --- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js +++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js @@ -159,7 +159,7 @@ } context.drawImage( - source, + sprite._tintedCanvas, 0, 0, width * resolution, diff --git a/packages/canvas/canvas-sprite/src/Sprite.js b/packages/canvas/canvas-sprite/src/Sprite.js index 4bef51d..d94950f 100644 --- a/packages/canvas/canvas-sprite/src/Sprite.js +++ b/packages/canvas/canvas-sprite/src/Sprite.js @@ -9,14 +9,6 @@ Sprite.prototype._tintedCanvas = null; /** - * Cached tint value so we can tell when the tint is changed. - * @memberof PIXI.Sprite# - * @member {number} _cachedTint - * @protected - */ -Sprite.prototype._cachedTint = 0xFFFFFF; - -/** * Renders the object using the Canvas renderer * * @private diff --git a/packages/core/src/context/ContextSystem.js b/packages/core/src/context/ContextSystem.js index dc6243d..6487683 100644 --- a/packages/core/src/context/ContextSystem.js +++ b/packages/core/src/context/ContextSystem.js @@ -163,6 +163,7 @@ vertexArrayObject: gl.getExtension('OES_vertex_array_object') || gl.getExtension('MOZ_OES_vertex_array_object') || gl.getExtension('WEBKIT_OES_vertex_array_object'), + uint32ElementIndex: gl.getExtension('OES_element_index_uint'), }); } diff --git a/packages/core/src/filters/FilterSystem.js b/packages/core/src/filters/FilterSystem.js index a2ae32f..e4edd02 100644 --- a/packages/core/src/filters/FilterSystem.js +++ b/packages/core/src/filters/FilterSystem.js @@ -451,12 +451,9 @@ if (!renderTexture) { - // temporary bypass cache.. - // internally - this will cause a texture to be bound.. renderTexture = RenderTexture.create({ - width: minWidth / resolution, - height: minHeight / resolution, - resolution, + width: minWidth, + height: minHeight, }); } diff --git a/packages/core/src/geometry/GeometrySystem.js b/packages/core/src/geometry/GeometrySystem.js index 3b83a89..3c56989 100644 --- a/packages/core/src/geometry/GeometrySystem.js +++ b/packages/core/src/geometry/GeometrySystem.js @@ -39,6 +39,13 @@ this.hasInstance = true; /** + * `true` if support `gl.UNSIGNED_INT` in `gl.drawElements` or `gl.drawElementsInstanced` + * @member {boolean} + * @readonly + */ + this.canUseUInt32ElementIndex = false; + + /** * A cache of currently bound buffer, * contains only two members with keys ARRAY_BUFFER and ELEMENT_ARRAY_BUFFER * @member {Object.} @@ -69,6 +76,7 @@ this.disposeAll(true); const gl = this.gl = this.renderer.gl; + const context = this.renderer.context; this.CONTEXT_UID = this.renderer.CONTEXT_UID; @@ -134,6 +142,8 @@ this.hasInstance = false; } } + + this.canUseUInt32ElementIndex = context.webGLVersion === 2 || !!context.extensions.uint32ElementIndex; } /** @@ -593,15 +603,27 @@ if (geometry.indexBuffer) { - if (geometry.instanced) + const byteSize = geometry.indexBuffer.data.BYTES_PER_ELEMENT; + const glType = byteSize === 2 ? gl.UNSIGNED_SHORT : gl.UNSIGNED_INT; + + if (byteSize === 2 || (byteSize === 4 && this.canUseUInt32ElementIndex)) { - /* eslint-disable max-len */ - gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2, instanceCount || 1); - /* eslint-enable max-len */ + if (geometry.instanced) + { + /* eslint-disable max-len */ + gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize, instanceCount || 1); + /* eslint-enable max-len */ + } + else + { + /* eslint-disable max-len */ + gl.drawElements(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize); + /* eslint-enable max-len */ + } } else { - gl.drawElements(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2); + console.warn('unsupported index buffer type: uint32'); } } else if (geometry.instanced) diff --git a/packages/core/src/renderTexture/RenderTexture.js b/packages/core/src/renderTexture/RenderTexture.js index f9c4f18..ecf5080 100644 --- a/packages/core/src/renderTexture/RenderTexture.js +++ b/packages/core/src/renderTexture/RenderTexture.js @@ -7,6 +7,9 @@ * __Hint__: All DisplayObjects (i.e. Sprites) that render to a RenderTexture should be preloaded * otherwise black rectangles will be drawn instead. * + * __Hint-2__: The actual memory allocation will happen on first render. + * You shouldn't create renderTextures each frame just to delete them after, try to reuse them. + * * A RenderTexture takes a snapshot of any Display Object given to its render method. For example: * * ```js diff --git a/packages/core/src/renderTexture/RenderTextureSystem.js b/packages/core/src/renderTexture/RenderTextureSystem.js index 7e29532..57c2fcc 100644 --- a/packages/core/src/renderTexture/RenderTextureSystem.js +++ b/packages/core/src/renderTexture/RenderTextureSystem.js @@ -61,9 +61,9 @@ /** * Bind the current render texture - * @param {PIXI.RenderTexture} renderTexture - * @param {PIXI.Rectangle} sourceFrame - * @param {PIXI.Rectangle} destinationFrame + * @param {PIXI.RenderTexture} [renderTexture] - RenderTexture to bind, by default its `null`, the screen + * @param {PIXI.Rectangle} [sourceFrame] - part of screen that is mapped to the renderTexture + * @param {PIXI.Rectangle} [destinationFrame] - part of renderTexture, by default it has the same size as sourceFrame */ bind(renderTexture = null, sourceFrame, destinationFrame) { diff --git a/packages/core/src/state/State.js b/packages/core/src/state/State.js index c87e268..9ef36dc 100644 --- a/packages/core/src/state/State.js +++ b/packages/core/src/state/State.js @@ -127,7 +127,7 @@ * The blend mode to be applied when this state is set. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode. * Setting this mode to anything other than NO_BLEND will automatically switch blending on. * - * @member {boolean} + * @member {number} * @default PIXI.BLEND_MODES.NORMAL * @see PIXI.BLEND_MODES */ diff --git a/packages/core/src/state/StateSystem.js b/packages/core/src/state/StateSystem.js index c7e35d2..f3be34e 100755 --- a/packages/core/src/state/StateSystem.js +++ b/packages/core/src/state/StateSystem.js @@ -182,6 +182,8 @@ */ setOffset(value) { + this.updateCheck(StateSystem.checkPolygonOffset, value); + this.gl[value ? 'enable' : 'disable'](this.gl.POLYGON_OFFSET_FILL); } @@ -314,5 +316,16 @@ system.setBlendMode(state.blendMode); } - // TODO - add polygon offset? + /** + * A private little wrapper function that we call to check the polygon offset. + * + * @static + * @private + * @param {PIXI.StateSystem} System the System to perform the state check on + * @param {PIXI.State} state the state that the blendMode will pulled from + */ + static checkPolygonOffset(system, state) + { + system.setPolygonOffset(state.polygonOffset, 0); + } } diff --git a/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js b/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js index fdebdc9..e53a723 100644 --- a/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js +++ b/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js @@ -15,7 +15,7 @@ // TODO - premultiply alpha would be different. // add a boolean for that! array[BLEND_MODES.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - array[BLEND_MODES.ADD] = [gl.ONE, gl.DST_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + array[BLEND_MODES.ADD] = [gl.ONE, gl.ONE]; array[BLEND_MODES.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; array[BLEND_MODES.SCREEN] = [gl.ONE, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; array[BLEND_MODES.OVERLAY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; @@ -35,7 +35,7 @@ // not-premultiplied blend modes array[BLEND_MODES.NORMAL_NPM] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - array[BLEND_MODES.ADD_NPM] = [gl.SRC_ALPHA, gl.DST_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + array[BLEND_MODES.ADD_NPM] = [gl.SRC_ALPHA, gl.ONE, gl.ONE, gl.ONE]; array[BLEND_MODES.SCREEN_NPM] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; // composite operations diff --git a/packages/core/src/textures/resources/SVGResource.js b/packages/core/src/textures/resources/SVGResource.js index 04eb33d..a87a355 100644 --- a/packages/core/src/textures/resources/SVGResource.js +++ b/packages/core/src/textures/resources/SVGResource.js @@ -1,4 +1,4 @@ -import { decomposeDataUri, uid } from '@pixi/utils'; +import { uid } from '@pixi/utils'; import BaseImageResource from './BaseImageResource'; /** @@ -41,6 +41,13 @@ this._resolve = null; /** + * Cross origin value to use + * @private + * @member {boolean|string} + */ + this._crossorigin = options.crossorigin; + + /** * Promise when loading * @member {Promise} * @private @@ -73,112 +80,35 @@ // Convert SVG inline string to data-uri if ((/^\ - { - if (svgXhr.readyState !== svgXhr.DONE || svgXhr.status !== 200) - { - throw new Error('Failed to load SVG using XHR.'); - } - - this._loadString(svgXhr.response); - }; - - // svgXhr.onerror = () => this.emit('error', this); - - svgXhr.open('GET', this.svg, true); - svgXhr.send(); - } - - /** - * Loads texture using an SVG string. The original SVG Image is stored as `origSource` and the - * created canvas is the new `source`. The SVG is scaled using `sourceScale`. Called by - * `_loadXhr` or `_loadDataUri`. - * - * @private - * @param {string} svgString SVG source as string - * - * @fires loaded - */ - _loadString(svgString) - { - const svgSize = SVGResource.getSize(svgString); - const tempImage = new Image(); - tempImage.src = `data:image/svg+xml,${svgString}`; - - tempImage.onerror = () => - { - throw new Error(`Unable to load image from: ${tempImage.src}`); - }; + BaseImageResource.crossOrigin(tempImage, this.svg, this._crossorigin); + tempImage.src = this.svg; tempImage.onload = () => { - const svgWidth = svgSize.width; - const svgHeight = svgSize.height; + const svgWidth = tempImage.width; + const svgHeight = tempImage.height; if (!svgWidth || !svgHeight) { @@ -244,6 +174,7 @@ { super.dispose(); this._resolve = null; + this._crossorigin = null; } /** @@ -258,7 +189,9 @@ // url file extension is SVG return extension === 'svg' // source is SVG data-uri - || (typeof source === 'string' && source.indexOf('data:image/svg+xml') === 0); + || (typeof source === 'string' && source.indexOf('data:image/svg+xml;base64') === 0) + // source is SVG inline + || (typeof source === 'string' && source.indexOf(' maxSize) - { - batchSize = maxSize; - } - /** * Set properties to be dynamic (true) / static (false) * diff --git a/packages/particles/src/ParticleRenderer.js b/packages/particles/src/ParticleRenderer.js index 253b0ed..d5e4c03 100644 --- a/packages/particles/src/ParticleRenderer.js +++ b/packages/particles/src/ParticleRenderer.js @@ -109,7 +109,7 @@ { return; } - else if (totalChildren > maxSize) + else if (totalChildren > maxSize && !container.autoResize) { totalChildren = maxSize; } @@ -155,10 +155,6 @@ if (j >= buffers.length) { - if (!container.autoResize) - { - break; - } buffers.push(this._generateOneMoreBuffer(container)); } diff --git a/packages/sprite-animated/src/AnimatedSprite.js b/packages/sprite-animated/src/AnimatedSprite.js index 5adaba2..5b63574 100644 --- a/packages/sprite-animated/src/AnimatedSprite.js +++ b/packages/sprite-animated/src/AnimatedSprite.js @@ -296,7 +296,7 @@ this._texture = this._textures[this.currentFrame]; this._textureID = -1; this._textureTrimmedID = -1; - this.cachedTint = 0xFFFFFF; + this._cachedTint = 0xFFFFFF; this.uvs = this._texture._uvs.uvsFloat32; if (this.updateAnchor) diff --git a/packages/sprite-tiling/src/TilingSprite.js b/packages/sprite-tiling/src/TilingSprite.js index 8bde45e..9f381ab 100644 --- a/packages/sprite-tiling/src/TilingSprite.js +++ b/packages/sprite-tiling/src/TilingSprite.js @@ -137,7 +137,7 @@ { this.uvMatrix.texture = this._texture; } - this.cachedTint = 0xFFFFFF; + this._cachedTint = 0xFFFFFF; } /** diff --git a/package-lock.json b/package-lock.json index eb731c3..a16c04b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2868,7 +2868,7 @@ }, "yargs": { "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { @@ -9992,14 +9992,28 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" + }, + "dependencies": { + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + } } }, "temp-dir": { diff --git a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js index fde693f..b7b7a7e 100644 --- a/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js +++ b/packages/canvas/canvas-graphics/src/CanvasGraphicsRenderer.js @@ -82,6 +82,8 @@ const holes = data.holes; let outerArea; let innerArea; + let px; + let py; context.moveTo(points[0], points[1]); @@ -98,19 +100,30 @@ if (holes.length > 0) { outerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + outerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } for (let k = 0; k < holes.length; k++) { - points = holes[k].points; + points = holes[k].shape.points; + + if (!points) + { + continue; + } innerArea = 0; - for (let j = 0; j < points.length; j += 2) + px = points[0]; + py = points[1]; + for (let j = 2; j + 2 < points.length; j += 2) { - innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + innerArea += ((points[j] - px) * (points[j + 3] - py)) + - ((points[j + 2] - px) * (points[j + 1] - py)); } if (innerArea * outerArea < 0) diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js index 8f4e0e4..4eac1d7 100644 --- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js +++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js @@ -29,7 +29,7 @@ const modY = ((this.tilePosition.y / this.tileScale.y) % texture._frame.height) * baseTextureResolution; // create a nice shiny pattern! - if (this._textureID !== this._texture._updateID || this.cachedTint !== this.tint) + if (this._textureID !== this._texture._updateID || this._cachedTint !== this.tint) { this._textureID = this._texture._updateID; // cut an object from a spritesheet.. @@ -48,7 +48,7 @@ tempCanvas.context.drawImage(source, -texture._frame.x * baseTextureResolution, -texture._frame.y * baseTextureResolution); } - this.cachedTint = this.tint; + this._cachedTint = this.tint; this._canvasPattern = tempCanvas.context.createPattern(tempCanvas.canvas, 'repeat'); } diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js index 297cb75..225beb0 100644 --- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js +++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js @@ -159,7 +159,7 @@ } context.drawImage( - source, + sprite._tintedCanvas, 0, 0, width * resolution, diff --git a/packages/canvas/canvas-sprite/src/Sprite.js b/packages/canvas/canvas-sprite/src/Sprite.js index 4bef51d..d94950f 100644 --- a/packages/canvas/canvas-sprite/src/Sprite.js +++ b/packages/canvas/canvas-sprite/src/Sprite.js @@ -9,14 +9,6 @@ Sprite.prototype._tintedCanvas = null; /** - * Cached tint value so we can tell when the tint is changed. - * @memberof PIXI.Sprite# - * @member {number} _cachedTint - * @protected - */ -Sprite.prototype._cachedTint = 0xFFFFFF; - -/** * Renders the object using the Canvas renderer * * @private diff --git a/packages/core/src/context/ContextSystem.js b/packages/core/src/context/ContextSystem.js index dc6243d..6487683 100644 --- a/packages/core/src/context/ContextSystem.js +++ b/packages/core/src/context/ContextSystem.js @@ -163,6 +163,7 @@ vertexArrayObject: gl.getExtension('OES_vertex_array_object') || gl.getExtension('MOZ_OES_vertex_array_object') || gl.getExtension('WEBKIT_OES_vertex_array_object'), + uint32ElementIndex: gl.getExtension('OES_element_index_uint'), }); } diff --git a/packages/core/src/filters/FilterSystem.js b/packages/core/src/filters/FilterSystem.js index a2ae32f..e4edd02 100644 --- a/packages/core/src/filters/FilterSystem.js +++ b/packages/core/src/filters/FilterSystem.js @@ -451,12 +451,9 @@ if (!renderTexture) { - // temporary bypass cache.. - // internally - this will cause a texture to be bound.. renderTexture = RenderTexture.create({ - width: minWidth / resolution, - height: minHeight / resolution, - resolution, + width: minWidth, + height: minHeight, }); } diff --git a/packages/core/src/geometry/GeometrySystem.js b/packages/core/src/geometry/GeometrySystem.js index 3b83a89..3c56989 100644 --- a/packages/core/src/geometry/GeometrySystem.js +++ b/packages/core/src/geometry/GeometrySystem.js @@ -39,6 +39,13 @@ this.hasInstance = true; /** + * `true` if support `gl.UNSIGNED_INT` in `gl.drawElements` or `gl.drawElementsInstanced` + * @member {boolean} + * @readonly + */ + this.canUseUInt32ElementIndex = false; + + /** * A cache of currently bound buffer, * contains only two members with keys ARRAY_BUFFER and ELEMENT_ARRAY_BUFFER * @member {Object.} @@ -69,6 +76,7 @@ this.disposeAll(true); const gl = this.gl = this.renderer.gl; + const context = this.renderer.context; this.CONTEXT_UID = this.renderer.CONTEXT_UID; @@ -134,6 +142,8 @@ this.hasInstance = false; } } + + this.canUseUInt32ElementIndex = context.webGLVersion === 2 || !!context.extensions.uint32ElementIndex; } /** @@ -593,15 +603,27 @@ if (geometry.indexBuffer) { - if (geometry.instanced) + const byteSize = geometry.indexBuffer.data.BYTES_PER_ELEMENT; + const glType = byteSize === 2 ? gl.UNSIGNED_SHORT : gl.UNSIGNED_INT; + + if (byteSize === 2 || (byteSize === 4 && this.canUseUInt32ElementIndex)) { - /* eslint-disable max-len */ - gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2, instanceCount || 1); - /* eslint-enable max-len */ + if (geometry.instanced) + { + /* eslint-disable max-len */ + gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize, instanceCount || 1); + /* eslint-enable max-len */ + } + else + { + /* eslint-disable max-len */ + gl.drawElements(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize); + /* eslint-enable max-len */ + } } else { - gl.drawElements(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2); + console.warn('unsupported index buffer type: uint32'); } } else if (geometry.instanced) diff --git a/packages/core/src/renderTexture/RenderTexture.js b/packages/core/src/renderTexture/RenderTexture.js index f9c4f18..ecf5080 100644 --- a/packages/core/src/renderTexture/RenderTexture.js +++ b/packages/core/src/renderTexture/RenderTexture.js @@ -7,6 +7,9 @@ * __Hint__: All DisplayObjects (i.e. Sprites) that render to a RenderTexture should be preloaded * otherwise black rectangles will be drawn instead. * + * __Hint-2__: The actual memory allocation will happen on first render. + * You shouldn't create renderTextures each frame just to delete them after, try to reuse them. + * * A RenderTexture takes a snapshot of any Display Object given to its render method. For example: * * ```js diff --git a/packages/core/src/renderTexture/RenderTextureSystem.js b/packages/core/src/renderTexture/RenderTextureSystem.js index 7e29532..57c2fcc 100644 --- a/packages/core/src/renderTexture/RenderTextureSystem.js +++ b/packages/core/src/renderTexture/RenderTextureSystem.js @@ -61,9 +61,9 @@ /** * Bind the current render texture - * @param {PIXI.RenderTexture} renderTexture - * @param {PIXI.Rectangle} sourceFrame - * @param {PIXI.Rectangle} destinationFrame + * @param {PIXI.RenderTexture} [renderTexture] - RenderTexture to bind, by default its `null`, the screen + * @param {PIXI.Rectangle} [sourceFrame] - part of screen that is mapped to the renderTexture + * @param {PIXI.Rectangle} [destinationFrame] - part of renderTexture, by default it has the same size as sourceFrame */ bind(renderTexture = null, sourceFrame, destinationFrame) { diff --git a/packages/core/src/state/State.js b/packages/core/src/state/State.js index c87e268..9ef36dc 100644 --- a/packages/core/src/state/State.js +++ b/packages/core/src/state/State.js @@ -127,7 +127,7 @@ * The blend mode to be applied when this state is set. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode. * Setting this mode to anything other than NO_BLEND will automatically switch blending on. * - * @member {boolean} + * @member {number} * @default PIXI.BLEND_MODES.NORMAL * @see PIXI.BLEND_MODES */ diff --git a/packages/core/src/state/StateSystem.js b/packages/core/src/state/StateSystem.js index c7e35d2..f3be34e 100755 --- a/packages/core/src/state/StateSystem.js +++ b/packages/core/src/state/StateSystem.js @@ -182,6 +182,8 @@ */ setOffset(value) { + this.updateCheck(StateSystem.checkPolygonOffset, value); + this.gl[value ? 'enable' : 'disable'](this.gl.POLYGON_OFFSET_FILL); } @@ -314,5 +316,16 @@ system.setBlendMode(state.blendMode); } - // TODO - add polygon offset? + /** + * A private little wrapper function that we call to check the polygon offset. + * + * @static + * @private + * @param {PIXI.StateSystem} System the System to perform the state check on + * @param {PIXI.State} state the state that the blendMode will pulled from + */ + static checkPolygonOffset(system, state) + { + system.setPolygonOffset(state.polygonOffset, 0); + } } diff --git a/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js b/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js index fdebdc9..e53a723 100644 --- a/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js +++ b/packages/core/src/state/utils/mapWebGLBlendModesToPixi.js @@ -15,7 +15,7 @@ // TODO - premultiply alpha would be different. // add a boolean for that! array[BLEND_MODES.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - array[BLEND_MODES.ADD] = [gl.ONE, gl.DST_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + array[BLEND_MODES.ADD] = [gl.ONE, gl.ONE]; array[BLEND_MODES.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; array[BLEND_MODES.SCREEN] = [gl.ONE, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; array[BLEND_MODES.OVERLAY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; @@ -35,7 +35,7 @@ // not-premultiplied blend modes array[BLEND_MODES.NORMAL_NPM] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - array[BLEND_MODES.ADD_NPM] = [gl.SRC_ALPHA, gl.DST_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + array[BLEND_MODES.ADD_NPM] = [gl.SRC_ALPHA, gl.ONE, gl.ONE, gl.ONE]; array[BLEND_MODES.SCREEN_NPM] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; // composite operations diff --git a/packages/core/src/textures/resources/SVGResource.js b/packages/core/src/textures/resources/SVGResource.js index 04eb33d..a87a355 100644 --- a/packages/core/src/textures/resources/SVGResource.js +++ b/packages/core/src/textures/resources/SVGResource.js @@ -1,4 +1,4 @@ -import { decomposeDataUri, uid } from '@pixi/utils'; +import { uid } from '@pixi/utils'; import BaseImageResource from './BaseImageResource'; /** @@ -41,6 +41,13 @@ this._resolve = null; /** + * Cross origin value to use + * @private + * @member {boolean|string} + */ + this._crossorigin = options.crossorigin; + + /** * Promise when loading * @member {Promise} * @private @@ -73,112 +80,35 @@ // Convert SVG inline string to data-uri if ((/^\ - { - if (svgXhr.readyState !== svgXhr.DONE || svgXhr.status !== 200) - { - throw new Error('Failed to load SVG using XHR.'); - } - - this._loadString(svgXhr.response); - }; - - // svgXhr.onerror = () => this.emit('error', this); - - svgXhr.open('GET', this.svg, true); - svgXhr.send(); - } - - /** - * Loads texture using an SVG string. The original SVG Image is stored as `origSource` and the - * created canvas is the new `source`. The SVG is scaled using `sourceScale`. Called by - * `_loadXhr` or `_loadDataUri`. - * - * @private - * @param {string} svgString SVG source as string - * - * @fires loaded - */ - _loadString(svgString) - { - const svgSize = SVGResource.getSize(svgString); - const tempImage = new Image(); - tempImage.src = `data:image/svg+xml,${svgString}`; - - tempImage.onerror = () => - { - throw new Error(`Unable to load image from: ${tempImage.src}`); - }; + BaseImageResource.crossOrigin(tempImage, this.svg, this._crossorigin); + tempImage.src = this.svg; tempImage.onload = () => { - const svgWidth = svgSize.width; - const svgHeight = svgSize.height; + const svgWidth = tempImage.width; + const svgHeight = tempImage.height; if (!svgWidth || !svgHeight) { @@ -244,6 +174,7 @@ { super.dispose(); this._resolve = null; + this._crossorigin = null; } /** @@ -258,7 +189,9 @@ // url file extension is SVG return extension === 'svg' // source is SVG data-uri - || (typeof source === 'string' && source.indexOf('data:image/svg+xml') === 0); + || (typeof source === 'string' && source.indexOf('data:image/svg+xml;base64') === 0) + // source is SVG inline + || (typeof source === 'string' && source.indexOf(' maxSize) - { - batchSize = maxSize; - } - /** * Set properties to be dynamic (true) / static (false) * diff --git a/packages/particles/src/ParticleRenderer.js b/packages/particles/src/ParticleRenderer.js index 253b0ed..d5e4c03 100644 --- a/packages/particles/src/ParticleRenderer.js +++ b/packages/particles/src/ParticleRenderer.js @@ -109,7 +109,7 @@ { return; } - else if (totalChildren > maxSize) + else if (totalChildren > maxSize && !container.autoResize) { totalChildren = maxSize; } @@ -155,10 +155,6 @@ if (j >= buffers.length) { - if (!container.autoResize) - { - break; - } buffers.push(this._generateOneMoreBuffer(container)); } diff --git a/packages/sprite-animated/src/AnimatedSprite.js b/packages/sprite-animated/src/AnimatedSprite.js index 5adaba2..5b63574 100644 --- a/packages/sprite-animated/src/AnimatedSprite.js +++ b/packages/sprite-animated/src/AnimatedSprite.js @@ -296,7 +296,7 @@ this._texture = this._textures[this.currentFrame]; this._textureID = -1; this._textureTrimmedID = -1; - this.cachedTint = 0xFFFFFF; + this._cachedTint = 0xFFFFFF; this.uvs = this._texture._uvs.uvsFloat32; if (this.updateAnchor) diff --git a/packages/sprite-tiling/src/TilingSprite.js b/packages/sprite-tiling/src/TilingSprite.js index 8bde45e..9f381ab 100644 --- a/packages/sprite-tiling/src/TilingSprite.js +++ b/packages/sprite-tiling/src/TilingSprite.js @@ -137,7 +137,7 @@ { this.uvMatrix.texture = this._texture; } - this.cachedTint = 0xFFFFFF; + this._cachedTint = 0xFFFFFF; } /** diff --git a/packages/sprite/src/Sprite.js b/packages/sprite/src/Sprite.js index e1604a9..b2047de 100644 --- a/packages/sprite/src/Sprite.js +++ b/packages/sprite/src/Sprite.js @@ -114,13 +114,14 @@ this.shader = null; /** - * An internal cached value of the tint. + * Cached tint value so we can tell when the tint is changed. + * Value is used for 2d CanvasRenderer. * - * @private + * @protected * @member {number} * @default 0xFFFFFF */ - this.cachedTint = 0xFFFFFF; + this._cachedTint = 0xFFFFFF; this.uvs = null; @@ -188,7 +189,7 @@ { this._textureID = -1; this._textureTrimmedID = -1; - this.cachedTint = 0xFFFFFF; + this._cachedTint = 0xFFFFFF; this.uvs = this._texture._uvs.uvsFloat32; // so if _width is 0 then width was not set.. @@ -622,7 +623,7 @@ } this._texture = value || Texture.EMPTY; - this.cachedTint = 0xFFFFFF; + this._cachedTint = 0xFFFFFF; this._textureID = -1; this._textureTrimmedID = -1;