diff --git a/build/config.php b/build/config.php
index e506e0079..388752e26 100644
--- a/build/config.php
+++ b/build/config.php
@@ -136,7 +136,10 @@ EOL;
+
+
+
@@ -147,6 +150,9 @@ EOL;
+
+
+
EOL;
diff --git a/src/core/Group.js b/src/core/Group.js
index 14b791eec..35f5a3111 100644
--- a/src/core/Group.js
+++ b/src/core/Group.js
@@ -291,6 +291,15 @@ Phaser.Group = function (game, parent, name, addToStage, enableBody, physicsBody
*/
this._sortProperty = 'z';
+ if (this.game.renderType === Phaser.CANVAS)
+ {
+ this.render = Phaser.Renderer.Canvas.GameObjects.Container.render;
+ }
+ else
+ {
+ this.render = Phaser.Renderer.WebGL.GameObjects.Container.render;
+ }
+
};
Phaser.Group.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
diff --git a/src/core/Stage.js b/src/core/Stage.js
index 77046ad48..c18b826e1 100644
--- a/src/core/Stage.js
+++ b/src/core/Stage.js
@@ -93,6 +93,15 @@ Phaser.Stage = function (game) {
this.parseConfig(game.config);
}
+ if (this.game.renderType === Phaser.CANVAS)
+ {
+ this.render = Phaser.Renderer.Canvas.GameObjects.Stage.render;
+ }
+ else
+ {
+ this.render = Phaser.Renderer.WebGL.GameObjects.Stage.render;
+ }
+
};
Phaser.Stage.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
diff --git a/src/gameobjects/Graphics.js b/src/gameobjects/Graphics.js
index 61d66c374..2c9e3a318 100644
--- a/src/gameobjects/Graphics.js
+++ b/src/gameobjects/Graphics.js
@@ -201,6 +201,15 @@ Phaser.Graphics = function (game, x, y) {
Phaser.Component.Core.init.call(this, game, x, y, '', null);
+ if (this.game.renderType === Phaser.CANVAS)
+ {
+ this.render = Phaser.Renderer.Canvas.GameObjects.Graphics.render;
+ }
+ else
+ {
+ this.render = Phaser.Renderer.WebGL.GameObjects.Graphics.render;
+ }
+
};
Phaser.Graphics.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
@@ -1513,6 +1522,30 @@ Phaser.Graphics.prototype.drawShape = function (shape) {
};
+Phaser.Graphics.prototype.updateGraphicsTint = function () {
+
+ if (this.tint === 0xFFFFFF)
+ {
+ return;
+ }
+
+ var tintR = (this.tint >> 16 & 0xFF) / 255;
+ var tintG = (this.tint >> 8 & 0xFF) / 255;
+ var tintB = (this.tint & 0xFF) / 255;
+
+ for (var i = 0; i < this.graphicsData.length; i++)
+ {
+ var data = this.graphicsData[i];
+
+ var fillColor = data.fillColor | 0;
+ var lineColor = data.lineColor | 0;
+
+ data._fillTint = (((fillColor >> 16 & 0xFF) / 255 * tintR * 255 << 16) + ((fillColor >> 8 & 0xFF) / 255 * tintG * 255 << 8) + (fillColor & 0xFF) / 255 * tintB * 255);
+ data._lineTint = (((lineColor >> 16 & 0xFF) / 255 * tintR * 255 << 16) + ((lineColor >> 8 & 0xFF) / 255 * tintG * 255 << 8) + (lineColor & 0xFF) / 255 * tintB * 255);
+ }
+
+};
+
/**
* When cacheAsBitmap is set to true the graphics object will be rendered as if it was a sprite.
* This is useful if your graphics element does not change often, as it will speed up the rendering of the object in exchange for taking up texture memory.
diff --git a/src/gameobjects/Image.js b/src/gameobjects/Image.js
index 596c0c1eb..2ba7cfd41 100644
--- a/src/gameobjects/Image.js
+++ b/src/gameobjects/Image.js
@@ -50,6 +50,15 @@ Phaser.Image = function (game, x, y, key, frame) {
Phaser.Component.Core.init.call(this, game, x, y, key, frame);
+ if (this.game.renderType === Phaser.CANVAS)
+ {
+ this.render = Phaser.Renderer.Canvas.GameObjects.Sprite.render;
+ }
+ else
+ {
+ this.render = Phaser.Renderer.WebGL.GameObjects.Sprite.render;
+ }
+
};
Phaser.Image.prototype = Object.create(PIXI.Sprite.prototype);
diff --git a/src/gameobjects/Sprite.js b/src/gameobjects/Sprite.js
index 73b83796b..38fddfee2 100644
--- a/src/gameobjects/Sprite.js
+++ b/src/gameobjects/Sprite.js
@@ -64,6 +64,15 @@ Phaser.Sprite = function (game, x, y, key, frame) {
Phaser.Component.Core.init.call(this, game, x, y, key, frame);
+ if (this.game.renderType === Phaser.CANVAS)
+ {
+ this.render = Phaser.Renderer.Canvas.GameObjects.Sprite.render;
+ }
+ else
+ {
+ this.render = Phaser.Renderer.WebGL.GameObjects.Sprite.render;
+ }
+
};
Phaser.Sprite.prototype = Object.create(PIXI.Sprite.prototype);
diff --git a/src/gameobjects/SpriteBatch.js b/src/gameobjects/SpriteBatch.js
index 5f620f015..19d8ffffc 100644
--- a/src/gameobjects/SpriteBatch.js
+++ b/src/gameobjects/SpriteBatch.js
@@ -44,6 +44,15 @@ Phaser.SpriteBatch = function (game, parent, name, addToStage) {
*/
this.ready = false;
+ if (this.game.renderType === Phaser.CANVAS)
+ {
+ this.render = Phaser.Renderer.Canvas.GameObjects.SpriteBatch.render;
+ }
+ else
+ {
+ this.render = Phaser.Renderer.WebGL.GameObjects.SpriteBatch.render;
+ }
+
};
Phaser.SpriteBatch.prototype = Object.create(Phaser.Group.prototype);
diff --git a/src/gameobjects/Text.js b/src/gameobjects/Text.js
index 2083e9805..a8db74b4d 100644
--- a/src/gameobjects/Text.js
+++ b/src/gameobjects/Text.js
@@ -190,6 +190,15 @@ Phaser.Text = function (game, x, y, text, style) {
this.updateText();
}
+ if (this.game.renderType === Phaser.CANVAS)
+ {
+ this.render = Phaser.Renderer.Canvas.GameObjects.Text.render;
+ }
+ else
+ {
+ this.render = Phaser.Renderer.WebGL.GameObjects.Text.render;
+ }
+
};
Phaser.Text.prototype = Object.create(Phaser.Sprite.prototype);
diff --git a/src/pixi/display/DisplayObjectContainer.js b/src/pixi/display/DisplayObjectContainer.js
index 6a00a4fd1..d67d82ebc 100644
--- a/src/pixi/display/DisplayObjectContainer.js
+++ b/src/pixi/display/DisplayObjectContainer.js
@@ -33,9 +33,6 @@ PIXI.DisplayObjectContainer = function () {
* @default
*/
this.ignoreChildInput = false;
-
- // this.render = Phaser.Renderer.Canvas.GameObjects.Container.render;
- this.render = Phaser.Renderer.WebGL.GameObjects.Container.render;
};
diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js
index 29a33cea8..49ce59bcb 100644
--- a/src/pixi/display/Sprite.js
+++ b/src/pixi/display/Sprite.js
@@ -116,9 +116,6 @@ PIXI.Sprite = function (texture) {
this.renderable = true;
- // this.render = Phaser.Renderer.Canvas.GameObjects.Sprite.render;
- this.render = Phaser.Renderer.WebGL.GameObjects.Sprite.render;
-
};
// constructor
diff --git a/src/renderer/canvas/CanvasRenderer.js b/src/renderer/canvas/CanvasRenderer.js
index e290897f7..4d8c8b7bc 100644
--- a/src/renderer/canvas/CanvasRenderer.js
+++ b/src/renderer/canvas/CanvasRenderer.js
@@ -104,9 +104,7 @@ Phaser.Renderer.Canvas = function (game)
};
-Phaser.Renderer.Canvas.GameObjects = {
- // Populated by the GameObjects classes
-};
+Phaser.Renderer.Canvas.GameObjects = {};
Phaser.Renderer.Canvas.prototype.constructor = Phaser.Renderer.Canvas;
diff --git a/src/renderer/canvas/gameobjects/Graphics.js b/src/renderer/canvas/gameobjects/Graphics.js
index 31c19c632..b729d746d 100644
--- a/src/renderer/canvas/gameobjects/Graphics.js
+++ b/src/renderer/canvas/gameobjects/Graphics.js
@@ -8,10 +8,12 @@ Phaser.Renderer.Canvas.GameObjects.Graphics = {
render: function (renderer)
{
var context = renderer.context;
+ var local = Phaser.Renderer.Canvas.GameObjects.Graphics;
if (this.dirty)
{
this.updateGraphicsTint();
+
this.dirty = false;
}
@@ -24,23 +26,23 @@ Phaser.Renderer.Canvas.GameObjects.Graphics = {
switch (data.type)
{
case Phaser.RECTANGLE:
- this.drawRectangle(data, context);
+ local.drawRectangle(data, context);
break;
case Phaser.CIRCLE:
- this.drawCircle(data, context);
+ local.drawCircle(data, context);
break;
case Phaser.POLYGON:
- this.drawPolygon(data, context);
+ local.drawPolygon(data, context);
break;
case Phaser.ELLIPSE:
- this.drawEllipse(data, context);
+ local.drawEllipse(data, context);
break;
case Phaser.ROUNDEDRECTANGLE:
- this.drawRoundedRectangle(data, context);
+ local.drawRoundedRectangle(data, context);
break;
}
}
@@ -218,30 +220,6 @@ Phaser.Renderer.Canvas.GameObjects.Graphics = {
context.stroke();
}
- },
-
- updateGraphicsTint: function ()
- {
- if (this.tint === 0xFFFFFF)
- {
- return;
- }
-
- var tintR = (this.tint >> 16 & 0xFF) / 255;
- var tintG = (this.tint >> 8 & 0xFF) / 255;
- var tintB = (this.tint & 0xFF) / 255;
-
- for (var i = 0; i < this.graphicsData.length; i++)
- {
- var data = this.graphicsData[i];
-
- var fillColor = data.fillColor | 0;
- var lineColor = data.lineColor | 0;
-
- data._fillTint = (((fillColor >> 16 & 0xFF) / 255 * tintR * 255 << 16) + ((fillColor >> 8 & 0xFF) / 255 * tintG * 255 << 8) + (fillColor & 0xFF) / 255 * tintB * 255);
- data._lineTint = (((lineColor >> 16 & 0xFF) / 255 * tintR * 255 << 16) + ((lineColor >> 8 & 0xFF) / 255 * tintG * 255 << 8) + (lineColor & 0xFF) / 255 * tintB * 255);
- }
-
}
};
diff --git a/src/renderer/canvas/gameobjects/SpriteBatch.js b/src/renderer/canvas/gameobjects/SpriteBatch.js
index dd85d8b0a..bc3e95d9a 100644
--- a/src/renderer/canvas/gameobjects/SpriteBatch.js
+++ b/src/renderer/canvas/gameobjects/SpriteBatch.js
@@ -3,7 +3,7 @@
* For example the Group, Stage, Sprite, etc. because the render function
* here is mapped to the prototype for the game object.
*/
-Phaser.Renderer.Canvas.GameObjects.Container = {
+Phaser.Renderer.Canvas.GameObjects.SpriteBatch = {
render: function (renderer)
{
diff --git a/src/renderer/canvas/gameobjects/Stage.js b/src/renderer/canvas/gameobjects/Stage.js
new file mode 100644
index 000000000..662cccc31
--- /dev/null
+++ b/src/renderer/canvas/gameobjects/Stage.js
@@ -0,0 +1,34 @@
+/**
+* Note that 'this' in all functions here refer to the owning object.
+* For example the Group, Stage, Sprite, etc. because the render function
+* here is mapped to the prototype for the game object.
+*/
+Phaser.Renderer.Canvas.GameObjects.Stage = {
+
+ render: function (renderer)
+ {
+ if (this.visible === false || this.alpha === 0)
+ {
+ return;
+ }
+
+ if (this._mask)
+ {
+ renderer.pushMask(this._mask);
+ }
+
+ for (var i = 0; i < this.children.length; i++)
+ {
+ var child = this.children[i];
+
+ child.render(renderer, child);
+ }
+
+ if (this._mask)
+ {
+ renderer.popMask();
+ }
+
+ }
+
+};
diff --git a/src/renderer/canvas/gameobjects/Text.js b/src/renderer/canvas/gameobjects/Text.js
new file mode 100644
index 000000000..e69f1e342
--- /dev/null
+++ b/src/renderer/canvas/gameobjects/Text.js
@@ -0,0 +1,127 @@
+/**
+* Note that 'this' in all functions here refer to the owning object.
+* For example the Group, Stage, Sprite, etc. because the render function
+* here is mapped to the prototype for the game object.
+*/
+Phaser.Renderer.Canvas.GameObjects.Text = {
+
+ render: function (renderer)
+ {
+ // If the sprite is not visible or the alpha is 0 then no need to render this element
+ if (!this.visible || this.alpha === 0 || !this.renderable)
+ {
+ return;
+ }
+
+ // Add back in: || src.texture.crop.width <= 0 || src.texture.crop.height <= 0
+
+ var wt = this.worldTransform;
+
+ if (this.blendMode !== renderer.currentBlendMode)
+ {
+ renderer.currentBlendMode = this.blendMode;
+ renderer.context.globalCompositeOperation = Phaser.blendModesCanvas[renderer.currentBlendMode];
+ }
+
+ // Check if the texture can be rendered
+
+ if (this._mask)
+ {
+ renderer.pushMask(this._mask);
+ }
+
+ var resolution = this.texture.baseTexture.resolution / renderer.game.resolution;
+
+ renderer.context.globalAlpha = this.worldAlpha;
+
+ // If smoothingEnabled is supported and we need to change the smoothing property for src texture
+ if (renderer.smoothProperty && renderer.currentScaleMode !== this.texture.baseTexture.scaleMode)
+ {
+ renderer.currentScaleMode = this.texture.baseTexture.scaleMode;
+ renderer.context[renderer.smoothProperty] = (renderer.currentScaleMode === Phaser.scaleModes.LINEAR);
+ }
+
+ // If the texture is trimmed we offset by the trim x/y, otherwise we use the frame dimensions
+ var dx = (this.texture.trim) ? this.texture.trim.x - this.anchor.x * this.texture.trim.width : this.anchor.x * -this.texture.frame.width;
+ var dy = (this.texture.trim) ? this.texture.trim.y - this.anchor.y * this.texture.trim.height : this.anchor.y * -this.texture.frame.height;
+
+ var tx = (wt.tx * renderer.game.resolution) + renderer.game.camera._shake.x;
+ var ty = (wt.ty * renderer.game.resolution) + renderer.game.camera._shake.y;
+
+ var cw = this.texture.crop.width;
+ var ch = this.texture.crop.height;
+
+ if (this.texture.rotated)
+ {
+ var a = wt.a;
+ var b = wt.b;
+ var c = wt.c;
+ var d = wt.d;
+ var e = cw;
+
+ // Offset before rotating
+ tx = wt.c * ch + tx;
+ ty = wt.d * ch + ty;
+
+ // Rotate matrix by 90 degrees
+ // We use precalculated values for sine and cosine of rad(90)
+ wt.a = a * 6.123233995736766e-17 + -c;
+ wt.b = b * 6.123233995736766e-17 + -d;
+ wt.c = a + c * 6.123233995736766e-17;
+ wt.d = b + d * 6.123233995736766e-17;
+
+ // Update cropping dimensions.
+ cw = ch;
+ ch = e;
+ }
+
+ // Allow for pixel rounding
+ if (renderer.roundPixels)
+ {
+ renderer.context.setTransform(wt.a, wt.b, wt.c, wt.d, tx | 0, ty | 0);
+ dx |= 0;
+ dy |= 0;
+ }
+ else
+ {
+ renderer.context.setTransform(wt.a, wt.b, wt.c, wt.d, tx, ty);
+ }
+
+ dx /= resolution;
+ dy /= resolution;
+
+ if (this.tint !== 0xFFFFFF)
+ {
+ if (this.texture.requiresReTint || this.cachedTint !== this.tint)
+ {
+ this.tintedTexture = PIXI.CanvasTinter.getTintedTexture(this, this.tint);
+
+ this.cachedTint = this.tint;
+ this.texture.requiresReTint = false;
+ }
+
+ renderer.context.drawImage(this.tintedTexture, 0, 0, cw, ch, dx, dy, cw / resolution, ch / resolution);
+ }
+ else
+ {
+ var cx = this.texture.crop.x;
+ var cy = this.texture.crop.y;
+
+ renderer.context.drawImage(this.texture.baseTexture.source, cx, cy, cw, ch, dx, dy, cw / resolution, ch / resolution);
+ }
+
+ for (var i = 0; i < this.children.length; i++)
+ {
+ var child = this.children[i];
+
+ child.render(renderer, child);
+ }
+
+ if (this._mask)
+ {
+ renderer.popMask();
+ }
+
+ }
+
+};
diff --git a/src/renderer/webgl/gameobjects/Graphics.js b/src/renderer/webgl/gameobjects/Graphics.js
new file mode 100644
index 000000000..37d0db273
--- /dev/null
+++ b/src/renderer/webgl/gameobjects/Graphics.js
@@ -0,0 +1,100 @@
+/**
+* Note that 'this' in all functions here refer to the owning object.
+* For example the Group, Stage, Sprite, etc. because the render function
+* here is mapped to the prototype for the game object.
+*/
+Phaser.Renderer.WebGL.GameObjects.Graphics = {
+
+ render: function (renderer)
+ {
+ var local = Phaser.Renderer.Canvas.GameObjects.Graphics;
+
+ if (this.visible === false || this.alpha === 0 || this.isMask === true)
+ {
+ return;
+ }
+
+ if (this._cacheAsBitmap)
+ {
+ if (this.dirty || this.cachedSpriteDirty)
+ {
+ this._generateCachedSprite();
+
+ // we will also need to update the texture on the gpu too!
+ this.updateCachedSpriteTexture();
+
+ this.cachedSpriteDirty = false;
+ this.dirty = false;
+ }
+
+ this._cachedSprite.worldAlpha = this.worldAlpha;
+
+ // PIXI.Sprite.prototype._renderWebGL.call(this._cachedSprite, renderSession);
+
+ return;
+ }
+ else
+ {
+ renderer.spriteBatch.stop();
+ renderer.setBlendMode(this.blendMode);
+
+ if (this._mask)
+ {
+ renderer.pushMask(this._mask);
+ }
+
+ if (this._filters)
+ {
+ renderer.filterManager.pushFilter(this._filterBlock);
+ }
+
+ // check blend mode
+ if (this.blendMode !== renderer.spriteBatch.currentBlendMode)
+ {
+ renderer.spriteBatch.currentBlendMode = this.blendMode;
+
+ var blendModeWebGL = renderer.blendModes[renderer.spriteBatch.currentBlendMode];
+
+ renderer.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]);
+ }
+
+ // check if the webgl graphic needs to be updated
+ if (this.webGLDirty)
+ {
+ this.dirty = true;
+ this.webGLDirty = false;
+ }
+
+ // Merge with this class
+ // PIXI.WebGLGraphics.renderGraphics(this, renderSession);
+
+ // only render if it has children!
+ if (this.children.length)
+ {
+ renderer.spriteBatch.start();
+
+ for (var i = 0; i < this.children.length; i++)
+ {
+ this.children[i].render(renderer);
+ }
+
+ renderer.spriteBatch.stop();
+ }
+
+ if (this._filters)
+ {
+ renderer.filterManager.popFilter();
+ }
+
+ if (this._mask)
+ {
+ renderer.popMask(this.mask);
+ }
+
+ renderer.drawCount++;
+
+ renderer.spriteBatch.start();
+ }
+ }
+
+};
diff --git a/src/renderer/webgl/gameobjects/Sprite.js b/src/renderer/webgl/gameobjects/Sprite.js
index b9c1bdb78..229a9ecc1 100644
--- a/src/renderer/webgl/gameobjects/Sprite.js
+++ b/src/renderer/webgl/gameobjects/Sprite.js
@@ -67,7 +67,7 @@ Phaser.Renderer.WebGL.GameObjects.Sprite = {
// Render children!
for (i = 0; i < this.children.length; i++)
{
- this.children[i].render(renderSession);
+ this.children[i].render(renderer);
}
}
}
diff --git a/src/renderer/webgl/gameobjects/Stage.js b/src/renderer/webgl/gameobjects/Stage.js
new file mode 100644
index 000000000..4cc386ad1
--- /dev/null
+++ b/src/renderer/webgl/gameobjects/Stage.js
@@ -0,0 +1,76 @@
+/**
+* Note that 'this' in all functions here refer to the owning object.
+* For example the Group, Stage, Sprite, etc. because the render function
+* here is mapped to the prototype for the game object.
+*/
+Phaser.Renderer.WebGL.GameObjects.Stage = {
+
+ render: function (renderer)
+ {
+ if (this.visible === false || this.alpha === 0 || this.children.length === 0)
+ {
+ return;
+ }
+
+ var i;
+
+ if (this._mask || this._filters)
+ {
+ // push filter first as we need to ensure the stencil buffer is correct for any masking
+ if (this._filters)
+ {
+ renderer.spriteBatch.flush();
+ renderer.filterManager.pushFilter(this._filterBlock);
+ }
+
+ if (this._mask)
+ {
+ renderer.spriteBatch.stop();
+ renderer.pushMask(this.mask);
+ renderer.spriteBatch.start();
+ }
+
+ // simple render children!
+ for (i = 0; i < this.children.length; i++)
+ {
+ if (!this.children[i].render)
+ {
+ console.dir(this.children[i]);
+ debugger;
+ }
+
+ this.children[i].render(renderer);
+ }
+
+ renderer.spriteBatch.stop();
+
+ if (this._mask)
+ {
+ renderer.popMask(this._mask);
+ }
+
+ if (this._filters)
+ {
+ renderer.filterManager.popFilter();
+ }
+
+ renderer.spriteBatch.start();
+ }
+ else
+ {
+ // simple render children!
+ for (i = 0; i < this.children.length; i++)
+ {
+ if (!this.children[i].render)
+ {
+ console.dir(this.children[i]);
+ debugger;
+ }
+
+ this.children[i].render(renderer);
+ }
+ }
+
+ }
+
+};
diff --git a/src/renderer/webgl/gameobjects/Text.js b/src/renderer/webgl/gameobjects/Text.js
new file mode 100644
index 000000000..05dbe9274
--- /dev/null
+++ b/src/renderer/webgl/gameobjects/Text.js
@@ -0,0 +1,82 @@
+/**
+* Note that 'this' in all functions here refer to the owning object.
+* For example the Group, Stage, Sprite, etc. because the render function
+* here is mapped to the prototype for the game object.
+*/
+Phaser.Renderer.WebGL.GameObjects.Text = {
+
+ render: function (renderer)
+ {
+ if (this.dirty)
+ {
+ this.updateText();
+ this.dirty = false;
+ }
+
+ // If the sprite is not visible or the alpha is 0 then no need to render this element
+ if (!this.visible || this.alpha === 0 || !this.renderable)
+ {
+ return;
+ }
+
+ // Add back in: || src.texture.crop.width <= 0 || src.texture.crop.height <= 0
+
+ var i;
+
+ // Would be good to get this down to 1 check, or even none.
+ if (this._mask || this._filters)
+ {
+ var spriteBatch = renderer.spriteBatch;
+
+ // push filter first as we need to ensure the stencil buffer is correct for any masking
+ if (this._filters)
+ {
+ spriteBatch.flush();
+ renderer.filterManager.pushFilter(this._filterBlock);
+ }
+
+ if (this._mask)
+ {
+ spriteBatch.stop();
+ renderer.pushMask(this.mask);
+ spriteBatch.start();
+ }
+
+ // add this sprite to the batch
+ spriteBatch.render(this);
+
+ // now loop through the children and make sure they get rendered
+ for (i = 0; i < this.children.length; i++)
+ {
+ this.children[i].render(renderer);
+ }
+
+ // time to stop the sprite batch as either a mask element or a filter draw will happen next
+ spriteBatch.stop();
+
+ if (this._mask)
+ {
+ renderer.popMask(this._mask);
+ }
+
+ if (this._filters)
+ {
+ renderer.filterManager.popFilter();
+ }
+
+ spriteBatch.start();
+ }
+ else
+ {
+ renderer.spriteBatch.render(this);
+
+ // Render children!
+ for (i = 0; i < this.children.length; i++)
+ {
+ this.children[i].render(renderer);
+ }
+ }
+
+ }
+
+};