diff --git a/bundles/pixi.js-legacy/package.json b/bundles/pixi.js-legacy/package.json index 56d8e1a..a0e6aa8 100644 --- a/bundles/pixi.js-legacy/package.json +++ b/bundles/pixi.js-legacy/package.json @@ -32,6 +32,7 @@ "@pixi/canvas-extract": "^5.0.0-alpha", "@pixi/canvas-graphics": "^5.0.0-alpha", "@pixi/canvas-mesh": "^5.0.0-alpha", + "@pixi/canvas-particles": "^5.0.0-alpha", "@pixi/canvas-prepare": "^5.0.0-alpha", "@pixi/canvas-renderer": "^5.0.0-alpha", "@pixi/canvas-sprite": "^5.0.0-alpha", diff --git a/bundles/pixi.js-legacy/package.json b/bundles/pixi.js-legacy/package.json index 56d8e1a..a0e6aa8 100644 --- a/bundles/pixi.js-legacy/package.json +++ b/bundles/pixi.js-legacy/package.json @@ -32,6 +32,7 @@ "@pixi/canvas-extract": "^5.0.0-alpha", "@pixi/canvas-graphics": "^5.0.0-alpha", "@pixi/canvas-mesh": "^5.0.0-alpha", + "@pixi/canvas-particles": "^5.0.0-alpha", "@pixi/canvas-prepare": "^5.0.0-alpha", "@pixi/canvas-renderer": "^5.0.0-alpha", "@pixi/canvas-sprite": "^5.0.0-alpha", diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js index b29ba1e..6c9d2b8 100644 --- a/bundles/pixi.js-legacy/src/index.js +++ b/bundles/pixi.js-legacy/src/index.js @@ -8,6 +8,7 @@ import * as canvasExtract from '@pixi/canvas-extract'; import * as canvasPrepare from '@pixi/canvas-prepare'; import '@pixi/canvas-sprite-tiling'; +import '@pixi/canvas-particles'; import '@pixi/canvas-display'; CanvasRenderer.registerPlugin('accessibility', PIXI.accessibility.AccessibilityManager); diff --git a/bundles/pixi.js-legacy/package.json b/bundles/pixi.js-legacy/package.json index 56d8e1a..a0e6aa8 100644 --- a/bundles/pixi.js-legacy/package.json +++ b/bundles/pixi.js-legacy/package.json @@ -32,6 +32,7 @@ "@pixi/canvas-extract": "^5.0.0-alpha", "@pixi/canvas-graphics": "^5.0.0-alpha", "@pixi/canvas-mesh": "^5.0.0-alpha", + "@pixi/canvas-particles": "^5.0.0-alpha", "@pixi/canvas-prepare": "^5.0.0-alpha", "@pixi/canvas-renderer": "^5.0.0-alpha", "@pixi/canvas-sprite": "^5.0.0-alpha", diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js index b29ba1e..6c9d2b8 100644 --- a/bundles/pixi.js-legacy/src/index.js +++ b/bundles/pixi.js-legacy/src/index.js @@ -8,6 +8,7 @@ import * as canvasExtract from '@pixi/canvas-extract'; import * as canvasPrepare from '@pixi/canvas-prepare'; import '@pixi/canvas-sprite-tiling'; +import '@pixi/canvas-particles'; import '@pixi/canvas-display'; CanvasRenderer.registerPlugin('accessibility', PIXI.accessibility.AccessibilityManager); diff --git a/bundles/pixi.js/src/index.js b/bundles/pixi.js/src/index.js index a879872..fb839a0 100644 --- a/bundles/pixi.js/src/index.js +++ b/bundles/pixi.js/src/index.js @@ -9,7 +9,7 @@ import * as loaders from '@pixi/loaders'; import * as math from '@pixi/math'; import * as mesh from '@pixi/mesh'; -// import * as particles from '@pixi/particles'; +import * as particles from '@pixi/particles'; import * as prepare from '@pixi/prepare'; import * as sprite from '@pixi/sprite'; import * as spriteAnimated from '@pixi/sprite-animated'; @@ -38,7 +38,7 @@ core.Renderer.registerPlugin('graphics', graphics.GraphicsRenderer); core.Renderer.registerPlugin('interaction', interaction.InteractionManager); core.Renderer.registerPlugin('mesh', mesh.MeshRenderer); -// core.Renderer.registerPlugin('particle', particles.ParticleRenderer); +core.Renderer.registerPlugin('particle', particles.ParticleRenderer); core.Renderer.registerPlugin('prepare', prepare.Prepare); core.Renderer.registerPlugin('sprite', sprite.SpriteRenderer); core.Renderer.registerPlugin('tilingSprite', spriteTiling.TilingSpriteRenderer); @@ -120,7 +120,7 @@ loaders, math, mesh, - // particles, + particles, sprite, spriteAnimated, spritesheet, diff --git a/bundles/pixi.js-legacy/package.json b/bundles/pixi.js-legacy/package.json index 56d8e1a..a0e6aa8 100644 --- a/bundles/pixi.js-legacy/package.json +++ b/bundles/pixi.js-legacy/package.json @@ -32,6 +32,7 @@ "@pixi/canvas-extract": "^5.0.0-alpha", "@pixi/canvas-graphics": "^5.0.0-alpha", "@pixi/canvas-mesh": "^5.0.0-alpha", + "@pixi/canvas-particles": "^5.0.0-alpha", "@pixi/canvas-prepare": "^5.0.0-alpha", "@pixi/canvas-renderer": "^5.0.0-alpha", "@pixi/canvas-sprite": "^5.0.0-alpha", diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js index b29ba1e..6c9d2b8 100644 --- a/bundles/pixi.js-legacy/src/index.js +++ b/bundles/pixi.js-legacy/src/index.js @@ -8,6 +8,7 @@ import * as canvasExtract from '@pixi/canvas-extract'; import * as canvasPrepare from '@pixi/canvas-prepare'; import '@pixi/canvas-sprite-tiling'; +import '@pixi/canvas-particles'; import '@pixi/canvas-display'; CanvasRenderer.registerPlugin('accessibility', PIXI.accessibility.AccessibilityManager); diff --git a/bundles/pixi.js/src/index.js b/bundles/pixi.js/src/index.js index a879872..fb839a0 100644 --- a/bundles/pixi.js/src/index.js +++ b/bundles/pixi.js/src/index.js @@ -9,7 +9,7 @@ import * as loaders from '@pixi/loaders'; import * as math from '@pixi/math'; import * as mesh from '@pixi/mesh'; -// import * as particles from '@pixi/particles'; +import * as particles from '@pixi/particles'; import * as prepare from '@pixi/prepare'; import * as sprite from '@pixi/sprite'; import * as spriteAnimated from '@pixi/sprite-animated'; @@ -38,7 +38,7 @@ core.Renderer.registerPlugin('graphics', graphics.GraphicsRenderer); core.Renderer.registerPlugin('interaction', interaction.InteractionManager); core.Renderer.registerPlugin('mesh', mesh.MeshRenderer); -// core.Renderer.registerPlugin('particle', particles.ParticleRenderer); +core.Renderer.registerPlugin('particle', particles.ParticleRenderer); core.Renderer.registerPlugin('prepare', prepare.Prepare); core.Renderer.registerPlugin('sprite', sprite.SpriteRenderer); core.Renderer.registerPlugin('tilingSprite', spriteTiling.TilingSpriteRenderer); @@ -120,7 +120,7 @@ loaders, math, mesh, - // particles, + particles, sprite, spriteAnimated, spritesheet, diff --git a/packages/canvas/canvas-particles/LICENSE b/packages/canvas/canvas-particles/LICENSE new file mode 100644 index 0000000..148e3eb --- /dev/null +++ b/packages/canvas/canvas-particles/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2013-2018 Mathew Groves, Chad Engler + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/bundles/pixi.js-legacy/package.json b/bundles/pixi.js-legacy/package.json index 56d8e1a..a0e6aa8 100644 --- a/bundles/pixi.js-legacy/package.json +++ b/bundles/pixi.js-legacy/package.json @@ -32,6 +32,7 @@ "@pixi/canvas-extract": "^5.0.0-alpha", "@pixi/canvas-graphics": "^5.0.0-alpha", "@pixi/canvas-mesh": "^5.0.0-alpha", + "@pixi/canvas-particles": "^5.0.0-alpha", "@pixi/canvas-prepare": "^5.0.0-alpha", "@pixi/canvas-renderer": "^5.0.0-alpha", "@pixi/canvas-sprite": "^5.0.0-alpha", diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js index b29ba1e..6c9d2b8 100644 --- a/bundles/pixi.js-legacy/src/index.js +++ b/bundles/pixi.js-legacy/src/index.js @@ -8,6 +8,7 @@ import * as canvasExtract from '@pixi/canvas-extract'; import * as canvasPrepare from '@pixi/canvas-prepare'; import '@pixi/canvas-sprite-tiling'; +import '@pixi/canvas-particles'; import '@pixi/canvas-display'; CanvasRenderer.registerPlugin('accessibility', PIXI.accessibility.AccessibilityManager); diff --git a/bundles/pixi.js/src/index.js b/bundles/pixi.js/src/index.js index a879872..fb839a0 100644 --- a/bundles/pixi.js/src/index.js +++ b/bundles/pixi.js/src/index.js @@ -9,7 +9,7 @@ import * as loaders from '@pixi/loaders'; import * as math from '@pixi/math'; import * as mesh from '@pixi/mesh'; -// import * as particles from '@pixi/particles'; +import * as particles from '@pixi/particles'; import * as prepare from '@pixi/prepare'; import * as sprite from '@pixi/sprite'; import * as spriteAnimated from '@pixi/sprite-animated'; @@ -38,7 +38,7 @@ core.Renderer.registerPlugin('graphics', graphics.GraphicsRenderer); core.Renderer.registerPlugin('interaction', interaction.InteractionManager); core.Renderer.registerPlugin('mesh', mesh.MeshRenderer); -// core.Renderer.registerPlugin('particle', particles.ParticleRenderer); +core.Renderer.registerPlugin('particle', particles.ParticleRenderer); core.Renderer.registerPlugin('prepare', prepare.Prepare); core.Renderer.registerPlugin('sprite', sprite.SpriteRenderer); core.Renderer.registerPlugin('tilingSprite', spriteTiling.TilingSpriteRenderer); @@ -120,7 +120,7 @@ loaders, math, mesh, - // particles, + particles, sprite, spriteAnimated, spritesheet, diff --git a/packages/canvas/canvas-particles/LICENSE b/packages/canvas/canvas-particles/LICENSE new file mode 100644 index 0000000..148e3eb --- /dev/null +++ b/packages/canvas/canvas-particles/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2013-2018 Mathew Groves, Chad Engler + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/packages/canvas/canvas-particles/README.md b/packages/canvas/canvas-particles/README.md new file mode 100644 index 0000000..5560aea --- /dev/null +++ b/packages/canvas/canvas-particles/README.md @@ -0,0 +1,13 @@ +# @pixi/canvas-sprite-tiling + +## Installation + +```bash +npm install @pixi/canvas-sprite-tiling +``` + +## Usage + +```js +import '@pixi/canvas-sprite-tiling'; +``` \ No newline at end of file diff --git a/bundles/pixi.js-legacy/package.json b/bundles/pixi.js-legacy/package.json index 56d8e1a..a0e6aa8 100644 --- a/bundles/pixi.js-legacy/package.json +++ b/bundles/pixi.js-legacy/package.json @@ -32,6 +32,7 @@ "@pixi/canvas-extract": "^5.0.0-alpha", "@pixi/canvas-graphics": "^5.0.0-alpha", "@pixi/canvas-mesh": "^5.0.0-alpha", + "@pixi/canvas-particles": "^5.0.0-alpha", "@pixi/canvas-prepare": "^5.0.0-alpha", "@pixi/canvas-renderer": "^5.0.0-alpha", "@pixi/canvas-sprite": "^5.0.0-alpha", diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js index b29ba1e..6c9d2b8 100644 --- a/bundles/pixi.js-legacy/src/index.js +++ b/bundles/pixi.js-legacy/src/index.js @@ -8,6 +8,7 @@ import * as canvasExtract from '@pixi/canvas-extract'; import * as canvasPrepare from '@pixi/canvas-prepare'; import '@pixi/canvas-sprite-tiling'; +import '@pixi/canvas-particles'; import '@pixi/canvas-display'; CanvasRenderer.registerPlugin('accessibility', PIXI.accessibility.AccessibilityManager); diff --git a/bundles/pixi.js/src/index.js b/bundles/pixi.js/src/index.js index a879872..fb839a0 100644 --- a/bundles/pixi.js/src/index.js +++ b/bundles/pixi.js/src/index.js @@ -9,7 +9,7 @@ import * as loaders from '@pixi/loaders'; import * as math from '@pixi/math'; import * as mesh from '@pixi/mesh'; -// import * as particles from '@pixi/particles'; +import * as particles from '@pixi/particles'; import * as prepare from '@pixi/prepare'; import * as sprite from '@pixi/sprite'; import * as spriteAnimated from '@pixi/sprite-animated'; @@ -38,7 +38,7 @@ core.Renderer.registerPlugin('graphics', graphics.GraphicsRenderer); core.Renderer.registerPlugin('interaction', interaction.InteractionManager); core.Renderer.registerPlugin('mesh', mesh.MeshRenderer); -// core.Renderer.registerPlugin('particle', particles.ParticleRenderer); +core.Renderer.registerPlugin('particle', particles.ParticleRenderer); core.Renderer.registerPlugin('prepare', prepare.Prepare); core.Renderer.registerPlugin('sprite', sprite.SpriteRenderer); core.Renderer.registerPlugin('tilingSprite', spriteTiling.TilingSpriteRenderer); @@ -120,7 +120,7 @@ loaders, math, mesh, - // particles, + particles, sprite, spriteAnimated, spritesheet, diff --git a/packages/canvas/canvas-particles/LICENSE b/packages/canvas/canvas-particles/LICENSE new file mode 100644 index 0000000..148e3eb --- /dev/null +++ b/packages/canvas/canvas-particles/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2013-2018 Mathew Groves, Chad Engler + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/packages/canvas/canvas-particles/README.md b/packages/canvas/canvas-particles/README.md new file mode 100644 index 0000000..5560aea --- /dev/null +++ b/packages/canvas/canvas-particles/README.md @@ -0,0 +1,13 @@ +# @pixi/canvas-sprite-tiling + +## Installation + +```bash +npm install @pixi/canvas-sprite-tiling +``` + +## Usage + +```js +import '@pixi/canvas-sprite-tiling'; +``` \ No newline at end of file diff --git a/packages/canvas/canvas-particles/package.json b/packages/canvas/canvas-particles/package.json new file mode 100644 index 0000000..22c5b71 --- /dev/null +++ b/packages/canvas/canvas-particles/package.json @@ -0,0 +1,30 @@ +{ + "name": "@pixi/canvas-particles", + "version": "5.0.0-alpha", + "main": "lib/canvas-sprite-tiling.js", + "module": "lib/canvas-sprite-tiling.es.js", + "description": "Support for legacy browser JavaScript environments", + "author": "Mat Groves", + "contributors": [ + "Matt Karl " + ], + "homepage": "http://pixijs.com/", + "bugs": "https://github.com/pixijs/pixi.js/issues", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/pixijs/pixi.js.git" + }, + "publishConfig": { + "access": "public" + }, + "files": [ + "lib" + ], + "dependencies": { + "@pixi/particles": "^5.0.0-alpha" + }, + "devDependencies": { + "floss": "^2.1.3" + } +} diff --git a/bundles/pixi.js-legacy/package.json b/bundles/pixi.js-legacy/package.json index 56d8e1a..a0e6aa8 100644 --- a/bundles/pixi.js-legacy/package.json +++ b/bundles/pixi.js-legacy/package.json @@ -32,6 +32,7 @@ "@pixi/canvas-extract": "^5.0.0-alpha", "@pixi/canvas-graphics": "^5.0.0-alpha", "@pixi/canvas-mesh": "^5.0.0-alpha", + "@pixi/canvas-particles": "^5.0.0-alpha", "@pixi/canvas-prepare": "^5.0.0-alpha", "@pixi/canvas-renderer": "^5.0.0-alpha", "@pixi/canvas-sprite": "^5.0.0-alpha", diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js index b29ba1e..6c9d2b8 100644 --- a/bundles/pixi.js-legacy/src/index.js +++ b/bundles/pixi.js-legacy/src/index.js @@ -8,6 +8,7 @@ import * as canvasExtract from '@pixi/canvas-extract'; import * as canvasPrepare from '@pixi/canvas-prepare'; import '@pixi/canvas-sprite-tiling'; +import '@pixi/canvas-particles'; import '@pixi/canvas-display'; CanvasRenderer.registerPlugin('accessibility', PIXI.accessibility.AccessibilityManager); diff --git a/bundles/pixi.js/src/index.js b/bundles/pixi.js/src/index.js index a879872..fb839a0 100644 --- a/bundles/pixi.js/src/index.js +++ b/bundles/pixi.js/src/index.js @@ -9,7 +9,7 @@ import * as loaders from '@pixi/loaders'; import * as math from '@pixi/math'; import * as mesh from '@pixi/mesh'; -// import * as particles from '@pixi/particles'; +import * as particles from '@pixi/particles'; import * as prepare from '@pixi/prepare'; import * as sprite from '@pixi/sprite'; import * as spriteAnimated from '@pixi/sprite-animated'; @@ -38,7 +38,7 @@ core.Renderer.registerPlugin('graphics', graphics.GraphicsRenderer); core.Renderer.registerPlugin('interaction', interaction.InteractionManager); core.Renderer.registerPlugin('mesh', mesh.MeshRenderer); -// core.Renderer.registerPlugin('particle', particles.ParticleRenderer); +core.Renderer.registerPlugin('particle', particles.ParticleRenderer); core.Renderer.registerPlugin('prepare', prepare.Prepare); core.Renderer.registerPlugin('sprite', sprite.SpriteRenderer); core.Renderer.registerPlugin('tilingSprite', spriteTiling.TilingSpriteRenderer); @@ -120,7 +120,7 @@ loaders, math, mesh, - // particles, + particles, sprite, spriteAnimated, spritesheet, diff --git a/packages/canvas/canvas-particles/LICENSE b/packages/canvas/canvas-particles/LICENSE new file mode 100644 index 0000000..148e3eb --- /dev/null +++ b/packages/canvas/canvas-particles/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2013-2018 Mathew Groves, Chad Engler + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/packages/canvas/canvas-particles/README.md b/packages/canvas/canvas-particles/README.md new file mode 100644 index 0000000..5560aea --- /dev/null +++ b/packages/canvas/canvas-particles/README.md @@ -0,0 +1,13 @@ +# @pixi/canvas-sprite-tiling + +## Installation + +```bash +npm install @pixi/canvas-sprite-tiling +``` + +## Usage + +```js +import '@pixi/canvas-sprite-tiling'; +``` \ No newline at end of file diff --git a/packages/canvas/canvas-particles/package.json b/packages/canvas/canvas-particles/package.json new file mode 100644 index 0000000..22c5b71 --- /dev/null +++ b/packages/canvas/canvas-particles/package.json @@ -0,0 +1,30 @@ +{ + "name": "@pixi/canvas-particles", + "version": "5.0.0-alpha", + "main": "lib/canvas-sprite-tiling.js", + "module": "lib/canvas-sprite-tiling.es.js", + "description": "Support for legacy browser JavaScript environments", + "author": "Mat Groves", + "contributors": [ + "Matt Karl " + ], + "homepage": "http://pixijs.com/", + "bugs": "https://github.com/pixijs/pixi.js/issues", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/pixijs/pixi.js.git" + }, + "publishConfig": { + "access": "public" + }, + "files": [ + "lib" + ], + "dependencies": { + "@pixi/particles": "^5.0.0-alpha" + }, + "devDependencies": { + "floss": "^2.1.3" + } +} diff --git a/packages/canvas/canvas-particles/src/ParticleContainer.js b/packages/canvas/canvas-particles/src/ParticleContainer.js new file mode 100644 index 0000000..9145c56 --- /dev/null +++ b/packages/canvas/canvas-particles/src/ParticleContainer.js @@ -0,0 +1,123 @@ +import { ParticleContainer } from '@pixi/particles'; + +/** + * Renders the object using the Canvas renderer + * + * @private + * @param {PIXI.CanvasRenderer} renderer - a reference to the canvas renderer + */ +ParticleContainer.prototype.renderCanvas = function renderCanvas(renderer) +{ + if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable) + { + return; + } + + const context = renderer.context; + const transform = this.worldTransform; + let isRotated = true; + + let positionX = 0; + let positionY = 0; + + let finalWidth = 0; + let finalHeight = 0; + + renderer.setBlendMode(this.blendMode); + + context.globalAlpha = this.worldAlpha; + + this.displayObjectUpdateTransform(); + + for (let i = 0; i < this.children.length; ++i) + { + const child = this.children[i]; + + if (!child.visible) + { + continue; + } + + const frame = child._texture.frame; + + context.globalAlpha = this.worldAlpha * child.alpha; + + if (child.rotation % (Math.PI * 2) === 0) + { + // this is the fastest way to optimise! - if rotation is 0 then we can avoid any kind of setTransform call + if (isRotated) + { + context.setTransform( + transform.a, + transform.b, + transform.c, + transform.d, + transform.tx * renderer.resolution, + transform.ty * renderer.resolution + ); + + isRotated = false; + } + + positionX = ((child.anchor.x) * (-frame.width * child.scale.x)) + child.position.x + 0.5; + positionY = ((child.anchor.y) * (-frame.height * child.scale.y)) + child.position.y + 0.5; + + finalWidth = frame.width * child.scale.x; + finalHeight = frame.height * child.scale.y; + } + else + { + if (!isRotated) + { + isRotated = true; + } + + child.displayObjectUpdateTransform(); + + const childTransform = child.worldTransform; + + if (renderer.roundPixels) + { + context.setTransform( + childTransform.a, + childTransform.b, + childTransform.c, + childTransform.d, + (childTransform.tx * renderer.resolution) | 0, + (childTransform.ty * renderer.resolution) | 0 + ); + } + else + { + context.setTransform( + childTransform.a, + childTransform.b, + childTransform.c, + childTransform.d, + childTransform.tx * renderer.resolution, + childTransform.ty * renderer.resolution + ); + } + + positionX = ((child.anchor.x) * (-frame.width)) + 0.5; + positionY = ((child.anchor.y) * (-frame.height)) + 0.5; + + finalWidth = frame.width; + finalHeight = frame.height; + } + + const resolution = child._texture.baseTexture.resolution; + + context.drawImage( + child._texture.baseTexture.source, + frame.x * resolution, + frame.y * resolution, + frame.width * resolution, + frame.height * resolution, + positionX * renderer.resolution, + positionY * renderer.resolution, + finalWidth * renderer.resolution, + finalHeight * renderer.resolution + ); + } +}; diff --git a/bundles/pixi.js-legacy/package.json b/bundles/pixi.js-legacy/package.json index 56d8e1a..a0e6aa8 100644 --- a/bundles/pixi.js-legacy/package.json +++ b/bundles/pixi.js-legacy/package.json @@ -32,6 +32,7 @@ "@pixi/canvas-extract": "^5.0.0-alpha", "@pixi/canvas-graphics": "^5.0.0-alpha", "@pixi/canvas-mesh": "^5.0.0-alpha", + "@pixi/canvas-particles": "^5.0.0-alpha", "@pixi/canvas-prepare": "^5.0.0-alpha", "@pixi/canvas-renderer": "^5.0.0-alpha", "@pixi/canvas-sprite": "^5.0.0-alpha", diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js index b29ba1e..6c9d2b8 100644 --- a/bundles/pixi.js-legacy/src/index.js +++ b/bundles/pixi.js-legacy/src/index.js @@ -8,6 +8,7 @@ import * as canvasExtract from '@pixi/canvas-extract'; import * as canvasPrepare from '@pixi/canvas-prepare'; import '@pixi/canvas-sprite-tiling'; +import '@pixi/canvas-particles'; import '@pixi/canvas-display'; CanvasRenderer.registerPlugin('accessibility', PIXI.accessibility.AccessibilityManager); diff --git a/bundles/pixi.js/src/index.js b/bundles/pixi.js/src/index.js index a879872..fb839a0 100644 --- a/bundles/pixi.js/src/index.js +++ b/bundles/pixi.js/src/index.js @@ -9,7 +9,7 @@ import * as loaders from '@pixi/loaders'; import * as math from '@pixi/math'; import * as mesh from '@pixi/mesh'; -// import * as particles from '@pixi/particles'; +import * as particles from '@pixi/particles'; import * as prepare from '@pixi/prepare'; import * as sprite from '@pixi/sprite'; import * as spriteAnimated from '@pixi/sprite-animated'; @@ -38,7 +38,7 @@ core.Renderer.registerPlugin('graphics', graphics.GraphicsRenderer); core.Renderer.registerPlugin('interaction', interaction.InteractionManager); core.Renderer.registerPlugin('mesh', mesh.MeshRenderer); -// core.Renderer.registerPlugin('particle', particles.ParticleRenderer); +core.Renderer.registerPlugin('particle', particles.ParticleRenderer); core.Renderer.registerPlugin('prepare', prepare.Prepare); core.Renderer.registerPlugin('sprite', sprite.SpriteRenderer); core.Renderer.registerPlugin('tilingSprite', spriteTiling.TilingSpriteRenderer); @@ -120,7 +120,7 @@ loaders, math, mesh, - // particles, + particles, sprite, spriteAnimated, spritesheet, diff --git a/packages/canvas/canvas-particles/LICENSE b/packages/canvas/canvas-particles/LICENSE new file mode 100644 index 0000000..148e3eb --- /dev/null +++ b/packages/canvas/canvas-particles/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2013-2018 Mathew Groves, Chad Engler + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/packages/canvas/canvas-particles/README.md b/packages/canvas/canvas-particles/README.md new file mode 100644 index 0000000..5560aea --- /dev/null +++ b/packages/canvas/canvas-particles/README.md @@ -0,0 +1,13 @@ +# @pixi/canvas-sprite-tiling + +## Installation + +```bash +npm install @pixi/canvas-sprite-tiling +``` + +## Usage + +```js +import '@pixi/canvas-sprite-tiling'; +``` \ No newline at end of file diff --git a/packages/canvas/canvas-particles/package.json b/packages/canvas/canvas-particles/package.json new file mode 100644 index 0000000..22c5b71 --- /dev/null +++ b/packages/canvas/canvas-particles/package.json @@ -0,0 +1,30 @@ +{ + "name": "@pixi/canvas-particles", + "version": "5.0.0-alpha", + "main": "lib/canvas-sprite-tiling.js", + "module": "lib/canvas-sprite-tiling.es.js", + "description": "Support for legacy browser JavaScript environments", + "author": "Mat Groves", + "contributors": [ + "Matt Karl " + ], + "homepage": "http://pixijs.com/", + "bugs": "https://github.com/pixijs/pixi.js/issues", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/pixijs/pixi.js.git" + }, + "publishConfig": { + "access": "public" + }, + "files": [ + "lib" + ], + "dependencies": { + "@pixi/particles": "^5.0.0-alpha" + }, + "devDependencies": { + "floss": "^2.1.3" + } +} diff --git a/packages/canvas/canvas-particles/src/ParticleContainer.js b/packages/canvas/canvas-particles/src/ParticleContainer.js new file mode 100644 index 0000000..9145c56 --- /dev/null +++ b/packages/canvas/canvas-particles/src/ParticleContainer.js @@ -0,0 +1,123 @@ +import { ParticleContainer } from '@pixi/particles'; + +/** + * Renders the object using the Canvas renderer + * + * @private + * @param {PIXI.CanvasRenderer} renderer - a reference to the canvas renderer + */ +ParticleContainer.prototype.renderCanvas = function renderCanvas(renderer) +{ + if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable) + { + return; + } + + const context = renderer.context; + const transform = this.worldTransform; + let isRotated = true; + + let positionX = 0; + let positionY = 0; + + let finalWidth = 0; + let finalHeight = 0; + + renderer.setBlendMode(this.blendMode); + + context.globalAlpha = this.worldAlpha; + + this.displayObjectUpdateTransform(); + + for (let i = 0; i < this.children.length; ++i) + { + const child = this.children[i]; + + if (!child.visible) + { + continue; + } + + const frame = child._texture.frame; + + context.globalAlpha = this.worldAlpha * child.alpha; + + if (child.rotation % (Math.PI * 2) === 0) + { + // this is the fastest way to optimise! - if rotation is 0 then we can avoid any kind of setTransform call + if (isRotated) + { + context.setTransform( + transform.a, + transform.b, + transform.c, + transform.d, + transform.tx * renderer.resolution, + transform.ty * renderer.resolution + ); + + isRotated = false; + } + + positionX = ((child.anchor.x) * (-frame.width * child.scale.x)) + child.position.x + 0.5; + positionY = ((child.anchor.y) * (-frame.height * child.scale.y)) + child.position.y + 0.5; + + finalWidth = frame.width * child.scale.x; + finalHeight = frame.height * child.scale.y; + } + else + { + if (!isRotated) + { + isRotated = true; + } + + child.displayObjectUpdateTransform(); + + const childTransform = child.worldTransform; + + if (renderer.roundPixels) + { + context.setTransform( + childTransform.a, + childTransform.b, + childTransform.c, + childTransform.d, + (childTransform.tx * renderer.resolution) | 0, + (childTransform.ty * renderer.resolution) | 0 + ); + } + else + { + context.setTransform( + childTransform.a, + childTransform.b, + childTransform.c, + childTransform.d, + childTransform.tx * renderer.resolution, + childTransform.ty * renderer.resolution + ); + } + + positionX = ((child.anchor.x) * (-frame.width)) + 0.5; + positionY = ((child.anchor.y) * (-frame.height)) + 0.5; + + finalWidth = frame.width; + finalHeight = frame.height; + } + + const resolution = child._texture.baseTexture.resolution; + + context.drawImage( + child._texture.baseTexture.source, + frame.x * resolution, + frame.y * resolution, + frame.width * resolution, + frame.height * resolution, + positionX * renderer.resolution, + positionY * renderer.resolution, + finalWidth * renderer.resolution, + finalHeight * renderer.resolution + ); + } +}; diff --git a/packages/canvas/canvas-particles/src/index.js b/packages/canvas/canvas-particles/src/index.js new file mode 100644 index 0000000..2ea3720 --- /dev/null +++ b/packages/canvas/canvas-particles/src/index.js @@ -0,0 +1 @@ +import './ParticleContainer'; diff --git a/bundles/pixi.js-legacy/package.json b/bundles/pixi.js-legacy/package.json index 56d8e1a..a0e6aa8 100644 --- a/bundles/pixi.js-legacy/package.json +++ b/bundles/pixi.js-legacy/package.json @@ -32,6 +32,7 @@ "@pixi/canvas-extract": "^5.0.0-alpha", "@pixi/canvas-graphics": "^5.0.0-alpha", "@pixi/canvas-mesh": "^5.0.0-alpha", + "@pixi/canvas-particles": "^5.0.0-alpha", "@pixi/canvas-prepare": "^5.0.0-alpha", "@pixi/canvas-renderer": "^5.0.0-alpha", "@pixi/canvas-sprite": "^5.0.0-alpha", diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js index b29ba1e..6c9d2b8 100644 --- a/bundles/pixi.js-legacy/src/index.js +++ b/bundles/pixi.js-legacy/src/index.js @@ -8,6 +8,7 @@ import * as canvasExtract from '@pixi/canvas-extract'; import * as canvasPrepare from '@pixi/canvas-prepare'; import '@pixi/canvas-sprite-tiling'; +import '@pixi/canvas-particles'; import '@pixi/canvas-display'; CanvasRenderer.registerPlugin('accessibility', PIXI.accessibility.AccessibilityManager); diff --git a/bundles/pixi.js/src/index.js b/bundles/pixi.js/src/index.js index a879872..fb839a0 100644 --- a/bundles/pixi.js/src/index.js +++ b/bundles/pixi.js/src/index.js @@ -9,7 +9,7 @@ import * as loaders from '@pixi/loaders'; import * as math from '@pixi/math'; import * as mesh from '@pixi/mesh'; -// import * as particles from '@pixi/particles'; +import * as particles from '@pixi/particles'; import * as prepare from '@pixi/prepare'; import * as sprite from '@pixi/sprite'; import * as spriteAnimated from '@pixi/sprite-animated'; @@ -38,7 +38,7 @@ core.Renderer.registerPlugin('graphics', graphics.GraphicsRenderer); core.Renderer.registerPlugin('interaction', interaction.InteractionManager); core.Renderer.registerPlugin('mesh', mesh.MeshRenderer); -// core.Renderer.registerPlugin('particle', particles.ParticleRenderer); +core.Renderer.registerPlugin('particle', particles.ParticleRenderer); core.Renderer.registerPlugin('prepare', prepare.Prepare); core.Renderer.registerPlugin('sprite', sprite.SpriteRenderer); core.Renderer.registerPlugin('tilingSprite', spriteTiling.TilingSpriteRenderer); @@ -120,7 +120,7 @@ loaders, math, mesh, - // particles, + particles, sprite, spriteAnimated, spritesheet, diff --git a/packages/canvas/canvas-particles/LICENSE b/packages/canvas/canvas-particles/LICENSE new file mode 100644 index 0000000..148e3eb --- /dev/null +++ b/packages/canvas/canvas-particles/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2013-2018 Mathew Groves, Chad Engler + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/packages/canvas/canvas-particles/README.md b/packages/canvas/canvas-particles/README.md new file mode 100644 index 0000000..5560aea --- /dev/null +++ b/packages/canvas/canvas-particles/README.md @@ -0,0 +1,13 @@ +# @pixi/canvas-sprite-tiling + +## Installation + +```bash +npm install @pixi/canvas-sprite-tiling +``` + +## Usage + +```js +import '@pixi/canvas-sprite-tiling'; +``` \ No newline at end of file diff --git a/packages/canvas/canvas-particles/package.json b/packages/canvas/canvas-particles/package.json new file mode 100644 index 0000000..22c5b71 --- /dev/null +++ b/packages/canvas/canvas-particles/package.json @@ -0,0 +1,30 @@ +{ + "name": "@pixi/canvas-particles", + "version": "5.0.0-alpha", + "main": "lib/canvas-sprite-tiling.js", + "module": "lib/canvas-sprite-tiling.es.js", + "description": "Support for legacy browser JavaScript environments", + "author": "Mat Groves", + "contributors": [ + "Matt Karl " + ], + "homepage": "http://pixijs.com/", + "bugs": "https://github.com/pixijs/pixi.js/issues", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/pixijs/pixi.js.git" + }, + "publishConfig": { + "access": "public" + }, + "files": [ + "lib" + ], + "dependencies": { + "@pixi/particles": "^5.0.0-alpha" + }, + "devDependencies": { + "floss": "^2.1.3" + } +} diff --git a/packages/canvas/canvas-particles/src/ParticleContainer.js b/packages/canvas/canvas-particles/src/ParticleContainer.js new file mode 100644 index 0000000..9145c56 --- /dev/null +++ b/packages/canvas/canvas-particles/src/ParticleContainer.js @@ -0,0 +1,123 @@ +import { ParticleContainer } from '@pixi/particles'; + +/** + * Renders the object using the Canvas renderer + * + * @private + * @param {PIXI.CanvasRenderer} renderer - a reference to the canvas renderer + */ +ParticleContainer.prototype.renderCanvas = function renderCanvas(renderer) +{ + if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable) + { + return; + } + + const context = renderer.context; + const transform = this.worldTransform; + let isRotated = true; + + let positionX = 0; + let positionY = 0; + + let finalWidth = 0; + let finalHeight = 0; + + renderer.setBlendMode(this.blendMode); + + context.globalAlpha = this.worldAlpha; + + this.displayObjectUpdateTransform(); + + for (let i = 0; i < this.children.length; ++i) + { + const child = this.children[i]; + + if (!child.visible) + { + continue; + } + + const frame = child._texture.frame; + + context.globalAlpha = this.worldAlpha * child.alpha; + + if (child.rotation % (Math.PI * 2) === 0) + { + // this is the fastest way to optimise! - if rotation is 0 then we can avoid any kind of setTransform call + if (isRotated) + { + context.setTransform( + transform.a, + transform.b, + transform.c, + transform.d, + transform.tx * renderer.resolution, + transform.ty * renderer.resolution + ); + + isRotated = false; + } + + positionX = ((child.anchor.x) * (-frame.width * child.scale.x)) + child.position.x + 0.5; + positionY = ((child.anchor.y) * (-frame.height * child.scale.y)) + child.position.y + 0.5; + + finalWidth = frame.width * child.scale.x; + finalHeight = frame.height * child.scale.y; + } + else + { + if (!isRotated) + { + isRotated = true; + } + + child.displayObjectUpdateTransform(); + + const childTransform = child.worldTransform; + + if (renderer.roundPixels) + { + context.setTransform( + childTransform.a, + childTransform.b, + childTransform.c, + childTransform.d, + (childTransform.tx * renderer.resolution) | 0, + (childTransform.ty * renderer.resolution) | 0 + ); + } + else + { + context.setTransform( + childTransform.a, + childTransform.b, + childTransform.c, + childTransform.d, + childTransform.tx * renderer.resolution, + childTransform.ty * renderer.resolution + ); + } + + positionX = ((child.anchor.x) * (-frame.width)) + 0.5; + positionY = ((child.anchor.y) * (-frame.height)) + 0.5; + + finalWidth = frame.width; + finalHeight = frame.height; + } + + const resolution = child._texture.baseTexture.resolution; + + context.drawImage( + child._texture.baseTexture.source, + frame.x * resolution, + frame.y * resolution, + frame.width * resolution, + frame.height * resolution, + positionX * renderer.resolution, + positionY * renderer.resolution, + finalWidth * renderer.resolution, + finalHeight * renderer.resolution + ); + } +}; diff --git a/packages/canvas/canvas-particles/src/index.js b/packages/canvas/canvas-particles/src/index.js new file mode 100644 index 0000000..2ea3720 --- /dev/null +++ b/packages/canvas/canvas-particles/src/index.js @@ -0,0 +1 @@ +import './ParticleContainer'; diff --git a/packages/core/src/renderers/systems/geometry/GeometrySystem.js b/packages/core/src/renderers/systems/geometry/GeometrySystem.js index d205a6d..26c8e9e 100644 --- a/packages/core/src/renderers/systems/geometry/GeometrySystem.js +++ b/packages/core/src/renderers/systems/geometry/GeometrySystem.js @@ -145,6 +145,11 @@ this.updateBuffers(); } + reset() + { + this.unbind(); + } + updateBuffers() { const geometry = this._activeGeometry; diff --git a/bundles/pixi.js-legacy/package.json b/bundles/pixi.js-legacy/package.json index 56d8e1a..a0e6aa8 100644 --- a/bundles/pixi.js-legacy/package.json +++ b/bundles/pixi.js-legacy/package.json @@ -32,6 +32,7 @@ "@pixi/canvas-extract": "^5.0.0-alpha", "@pixi/canvas-graphics": "^5.0.0-alpha", "@pixi/canvas-mesh": "^5.0.0-alpha", + "@pixi/canvas-particles": "^5.0.0-alpha", "@pixi/canvas-prepare": "^5.0.0-alpha", "@pixi/canvas-renderer": "^5.0.0-alpha", "@pixi/canvas-sprite": "^5.0.0-alpha", diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js index b29ba1e..6c9d2b8 100644 --- a/bundles/pixi.js-legacy/src/index.js +++ b/bundles/pixi.js-legacy/src/index.js @@ -8,6 +8,7 @@ import * as canvasExtract from '@pixi/canvas-extract'; import * as canvasPrepare from '@pixi/canvas-prepare'; import '@pixi/canvas-sprite-tiling'; +import '@pixi/canvas-particles'; import '@pixi/canvas-display'; CanvasRenderer.registerPlugin('accessibility', PIXI.accessibility.AccessibilityManager); diff --git a/bundles/pixi.js/src/index.js b/bundles/pixi.js/src/index.js index a879872..fb839a0 100644 --- a/bundles/pixi.js/src/index.js +++ b/bundles/pixi.js/src/index.js @@ -9,7 +9,7 @@ import * as loaders from '@pixi/loaders'; import * as math from '@pixi/math'; import * as mesh from '@pixi/mesh'; -// import * as particles from '@pixi/particles'; +import * as particles from '@pixi/particles'; import * as prepare from '@pixi/prepare'; import * as sprite from '@pixi/sprite'; import * as spriteAnimated from '@pixi/sprite-animated'; @@ -38,7 +38,7 @@ core.Renderer.registerPlugin('graphics', graphics.GraphicsRenderer); core.Renderer.registerPlugin('interaction', interaction.InteractionManager); core.Renderer.registerPlugin('mesh', mesh.MeshRenderer); -// core.Renderer.registerPlugin('particle', particles.ParticleRenderer); +core.Renderer.registerPlugin('particle', particles.ParticleRenderer); core.Renderer.registerPlugin('prepare', prepare.Prepare); core.Renderer.registerPlugin('sprite', sprite.SpriteRenderer); core.Renderer.registerPlugin('tilingSprite', spriteTiling.TilingSpriteRenderer); @@ -120,7 +120,7 @@ loaders, math, mesh, - // particles, + particles, sprite, spriteAnimated, spritesheet, diff --git a/packages/canvas/canvas-particles/LICENSE b/packages/canvas/canvas-particles/LICENSE new file mode 100644 index 0000000..148e3eb --- /dev/null +++ b/packages/canvas/canvas-particles/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2013-2018 Mathew Groves, Chad Engler + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/packages/canvas/canvas-particles/README.md b/packages/canvas/canvas-particles/README.md new file mode 100644 index 0000000..5560aea --- /dev/null +++ b/packages/canvas/canvas-particles/README.md @@ -0,0 +1,13 @@ +# @pixi/canvas-sprite-tiling + +## Installation + +```bash +npm install @pixi/canvas-sprite-tiling +``` + +## Usage + +```js +import '@pixi/canvas-sprite-tiling'; +``` \ No newline at end of file diff --git a/packages/canvas/canvas-particles/package.json b/packages/canvas/canvas-particles/package.json new file mode 100644 index 0000000..22c5b71 --- /dev/null +++ b/packages/canvas/canvas-particles/package.json @@ -0,0 +1,30 @@ +{ + "name": "@pixi/canvas-particles", + "version": "5.0.0-alpha", + "main": "lib/canvas-sprite-tiling.js", + "module": "lib/canvas-sprite-tiling.es.js", + "description": "Support for legacy browser JavaScript environments", + "author": "Mat Groves", + "contributors": [ + "Matt Karl " + ], + "homepage": "http://pixijs.com/", + "bugs": "https://github.com/pixijs/pixi.js/issues", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/pixijs/pixi.js.git" + }, + "publishConfig": { + "access": "public" + }, + "files": [ + "lib" + ], + "dependencies": { + "@pixi/particles": "^5.0.0-alpha" + }, + "devDependencies": { + "floss": "^2.1.3" + } +} diff --git a/packages/canvas/canvas-particles/src/ParticleContainer.js b/packages/canvas/canvas-particles/src/ParticleContainer.js new file mode 100644 index 0000000..9145c56 --- /dev/null +++ b/packages/canvas/canvas-particles/src/ParticleContainer.js @@ -0,0 +1,123 @@ +import { ParticleContainer } from '@pixi/particles'; + +/** + * Renders the object using the Canvas renderer + * + * @private + * @param {PIXI.CanvasRenderer} renderer - a reference to the canvas renderer + */ +ParticleContainer.prototype.renderCanvas = function renderCanvas(renderer) +{ + if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable) + { + return; + } + + const context = renderer.context; + const transform = this.worldTransform; + let isRotated = true; + + let positionX = 0; + let positionY = 0; + + let finalWidth = 0; + let finalHeight = 0; + + renderer.setBlendMode(this.blendMode); + + context.globalAlpha = this.worldAlpha; + + this.displayObjectUpdateTransform(); + + for (let i = 0; i < this.children.length; ++i) + { + const child = this.children[i]; + + if (!child.visible) + { + continue; + } + + const frame = child._texture.frame; + + context.globalAlpha = this.worldAlpha * child.alpha; + + if (child.rotation % (Math.PI * 2) === 0) + { + // this is the fastest way to optimise! - if rotation is 0 then we can avoid any kind of setTransform call + if (isRotated) + { + context.setTransform( + transform.a, + transform.b, + transform.c, + transform.d, + transform.tx * renderer.resolution, + transform.ty * renderer.resolution + ); + + isRotated = false; + } + + positionX = ((child.anchor.x) * (-frame.width * child.scale.x)) + child.position.x + 0.5; + positionY = ((child.anchor.y) * (-frame.height * child.scale.y)) + child.position.y + 0.5; + + finalWidth = frame.width * child.scale.x; + finalHeight = frame.height * child.scale.y; + } + else + { + if (!isRotated) + { + isRotated = true; + } + + child.displayObjectUpdateTransform(); + + const childTransform = child.worldTransform; + + if (renderer.roundPixels) + { + context.setTransform( + childTransform.a, + childTransform.b, + childTransform.c, + childTransform.d, + (childTransform.tx * renderer.resolution) | 0, + (childTransform.ty * renderer.resolution) | 0 + ); + } + else + { + context.setTransform( + childTransform.a, + childTransform.b, + childTransform.c, + childTransform.d, + childTransform.tx * renderer.resolution, + childTransform.ty * renderer.resolution + ); + } + + positionX = ((child.anchor.x) * (-frame.width)) + 0.5; + positionY = ((child.anchor.y) * (-frame.height)) + 0.5; + + finalWidth = frame.width; + finalHeight = frame.height; + } + + const resolution = child._texture.baseTexture.resolution; + + context.drawImage( + child._texture.baseTexture.source, + frame.x * resolution, + frame.y * resolution, + frame.width * resolution, + frame.height * resolution, + positionX * renderer.resolution, + positionY * renderer.resolution, + finalWidth * renderer.resolution, + finalHeight * renderer.resolution + ); + } +}; diff --git a/packages/canvas/canvas-particles/src/index.js b/packages/canvas/canvas-particles/src/index.js new file mode 100644 index 0000000..2ea3720 --- /dev/null +++ b/packages/canvas/canvas-particles/src/index.js @@ -0,0 +1 @@ +import './ParticleContainer'; diff --git a/packages/core/src/renderers/systems/geometry/GeometrySystem.js b/packages/core/src/renderers/systems/geometry/GeometrySystem.js index d205a6d..26c8e9e 100644 --- a/packages/core/src/renderers/systems/geometry/GeometrySystem.js +++ b/packages/core/src/renderers/systems/geometry/GeometrySystem.js @@ -145,6 +145,11 @@ this.updateBuffers(); } + reset() + { + this.unbind(); + } + updateBuffers() { const geometry = this._activeGeometry; diff --git a/packages/particles/src/ParticleBuffer.js b/packages/particles/src/ParticleBuffer.js index 6306bda..68f5dc8 100644 --- a/packages/particles/src/ParticleBuffer.js +++ b/packages/particles/src/ParticleBuffer.js @@ -1,6 +1,6 @@ -// import { VertexArrayObject } from 'pixi-gl-core'; import { createIndicesForQuads } from '@pixi/utils'; -import { GLBuffer } from 'pixi-gl-core'; +import { Geometry, Buffer } from '@pixi/core'; +import { TYPES } from '@pixi/constants'; /** * @author Mat Groves @@ -24,19 +24,15 @@ export default class ParticleBuffer { /** - * @param {WebGLRenderingContext} gl - The rendering context. * @param {object} properties - The properties to upload. * @param {boolean[]} dynamicPropertyFlags - Flags for which properties are dynamic. * @param {number} size - The size of the batch. */ - constructor(gl, properties, dynamicPropertyFlags, size) + constructor(properties, dynamicPropertyFlags, size) { - /** - * The current WebGL drawing context. - * - * @member {WebGLRenderingContext} - */ - this.gl = gl; + this.geometry = new Geometry(); + + this.indexBuffer = null; /** * The number of particles the buffer can hold @@ -66,10 +62,10 @@ // Make copy of properties object so that when we edit the offset it doesn't // change all other instances of the object literal property = { - attribute: property.attribute, + attributeName: property.attributeName, size: property.size, uploadFunction: property.uploadFunction, - unsignedByte: property.unsignedByte, + type: property.type || TYPES.FLOAT, offset: property.offset, }; @@ -103,7 +99,8 @@ */ initBuffers() { - const gl = this.gl; + const geometry = this.geometry; + let dynamicOffset = 0; /** @@ -111,8 +108,8 @@ * * @member {Uint16Array} */ - this.indices = createIndicesForQuads(this.size); - this.indexBuffer = GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW); + this.indexBuffer = new Buffer(createIndicesForQuads(this.size), true, true); + geometry.addIndex(this.indexBuffer); this.dynamicStride = 0; @@ -125,8 +122,11 @@ this.dynamicStride += property.size; } - this.dynamicData = new Float32Array(this.size * this.dynamicStride * 4); - this.dynamicBuffer = GLBuffer.createVertexBuffer(gl, this.dynamicData, gl.STREAM_DRAW); + const dynBuffer = new ArrayBuffer(this.size * this.dynamicStride * 4 * 4); + + this.dynamicData = new Float32Array(dynBuffer); + this.dynamicDataUint32 = new Uint32Array(dynBuffer); + this.dynamicBuffer = new Buffer(this.dynamicData, false, false); // static // let staticOffset = 0; @@ -142,66 +142,40 @@ this.staticStride += property.size; } - this.staticData = new Float32Array(this.size * this.staticStride * 4); - this.staticBuffer = GLBuffer.createVertexBuffer(gl, this.staticData, gl.STATIC_DRAW); + const statBuffer = new ArrayBuffer(this.size * this.staticStride * 4 * 4); - // this.vao = new VertexArrayObject(gl) - // .addIndex(this.indexBuffer); + this.staticData = new Float32Array(statBuffer); + this.staticDataUint32 = new Uint32Array(statBuffer); + this.staticBuffer = new Buffer(this.staticData, true, false); for (let i = 0; i < this.dynamicProperties.length; ++i) { const property = this.dynamicProperties[i]; - if (property.unsignedByte) - { - this.vao.addAttribute( - this.dynamicBuffer, - property.attribute, - gl.UNSIGNED_BYTE, - true, - this.dynamicStride * 4, - property.offset * 4 - ); - } - else - { - this.vao.addAttribute( - this.dynamicBuffer, - property.attribute, - gl.FLOAT, - false, - this.dynamicStride * 4, - property.offset * 4 - ); - } + geometry.addAttribute( + property.attributeName, + this.dynamicBuffer, + 0, + property.type === TYPES.UNSIGNED_BYTE, + property.type, + this.dynamicStride * 4, + property.offset * 4 + ); } for (let i = 0; i < this.staticProperties.length; ++i) { const property = this.staticProperties[i]; - if (property.unsignedByte) - { - this.vao.addAttribute( - this.staticBuffer, - property.attribute, - gl.UNSIGNED_BYTE, - true, - this.staticStride * 4, - property.offset * 4 - ); - } - else - { - this.vao.addAttribute( - this.staticBuffer, - property.attribute, - gl.FLOAT, - false, - this.staticStride * 4, - property.offset * 4 - ); - } + geometry.addAttribute( + property.attributeName, + this.staticBuffer, + 0, + property.type === TYPES.UNSIGNED_BYTE, + property.type, + this.staticStride * 4, + property.offset * 4 + ); } } @@ -219,11 +193,11 @@ const property = this.dynamicProperties[i]; property.uploadFunction(children, startIndex, amount, - property.unsignedByte ? this.dynamicDataUint32 : this.dynamicData, + property.type === TYPES.UNSIGNED_BYTE ? this.dynamicDataUint32 : this.dynamicData, this.dynamicStride, property.offset); } - this.dynamicBuffer.upload(); + this.dynamicBuffer._updateID++; } /** @@ -240,11 +214,11 @@ const property = this.staticProperties[i]; property.uploadFunction(children, startIndex, amount, - property.unsignedByte ? this.staticDataUint32 : this.staticData, + property.type === TYPES.UNSIGNED_BYTE ? this.staticDataUint32 : this.staticData, this.staticStride, property.offset); } - this.staticBuffer.upload(); + this.staticBuffer._updateID++; } /** @@ -253,16 +227,20 @@ */ destroy() { + this.indexBuffer = null; + this.dynamicProperties = null; - this.dynamicBuffer.destroy(); + // this.dynamicBuffer.destroy(); this.dynamicBuffer = null; this.dynamicData = null; this.dynamicDataUint32 = null; this.staticProperties = null; - this.staticBuffer.destroy(); + // this.staticBuffer.destroy(); this.staticBuffer = null; this.staticData = null; this.staticDataUint32 = null; + // all buffers are destroyed inside geometry + this.geometry.destroy(); } } diff --git a/bundles/pixi.js-legacy/package.json b/bundles/pixi.js-legacy/package.json index 56d8e1a..a0e6aa8 100644 --- a/bundles/pixi.js-legacy/package.json +++ b/bundles/pixi.js-legacy/package.json @@ -32,6 +32,7 @@ "@pixi/canvas-extract": "^5.0.0-alpha", "@pixi/canvas-graphics": "^5.0.0-alpha", "@pixi/canvas-mesh": "^5.0.0-alpha", + "@pixi/canvas-particles": "^5.0.0-alpha", "@pixi/canvas-prepare": "^5.0.0-alpha", "@pixi/canvas-renderer": "^5.0.0-alpha", "@pixi/canvas-sprite": "^5.0.0-alpha", diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js index b29ba1e..6c9d2b8 100644 --- a/bundles/pixi.js-legacy/src/index.js +++ b/bundles/pixi.js-legacy/src/index.js @@ -8,6 +8,7 @@ import * as canvasExtract from '@pixi/canvas-extract'; import * as canvasPrepare from '@pixi/canvas-prepare'; import '@pixi/canvas-sprite-tiling'; +import '@pixi/canvas-particles'; import '@pixi/canvas-display'; CanvasRenderer.registerPlugin('accessibility', PIXI.accessibility.AccessibilityManager); diff --git a/bundles/pixi.js/src/index.js b/bundles/pixi.js/src/index.js index a879872..fb839a0 100644 --- a/bundles/pixi.js/src/index.js +++ b/bundles/pixi.js/src/index.js @@ -9,7 +9,7 @@ import * as loaders from '@pixi/loaders'; import * as math from '@pixi/math'; import * as mesh from '@pixi/mesh'; -// import * as particles from '@pixi/particles'; +import * as particles from '@pixi/particles'; import * as prepare from '@pixi/prepare'; import * as sprite from '@pixi/sprite'; import * as spriteAnimated from '@pixi/sprite-animated'; @@ -38,7 +38,7 @@ core.Renderer.registerPlugin('graphics', graphics.GraphicsRenderer); core.Renderer.registerPlugin('interaction', interaction.InteractionManager); core.Renderer.registerPlugin('mesh', mesh.MeshRenderer); -// core.Renderer.registerPlugin('particle', particles.ParticleRenderer); +core.Renderer.registerPlugin('particle', particles.ParticleRenderer); core.Renderer.registerPlugin('prepare', prepare.Prepare); core.Renderer.registerPlugin('sprite', sprite.SpriteRenderer); core.Renderer.registerPlugin('tilingSprite', spriteTiling.TilingSpriteRenderer); @@ -120,7 +120,7 @@ loaders, math, mesh, - // particles, + particles, sprite, spriteAnimated, spritesheet, diff --git a/packages/canvas/canvas-particles/LICENSE b/packages/canvas/canvas-particles/LICENSE new file mode 100644 index 0000000..148e3eb --- /dev/null +++ b/packages/canvas/canvas-particles/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2013-2018 Mathew Groves, Chad Engler + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/packages/canvas/canvas-particles/README.md b/packages/canvas/canvas-particles/README.md new file mode 100644 index 0000000..5560aea --- /dev/null +++ b/packages/canvas/canvas-particles/README.md @@ -0,0 +1,13 @@ +# @pixi/canvas-sprite-tiling + +## Installation + +```bash +npm install @pixi/canvas-sprite-tiling +``` + +## Usage + +```js +import '@pixi/canvas-sprite-tiling'; +``` \ No newline at end of file diff --git a/packages/canvas/canvas-particles/package.json b/packages/canvas/canvas-particles/package.json new file mode 100644 index 0000000..22c5b71 --- /dev/null +++ b/packages/canvas/canvas-particles/package.json @@ -0,0 +1,30 @@ +{ + "name": "@pixi/canvas-particles", + "version": "5.0.0-alpha", + "main": "lib/canvas-sprite-tiling.js", + "module": "lib/canvas-sprite-tiling.es.js", + "description": "Support for legacy browser JavaScript environments", + "author": "Mat Groves", + "contributors": [ + "Matt Karl " + ], + "homepage": "http://pixijs.com/", + "bugs": "https://github.com/pixijs/pixi.js/issues", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/pixijs/pixi.js.git" + }, + "publishConfig": { + "access": "public" + }, + "files": [ + "lib" + ], + "dependencies": { + "@pixi/particles": "^5.0.0-alpha" + }, + "devDependencies": { + "floss": "^2.1.3" + } +} diff --git a/packages/canvas/canvas-particles/src/ParticleContainer.js b/packages/canvas/canvas-particles/src/ParticleContainer.js new file mode 100644 index 0000000..9145c56 --- /dev/null +++ b/packages/canvas/canvas-particles/src/ParticleContainer.js @@ -0,0 +1,123 @@ +import { ParticleContainer } from '@pixi/particles'; + +/** + * Renders the object using the Canvas renderer + * + * @private + * @param {PIXI.CanvasRenderer} renderer - a reference to the canvas renderer + */ +ParticleContainer.prototype.renderCanvas = function renderCanvas(renderer) +{ + if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable) + { + return; + } + + const context = renderer.context; + const transform = this.worldTransform; + let isRotated = true; + + let positionX = 0; + let positionY = 0; + + let finalWidth = 0; + let finalHeight = 0; + + renderer.setBlendMode(this.blendMode); + + context.globalAlpha = this.worldAlpha; + + this.displayObjectUpdateTransform(); + + for (let i = 0; i < this.children.length; ++i) + { + const child = this.children[i]; + + if (!child.visible) + { + continue; + } + + const frame = child._texture.frame; + + context.globalAlpha = this.worldAlpha * child.alpha; + + if (child.rotation % (Math.PI * 2) === 0) + { + // this is the fastest way to optimise! - if rotation is 0 then we can avoid any kind of setTransform call + if (isRotated) + { + context.setTransform( + transform.a, + transform.b, + transform.c, + transform.d, + transform.tx * renderer.resolution, + transform.ty * renderer.resolution + ); + + isRotated = false; + } + + positionX = ((child.anchor.x) * (-frame.width * child.scale.x)) + child.position.x + 0.5; + positionY = ((child.anchor.y) * (-frame.height * child.scale.y)) + child.position.y + 0.5; + + finalWidth = frame.width * child.scale.x; + finalHeight = frame.height * child.scale.y; + } + else + { + if (!isRotated) + { + isRotated = true; + } + + child.displayObjectUpdateTransform(); + + const childTransform = child.worldTransform; + + if (renderer.roundPixels) + { + context.setTransform( + childTransform.a, + childTransform.b, + childTransform.c, + childTransform.d, + (childTransform.tx * renderer.resolution) | 0, + (childTransform.ty * renderer.resolution) | 0 + ); + } + else + { + context.setTransform( + childTransform.a, + childTransform.b, + childTransform.c, + childTransform.d, + childTransform.tx * renderer.resolution, + childTransform.ty * renderer.resolution + ); + } + + positionX = ((child.anchor.x) * (-frame.width)) + 0.5; + positionY = ((child.anchor.y) * (-frame.height)) + 0.5; + + finalWidth = frame.width; + finalHeight = frame.height; + } + + const resolution = child._texture.baseTexture.resolution; + + context.drawImage( + child._texture.baseTexture.source, + frame.x * resolution, + frame.y * resolution, + frame.width * resolution, + frame.height * resolution, + positionX * renderer.resolution, + positionY * renderer.resolution, + finalWidth * renderer.resolution, + finalHeight * renderer.resolution + ); + } +}; diff --git a/packages/canvas/canvas-particles/src/index.js b/packages/canvas/canvas-particles/src/index.js new file mode 100644 index 0000000..2ea3720 --- /dev/null +++ b/packages/canvas/canvas-particles/src/index.js @@ -0,0 +1 @@ +import './ParticleContainer'; diff --git a/packages/core/src/renderers/systems/geometry/GeometrySystem.js b/packages/core/src/renderers/systems/geometry/GeometrySystem.js index d205a6d..26c8e9e 100644 --- a/packages/core/src/renderers/systems/geometry/GeometrySystem.js +++ b/packages/core/src/renderers/systems/geometry/GeometrySystem.js @@ -145,6 +145,11 @@ this.updateBuffers(); } + reset() + { + this.unbind(); + } + updateBuffers() { const geometry = this._activeGeometry; diff --git a/packages/particles/src/ParticleBuffer.js b/packages/particles/src/ParticleBuffer.js index 6306bda..68f5dc8 100644 --- a/packages/particles/src/ParticleBuffer.js +++ b/packages/particles/src/ParticleBuffer.js @@ -1,6 +1,6 @@ -// import { VertexArrayObject } from 'pixi-gl-core'; import { createIndicesForQuads } from '@pixi/utils'; -import { GLBuffer } from 'pixi-gl-core'; +import { Geometry, Buffer } from '@pixi/core'; +import { TYPES } from '@pixi/constants'; /** * @author Mat Groves @@ -24,19 +24,15 @@ export default class ParticleBuffer { /** - * @param {WebGLRenderingContext} gl - The rendering context. * @param {object} properties - The properties to upload. * @param {boolean[]} dynamicPropertyFlags - Flags for which properties are dynamic. * @param {number} size - The size of the batch. */ - constructor(gl, properties, dynamicPropertyFlags, size) + constructor(properties, dynamicPropertyFlags, size) { - /** - * The current WebGL drawing context. - * - * @member {WebGLRenderingContext} - */ - this.gl = gl; + this.geometry = new Geometry(); + + this.indexBuffer = null; /** * The number of particles the buffer can hold @@ -66,10 +62,10 @@ // Make copy of properties object so that when we edit the offset it doesn't // change all other instances of the object literal property = { - attribute: property.attribute, + attributeName: property.attributeName, size: property.size, uploadFunction: property.uploadFunction, - unsignedByte: property.unsignedByte, + type: property.type || TYPES.FLOAT, offset: property.offset, }; @@ -103,7 +99,8 @@ */ initBuffers() { - const gl = this.gl; + const geometry = this.geometry; + let dynamicOffset = 0; /** @@ -111,8 +108,8 @@ * * @member {Uint16Array} */ - this.indices = createIndicesForQuads(this.size); - this.indexBuffer = GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW); + this.indexBuffer = new Buffer(createIndicesForQuads(this.size), true, true); + geometry.addIndex(this.indexBuffer); this.dynamicStride = 0; @@ -125,8 +122,11 @@ this.dynamicStride += property.size; } - this.dynamicData = new Float32Array(this.size * this.dynamicStride * 4); - this.dynamicBuffer = GLBuffer.createVertexBuffer(gl, this.dynamicData, gl.STREAM_DRAW); + const dynBuffer = new ArrayBuffer(this.size * this.dynamicStride * 4 * 4); + + this.dynamicData = new Float32Array(dynBuffer); + this.dynamicDataUint32 = new Uint32Array(dynBuffer); + this.dynamicBuffer = new Buffer(this.dynamicData, false, false); // static // let staticOffset = 0; @@ -142,66 +142,40 @@ this.staticStride += property.size; } - this.staticData = new Float32Array(this.size * this.staticStride * 4); - this.staticBuffer = GLBuffer.createVertexBuffer(gl, this.staticData, gl.STATIC_DRAW); + const statBuffer = new ArrayBuffer(this.size * this.staticStride * 4 * 4); - // this.vao = new VertexArrayObject(gl) - // .addIndex(this.indexBuffer); + this.staticData = new Float32Array(statBuffer); + this.staticDataUint32 = new Uint32Array(statBuffer); + this.staticBuffer = new Buffer(this.staticData, true, false); for (let i = 0; i < this.dynamicProperties.length; ++i) { const property = this.dynamicProperties[i]; - if (property.unsignedByte) - { - this.vao.addAttribute( - this.dynamicBuffer, - property.attribute, - gl.UNSIGNED_BYTE, - true, - this.dynamicStride * 4, - property.offset * 4 - ); - } - else - { - this.vao.addAttribute( - this.dynamicBuffer, - property.attribute, - gl.FLOAT, - false, - this.dynamicStride * 4, - property.offset * 4 - ); - } + geometry.addAttribute( + property.attributeName, + this.dynamicBuffer, + 0, + property.type === TYPES.UNSIGNED_BYTE, + property.type, + this.dynamicStride * 4, + property.offset * 4 + ); } for (let i = 0; i < this.staticProperties.length; ++i) { const property = this.staticProperties[i]; - if (property.unsignedByte) - { - this.vao.addAttribute( - this.staticBuffer, - property.attribute, - gl.UNSIGNED_BYTE, - true, - this.staticStride * 4, - property.offset * 4 - ); - } - else - { - this.vao.addAttribute( - this.staticBuffer, - property.attribute, - gl.FLOAT, - false, - this.staticStride * 4, - property.offset * 4 - ); - } + geometry.addAttribute( + property.attributeName, + this.staticBuffer, + 0, + property.type === TYPES.UNSIGNED_BYTE, + property.type, + this.staticStride * 4, + property.offset * 4 + ); } } @@ -219,11 +193,11 @@ const property = this.dynamicProperties[i]; property.uploadFunction(children, startIndex, amount, - property.unsignedByte ? this.dynamicDataUint32 : this.dynamicData, + property.type === TYPES.UNSIGNED_BYTE ? this.dynamicDataUint32 : this.dynamicData, this.dynamicStride, property.offset); } - this.dynamicBuffer.upload(); + this.dynamicBuffer._updateID++; } /** @@ -240,11 +214,11 @@ const property = this.staticProperties[i]; property.uploadFunction(children, startIndex, amount, - property.unsignedByte ? this.staticDataUint32 : this.staticData, + property.type === TYPES.UNSIGNED_BYTE ? this.staticDataUint32 : this.staticData, this.staticStride, property.offset); } - this.staticBuffer.upload(); + this.staticBuffer._updateID++; } /** @@ -253,16 +227,20 @@ */ destroy() { + this.indexBuffer = null; + this.dynamicProperties = null; - this.dynamicBuffer.destroy(); + // this.dynamicBuffer.destroy(); this.dynamicBuffer = null; this.dynamicData = null; this.dynamicDataUint32 = null; this.staticProperties = null; - this.staticBuffer.destroy(); + // this.staticBuffer.destroy(); this.staticBuffer = null; this.staticData = null; this.staticDataUint32 = null; + // all buffers are destroyed inside geometry + this.geometry.destroy(); } } diff --git a/packages/particles/src/ParticleContainer.js b/packages/particles/src/ParticleContainer.js index 1235474..3a36e98 100644 --- a/packages/particles/src/ParticleContainer.js +++ b/packages/particles/src/ParticleContainer.js @@ -83,10 +83,10 @@ this._batchSize = batchSize; /** - * @member {object} + * @member {Array} * @private */ - this._glBuffers = {}; + this._buffers = null; /** * @member {number} @@ -240,125 +240,16 @@ } } - /** - * Renders the object using the Canvas renderer - * - * @private - * @param {PIXI.CanvasRenderer} renderer - The canvas renderer - */ - renderCanvas(renderer) + dispose() { - if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable) + if (this._buffers) { - return; - } - - const context = renderer.context; - const transform = this.worldTransform; - let isRotated = true; - - let positionX = 0; - let positionY = 0; - - let finalWidth = 0; - let finalHeight = 0; - - renderer.setBlendMode(this.blendMode); - - context.globalAlpha = this.worldAlpha; - - this.displayObjectUpdateTransform(); - - for (let i = 0; i < this.children.length; ++i) - { - const child = this.children[i]; - - if (!child.visible) + for (let i = 0; i < this._buffers.length; ++i) { - continue; + this._buffers[i].destroy(); } - const frame = child._texture.frame; - - context.globalAlpha = this.worldAlpha * child.alpha; - - if (child.rotation % (Math.PI * 2) === 0) - { - // this is the fastest way to optimise! - if rotation is 0 then we can avoid any kind of setTransform call - if (isRotated) - { - context.setTransform( - transform.a, - transform.b, - transform.c, - transform.d, - transform.tx * renderer.resolution, - transform.ty * renderer.resolution - ); - - isRotated = false; - } - - positionX = ((child.anchor.x) * (-frame.width * child.scale.x)) + child.position.x + 0.5; - positionY = ((child.anchor.y) * (-frame.height * child.scale.y)) + child.position.y + 0.5; - - finalWidth = frame.width * child.scale.x; - finalHeight = frame.height * child.scale.y; - } - else - { - if (!isRotated) - { - isRotated = true; - } - - child.displayObjectUpdateTransform(); - - const childTransform = child.worldTransform; - - if (renderer.roundPixels) - { - context.setTransform( - childTransform.a, - childTransform.b, - childTransform.c, - childTransform.d, - (childTransform.tx * renderer.resolution) | 0, - (childTransform.ty * renderer.resolution) | 0 - ); - } - else - { - context.setTransform( - childTransform.a, - childTransform.b, - childTransform.c, - childTransform.d, - childTransform.tx * renderer.resolution, - childTransform.ty * renderer.resolution - ); - } - - positionX = ((child.anchor.x) * (-frame.width)) + 0.5; - positionY = ((child.anchor.y) * (-frame.height)) + 0.5; - - finalWidth = frame.width; - finalHeight = frame.height; - } - - const resolution = child._texture.baseTexture.resolution; - - context.drawImage( - child._texture.baseTexture.source, - frame.x * resolution, - frame.y * resolution, - frame.width * resolution, - frame.height * resolution, - positionX * renderer.resolution, - positionY * renderer.resolution, - finalWidth * renderer.resolution, - finalHeight * renderer.resolution - ); + this._buffers = null; } } @@ -378,15 +269,8 @@ { super.destroy(options); - if (this._buffers) - { - for (let i = 0; i < this._buffers.length; ++i) - { - this._buffers[i].destroy(); - } - } + this.dispose(); this._properties = null; - this._buffers = null; } } diff --git a/bundles/pixi.js-legacy/package.json b/bundles/pixi.js-legacy/package.json index 56d8e1a..a0e6aa8 100644 --- a/bundles/pixi.js-legacy/package.json +++ b/bundles/pixi.js-legacy/package.json @@ -32,6 +32,7 @@ "@pixi/canvas-extract": "^5.0.0-alpha", "@pixi/canvas-graphics": "^5.0.0-alpha", "@pixi/canvas-mesh": "^5.0.0-alpha", + "@pixi/canvas-particles": "^5.0.0-alpha", "@pixi/canvas-prepare": "^5.0.0-alpha", "@pixi/canvas-renderer": "^5.0.0-alpha", "@pixi/canvas-sprite": "^5.0.0-alpha", diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js index b29ba1e..6c9d2b8 100644 --- a/bundles/pixi.js-legacy/src/index.js +++ b/bundles/pixi.js-legacy/src/index.js @@ -8,6 +8,7 @@ import * as canvasExtract from '@pixi/canvas-extract'; import * as canvasPrepare from '@pixi/canvas-prepare'; import '@pixi/canvas-sprite-tiling'; +import '@pixi/canvas-particles'; import '@pixi/canvas-display'; CanvasRenderer.registerPlugin('accessibility', PIXI.accessibility.AccessibilityManager); diff --git a/bundles/pixi.js/src/index.js b/bundles/pixi.js/src/index.js index a879872..fb839a0 100644 --- a/bundles/pixi.js/src/index.js +++ b/bundles/pixi.js/src/index.js @@ -9,7 +9,7 @@ import * as loaders from '@pixi/loaders'; import * as math from '@pixi/math'; import * as mesh from '@pixi/mesh'; -// import * as particles from '@pixi/particles'; +import * as particles from '@pixi/particles'; import * as prepare from '@pixi/prepare'; import * as sprite from '@pixi/sprite'; import * as spriteAnimated from '@pixi/sprite-animated'; @@ -38,7 +38,7 @@ core.Renderer.registerPlugin('graphics', graphics.GraphicsRenderer); core.Renderer.registerPlugin('interaction', interaction.InteractionManager); core.Renderer.registerPlugin('mesh', mesh.MeshRenderer); -// core.Renderer.registerPlugin('particle', particles.ParticleRenderer); +core.Renderer.registerPlugin('particle', particles.ParticleRenderer); core.Renderer.registerPlugin('prepare', prepare.Prepare); core.Renderer.registerPlugin('sprite', sprite.SpriteRenderer); core.Renderer.registerPlugin('tilingSprite', spriteTiling.TilingSpriteRenderer); @@ -120,7 +120,7 @@ loaders, math, mesh, - // particles, + particles, sprite, spriteAnimated, spritesheet, diff --git a/packages/canvas/canvas-particles/LICENSE b/packages/canvas/canvas-particles/LICENSE new file mode 100644 index 0000000..148e3eb --- /dev/null +++ b/packages/canvas/canvas-particles/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2013-2018 Mathew Groves, Chad Engler + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/packages/canvas/canvas-particles/README.md b/packages/canvas/canvas-particles/README.md new file mode 100644 index 0000000..5560aea --- /dev/null +++ b/packages/canvas/canvas-particles/README.md @@ -0,0 +1,13 @@ +# @pixi/canvas-sprite-tiling + +## Installation + +```bash +npm install @pixi/canvas-sprite-tiling +``` + +## Usage + +```js +import '@pixi/canvas-sprite-tiling'; +``` \ No newline at end of file diff --git a/packages/canvas/canvas-particles/package.json b/packages/canvas/canvas-particles/package.json new file mode 100644 index 0000000..22c5b71 --- /dev/null +++ b/packages/canvas/canvas-particles/package.json @@ -0,0 +1,30 @@ +{ + "name": "@pixi/canvas-particles", + "version": "5.0.0-alpha", + "main": "lib/canvas-sprite-tiling.js", + "module": "lib/canvas-sprite-tiling.es.js", + "description": "Support for legacy browser JavaScript environments", + "author": "Mat Groves", + "contributors": [ + "Matt Karl " + ], + "homepage": "http://pixijs.com/", + "bugs": "https://github.com/pixijs/pixi.js/issues", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/pixijs/pixi.js.git" + }, + "publishConfig": { + "access": "public" + }, + "files": [ + "lib" + ], + "dependencies": { + "@pixi/particles": "^5.0.0-alpha" + }, + "devDependencies": { + "floss": "^2.1.3" + } +} diff --git a/packages/canvas/canvas-particles/src/ParticleContainer.js b/packages/canvas/canvas-particles/src/ParticleContainer.js new file mode 100644 index 0000000..9145c56 --- /dev/null +++ b/packages/canvas/canvas-particles/src/ParticleContainer.js @@ -0,0 +1,123 @@ +import { ParticleContainer } from '@pixi/particles'; + +/** + * Renders the object using the Canvas renderer + * + * @private + * @param {PIXI.CanvasRenderer} renderer - a reference to the canvas renderer + */ +ParticleContainer.prototype.renderCanvas = function renderCanvas(renderer) +{ + if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable) + { + return; + } + + const context = renderer.context; + const transform = this.worldTransform; + let isRotated = true; + + let positionX = 0; + let positionY = 0; + + let finalWidth = 0; + let finalHeight = 0; + + renderer.setBlendMode(this.blendMode); + + context.globalAlpha = this.worldAlpha; + + this.displayObjectUpdateTransform(); + + for (let i = 0; i < this.children.length; ++i) + { + const child = this.children[i]; + + if (!child.visible) + { + continue; + } + + const frame = child._texture.frame; + + context.globalAlpha = this.worldAlpha * child.alpha; + + if (child.rotation % (Math.PI * 2) === 0) + { + // this is the fastest way to optimise! - if rotation is 0 then we can avoid any kind of setTransform call + if (isRotated) + { + context.setTransform( + transform.a, + transform.b, + transform.c, + transform.d, + transform.tx * renderer.resolution, + transform.ty * renderer.resolution + ); + + isRotated = false; + } + + positionX = ((child.anchor.x) * (-frame.width * child.scale.x)) + child.position.x + 0.5; + positionY = ((child.anchor.y) * (-frame.height * child.scale.y)) + child.position.y + 0.5; + + finalWidth = frame.width * child.scale.x; + finalHeight = frame.height * child.scale.y; + } + else + { + if (!isRotated) + { + isRotated = true; + } + + child.displayObjectUpdateTransform(); + + const childTransform = child.worldTransform; + + if (renderer.roundPixels) + { + context.setTransform( + childTransform.a, + childTransform.b, + childTransform.c, + childTransform.d, + (childTransform.tx * renderer.resolution) | 0, + (childTransform.ty * renderer.resolution) | 0 + ); + } + else + { + context.setTransform( + childTransform.a, + childTransform.b, + childTransform.c, + childTransform.d, + childTransform.tx * renderer.resolution, + childTransform.ty * renderer.resolution + ); + } + + positionX = ((child.anchor.x) * (-frame.width)) + 0.5; + positionY = ((child.anchor.y) * (-frame.height)) + 0.5; + + finalWidth = frame.width; + finalHeight = frame.height; + } + + const resolution = child._texture.baseTexture.resolution; + + context.drawImage( + child._texture.baseTexture.source, + frame.x * resolution, + frame.y * resolution, + frame.width * resolution, + frame.height * resolution, + positionX * renderer.resolution, + positionY * renderer.resolution, + finalWidth * renderer.resolution, + finalHeight * renderer.resolution + ); + } +}; diff --git a/packages/canvas/canvas-particles/src/index.js b/packages/canvas/canvas-particles/src/index.js new file mode 100644 index 0000000..2ea3720 --- /dev/null +++ b/packages/canvas/canvas-particles/src/index.js @@ -0,0 +1 @@ +import './ParticleContainer'; diff --git a/packages/core/src/renderers/systems/geometry/GeometrySystem.js b/packages/core/src/renderers/systems/geometry/GeometrySystem.js index d205a6d..26c8e9e 100644 --- a/packages/core/src/renderers/systems/geometry/GeometrySystem.js +++ b/packages/core/src/renderers/systems/geometry/GeometrySystem.js @@ -145,6 +145,11 @@ this.updateBuffers(); } + reset() + { + this.unbind(); + } + updateBuffers() { const geometry = this._activeGeometry; diff --git a/packages/particles/src/ParticleBuffer.js b/packages/particles/src/ParticleBuffer.js index 6306bda..68f5dc8 100644 --- a/packages/particles/src/ParticleBuffer.js +++ b/packages/particles/src/ParticleBuffer.js @@ -1,6 +1,6 @@ -// import { VertexArrayObject } from 'pixi-gl-core'; import { createIndicesForQuads } from '@pixi/utils'; -import { GLBuffer } from 'pixi-gl-core'; +import { Geometry, Buffer } from '@pixi/core'; +import { TYPES } from '@pixi/constants'; /** * @author Mat Groves @@ -24,19 +24,15 @@ export default class ParticleBuffer { /** - * @param {WebGLRenderingContext} gl - The rendering context. * @param {object} properties - The properties to upload. * @param {boolean[]} dynamicPropertyFlags - Flags for which properties are dynamic. * @param {number} size - The size of the batch. */ - constructor(gl, properties, dynamicPropertyFlags, size) + constructor(properties, dynamicPropertyFlags, size) { - /** - * The current WebGL drawing context. - * - * @member {WebGLRenderingContext} - */ - this.gl = gl; + this.geometry = new Geometry(); + + this.indexBuffer = null; /** * The number of particles the buffer can hold @@ -66,10 +62,10 @@ // Make copy of properties object so that when we edit the offset it doesn't // change all other instances of the object literal property = { - attribute: property.attribute, + attributeName: property.attributeName, size: property.size, uploadFunction: property.uploadFunction, - unsignedByte: property.unsignedByte, + type: property.type || TYPES.FLOAT, offset: property.offset, }; @@ -103,7 +99,8 @@ */ initBuffers() { - const gl = this.gl; + const geometry = this.geometry; + let dynamicOffset = 0; /** @@ -111,8 +108,8 @@ * * @member {Uint16Array} */ - this.indices = createIndicesForQuads(this.size); - this.indexBuffer = GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW); + this.indexBuffer = new Buffer(createIndicesForQuads(this.size), true, true); + geometry.addIndex(this.indexBuffer); this.dynamicStride = 0; @@ -125,8 +122,11 @@ this.dynamicStride += property.size; } - this.dynamicData = new Float32Array(this.size * this.dynamicStride * 4); - this.dynamicBuffer = GLBuffer.createVertexBuffer(gl, this.dynamicData, gl.STREAM_DRAW); + const dynBuffer = new ArrayBuffer(this.size * this.dynamicStride * 4 * 4); + + this.dynamicData = new Float32Array(dynBuffer); + this.dynamicDataUint32 = new Uint32Array(dynBuffer); + this.dynamicBuffer = new Buffer(this.dynamicData, false, false); // static // let staticOffset = 0; @@ -142,66 +142,40 @@ this.staticStride += property.size; } - this.staticData = new Float32Array(this.size * this.staticStride * 4); - this.staticBuffer = GLBuffer.createVertexBuffer(gl, this.staticData, gl.STATIC_DRAW); + const statBuffer = new ArrayBuffer(this.size * this.staticStride * 4 * 4); - // this.vao = new VertexArrayObject(gl) - // .addIndex(this.indexBuffer); + this.staticData = new Float32Array(statBuffer); + this.staticDataUint32 = new Uint32Array(statBuffer); + this.staticBuffer = new Buffer(this.staticData, true, false); for (let i = 0; i < this.dynamicProperties.length; ++i) { const property = this.dynamicProperties[i]; - if (property.unsignedByte) - { - this.vao.addAttribute( - this.dynamicBuffer, - property.attribute, - gl.UNSIGNED_BYTE, - true, - this.dynamicStride * 4, - property.offset * 4 - ); - } - else - { - this.vao.addAttribute( - this.dynamicBuffer, - property.attribute, - gl.FLOAT, - false, - this.dynamicStride * 4, - property.offset * 4 - ); - } + geometry.addAttribute( + property.attributeName, + this.dynamicBuffer, + 0, + property.type === TYPES.UNSIGNED_BYTE, + property.type, + this.dynamicStride * 4, + property.offset * 4 + ); } for (let i = 0; i < this.staticProperties.length; ++i) { const property = this.staticProperties[i]; - if (property.unsignedByte) - { - this.vao.addAttribute( - this.staticBuffer, - property.attribute, - gl.UNSIGNED_BYTE, - true, - this.staticStride * 4, - property.offset * 4 - ); - } - else - { - this.vao.addAttribute( - this.staticBuffer, - property.attribute, - gl.FLOAT, - false, - this.staticStride * 4, - property.offset * 4 - ); - } + geometry.addAttribute( + property.attributeName, + this.staticBuffer, + 0, + property.type === TYPES.UNSIGNED_BYTE, + property.type, + this.staticStride * 4, + property.offset * 4 + ); } } @@ -219,11 +193,11 @@ const property = this.dynamicProperties[i]; property.uploadFunction(children, startIndex, amount, - property.unsignedByte ? this.dynamicDataUint32 : this.dynamicData, + property.type === TYPES.UNSIGNED_BYTE ? this.dynamicDataUint32 : this.dynamicData, this.dynamicStride, property.offset); } - this.dynamicBuffer.upload(); + this.dynamicBuffer._updateID++; } /** @@ -240,11 +214,11 @@ const property = this.staticProperties[i]; property.uploadFunction(children, startIndex, amount, - property.unsignedByte ? this.staticDataUint32 : this.staticData, + property.type === TYPES.UNSIGNED_BYTE ? this.staticDataUint32 : this.staticData, this.staticStride, property.offset); } - this.staticBuffer.upload(); + this.staticBuffer._updateID++; } /** @@ -253,16 +227,20 @@ */ destroy() { + this.indexBuffer = null; + this.dynamicProperties = null; - this.dynamicBuffer.destroy(); + // this.dynamicBuffer.destroy(); this.dynamicBuffer = null; this.dynamicData = null; this.dynamicDataUint32 = null; this.staticProperties = null; - this.staticBuffer.destroy(); + // this.staticBuffer.destroy(); this.staticBuffer = null; this.staticData = null; this.staticDataUint32 = null; + // all buffers are destroyed inside geometry + this.geometry.destroy(); } } diff --git a/packages/particles/src/ParticleContainer.js b/packages/particles/src/ParticleContainer.js index 1235474..3a36e98 100644 --- a/packages/particles/src/ParticleContainer.js +++ b/packages/particles/src/ParticleContainer.js @@ -83,10 +83,10 @@ this._batchSize = batchSize; /** - * @member {object} + * @member {Array} * @private */ - this._glBuffers = {}; + this._buffers = null; /** * @member {number} @@ -240,125 +240,16 @@ } } - /** - * Renders the object using the Canvas renderer - * - * @private - * @param {PIXI.CanvasRenderer} renderer - The canvas renderer - */ - renderCanvas(renderer) + dispose() { - if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable) + if (this._buffers) { - return; - } - - const context = renderer.context; - const transform = this.worldTransform; - let isRotated = true; - - let positionX = 0; - let positionY = 0; - - let finalWidth = 0; - let finalHeight = 0; - - renderer.setBlendMode(this.blendMode); - - context.globalAlpha = this.worldAlpha; - - this.displayObjectUpdateTransform(); - - for (let i = 0; i < this.children.length; ++i) - { - const child = this.children[i]; - - if (!child.visible) + for (let i = 0; i < this._buffers.length; ++i) { - continue; + this._buffers[i].destroy(); } - const frame = child._texture.frame; - - context.globalAlpha = this.worldAlpha * child.alpha; - - if (child.rotation % (Math.PI * 2) === 0) - { - // this is the fastest way to optimise! - if rotation is 0 then we can avoid any kind of setTransform call - if (isRotated) - { - context.setTransform( - transform.a, - transform.b, - transform.c, - transform.d, - transform.tx * renderer.resolution, - transform.ty * renderer.resolution - ); - - isRotated = false; - } - - positionX = ((child.anchor.x) * (-frame.width * child.scale.x)) + child.position.x + 0.5; - positionY = ((child.anchor.y) * (-frame.height * child.scale.y)) + child.position.y + 0.5; - - finalWidth = frame.width * child.scale.x; - finalHeight = frame.height * child.scale.y; - } - else - { - if (!isRotated) - { - isRotated = true; - } - - child.displayObjectUpdateTransform(); - - const childTransform = child.worldTransform; - - if (renderer.roundPixels) - { - context.setTransform( - childTransform.a, - childTransform.b, - childTransform.c, - childTransform.d, - (childTransform.tx * renderer.resolution) | 0, - (childTransform.ty * renderer.resolution) | 0 - ); - } - else - { - context.setTransform( - childTransform.a, - childTransform.b, - childTransform.c, - childTransform.d, - childTransform.tx * renderer.resolution, - childTransform.ty * renderer.resolution - ); - } - - positionX = ((child.anchor.x) * (-frame.width)) + 0.5; - positionY = ((child.anchor.y) * (-frame.height)) + 0.5; - - finalWidth = frame.width; - finalHeight = frame.height; - } - - const resolution = child._texture.baseTexture.resolution; - - context.drawImage( - child._texture.baseTexture.source, - frame.x * resolution, - frame.y * resolution, - frame.width * resolution, - frame.height * resolution, - positionX * renderer.resolution, - positionY * renderer.resolution, - finalWidth * renderer.resolution, - finalHeight * renderer.resolution - ); + this._buffers = null; } } @@ -378,15 +269,8 @@ { super.destroy(options); - if (this._buffers) - { - for (let i = 0; i < this._buffers.length; ++i) - { - this._buffers[i].destroy(); - } - } + this.dispose(); this._properties = null; - this._buffers = null; } } diff --git a/packages/particles/src/ParticleRenderer.js b/packages/particles/src/ParticleRenderer.js index a2ceaee..9c7ac97 100644 --- a/packages/particles/src/ParticleRenderer.js +++ b/packages/particles/src/ParticleRenderer.js @@ -1,8 +1,10 @@ -import { ObjectRenderer } from '@pixi/core'; +import { TYPES } from '@pixi/constants'; +import { ObjectRenderer, Shader } from '@pixi/core'; import { correctBlendMode, premultiplyRgba, premultiplyTint } from '@pixi/utils'; import { Matrix } from '@pixi/math'; -import ParticleShader from './ParticleShader'; import ParticleBuffer from './ParticleBuffer'; +import vertex from './particles.vert'; +import fragment from './particles.frag'; /** * @author Mat Groves @@ -43,76 +45,50 @@ */ this.shader = null; - this.indexBuffer = null; - this.properties = null; this.tempMatrix = new Matrix(); - this.CONTEXT_UID = 0; - } - - /** - * When there is a WebGL context change - * - * @private - */ - onContextChange() - { - const gl = this.renderer.gl; - - this.CONTEXT_UID = this.renderer.CONTEXT_UID; - - // setup default shader - this.shader = new ParticleShader(gl); - this.properties = [ // verticesData { - attribute: this.shader.attributes.aVertexPosition, + attributeName: 'aVertexPosition', size: 2, uploadFunction: this.uploadVertices, offset: 0, }, // positionData { - attribute: this.shader.attributes.aPositionCoord, + attributeName: 'aPositionCoord', size: 2, uploadFunction: this.uploadPosition, offset: 0, }, // rotationData { - attribute: this.shader.attributes.aRotation, + attributeName: 'aRotation', size: 1, uploadFunction: this.uploadRotation, offset: 0, }, // uvsData { - attribute: this.shader.attributes.aTextureCoord, + attributeName: 'aTextureCoord', size: 2, uploadFunction: this.uploadUvs, offset: 0, }, // tintData { - attribute: this.shader.attributes.aColor, + attributeName: 'aColor', size: 1, - unsignedByte: true, + type: TYPES.UNSIGNED_BYTE, uploadFunction: this.uploadTint, offset: 0, }, ]; - } - /** - * Starts a new particle batch. - * - */ - start() - { - this.renderer.shader.bind(this.shader); + this.shader = Shader.from(vertex, fragment, {}); } /** @@ -137,11 +113,11 @@ totalChildren = maxSize; } - let buffers = container._glBuffers[renderer.CONTEXT_UID]; + let buffers = container._buffers; if (!buffers) { - buffers = container._glBuffers[renderer.CONTEXT_UID] = this.generateBuffers(container); + buffers = container._buffers = this.generateBuffers(container); } const baseTexture = children[0]._texture.baseTexture; @@ -153,15 +129,16 @@ const m = container.worldTransform.copyTo(this.tempMatrix); - m.prepend(renderer._activeRenderTarget.projectionMatrix); + m.prepend(renderer.globalUniforms.uniforms.projectionMatrix); - this.shader.uniforms.projectionMatrix = m.toArray(true); + this.shader.uniforms.translationMatrix = m.toArray(true); this.shader.uniforms.uColor = premultiplyRgba(container.tintRgb, container.worldAlpha, this.shader.uniforms.uColor, baseTexture.premultiplyAlpha); - // make sure the texture is bound.. - this.shader.uniforms.uSampler = renderer.bindTexture(baseTexture); + this.shader.uniforms.uSampler = baseTexture; + + this.renderer.shader.bind(this.shader); // now lets upload and render the buffers.. for (let i = 0, j = 0; i < totalChildren; i += batchSize, j += 1) @@ -195,8 +172,8 @@ } // bind the buffer - renderer.bindVao(buffer.vao); - buffer.vao.draw(gl.TRIANGLES, amount * 6); + renderer.geometry.bind(buffer.geometry); + gl.drawElements(gl.TRIANGLES, amount * 6, gl.UNSIGNED_SHORT, 0); } } @@ -208,7 +185,6 @@ */ generateBuffers(container) { - const gl = this.renderer.gl; const buffers = []; const size = container._maxSize; const batchSize = container._batchSize; @@ -216,7 +192,7 @@ for (let i = 0; i < size; i += batchSize) { - buffers.push(new ParticleBuffer(gl, this.properties, dynamicPropertyFlags, batchSize)); + buffers.push(new ParticleBuffer(this.properties, dynamicPropertyFlags, batchSize)); } return buffers; @@ -231,11 +207,10 @@ */ _generateOneMoreBuffer(container) { - const gl = this.renderer.gl; const batchSize = container._batchSize; const dynamicPropertyFlags = container._properties; - return new ParticleBuffer(gl, this.properties, dynamicPropertyFlags, batchSize); + return new ParticleBuffer(this.properties, dynamicPropertyFlags, batchSize); } /** @@ -440,11 +415,6 @@ */ destroy() { - if (this.renderer.gl) - { - this.renderer.gl.deleteBuffer(this.indexBuffer); - } - super.destroy(); if (this.shader) @@ -453,7 +423,6 @@ this.shader = null; } - this.indices = null; this.tempMatrix = null; } } diff --git a/bundles/pixi.js-legacy/package.json b/bundles/pixi.js-legacy/package.json index 56d8e1a..a0e6aa8 100644 --- a/bundles/pixi.js-legacy/package.json +++ b/bundles/pixi.js-legacy/package.json @@ -32,6 +32,7 @@ "@pixi/canvas-extract": "^5.0.0-alpha", "@pixi/canvas-graphics": "^5.0.0-alpha", "@pixi/canvas-mesh": "^5.0.0-alpha", + "@pixi/canvas-particles": "^5.0.0-alpha", "@pixi/canvas-prepare": "^5.0.0-alpha", "@pixi/canvas-renderer": "^5.0.0-alpha", "@pixi/canvas-sprite": "^5.0.0-alpha", diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js index b29ba1e..6c9d2b8 100644 --- a/bundles/pixi.js-legacy/src/index.js +++ b/bundles/pixi.js-legacy/src/index.js @@ -8,6 +8,7 @@ import * as canvasExtract from '@pixi/canvas-extract'; import * as canvasPrepare from '@pixi/canvas-prepare'; import '@pixi/canvas-sprite-tiling'; +import '@pixi/canvas-particles'; import '@pixi/canvas-display'; CanvasRenderer.registerPlugin('accessibility', PIXI.accessibility.AccessibilityManager); diff --git a/bundles/pixi.js/src/index.js b/bundles/pixi.js/src/index.js index a879872..fb839a0 100644 --- a/bundles/pixi.js/src/index.js +++ b/bundles/pixi.js/src/index.js @@ -9,7 +9,7 @@ import * as loaders from '@pixi/loaders'; import * as math from '@pixi/math'; import * as mesh from '@pixi/mesh'; -// import * as particles from '@pixi/particles'; +import * as particles from '@pixi/particles'; import * as prepare from '@pixi/prepare'; import * as sprite from '@pixi/sprite'; import * as spriteAnimated from '@pixi/sprite-animated'; @@ -38,7 +38,7 @@ core.Renderer.registerPlugin('graphics', graphics.GraphicsRenderer); core.Renderer.registerPlugin('interaction', interaction.InteractionManager); core.Renderer.registerPlugin('mesh', mesh.MeshRenderer); -// core.Renderer.registerPlugin('particle', particles.ParticleRenderer); +core.Renderer.registerPlugin('particle', particles.ParticleRenderer); core.Renderer.registerPlugin('prepare', prepare.Prepare); core.Renderer.registerPlugin('sprite', sprite.SpriteRenderer); core.Renderer.registerPlugin('tilingSprite', spriteTiling.TilingSpriteRenderer); @@ -120,7 +120,7 @@ loaders, math, mesh, - // particles, + particles, sprite, spriteAnimated, spritesheet, diff --git a/packages/canvas/canvas-particles/LICENSE b/packages/canvas/canvas-particles/LICENSE new file mode 100644 index 0000000..148e3eb --- /dev/null +++ b/packages/canvas/canvas-particles/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2013-2018 Mathew Groves, Chad Engler + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/packages/canvas/canvas-particles/README.md b/packages/canvas/canvas-particles/README.md new file mode 100644 index 0000000..5560aea --- /dev/null +++ b/packages/canvas/canvas-particles/README.md @@ -0,0 +1,13 @@ +# @pixi/canvas-sprite-tiling + +## Installation + +```bash +npm install @pixi/canvas-sprite-tiling +``` + +## Usage + +```js +import '@pixi/canvas-sprite-tiling'; +``` \ No newline at end of file diff --git a/packages/canvas/canvas-particles/package.json b/packages/canvas/canvas-particles/package.json new file mode 100644 index 0000000..22c5b71 --- /dev/null +++ b/packages/canvas/canvas-particles/package.json @@ -0,0 +1,30 @@ +{ + "name": "@pixi/canvas-particles", + "version": "5.0.0-alpha", + "main": "lib/canvas-sprite-tiling.js", + "module": "lib/canvas-sprite-tiling.es.js", + "description": "Support for legacy browser JavaScript environments", + "author": "Mat Groves", + "contributors": [ + "Matt Karl " + ], + "homepage": "http://pixijs.com/", + "bugs": "https://github.com/pixijs/pixi.js/issues", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/pixijs/pixi.js.git" + }, + "publishConfig": { + "access": "public" + }, + "files": [ + "lib" + ], + "dependencies": { + "@pixi/particles": "^5.0.0-alpha" + }, + "devDependencies": { + "floss": "^2.1.3" + } +} diff --git a/packages/canvas/canvas-particles/src/ParticleContainer.js b/packages/canvas/canvas-particles/src/ParticleContainer.js new file mode 100644 index 0000000..9145c56 --- /dev/null +++ b/packages/canvas/canvas-particles/src/ParticleContainer.js @@ -0,0 +1,123 @@ +import { ParticleContainer } from '@pixi/particles'; + +/** + * Renders the object using the Canvas renderer + * + * @private + * @param {PIXI.CanvasRenderer} renderer - a reference to the canvas renderer + */ +ParticleContainer.prototype.renderCanvas = function renderCanvas(renderer) +{ + if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable) + { + return; + } + + const context = renderer.context; + const transform = this.worldTransform; + let isRotated = true; + + let positionX = 0; + let positionY = 0; + + let finalWidth = 0; + let finalHeight = 0; + + renderer.setBlendMode(this.blendMode); + + context.globalAlpha = this.worldAlpha; + + this.displayObjectUpdateTransform(); + + for (let i = 0; i < this.children.length; ++i) + { + const child = this.children[i]; + + if (!child.visible) + { + continue; + } + + const frame = child._texture.frame; + + context.globalAlpha = this.worldAlpha * child.alpha; + + if (child.rotation % (Math.PI * 2) === 0) + { + // this is the fastest way to optimise! - if rotation is 0 then we can avoid any kind of setTransform call + if (isRotated) + { + context.setTransform( + transform.a, + transform.b, + transform.c, + transform.d, + transform.tx * renderer.resolution, + transform.ty * renderer.resolution + ); + + isRotated = false; + } + + positionX = ((child.anchor.x) * (-frame.width * child.scale.x)) + child.position.x + 0.5; + positionY = ((child.anchor.y) * (-frame.height * child.scale.y)) + child.position.y + 0.5; + + finalWidth = frame.width * child.scale.x; + finalHeight = frame.height * child.scale.y; + } + else + { + if (!isRotated) + { + isRotated = true; + } + + child.displayObjectUpdateTransform(); + + const childTransform = child.worldTransform; + + if (renderer.roundPixels) + { + context.setTransform( + childTransform.a, + childTransform.b, + childTransform.c, + childTransform.d, + (childTransform.tx * renderer.resolution) | 0, + (childTransform.ty * renderer.resolution) | 0 + ); + } + else + { + context.setTransform( + childTransform.a, + childTransform.b, + childTransform.c, + childTransform.d, + childTransform.tx * renderer.resolution, + childTransform.ty * renderer.resolution + ); + } + + positionX = ((child.anchor.x) * (-frame.width)) + 0.5; + positionY = ((child.anchor.y) * (-frame.height)) + 0.5; + + finalWidth = frame.width; + finalHeight = frame.height; + } + + const resolution = child._texture.baseTexture.resolution; + + context.drawImage( + child._texture.baseTexture.source, + frame.x * resolution, + frame.y * resolution, + frame.width * resolution, + frame.height * resolution, + positionX * renderer.resolution, + positionY * renderer.resolution, + finalWidth * renderer.resolution, + finalHeight * renderer.resolution + ); + } +}; diff --git a/packages/canvas/canvas-particles/src/index.js b/packages/canvas/canvas-particles/src/index.js new file mode 100644 index 0000000..2ea3720 --- /dev/null +++ b/packages/canvas/canvas-particles/src/index.js @@ -0,0 +1 @@ +import './ParticleContainer'; diff --git a/packages/core/src/renderers/systems/geometry/GeometrySystem.js b/packages/core/src/renderers/systems/geometry/GeometrySystem.js index d205a6d..26c8e9e 100644 --- a/packages/core/src/renderers/systems/geometry/GeometrySystem.js +++ b/packages/core/src/renderers/systems/geometry/GeometrySystem.js @@ -145,6 +145,11 @@ this.updateBuffers(); } + reset() + { + this.unbind(); + } + updateBuffers() { const geometry = this._activeGeometry; diff --git a/packages/particles/src/ParticleBuffer.js b/packages/particles/src/ParticleBuffer.js index 6306bda..68f5dc8 100644 --- a/packages/particles/src/ParticleBuffer.js +++ b/packages/particles/src/ParticleBuffer.js @@ -1,6 +1,6 @@ -// import { VertexArrayObject } from 'pixi-gl-core'; import { createIndicesForQuads } from '@pixi/utils'; -import { GLBuffer } from 'pixi-gl-core'; +import { Geometry, Buffer } from '@pixi/core'; +import { TYPES } from '@pixi/constants'; /** * @author Mat Groves @@ -24,19 +24,15 @@ export default class ParticleBuffer { /** - * @param {WebGLRenderingContext} gl - The rendering context. * @param {object} properties - The properties to upload. * @param {boolean[]} dynamicPropertyFlags - Flags for which properties are dynamic. * @param {number} size - The size of the batch. */ - constructor(gl, properties, dynamicPropertyFlags, size) + constructor(properties, dynamicPropertyFlags, size) { - /** - * The current WebGL drawing context. - * - * @member {WebGLRenderingContext} - */ - this.gl = gl; + this.geometry = new Geometry(); + + this.indexBuffer = null; /** * The number of particles the buffer can hold @@ -66,10 +62,10 @@ // Make copy of properties object so that when we edit the offset it doesn't // change all other instances of the object literal property = { - attribute: property.attribute, + attributeName: property.attributeName, size: property.size, uploadFunction: property.uploadFunction, - unsignedByte: property.unsignedByte, + type: property.type || TYPES.FLOAT, offset: property.offset, }; @@ -103,7 +99,8 @@ */ initBuffers() { - const gl = this.gl; + const geometry = this.geometry; + let dynamicOffset = 0; /** @@ -111,8 +108,8 @@ * * @member {Uint16Array} */ - this.indices = createIndicesForQuads(this.size); - this.indexBuffer = GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW); + this.indexBuffer = new Buffer(createIndicesForQuads(this.size), true, true); + geometry.addIndex(this.indexBuffer); this.dynamicStride = 0; @@ -125,8 +122,11 @@ this.dynamicStride += property.size; } - this.dynamicData = new Float32Array(this.size * this.dynamicStride * 4); - this.dynamicBuffer = GLBuffer.createVertexBuffer(gl, this.dynamicData, gl.STREAM_DRAW); + const dynBuffer = new ArrayBuffer(this.size * this.dynamicStride * 4 * 4); + + this.dynamicData = new Float32Array(dynBuffer); + this.dynamicDataUint32 = new Uint32Array(dynBuffer); + this.dynamicBuffer = new Buffer(this.dynamicData, false, false); // static // let staticOffset = 0; @@ -142,66 +142,40 @@ this.staticStride += property.size; } - this.staticData = new Float32Array(this.size * this.staticStride * 4); - this.staticBuffer = GLBuffer.createVertexBuffer(gl, this.staticData, gl.STATIC_DRAW); + const statBuffer = new ArrayBuffer(this.size * this.staticStride * 4 * 4); - // this.vao = new VertexArrayObject(gl) - // .addIndex(this.indexBuffer); + this.staticData = new Float32Array(statBuffer); + this.staticDataUint32 = new Uint32Array(statBuffer); + this.staticBuffer = new Buffer(this.staticData, true, false); for (let i = 0; i < this.dynamicProperties.length; ++i) { const property = this.dynamicProperties[i]; - if (property.unsignedByte) - { - this.vao.addAttribute( - this.dynamicBuffer, - property.attribute, - gl.UNSIGNED_BYTE, - true, - this.dynamicStride * 4, - property.offset * 4 - ); - } - else - { - this.vao.addAttribute( - this.dynamicBuffer, - property.attribute, - gl.FLOAT, - false, - this.dynamicStride * 4, - property.offset * 4 - ); - } + geometry.addAttribute( + property.attributeName, + this.dynamicBuffer, + 0, + property.type === TYPES.UNSIGNED_BYTE, + property.type, + this.dynamicStride * 4, + property.offset * 4 + ); } for (let i = 0; i < this.staticProperties.length; ++i) { const property = this.staticProperties[i]; - if (property.unsignedByte) - { - this.vao.addAttribute( - this.staticBuffer, - property.attribute, - gl.UNSIGNED_BYTE, - true, - this.staticStride * 4, - property.offset * 4 - ); - } - else - { - this.vao.addAttribute( - this.staticBuffer, - property.attribute, - gl.FLOAT, - false, - this.staticStride * 4, - property.offset * 4 - ); - } + geometry.addAttribute( + property.attributeName, + this.staticBuffer, + 0, + property.type === TYPES.UNSIGNED_BYTE, + property.type, + this.staticStride * 4, + property.offset * 4 + ); } } @@ -219,11 +193,11 @@ const property = this.dynamicProperties[i]; property.uploadFunction(children, startIndex, amount, - property.unsignedByte ? this.dynamicDataUint32 : this.dynamicData, + property.type === TYPES.UNSIGNED_BYTE ? this.dynamicDataUint32 : this.dynamicData, this.dynamicStride, property.offset); } - this.dynamicBuffer.upload(); + this.dynamicBuffer._updateID++; } /** @@ -240,11 +214,11 @@ const property = this.staticProperties[i]; property.uploadFunction(children, startIndex, amount, - property.unsignedByte ? this.staticDataUint32 : this.staticData, + property.type === TYPES.UNSIGNED_BYTE ? this.staticDataUint32 : this.staticData, this.staticStride, property.offset); } - this.staticBuffer.upload(); + this.staticBuffer._updateID++; } /** @@ -253,16 +227,20 @@ */ destroy() { + this.indexBuffer = null; + this.dynamicProperties = null; - this.dynamicBuffer.destroy(); + // this.dynamicBuffer.destroy(); this.dynamicBuffer = null; this.dynamicData = null; this.dynamicDataUint32 = null; this.staticProperties = null; - this.staticBuffer.destroy(); + // this.staticBuffer.destroy(); this.staticBuffer = null; this.staticData = null; this.staticDataUint32 = null; + // all buffers are destroyed inside geometry + this.geometry.destroy(); } } diff --git a/packages/particles/src/ParticleContainer.js b/packages/particles/src/ParticleContainer.js index 1235474..3a36e98 100644 --- a/packages/particles/src/ParticleContainer.js +++ b/packages/particles/src/ParticleContainer.js @@ -83,10 +83,10 @@ this._batchSize = batchSize; /** - * @member {object} + * @member {Array} * @private */ - this._glBuffers = {}; + this._buffers = null; /** * @member {number} @@ -240,125 +240,16 @@ } } - /** - * Renders the object using the Canvas renderer - * - * @private - * @param {PIXI.CanvasRenderer} renderer - The canvas renderer - */ - renderCanvas(renderer) + dispose() { - if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable) + if (this._buffers) { - return; - } - - const context = renderer.context; - const transform = this.worldTransform; - let isRotated = true; - - let positionX = 0; - let positionY = 0; - - let finalWidth = 0; - let finalHeight = 0; - - renderer.setBlendMode(this.blendMode); - - context.globalAlpha = this.worldAlpha; - - this.displayObjectUpdateTransform(); - - for (let i = 0; i < this.children.length; ++i) - { - const child = this.children[i]; - - if (!child.visible) + for (let i = 0; i < this._buffers.length; ++i) { - continue; + this._buffers[i].destroy(); } - const frame = child._texture.frame; - - context.globalAlpha = this.worldAlpha * child.alpha; - - if (child.rotation % (Math.PI * 2) === 0) - { - // this is the fastest way to optimise! - if rotation is 0 then we can avoid any kind of setTransform call - if (isRotated) - { - context.setTransform( - transform.a, - transform.b, - transform.c, - transform.d, - transform.tx * renderer.resolution, - transform.ty * renderer.resolution - ); - - isRotated = false; - } - - positionX = ((child.anchor.x) * (-frame.width * child.scale.x)) + child.position.x + 0.5; - positionY = ((child.anchor.y) * (-frame.height * child.scale.y)) + child.position.y + 0.5; - - finalWidth = frame.width * child.scale.x; - finalHeight = frame.height * child.scale.y; - } - else - { - if (!isRotated) - { - isRotated = true; - } - - child.displayObjectUpdateTransform(); - - const childTransform = child.worldTransform; - - if (renderer.roundPixels) - { - context.setTransform( - childTransform.a, - childTransform.b, - childTransform.c, - childTransform.d, - (childTransform.tx * renderer.resolution) | 0, - (childTransform.ty * renderer.resolution) | 0 - ); - } - else - { - context.setTransform( - childTransform.a, - childTransform.b, - childTransform.c, - childTransform.d, - childTransform.tx * renderer.resolution, - childTransform.ty * renderer.resolution - ); - } - - positionX = ((child.anchor.x) * (-frame.width)) + 0.5; - positionY = ((child.anchor.y) * (-frame.height)) + 0.5; - - finalWidth = frame.width; - finalHeight = frame.height; - } - - const resolution = child._texture.baseTexture.resolution; - - context.drawImage( - child._texture.baseTexture.source, - frame.x * resolution, - frame.y * resolution, - frame.width * resolution, - frame.height * resolution, - positionX * renderer.resolution, - positionY * renderer.resolution, - finalWidth * renderer.resolution, - finalHeight * renderer.resolution - ); + this._buffers = null; } } @@ -378,15 +269,8 @@ { super.destroy(options); - if (this._buffers) - { - for (let i = 0; i < this._buffers.length; ++i) - { - this._buffers[i].destroy(); - } - } + this.dispose(); this._properties = null; - this._buffers = null; } } diff --git a/packages/particles/src/ParticleRenderer.js b/packages/particles/src/ParticleRenderer.js index a2ceaee..9c7ac97 100644 --- a/packages/particles/src/ParticleRenderer.js +++ b/packages/particles/src/ParticleRenderer.js @@ -1,8 +1,10 @@ -import { ObjectRenderer } from '@pixi/core'; +import { TYPES } from '@pixi/constants'; +import { ObjectRenderer, Shader } from '@pixi/core'; import { correctBlendMode, premultiplyRgba, premultiplyTint } from '@pixi/utils'; import { Matrix } from '@pixi/math'; -import ParticleShader from './ParticleShader'; import ParticleBuffer from './ParticleBuffer'; +import vertex from './particles.vert'; +import fragment from './particles.frag'; /** * @author Mat Groves @@ -43,76 +45,50 @@ */ this.shader = null; - this.indexBuffer = null; - this.properties = null; this.tempMatrix = new Matrix(); - this.CONTEXT_UID = 0; - } - - /** - * When there is a WebGL context change - * - * @private - */ - onContextChange() - { - const gl = this.renderer.gl; - - this.CONTEXT_UID = this.renderer.CONTEXT_UID; - - // setup default shader - this.shader = new ParticleShader(gl); - this.properties = [ // verticesData { - attribute: this.shader.attributes.aVertexPosition, + attributeName: 'aVertexPosition', size: 2, uploadFunction: this.uploadVertices, offset: 0, }, // positionData { - attribute: this.shader.attributes.aPositionCoord, + attributeName: 'aPositionCoord', size: 2, uploadFunction: this.uploadPosition, offset: 0, }, // rotationData { - attribute: this.shader.attributes.aRotation, + attributeName: 'aRotation', size: 1, uploadFunction: this.uploadRotation, offset: 0, }, // uvsData { - attribute: this.shader.attributes.aTextureCoord, + attributeName: 'aTextureCoord', size: 2, uploadFunction: this.uploadUvs, offset: 0, }, // tintData { - attribute: this.shader.attributes.aColor, + attributeName: 'aColor', size: 1, - unsignedByte: true, + type: TYPES.UNSIGNED_BYTE, uploadFunction: this.uploadTint, offset: 0, }, ]; - } - /** - * Starts a new particle batch. - * - */ - start() - { - this.renderer.shader.bind(this.shader); + this.shader = Shader.from(vertex, fragment, {}); } /** @@ -137,11 +113,11 @@ totalChildren = maxSize; } - let buffers = container._glBuffers[renderer.CONTEXT_UID]; + let buffers = container._buffers; if (!buffers) { - buffers = container._glBuffers[renderer.CONTEXT_UID] = this.generateBuffers(container); + buffers = container._buffers = this.generateBuffers(container); } const baseTexture = children[0]._texture.baseTexture; @@ -153,15 +129,16 @@ const m = container.worldTransform.copyTo(this.tempMatrix); - m.prepend(renderer._activeRenderTarget.projectionMatrix); + m.prepend(renderer.globalUniforms.uniforms.projectionMatrix); - this.shader.uniforms.projectionMatrix = m.toArray(true); + this.shader.uniforms.translationMatrix = m.toArray(true); this.shader.uniforms.uColor = premultiplyRgba(container.tintRgb, container.worldAlpha, this.shader.uniforms.uColor, baseTexture.premultiplyAlpha); - // make sure the texture is bound.. - this.shader.uniforms.uSampler = renderer.bindTexture(baseTexture); + this.shader.uniforms.uSampler = baseTexture; + + this.renderer.shader.bind(this.shader); // now lets upload and render the buffers.. for (let i = 0, j = 0; i < totalChildren; i += batchSize, j += 1) @@ -195,8 +172,8 @@ } // bind the buffer - renderer.bindVao(buffer.vao); - buffer.vao.draw(gl.TRIANGLES, amount * 6); + renderer.geometry.bind(buffer.geometry); + gl.drawElements(gl.TRIANGLES, amount * 6, gl.UNSIGNED_SHORT, 0); } } @@ -208,7 +185,6 @@ */ generateBuffers(container) { - const gl = this.renderer.gl; const buffers = []; const size = container._maxSize; const batchSize = container._batchSize; @@ -216,7 +192,7 @@ for (let i = 0; i < size; i += batchSize) { - buffers.push(new ParticleBuffer(gl, this.properties, dynamicPropertyFlags, batchSize)); + buffers.push(new ParticleBuffer(this.properties, dynamicPropertyFlags, batchSize)); } return buffers; @@ -231,11 +207,10 @@ */ _generateOneMoreBuffer(container) { - const gl = this.renderer.gl; const batchSize = container._batchSize; const dynamicPropertyFlags = container._properties; - return new ParticleBuffer(gl, this.properties, dynamicPropertyFlags, batchSize); + return new ParticleBuffer(this.properties, dynamicPropertyFlags, batchSize); } /** @@ -440,11 +415,6 @@ */ destroy() { - if (this.renderer.gl) - { - this.renderer.gl.deleteBuffer(this.indexBuffer); - } - super.destroy(); if (this.shader) @@ -453,7 +423,6 @@ this.shader = null; } - this.indices = null; this.tempMatrix = null; } } diff --git a/packages/particles/src/index.js b/packages/particles/src/index.js index b3abe5c..d315119 100644 --- a/packages/particles/src/index.js +++ b/packages/particles/src/index.js @@ -1,2 +1,2 @@ -// export { default as ParticleContainer } from './ParticleContainer'; -// export { default as ParticleRenderer } from './ParticleRenderer'; +export { default as ParticleContainer } from './ParticleContainer'; +export { default as ParticleRenderer } from './ParticleRenderer'; diff --git a/bundles/pixi.js-legacy/package.json b/bundles/pixi.js-legacy/package.json index 56d8e1a..a0e6aa8 100644 --- a/bundles/pixi.js-legacy/package.json +++ b/bundles/pixi.js-legacy/package.json @@ -32,6 +32,7 @@ "@pixi/canvas-extract": "^5.0.0-alpha", "@pixi/canvas-graphics": "^5.0.0-alpha", "@pixi/canvas-mesh": "^5.0.0-alpha", + "@pixi/canvas-particles": "^5.0.0-alpha", "@pixi/canvas-prepare": "^5.0.0-alpha", "@pixi/canvas-renderer": "^5.0.0-alpha", "@pixi/canvas-sprite": "^5.0.0-alpha", diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js index b29ba1e..6c9d2b8 100644 --- a/bundles/pixi.js-legacy/src/index.js +++ b/bundles/pixi.js-legacy/src/index.js @@ -8,6 +8,7 @@ import * as canvasExtract from '@pixi/canvas-extract'; import * as canvasPrepare from '@pixi/canvas-prepare'; import '@pixi/canvas-sprite-tiling'; +import '@pixi/canvas-particles'; import '@pixi/canvas-display'; CanvasRenderer.registerPlugin('accessibility', PIXI.accessibility.AccessibilityManager); diff --git a/bundles/pixi.js/src/index.js b/bundles/pixi.js/src/index.js index a879872..fb839a0 100644 --- a/bundles/pixi.js/src/index.js +++ b/bundles/pixi.js/src/index.js @@ -9,7 +9,7 @@ import * as loaders from '@pixi/loaders'; import * as math from '@pixi/math'; import * as mesh from '@pixi/mesh'; -// import * as particles from '@pixi/particles'; +import * as particles from '@pixi/particles'; import * as prepare from '@pixi/prepare'; import * as sprite from '@pixi/sprite'; import * as spriteAnimated from '@pixi/sprite-animated'; @@ -38,7 +38,7 @@ core.Renderer.registerPlugin('graphics', graphics.GraphicsRenderer); core.Renderer.registerPlugin('interaction', interaction.InteractionManager); core.Renderer.registerPlugin('mesh', mesh.MeshRenderer); -// core.Renderer.registerPlugin('particle', particles.ParticleRenderer); +core.Renderer.registerPlugin('particle', particles.ParticleRenderer); core.Renderer.registerPlugin('prepare', prepare.Prepare); core.Renderer.registerPlugin('sprite', sprite.SpriteRenderer); core.Renderer.registerPlugin('tilingSprite', spriteTiling.TilingSpriteRenderer); @@ -120,7 +120,7 @@ loaders, math, mesh, - // particles, + particles, sprite, spriteAnimated, spritesheet, diff --git a/packages/canvas/canvas-particles/LICENSE b/packages/canvas/canvas-particles/LICENSE new file mode 100644 index 0000000..148e3eb --- /dev/null +++ b/packages/canvas/canvas-particles/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2013-2018 Mathew Groves, Chad Engler + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/packages/canvas/canvas-particles/README.md b/packages/canvas/canvas-particles/README.md new file mode 100644 index 0000000..5560aea --- /dev/null +++ b/packages/canvas/canvas-particles/README.md @@ -0,0 +1,13 @@ +# @pixi/canvas-sprite-tiling + +## Installation + +```bash +npm install @pixi/canvas-sprite-tiling +``` + +## Usage + +```js +import '@pixi/canvas-sprite-tiling'; +``` \ No newline at end of file diff --git a/packages/canvas/canvas-particles/package.json b/packages/canvas/canvas-particles/package.json new file mode 100644 index 0000000..22c5b71 --- /dev/null +++ b/packages/canvas/canvas-particles/package.json @@ -0,0 +1,30 @@ +{ + "name": "@pixi/canvas-particles", + "version": "5.0.0-alpha", + "main": "lib/canvas-sprite-tiling.js", + "module": "lib/canvas-sprite-tiling.es.js", + "description": "Support for legacy browser JavaScript environments", + "author": "Mat Groves", + "contributors": [ + "Matt Karl " + ], + "homepage": "http://pixijs.com/", + "bugs": "https://github.com/pixijs/pixi.js/issues", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/pixijs/pixi.js.git" + }, + "publishConfig": { + "access": "public" + }, + "files": [ + "lib" + ], + "dependencies": { + "@pixi/particles": "^5.0.0-alpha" + }, + "devDependencies": { + "floss": "^2.1.3" + } +} diff --git a/packages/canvas/canvas-particles/src/ParticleContainer.js b/packages/canvas/canvas-particles/src/ParticleContainer.js new file mode 100644 index 0000000..9145c56 --- /dev/null +++ b/packages/canvas/canvas-particles/src/ParticleContainer.js @@ -0,0 +1,123 @@ +import { ParticleContainer } from '@pixi/particles'; + +/** + * Renders the object using the Canvas renderer + * + * @private + * @param {PIXI.CanvasRenderer} renderer - a reference to the canvas renderer + */ +ParticleContainer.prototype.renderCanvas = function renderCanvas(renderer) +{ + if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable) + { + return; + } + + const context = renderer.context; + const transform = this.worldTransform; + let isRotated = true; + + let positionX = 0; + let positionY = 0; + + let finalWidth = 0; + let finalHeight = 0; + + renderer.setBlendMode(this.blendMode); + + context.globalAlpha = this.worldAlpha; + + this.displayObjectUpdateTransform(); + + for (let i = 0; i < this.children.length; ++i) + { + const child = this.children[i]; + + if (!child.visible) + { + continue; + } + + const frame = child._texture.frame; + + context.globalAlpha = this.worldAlpha * child.alpha; + + if (child.rotation % (Math.PI * 2) === 0) + { + // this is the fastest way to optimise! - if rotation is 0 then we can avoid any kind of setTransform call + if (isRotated) + { + context.setTransform( + transform.a, + transform.b, + transform.c, + transform.d, + transform.tx * renderer.resolution, + transform.ty * renderer.resolution + ); + + isRotated = false; + } + + positionX = ((child.anchor.x) * (-frame.width * child.scale.x)) + child.position.x + 0.5; + positionY = ((child.anchor.y) * (-frame.height * child.scale.y)) + child.position.y + 0.5; + + finalWidth = frame.width * child.scale.x; + finalHeight = frame.height * child.scale.y; + } + else + { + if (!isRotated) + { + isRotated = true; + } + + child.displayObjectUpdateTransform(); + + const childTransform = child.worldTransform; + + if (renderer.roundPixels) + { + context.setTransform( + childTransform.a, + childTransform.b, + childTransform.c, + childTransform.d, + (childTransform.tx * renderer.resolution) | 0, + (childTransform.ty * renderer.resolution) | 0 + ); + } + else + { + context.setTransform( + childTransform.a, + childTransform.b, + childTransform.c, + childTransform.d, + childTransform.tx * renderer.resolution, + childTransform.ty * renderer.resolution + ); + } + + positionX = ((child.anchor.x) * (-frame.width)) + 0.5; + positionY = ((child.anchor.y) * (-frame.height)) + 0.5; + + finalWidth = frame.width; + finalHeight = frame.height; + } + + const resolution = child._texture.baseTexture.resolution; + + context.drawImage( + child._texture.baseTexture.source, + frame.x * resolution, + frame.y * resolution, + frame.width * resolution, + frame.height * resolution, + positionX * renderer.resolution, + positionY * renderer.resolution, + finalWidth * renderer.resolution, + finalHeight * renderer.resolution + ); + } +}; diff --git a/packages/canvas/canvas-particles/src/index.js b/packages/canvas/canvas-particles/src/index.js new file mode 100644 index 0000000..2ea3720 --- /dev/null +++ b/packages/canvas/canvas-particles/src/index.js @@ -0,0 +1 @@ +import './ParticleContainer'; diff --git a/packages/core/src/renderers/systems/geometry/GeometrySystem.js b/packages/core/src/renderers/systems/geometry/GeometrySystem.js index d205a6d..26c8e9e 100644 --- a/packages/core/src/renderers/systems/geometry/GeometrySystem.js +++ b/packages/core/src/renderers/systems/geometry/GeometrySystem.js @@ -145,6 +145,11 @@ this.updateBuffers(); } + reset() + { + this.unbind(); + } + updateBuffers() { const geometry = this._activeGeometry; diff --git a/packages/particles/src/ParticleBuffer.js b/packages/particles/src/ParticleBuffer.js index 6306bda..68f5dc8 100644 --- a/packages/particles/src/ParticleBuffer.js +++ b/packages/particles/src/ParticleBuffer.js @@ -1,6 +1,6 @@ -// import { VertexArrayObject } from 'pixi-gl-core'; import { createIndicesForQuads } from '@pixi/utils'; -import { GLBuffer } from 'pixi-gl-core'; +import { Geometry, Buffer } from '@pixi/core'; +import { TYPES } from '@pixi/constants'; /** * @author Mat Groves @@ -24,19 +24,15 @@ export default class ParticleBuffer { /** - * @param {WebGLRenderingContext} gl - The rendering context. * @param {object} properties - The properties to upload. * @param {boolean[]} dynamicPropertyFlags - Flags for which properties are dynamic. * @param {number} size - The size of the batch. */ - constructor(gl, properties, dynamicPropertyFlags, size) + constructor(properties, dynamicPropertyFlags, size) { - /** - * The current WebGL drawing context. - * - * @member {WebGLRenderingContext} - */ - this.gl = gl; + this.geometry = new Geometry(); + + this.indexBuffer = null; /** * The number of particles the buffer can hold @@ -66,10 +62,10 @@ // Make copy of properties object so that when we edit the offset it doesn't // change all other instances of the object literal property = { - attribute: property.attribute, + attributeName: property.attributeName, size: property.size, uploadFunction: property.uploadFunction, - unsignedByte: property.unsignedByte, + type: property.type || TYPES.FLOAT, offset: property.offset, }; @@ -103,7 +99,8 @@ */ initBuffers() { - const gl = this.gl; + const geometry = this.geometry; + let dynamicOffset = 0; /** @@ -111,8 +108,8 @@ * * @member {Uint16Array} */ - this.indices = createIndicesForQuads(this.size); - this.indexBuffer = GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW); + this.indexBuffer = new Buffer(createIndicesForQuads(this.size), true, true); + geometry.addIndex(this.indexBuffer); this.dynamicStride = 0; @@ -125,8 +122,11 @@ this.dynamicStride += property.size; } - this.dynamicData = new Float32Array(this.size * this.dynamicStride * 4); - this.dynamicBuffer = GLBuffer.createVertexBuffer(gl, this.dynamicData, gl.STREAM_DRAW); + const dynBuffer = new ArrayBuffer(this.size * this.dynamicStride * 4 * 4); + + this.dynamicData = new Float32Array(dynBuffer); + this.dynamicDataUint32 = new Uint32Array(dynBuffer); + this.dynamicBuffer = new Buffer(this.dynamicData, false, false); // static // let staticOffset = 0; @@ -142,66 +142,40 @@ this.staticStride += property.size; } - this.staticData = new Float32Array(this.size * this.staticStride * 4); - this.staticBuffer = GLBuffer.createVertexBuffer(gl, this.staticData, gl.STATIC_DRAW); + const statBuffer = new ArrayBuffer(this.size * this.staticStride * 4 * 4); - // this.vao = new VertexArrayObject(gl) - // .addIndex(this.indexBuffer); + this.staticData = new Float32Array(statBuffer); + this.staticDataUint32 = new Uint32Array(statBuffer); + this.staticBuffer = new Buffer(this.staticData, true, false); for (let i = 0; i < this.dynamicProperties.length; ++i) { const property = this.dynamicProperties[i]; - if (property.unsignedByte) - { - this.vao.addAttribute( - this.dynamicBuffer, - property.attribute, - gl.UNSIGNED_BYTE, - true, - this.dynamicStride * 4, - property.offset * 4 - ); - } - else - { - this.vao.addAttribute( - this.dynamicBuffer, - property.attribute, - gl.FLOAT, - false, - this.dynamicStride * 4, - property.offset * 4 - ); - } + geometry.addAttribute( + property.attributeName, + this.dynamicBuffer, + 0, + property.type === TYPES.UNSIGNED_BYTE, + property.type, + this.dynamicStride * 4, + property.offset * 4 + ); } for (let i = 0; i < this.staticProperties.length; ++i) { const property = this.staticProperties[i]; - if (property.unsignedByte) - { - this.vao.addAttribute( - this.staticBuffer, - property.attribute, - gl.UNSIGNED_BYTE, - true, - this.staticStride * 4, - property.offset * 4 - ); - } - else - { - this.vao.addAttribute( - this.staticBuffer, - property.attribute, - gl.FLOAT, - false, - this.staticStride * 4, - property.offset * 4 - ); - } + geometry.addAttribute( + property.attributeName, + this.staticBuffer, + 0, + property.type === TYPES.UNSIGNED_BYTE, + property.type, + this.staticStride * 4, + property.offset * 4 + ); } } @@ -219,11 +193,11 @@ const property = this.dynamicProperties[i]; property.uploadFunction(children, startIndex, amount, - property.unsignedByte ? this.dynamicDataUint32 : this.dynamicData, + property.type === TYPES.UNSIGNED_BYTE ? this.dynamicDataUint32 : this.dynamicData, this.dynamicStride, property.offset); } - this.dynamicBuffer.upload(); + this.dynamicBuffer._updateID++; } /** @@ -240,11 +214,11 @@ const property = this.staticProperties[i]; property.uploadFunction(children, startIndex, amount, - property.unsignedByte ? this.staticDataUint32 : this.staticData, + property.type === TYPES.UNSIGNED_BYTE ? this.staticDataUint32 : this.staticData, this.staticStride, property.offset); } - this.staticBuffer.upload(); + this.staticBuffer._updateID++; } /** @@ -253,16 +227,20 @@ */ destroy() { + this.indexBuffer = null; + this.dynamicProperties = null; - this.dynamicBuffer.destroy(); + // this.dynamicBuffer.destroy(); this.dynamicBuffer = null; this.dynamicData = null; this.dynamicDataUint32 = null; this.staticProperties = null; - this.staticBuffer.destroy(); + // this.staticBuffer.destroy(); this.staticBuffer = null; this.staticData = null; this.staticDataUint32 = null; + // all buffers are destroyed inside geometry + this.geometry.destroy(); } } diff --git a/packages/particles/src/ParticleContainer.js b/packages/particles/src/ParticleContainer.js index 1235474..3a36e98 100644 --- a/packages/particles/src/ParticleContainer.js +++ b/packages/particles/src/ParticleContainer.js @@ -83,10 +83,10 @@ this._batchSize = batchSize; /** - * @member {object} + * @member {Array} * @private */ - this._glBuffers = {}; + this._buffers = null; /** * @member {number} @@ -240,125 +240,16 @@ } } - /** - * Renders the object using the Canvas renderer - * - * @private - * @param {PIXI.CanvasRenderer} renderer - The canvas renderer - */ - renderCanvas(renderer) + dispose() { - if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable) + if (this._buffers) { - return; - } - - const context = renderer.context; - const transform = this.worldTransform; - let isRotated = true; - - let positionX = 0; - let positionY = 0; - - let finalWidth = 0; - let finalHeight = 0; - - renderer.setBlendMode(this.blendMode); - - context.globalAlpha = this.worldAlpha; - - this.displayObjectUpdateTransform(); - - for (let i = 0; i < this.children.length; ++i) - { - const child = this.children[i]; - - if (!child.visible) + for (let i = 0; i < this._buffers.length; ++i) { - continue; + this._buffers[i].destroy(); } - const frame = child._texture.frame; - - context.globalAlpha = this.worldAlpha * child.alpha; - - if (child.rotation % (Math.PI * 2) === 0) - { - // this is the fastest way to optimise! - if rotation is 0 then we can avoid any kind of setTransform call - if (isRotated) - { - context.setTransform( - transform.a, - transform.b, - transform.c, - transform.d, - transform.tx * renderer.resolution, - transform.ty * renderer.resolution - ); - - isRotated = false; - } - - positionX = ((child.anchor.x) * (-frame.width * child.scale.x)) + child.position.x + 0.5; - positionY = ((child.anchor.y) * (-frame.height * child.scale.y)) + child.position.y + 0.5; - - finalWidth = frame.width * child.scale.x; - finalHeight = frame.height * child.scale.y; - } - else - { - if (!isRotated) - { - isRotated = true; - } - - child.displayObjectUpdateTransform(); - - const childTransform = child.worldTransform; - - if (renderer.roundPixels) - { - context.setTransform( - childTransform.a, - childTransform.b, - childTransform.c, - childTransform.d, - (childTransform.tx * renderer.resolution) | 0, - (childTransform.ty * renderer.resolution) | 0 - ); - } - else - { - context.setTransform( - childTransform.a, - childTransform.b, - childTransform.c, - childTransform.d, - childTransform.tx * renderer.resolution, - childTransform.ty * renderer.resolution - ); - } - - positionX = ((child.anchor.x) * (-frame.width)) + 0.5; - positionY = ((child.anchor.y) * (-frame.height)) + 0.5; - - finalWidth = frame.width; - finalHeight = frame.height; - } - - const resolution = child._texture.baseTexture.resolution; - - context.drawImage( - child._texture.baseTexture.source, - frame.x * resolution, - frame.y * resolution, - frame.width * resolution, - frame.height * resolution, - positionX * renderer.resolution, - positionY * renderer.resolution, - finalWidth * renderer.resolution, - finalHeight * renderer.resolution - ); + this._buffers = null; } } @@ -378,15 +269,8 @@ { super.destroy(options); - if (this._buffers) - { - for (let i = 0; i < this._buffers.length; ++i) - { - this._buffers[i].destroy(); - } - } + this.dispose(); this._properties = null; - this._buffers = null; } } diff --git a/packages/particles/src/ParticleRenderer.js b/packages/particles/src/ParticleRenderer.js index a2ceaee..9c7ac97 100644 --- a/packages/particles/src/ParticleRenderer.js +++ b/packages/particles/src/ParticleRenderer.js @@ -1,8 +1,10 @@ -import { ObjectRenderer } from '@pixi/core'; +import { TYPES } from '@pixi/constants'; +import { ObjectRenderer, Shader } from '@pixi/core'; import { correctBlendMode, premultiplyRgba, premultiplyTint } from '@pixi/utils'; import { Matrix } from '@pixi/math'; -import ParticleShader from './ParticleShader'; import ParticleBuffer from './ParticleBuffer'; +import vertex from './particles.vert'; +import fragment from './particles.frag'; /** * @author Mat Groves @@ -43,76 +45,50 @@ */ this.shader = null; - this.indexBuffer = null; - this.properties = null; this.tempMatrix = new Matrix(); - this.CONTEXT_UID = 0; - } - - /** - * When there is a WebGL context change - * - * @private - */ - onContextChange() - { - const gl = this.renderer.gl; - - this.CONTEXT_UID = this.renderer.CONTEXT_UID; - - // setup default shader - this.shader = new ParticleShader(gl); - this.properties = [ // verticesData { - attribute: this.shader.attributes.aVertexPosition, + attributeName: 'aVertexPosition', size: 2, uploadFunction: this.uploadVertices, offset: 0, }, // positionData { - attribute: this.shader.attributes.aPositionCoord, + attributeName: 'aPositionCoord', size: 2, uploadFunction: this.uploadPosition, offset: 0, }, // rotationData { - attribute: this.shader.attributes.aRotation, + attributeName: 'aRotation', size: 1, uploadFunction: this.uploadRotation, offset: 0, }, // uvsData { - attribute: this.shader.attributes.aTextureCoord, + attributeName: 'aTextureCoord', size: 2, uploadFunction: this.uploadUvs, offset: 0, }, // tintData { - attribute: this.shader.attributes.aColor, + attributeName: 'aColor', size: 1, - unsignedByte: true, + type: TYPES.UNSIGNED_BYTE, uploadFunction: this.uploadTint, offset: 0, }, ]; - } - /** - * Starts a new particle batch. - * - */ - start() - { - this.renderer.shader.bind(this.shader); + this.shader = Shader.from(vertex, fragment, {}); } /** @@ -137,11 +113,11 @@ totalChildren = maxSize; } - let buffers = container._glBuffers[renderer.CONTEXT_UID]; + let buffers = container._buffers; if (!buffers) { - buffers = container._glBuffers[renderer.CONTEXT_UID] = this.generateBuffers(container); + buffers = container._buffers = this.generateBuffers(container); } const baseTexture = children[0]._texture.baseTexture; @@ -153,15 +129,16 @@ const m = container.worldTransform.copyTo(this.tempMatrix); - m.prepend(renderer._activeRenderTarget.projectionMatrix); + m.prepend(renderer.globalUniforms.uniforms.projectionMatrix); - this.shader.uniforms.projectionMatrix = m.toArray(true); + this.shader.uniforms.translationMatrix = m.toArray(true); this.shader.uniforms.uColor = premultiplyRgba(container.tintRgb, container.worldAlpha, this.shader.uniforms.uColor, baseTexture.premultiplyAlpha); - // make sure the texture is bound.. - this.shader.uniforms.uSampler = renderer.bindTexture(baseTexture); + this.shader.uniforms.uSampler = baseTexture; + + this.renderer.shader.bind(this.shader); // now lets upload and render the buffers.. for (let i = 0, j = 0; i < totalChildren; i += batchSize, j += 1) @@ -195,8 +172,8 @@ } // bind the buffer - renderer.bindVao(buffer.vao); - buffer.vao.draw(gl.TRIANGLES, amount * 6); + renderer.geometry.bind(buffer.geometry); + gl.drawElements(gl.TRIANGLES, amount * 6, gl.UNSIGNED_SHORT, 0); } } @@ -208,7 +185,6 @@ */ generateBuffers(container) { - const gl = this.renderer.gl; const buffers = []; const size = container._maxSize; const batchSize = container._batchSize; @@ -216,7 +192,7 @@ for (let i = 0; i < size; i += batchSize) { - buffers.push(new ParticleBuffer(gl, this.properties, dynamicPropertyFlags, batchSize)); + buffers.push(new ParticleBuffer(this.properties, dynamicPropertyFlags, batchSize)); } return buffers; @@ -231,11 +207,10 @@ */ _generateOneMoreBuffer(container) { - const gl = this.renderer.gl; const batchSize = container._batchSize; const dynamicPropertyFlags = container._properties; - return new ParticleBuffer(gl, this.properties, dynamicPropertyFlags, batchSize); + return new ParticleBuffer(this.properties, dynamicPropertyFlags, batchSize); } /** @@ -440,11 +415,6 @@ */ destroy() { - if (this.renderer.gl) - { - this.renderer.gl.deleteBuffer(this.indexBuffer); - } - super.destroy(); if (this.shader) @@ -453,7 +423,6 @@ this.shader = null; } - this.indices = null; this.tempMatrix = null; } } diff --git a/packages/particles/src/index.js b/packages/particles/src/index.js index b3abe5c..d315119 100644 --- a/packages/particles/src/index.js +++ b/packages/particles/src/index.js @@ -1,2 +1,2 @@ -// export { default as ParticleContainer } from './ParticleContainer'; -// export { default as ParticleRenderer } from './ParticleRenderer'; +export { default as ParticleContainer } from './ParticleContainer'; +export { default as ParticleRenderer } from './ParticleRenderer'; diff --git a/packages/particles/src/particles.vert b/packages/particles/src/particles.vert index 209e14d..f65b26b 100644 --- a/packages/particles/src/particles.vert +++ b/packages/particles/src/particles.vert @@ -5,7 +5,7 @@ attribute vec2 aPositionCoord; attribute float aRotation; -uniform mat3 projectionMatrix; +uniform mat3 translationMatrix; uniform vec4 uColor; varying vec2 vTextureCoord; @@ -18,8 +18,8 @@ vec2 v = vec2(x, y); v = v + aPositionCoord; - gl_Position = vec4((projectionMatrix * vec3(v, 1.0)).xy, 0.0, 1.0); + gl_Position = vec4((translationMatrix * vec3(v, 1.0)).xy, 0.0, 1.0); vTextureCoord = aTextureCoord; vColor = aColor * uColor; -} \ No newline at end of file +} diff --git a/bundles/pixi.js-legacy/package.json b/bundles/pixi.js-legacy/package.json index 56d8e1a..a0e6aa8 100644 --- a/bundles/pixi.js-legacy/package.json +++ b/bundles/pixi.js-legacy/package.json @@ -32,6 +32,7 @@ "@pixi/canvas-extract": "^5.0.0-alpha", "@pixi/canvas-graphics": "^5.0.0-alpha", "@pixi/canvas-mesh": "^5.0.0-alpha", + "@pixi/canvas-particles": "^5.0.0-alpha", "@pixi/canvas-prepare": "^5.0.0-alpha", "@pixi/canvas-renderer": "^5.0.0-alpha", "@pixi/canvas-sprite": "^5.0.0-alpha", diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js index b29ba1e..6c9d2b8 100644 --- a/bundles/pixi.js-legacy/src/index.js +++ b/bundles/pixi.js-legacy/src/index.js @@ -8,6 +8,7 @@ import * as canvasExtract from '@pixi/canvas-extract'; import * as canvasPrepare from '@pixi/canvas-prepare'; import '@pixi/canvas-sprite-tiling'; +import '@pixi/canvas-particles'; import '@pixi/canvas-display'; CanvasRenderer.registerPlugin('accessibility', PIXI.accessibility.AccessibilityManager); diff --git a/bundles/pixi.js/src/index.js b/bundles/pixi.js/src/index.js index a879872..fb839a0 100644 --- a/bundles/pixi.js/src/index.js +++ b/bundles/pixi.js/src/index.js @@ -9,7 +9,7 @@ import * as loaders from '@pixi/loaders'; import * as math from '@pixi/math'; import * as mesh from '@pixi/mesh'; -// import * as particles from '@pixi/particles'; +import * as particles from '@pixi/particles'; import * as prepare from '@pixi/prepare'; import * as sprite from '@pixi/sprite'; import * as spriteAnimated from '@pixi/sprite-animated'; @@ -38,7 +38,7 @@ core.Renderer.registerPlugin('graphics', graphics.GraphicsRenderer); core.Renderer.registerPlugin('interaction', interaction.InteractionManager); core.Renderer.registerPlugin('mesh', mesh.MeshRenderer); -// core.Renderer.registerPlugin('particle', particles.ParticleRenderer); +core.Renderer.registerPlugin('particle', particles.ParticleRenderer); core.Renderer.registerPlugin('prepare', prepare.Prepare); core.Renderer.registerPlugin('sprite', sprite.SpriteRenderer); core.Renderer.registerPlugin('tilingSprite', spriteTiling.TilingSpriteRenderer); @@ -120,7 +120,7 @@ loaders, math, mesh, - // particles, + particles, sprite, spriteAnimated, spritesheet, diff --git a/packages/canvas/canvas-particles/LICENSE b/packages/canvas/canvas-particles/LICENSE new file mode 100644 index 0000000..148e3eb --- /dev/null +++ b/packages/canvas/canvas-particles/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2013-2018 Mathew Groves, Chad Engler + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/packages/canvas/canvas-particles/README.md b/packages/canvas/canvas-particles/README.md new file mode 100644 index 0000000..5560aea --- /dev/null +++ b/packages/canvas/canvas-particles/README.md @@ -0,0 +1,13 @@ +# @pixi/canvas-sprite-tiling + +## Installation + +```bash +npm install @pixi/canvas-sprite-tiling +``` + +## Usage + +```js +import '@pixi/canvas-sprite-tiling'; +``` \ No newline at end of file diff --git a/packages/canvas/canvas-particles/package.json b/packages/canvas/canvas-particles/package.json new file mode 100644 index 0000000..22c5b71 --- /dev/null +++ b/packages/canvas/canvas-particles/package.json @@ -0,0 +1,30 @@ +{ + "name": "@pixi/canvas-particles", + "version": "5.0.0-alpha", + "main": "lib/canvas-sprite-tiling.js", + "module": "lib/canvas-sprite-tiling.es.js", + "description": "Support for legacy browser JavaScript environments", + "author": "Mat Groves", + "contributors": [ + "Matt Karl " + ], + "homepage": "http://pixijs.com/", + "bugs": "https://github.com/pixijs/pixi.js/issues", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/pixijs/pixi.js.git" + }, + "publishConfig": { + "access": "public" + }, + "files": [ + "lib" + ], + "dependencies": { + "@pixi/particles": "^5.0.0-alpha" + }, + "devDependencies": { + "floss": "^2.1.3" + } +} diff --git a/packages/canvas/canvas-particles/src/ParticleContainer.js b/packages/canvas/canvas-particles/src/ParticleContainer.js new file mode 100644 index 0000000..9145c56 --- /dev/null +++ b/packages/canvas/canvas-particles/src/ParticleContainer.js @@ -0,0 +1,123 @@ +import { ParticleContainer } from '@pixi/particles'; + +/** + * Renders the object using the Canvas renderer + * + * @private + * @param {PIXI.CanvasRenderer} renderer - a reference to the canvas renderer + */ +ParticleContainer.prototype.renderCanvas = function renderCanvas(renderer) +{ + if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable) + { + return; + } + + const context = renderer.context; + const transform = this.worldTransform; + let isRotated = true; + + let positionX = 0; + let positionY = 0; + + let finalWidth = 0; + let finalHeight = 0; + + renderer.setBlendMode(this.blendMode); + + context.globalAlpha = this.worldAlpha; + + this.displayObjectUpdateTransform(); + + for (let i = 0; i < this.children.length; ++i) + { + const child = this.children[i]; + + if (!child.visible) + { + continue; + } + + const frame = child._texture.frame; + + context.globalAlpha = this.worldAlpha * child.alpha; + + if (child.rotation % (Math.PI * 2) === 0) + { + // this is the fastest way to optimise! - if rotation is 0 then we can avoid any kind of setTransform call + if (isRotated) + { + context.setTransform( + transform.a, + transform.b, + transform.c, + transform.d, + transform.tx * renderer.resolution, + transform.ty * renderer.resolution + ); + + isRotated = false; + } + + positionX = ((child.anchor.x) * (-frame.width * child.scale.x)) + child.position.x + 0.5; + positionY = ((child.anchor.y) * (-frame.height * child.scale.y)) + child.position.y + 0.5; + + finalWidth = frame.width * child.scale.x; + finalHeight = frame.height * child.scale.y; + } + else + { + if (!isRotated) + { + isRotated = true; + } + + child.displayObjectUpdateTransform(); + + const childTransform = child.worldTransform; + + if (renderer.roundPixels) + { + context.setTransform( + childTransform.a, + childTransform.b, + childTransform.c, + childTransform.d, + (childTransform.tx * renderer.resolution) | 0, + (childTransform.ty * renderer.resolution) | 0 + ); + } + else + { + context.setTransform( + childTransform.a, + childTransform.b, + childTransform.c, + childTransform.d, + childTransform.tx * renderer.resolution, + childTransform.ty * renderer.resolution + ); + } + + positionX = ((child.anchor.x) * (-frame.width)) + 0.5; + positionY = ((child.anchor.y) * (-frame.height)) + 0.5; + + finalWidth = frame.width; + finalHeight = frame.height; + } + + const resolution = child._texture.baseTexture.resolution; + + context.drawImage( + child._texture.baseTexture.source, + frame.x * resolution, + frame.y * resolution, + frame.width * resolution, + frame.height * resolution, + positionX * renderer.resolution, + positionY * renderer.resolution, + finalWidth * renderer.resolution, + finalHeight * renderer.resolution + ); + } +}; diff --git a/packages/canvas/canvas-particles/src/index.js b/packages/canvas/canvas-particles/src/index.js new file mode 100644 index 0000000..2ea3720 --- /dev/null +++ b/packages/canvas/canvas-particles/src/index.js @@ -0,0 +1 @@ +import './ParticleContainer'; diff --git a/packages/core/src/renderers/systems/geometry/GeometrySystem.js b/packages/core/src/renderers/systems/geometry/GeometrySystem.js index d205a6d..26c8e9e 100644 --- a/packages/core/src/renderers/systems/geometry/GeometrySystem.js +++ b/packages/core/src/renderers/systems/geometry/GeometrySystem.js @@ -145,6 +145,11 @@ this.updateBuffers(); } + reset() + { + this.unbind(); + } + updateBuffers() { const geometry = this._activeGeometry; diff --git a/packages/particles/src/ParticleBuffer.js b/packages/particles/src/ParticleBuffer.js index 6306bda..68f5dc8 100644 --- a/packages/particles/src/ParticleBuffer.js +++ b/packages/particles/src/ParticleBuffer.js @@ -1,6 +1,6 @@ -// import { VertexArrayObject } from 'pixi-gl-core'; import { createIndicesForQuads } from '@pixi/utils'; -import { GLBuffer } from 'pixi-gl-core'; +import { Geometry, Buffer } from '@pixi/core'; +import { TYPES } from '@pixi/constants'; /** * @author Mat Groves @@ -24,19 +24,15 @@ export default class ParticleBuffer { /** - * @param {WebGLRenderingContext} gl - The rendering context. * @param {object} properties - The properties to upload. * @param {boolean[]} dynamicPropertyFlags - Flags for which properties are dynamic. * @param {number} size - The size of the batch. */ - constructor(gl, properties, dynamicPropertyFlags, size) + constructor(properties, dynamicPropertyFlags, size) { - /** - * The current WebGL drawing context. - * - * @member {WebGLRenderingContext} - */ - this.gl = gl; + this.geometry = new Geometry(); + + this.indexBuffer = null; /** * The number of particles the buffer can hold @@ -66,10 +62,10 @@ // Make copy of properties object so that when we edit the offset it doesn't // change all other instances of the object literal property = { - attribute: property.attribute, + attributeName: property.attributeName, size: property.size, uploadFunction: property.uploadFunction, - unsignedByte: property.unsignedByte, + type: property.type || TYPES.FLOAT, offset: property.offset, }; @@ -103,7 +99,8 @@ */ initBuffers() { - const gl = this.gl; + const geometry = this.geometry; + let dynamicOffset = 0; /** @@ -111,8 +108,8 @@ * * @member {Uint16Array} */ - this.indices = createIndicesForQuads(this.size); - this.indexBuffer = GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW); + this.indexBuffer = new Buffer(createIndicesForQuads(this.size), true, true); + geometry.addIndex(this.indexBuffer); this.dynamicStride = 0; @@ -125,8 +122,11 @@ this.dynamicStride += property.size; } - this.dynamicData = new Float32Array(this.size * this.dynamicStride * 4); - this.dynamicBuffer = GLBuffer.createVertexBuffer(gl, this.dynamicData, gl.STREAM_DRAW); + const dynBuffer = new ArrayBuffer(this.size * this.dynamicStride * 4 * 4); + + this.dynamicData = new Float32Array(dynBuffer); + this.dynamicDataUint32 = new Uint32Array(dynBuffer); + this.dynamicBuffer = new Buffer(this.dynamicData, false, false); // static // let staticOffset = 0; @@ -142,66 +142,40 @@ this.staticStride += property.size; } - this.staticData = new Float32Array(this.size * this.staticStride * 4); - this.staticBuffer = GLBuffer.createVertexBuffer(gl, this.staticData, gl.STATIC_DRAW); + const statBuffer = new ArrayBuffer(this.size * this.staticStride * 4 * 4); - // this.vao = new VertexArrayObject(gl) - // .addIndex(this.indexBuffer); + this.staticData = new Float32Array(statBuffer); + this.staticDataUint32 = new Uint32Array(statBuffer); + this.staticBuffer = new Buffer(this.staticData, true, false); for (let i = 0; i < this.dynamicProperties.length; ++i) { const property = this.dynamicProperties[i]; - if (property.unsignedByte) - { - this.vao.addAttribute( - this.dynamicBuffer, - property.attribute, - gl.UNSIGNED_BYTE, - true, - this.dynamicStride * 4, - property.offset * 4 - ); - } - else - { - this.vao.addAttribute( - this.dynamicBuffer, - property.attribute, - gl.FLOAT, - false, - this.dynamicStride * 4, - property.offset * 4 - ); - } + geometry.addAttribute( + property.attributeName, + this.dynamicBuffer, + 0, + property.type === TYPES.UNSIGNED_BYTE, + property.type, + this.dynamicStride * 4, + property.offset * 4 + ); } for (let i = 0; i < this.staticProperties.length; ++i) { const property = this.staticProperties[i]; - if (property.unsignedByte) - { - this.vao.addAttribute( - this.staticBuffer, - property.attribute, - gl.UNSIGNED_BYTE, - true, - this.staticStride * 4, - property.offset * 4 - ); - } - else - { - this.vao.addAttribute( - this.staticBuffer, - property.attribute, - gl.FLOAT, - false, - this.staticStride * 4, - property.offset * 4 - ); - } + geometry.addAttribute( + property.attributeName, + this.staticBuffer, + 0, + property.type === TYPES.UNSIGNED_BYTE, + property.type, + this.staticStride * 4, + property.offset * 4 + ); } } @@ -219,11 +193,11 @@ const property = this.dynamicProperties[i]; property.uploadFunction(children, startIndex, amount, - property.unsignedByte ? this.dynamicDataUint32 : this.dynamicData, + property.type === TYPES.UNSIGNED_BYTE ? this.dynamicDataUint32 : this.dynamicData, this.dynamicStride, property.offset); } - this.dynamicBuffer.upload(); + this.dynamicBuffer._updateID++; } /** @@ -240,11 +214,11 @@ const property = this.staticProperties[i]; property.uploadFunction(children, startIndex, amount, - property.unsignedByte ? this.staticDataUint32 : this.staticData, + property.type === TYPES.UNSIGNED_BYTE ? this.staticDataUint32 : this.staticData, this.staticStride, property.offset); } - this.staticBuffer.upload(); + this.staticBuffer._updateID++; } /** @@ -253,16 +227,20 @@ */ destroy() { + this.indexBuffer = null; + this.dynamicProperties = null; - this.dynamicBuffer.destroy(); + // this.dynamicBuffer.destroy(); this.dynamicBuffer = null; this.dynamicData = null; this.dynamicDataUint32 = null; this.staticProperties = null; - this.staticBuffer.destroy(); + // this.staticBuffer.destroy(); this.staticBuffer = null; this.staticData = null; this.staticDataUint32 = null; + // all buffers are destroyed inside geometry + this.geometry.destroy(); } } diff --git a/packages/particles/src/ParticleContainer.js b/packages/particles/src/ParticleContainer.js index 1235474..3a36e98 100644 --- a/packages/particles/src/ParticleContainer.js +++ b/packages/particles/src/ParticleContainer.js @@ -83,10 +83,10 @@ this._batchSize = batchSize; /** - * @member {object} + * @member {Array} * @private */ - this._glBuffers = {}; + this._buffers = null; /** * @member {number} @@ -240,125 +240,16 @@ } } - /** - * Renders the object using the Canvas renderer - * - * @private - * @param {PIXI.CanvasRenderer} renderer - The canvas renderer - */ - renderCanvas(renderer) + dispose() { - if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable) + if (this._buffers) { - return; - } - - const context = renderer.context; - const transform = this.worldTransform; - let isRotated = true; - - let positionX = 0; - let positionY = 0; - - let finalWidth = 0; - let finalHeight = 0; - - renderer.setBlendMode(this.blendMode); - - context.globalAlpha = this.worldAlpha; - - this.displayObjectUpdateTransform(); - - for (let i = 0; i < this.children.length; ++i) - { - const child = this.children[i]; - - if (!child.visible) + for (let i = 0; i < this._buffers.length; ++i) { - continue; + this._buffers[i].destroy(); } - const frame = child._texture.frame; - - context.globalAlpha = this.worldAlpha * child.alpha; - - if (child.rotation % (Math.PI * 2) === 0) - { - // this is the fastest way to optimise! - if rotation is 0 then we can avoid any kind of setTransform call - if (isRotated) - { - context.setTransform( - transform.a, - transform.b, - transform.c, - transform.d, - transform.tx * renderer.resolution, - transform.ty * renderer.resolution - ); - - isRotated = false; - } - - positionX = ((child.anchor.x) * (-frame.width * child.scale.x)) + child.position.x + 0.5; - positionY = ((child.anchor.y) * (-frame.height * child.scale.y)) + child.position.y + 0.5; - - finalWidth = frame.width * child.scale.x; - finalHeight = frame.height * child.scale.y; - } - else - { - if (!isRotated) - { - isRotated = true; - } - - child.displayObjectUpdateTransform(); - - const childTransform = child.worldTransform; - - if (renderer.roundPixels) - { - context.setTransform( - childTransform.a, - childTransform.b, - childTransform.c, - childTransform.d, - (childTransform.tx * renderer.resolution) | 0, - (childTransform.ty * renderer.resolution) | 0 - ); - } - else - { - context.setTransform( - childTransform.a, - childTransform.b, - childTransform.c, - childTransform.d, - childTransform.tx * renderer.resolution, - childTransform.ty * renderer.resolution - ); - } - - positionX = ((child.anchor.x) * (-frame.width)) + 0.5; - positionY = ((child.anchor.y) * (-frame.height)) + 0.5; - - finalWidth = frame.width; - finalHeight = frame.height; - } - - const resolution = child._texture.baseTexture.resolution; - - context.drawImage( - child._texture.baseTexture.source, - frame.x * resolution, - frame.y * resolution, - frame.width * resolution, - frame.height * resolution, - positionX * renderer.resolution, - positionY * renderer.resolution, - finalWidth * renderer.resolution, - finalHeight * renderer.resolution - ); + this._buffers = null; } } @@ -378,15 +269,8 @@ { super.destroy(options); - if (this._buffers) - { - for (let i = 0; i < this._buffers.length; ++i) - { - this._buffers[i].destroy(); - } - } + this.dispose(); this._properties = null; - this._buffers = null; } } diff --git a/packages/particles/src/ParticleRenderer.js b/packages/particles/src/ParticleRenderer.js index a2ceaee..9c7ac97 100644 --- a/packages/particles/src/ParticleRenderer.js +++ b/packages/particles/src/ParticleRenderer.js @@ -1,8 +1,10 @@ -import { ObjectRenderer } from '@pixi/core'; +import { TYPES } from '@pixi/constants'; +import { ObjectRenderer, Shader } from '@pixi/core'; import { correctBlendMode, premultiplyRgba, premultiplyTint } from '@pixi/utils'; import { Matrix } from '@pixi/math'; -import ParticleShader from './ParticleShader'; import ParticleBuffer from './ParticleBuffer'; +import vertex from './particles.vert'; +import fragment from './particles.frag'; /** * @author Mat Groves @@ -43,76 +45,50 @@ */ this.shader = null; - this.indexBuffer = null; - this.properties = null; this.tempMatrix = new Matrix(); - this.CONTEXT_UID = 0; - } - - /** - * When there is a WebGL context change - * - * @private - */ - onContextChange() - { - const gl = this.renderer.gl; - - this.CONTEXT_UID = this.renderer.CONTEXT_UID; - - // setup default shader - this.shader = new ParticleShader(gl); - this.properties = [ // verticesData { - attribute: this.shader.attributes.aVertexPosition, + attributeName: 'aVertexPosition', size: 2, uploadFunction: this.uploadVertices, offset: 0, }, // positionData { - attribute: this.shader.attributes.aPositionCoord, + attributeName: 'aPositionCoord', size: 2, uploadFunction: this.uploadPosition, offset: 0, }, // rotationData { - attribute: this.shader.attributes.aRotation, + attributeName: 'aRotation', size: 1, uploadFunction: this.uploadRotation, offset: 0, }, // uvsData { - attribute: this.shader.attributes.aTextureCoord, + attributeName: 'aTextureCoord', size: 2, uploadFunction: this.uploadUvs, offset: 0, }, // tintData { - attribute: this.shader.attributes.aColor, + attributeName: 'aColor', size: 1, - unsignedByte: true, + type: TYPES.UNSIGNED_BYTE, uploadFunction: this.uploadTint, offset: 0, }, ]; - } - /** - * Starts a new particle batch. - * - */ - start() - { - this.renderer.shader.bind(this.shader); + this.shader = Shader.from(vertex, fragment, {}); } /** @@ -137,11 +113,11 @@ totalChildren = maxSize; } - let buffers = container._glBuffers[renderer.CONTEXT_UID]; + let buffers = container._buffers; if (!buffers) { - buffers = container._glBuffers[renderer.CONTEXT_UID] = this.generateBuffers(container); + buffers = container._buffers = this.generateBuffers(container); } const baseTexture = children[0]._texture.baseTexture; @@ -153,15 +129,16 @@ const m = container.worldTransform.copyTo(this.tempMatrix); - m.prepend(renderer._activeRenderTarget.projectionMatrix); + m.prepend(renderer.globalUniforms.uniforms.projectionMatrix); - this.shader.uniforms.projectionMatrix = m.toArray(true); + this.shader.uniforms.translationMatrix = m.toArray(true); this.shader.uniforms.uColor = premultiplyRgba(container.tintRgb, container.worldAlpha, this.shader.uniforms.uColor, baseTexture.premultiplyAlpha); - // make sure the texture is bound.. - this.shader.uniforms.uSampler = renderer.bindTexture(baseTexture); + this.shader.uniforms.uSampler = baseTexture; + + this.renderer.shader.bind(this.shader); // now lets upload and render the buffers.. for (let i = 0, j = 0; i < totalChildren; i += batchSize, j += 1) @@ -195,8 +172,8 @@ } // bind the buffer - renderer.bindVao(buffer.vao); - buffer.vao.draw(gl.TRIANGLES, amount * 6); + renderer.geometry.bind(buffer.geometry); + gl.drawElements(gl.TRIANGLES, amount * 6, gl.UNSIGNED_SHORT, 0); } } @@ -208,7 +185,6 @@ */ generateBuffers(container) { - const gl = this.renderer.gl; const buffers = []; const size = container._maxSize; const batchSize = container._batchSize; @@ -216,7 +192,7 @@ for (let i = 0; i < size; i += batchSize) { - buffers.push(new ParticleBuffer(gl, this.properties, dynamicPropertyFlags, batchSize)); + buffers.push(new ParticleBuffer(this.properties, dynamicPropertyFlags, batchSize)); } return buffers; @@ -231,11 +207,10 @@ */ _generateOneMoreBuffer(container) { - const gl = this.renderer.gl; const batchSize = container._batchSize; const dynamicPropertyFlags = container._properties; - return new ParticleBuffer(gl, this.properties, dynamicPropertyFlags, batchSize); + return new ParticleBuffer(this.properties, dynamicPropertyFlags, batchSize); } /** @@ -440,11 +415,6 @@ */ destroy() { - if (this.renderer.gl) - { - this.renderer.gl.deleteBuffer(this.indexBuffer); - } - super.destroy(); if (this.shader) @@ -453,7 +423,6 @@ this.shader = null; } - this.indices = null; this.tempMatrix = null; } } diff --git a/packages/particles/src/index.js b/packages/particles/src/index.js index b3abe5c..d315119 100644 --- a/packages/particles/src/index.js +++ b/packages/particles/src/index.js @@ -1,2 +1,2 @@ -// export { default as ParticleContainer } from './ParticleContainer'; -// export { default as ParticleRenderer } from './ParticleRenderer'; +export { default as ParticleContainer } from './ParticleContainer'; +export { default as ParticleRenderer } from './ParticleRenderer'; diff --git a/packages/particles/src/particles.vert b/packages/particles/src/particles.vert index 209e14d..f65b26b 100644 --- a/packages/particles/src/particles.vert +++ b/packages/particles/src/particles.vert @@ -5,7 +5,7 @@ attribute vec2 aPositionCoord; attribute float aRotation; -uniform mat3 projectionMatrix; +uniform mat3 translationMatrix; uniform vec4 uColor; varying vec2 vTextureCoord; @@ -18,8 +18,8 @@ vec2 v = vec2(x, y); v = v + aPositionCoord; - gl_Position = vec4((projectionMatrix * vec3(v, 1.0)).xy, 0.0, 1.0); + gl_Position = vec4((translationMatrix * vec3(v, 1.0)).xy, 0.0, 1.0); vTextureCoord = aTextureCoord; vColor = aColor * uColor; -} \ No newline at end of file +} diff --git a/packages/sprite-tiling/src/TilingSpriteRenderer.js b/packages/sprite-tiling/src/TilingSpriteRenderer.js index 276c20a..3ec4e89 100644 --- a/packages/sprite-tiling/src/TilingSpriteRenderer.js +++ b/packages/sprite-tiling/src/TilingSpriteRenderer.js @@ -29,9 +29,9 @@ const uniforms = { globals: this.renderer.globalUniforms }; - this.shader = new Shader.from(vertex, fragment, uniforms); + this.shader = Shader.from(vertex, fragment, uniforms); - this.simpleShader = new Shader.from(vertex, fragmentSimple, uniforms); + this.simpleShader = Shader.from(vertex, fragmentSimple, uniforms); this.quad = new Quad(); }