var DisplayObjectContainer = require('./DisplayObjectContainer'), WebGLFastSpriteBatch = require('../renderers/webgl/utils/WebGLFastSpriteBatch'); /** * The SpriteBatch class is a really fast version of the DisplayObjectContainer built solely for speed, * so use when you need a lot of sprites or particles. The tradeoff of the SpriteBatch is that advanced * functionality will not work. SpriteBatch implements only the basic object transform (position, scale, rotation). * Any other functionality like interactions, tinting, etc will not work on sprites in this batch. * * It's extremely easy to use : * * ```js * var container = new SpriteBatch(); * * stage.addChild(container); * * for(var i = 0; i < 100; ++i) { * var sprite = new PIXI.Sprite.fromImage("myImage.png"); * container.addChild(sprite); * } * ``` * * And here you have a hundred sprites that will be renderer at the speed of light. * * @class * @namespace PIXI */ //TODO RENAME to PARTICLE CONTAINER? function SpriteBatch() { DisplayObjectContainer.call(this); this.ready = false; } SpriteBatch.prototype = Object.create(DisplayObjectContainer.prototype); SpriteBatch.prototype.constructor = SpriteBatch; /** * Initialises the spriteBatch for WebGL * * @param gl {WebGLContext} the current WebGL drawing context */ SpriteBatch.prototype.initWebGL = function (gl) { // TODO only one needed for the whole engine really? this.fastSpriteBatch = new WebGLFastSpriteBatch(gl); this.ready = true; }; /** * Updates the object transform for rendering * * @private */ SpriteBatch.prototype.updateTransform = function () { // TODO don't need to! this.displayObjectUpdateTransform(); // PIXI.DisplayObjectContainer.prototype.updateTransform.call( this ); }; /** * Renders the object using the WebGL renderer * * @param renderSession {RenderSession} * @private */ SpriteBatch.prototype._renderWebGL = function (renderSession) { if (!this.visible || this.alpha <= 0 || !this.children.length) { return; } if (!this.ready) { this.initWebGL(renderSession.gl); } renderSession.spriteBatch.stop(); renderSession.shaderManager.setShader(renderSession.shaderManager.fastShader); this.fastSpriteBatch.begin(this, renderSession); this.fastSpriteBatch.render(this); renderSession.spriteBatch.start(); }; /** * Renders the object using the Canvas renderer * * @param renderSession {RenderSession} * @private */ SpriteBatch.prototype._renderCanvas = function (renderSession) { if (!this.visible || this.alpha <= 0 || !this.children.length) { return; } var context = renderSession.context; var transform = this.worldTransform; var isRotated = true; context.globalAlpha = this.worldAlpha; this.displayObjectUpdateTransform(); for (var i = 0; i < this.children.length; ++i) { var child = this.children[i]; if (!child.visible) { continue; } var 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, transform.ty ); isRotated = false; } context.drawImage( child.texture.baseTexture.source, frame.x, frame.y, frame.width, frame.height, ((child.anchor.x) * (-frame.width * child.scale.x) + child.position.x + 0.5) | 0, ((child.anchor.y) * (-frame.height * child.scale.y) + child.position.y + 0.5) | 0, frame.width * child.scale.x, frame.height * child.scale.y ); } else { if (!isRotated) { isRotated = true; } child.displayObjectUpdateTransform(); var childTransform = child.worldTransform; if (renderSession.roundPixels) { context.setTransform( childTransform.a, childTransform.b, childTransform.c, childTransform.d, childTransform.tx | 0, childTransform.ty | 0 ); } else { context.setTransform( childTransform.a, childTransform.b, childTransform.c, childTransform.d, childTransform.tx, childTransform.ty ); } context.drawImage( child.texture.baseTexture.source, frame.x, frame.y, frame.width, frame.height, ((child.anchor.x) * (-frame.width) + 0.5) | 0, ((child.anchor.y) * (-frame.height) + 0.5) | 0, frame.width, frame.height ); } } };