mirror of
https://github.com/photonstorm/phaser
synced 2024-11-27 15:12:18 +00:00
First pass of the newly re-structured Canvas Renderer (still using old texture system though).
This commit is contained in:
parent
42b8118fa0
commit
1da95994a5
13 changed files with 575 additions and 147 deletions
|
@ -133,6 +133,10 @@ EOL;
|
|||
<script src="$path/src/textures/parsers/JSONHash.js"></script>
|
||||
<script src="$path/src/textures/parsers/SpriteSheet.js"></script>
|
||||
|
||||
<script src="$path/src/renderer/canvas/CanvasRenderer.js"></script>
|
||||
<script src="$path/src/renderer/canvas/gameobjects/Container.js"></script>
|
||||
<script src="$path/src/renderer/canvas/gameobjects/Sprite.js"></script>
|
||||
|
||||
|
||||
EOL;
|
||||
|
||||
|
|
|
@ -542,7 +542,13 @@ var Phaser = Phaser || { // jshint ignore:line
|
|||
NEAREST: 1
|
||||
},
|
||||
|
||||
PIXI: PIXI || {},
|
||||
Renderer: {
|
||||
|
||||
},
|
||||
|
||||
PIXI: PIXI || {
|
||||
|
||||
},
|
||||
|
||||
// Used to create IDs for various Pixi objects.
|
||||
_UID: 0
|
||||
|
|
|
@ -685,10 +685,12 @@ Phaser.Game.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
var c = (this.renderType === Phaser.CANVAS) ? 'Canvas' : 'WebGL';
|
||||
|
||||
if (!this.device.ie)
|
||||
{
|
||||
var args = [
|
||||
'%c %c %c %c %c Phaser v' + Phaser.VERSION + ' / Pixi.js %c http://phaser.io',
|
||||
'%c %c %c %c %c Phaser v' + Phaser.VERSION + ' / Pixi.js / ' + c + ' %c http://phaser.io',
|
||||
'background: #ff0000',
|
||||
'background: #ffff00',
|
||||
'background: #00ff00',
|
||||
|
@ -739,7 +741,8 @@ Phaser.Game.prototype = {
|
|||
// They requested Canvas and their browser supports it
|
||||
this.renderType = Phaser.CANVAS;
|
||||
|
||||
this.renderer = new PIXI.CanvasRenderer(this);
|
||||
// this.renderer = new PIXI.CanvasRenderer(this);
|
||||
this.renderer = new Phaser.Renderer.Canvas(this);
|
||||
|
||||
this.context = this.renderer.context;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,11 @@ Phaser.Component.Children.prototype = {
|
|||
|
||||
addAt: function (child, index) {
|
||||
|
||||
if (this.list.length === 0)
|
||||
{
|
||||
return this.add(child);
|
||||
}
|
||||
|
||||
if (index >= 0 && index <= this.list.length)
|
||||
{
|
||||
if (child.parent)
|
||||
|
|
|
@ -33,6 +33,8 @@ PIXI.DisplayObjectContainer = function () {
|
|||
* @default
|
||||
*/
|
||||
this.ignoreChildInput = false;
|
||||
|
||||
this.render = Phaser.Renderer.Canvas.GameObjects.Container.render;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -116,6 +116,8 @@ PIXI.Sprite = function (texture) {
|
|||
|
||||
this.renderable = true;
|
||||
|
||||
this.render = Phaser.Renderer.Canvas.GameObjects.Sprite.render;
|
||||
|
||||
};
|
||||
|
||||
// constructor
|
||||
|
|
|
@ -499,6 +499,8 @@ PIXI.WebGLRenderer.prototype.updateCompressedTexture = function (texture) {
|
|||
};
|
||||
|
||||
/**
|
||||
* Note: Moved to TextureManager class.
|
||||
*
|
||||
* Updates and Creates a WebGL texture for the renderers context.
|
||||
*
|
||||
* @method updateTexture
|
||||
|
|
277
src/renderer/canvas/CanvasRenderer.js
Normal file
277
src/renderer/canvas/CanvasRenderer.js
Normal file
|
@ -0,0 +1,277 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @author Mat Groves (@Doormat23)
|
||||
* @copyright 2016 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
* A Camera is your view into the game world. It has a position and size and renders only those objects within its field of view.
|
||||
* The game automatically creates a single Stage sized camera on boot. Move the camera around the world with Phaser.Camera.x/y
|
||||
*
|
||||
* @class Phaser.Camera
|
||||
* @constructor
|
||||
* @param {Phaser.Game} game - Game reference to the currently running game.
|
||||
*/
|
||||
Phaser.Renderer.Canvas = function (game)
|
||||
{
|
||||
console.log('CanvasRenderer Alive');
|
||||
|
||||
/**
|
||||
* @property {Phaser.Game} game - A reference to the currently running Game.
|
||||
*/
|
||||
this.game = game;
|
||||
|
||||
this.type = Phaser.CANVAS;
|
||||
|
||||
// this.resolution = game.resolution;
|
||||
|
||||
/**
|
||||
* This sets if the CanvasRenderer will clear the canvas or not before the new render pass.
|
||||
* If the Stage is NOT transparent Pixi will use a canvas sized fillRect operation every frame to set the canvas background color.
|
||||
* If the Stage is transparent Pixi will use clearRect to clear the canvas every frame.
|
||||
* Disable this by setting this to false. For example if your game has a canvas filling background image you often don't need this set.
|
||||
*
|
||||
* @property clearBeforeRender
|
||||
* @type Boolean
|
||||
* @default
|
||||
*/
|
||||
this.clearBeforeRender = game.clearBeforeRender;
|
||||
|
||||
/**
|
||||
* Whether the render view is transparent
|
||||
*
|
||||
* @property transparent
|
||||
* @type Boolean
|
||||
*/
|
||||
this.transparent = game.transparent;
|
||||
|
||||
/**
|
||||
* Whether the render view should be resized automatically
|
||||
*
|
||||
* @property autoResize
|
||||
* @type Boolean
|
||||
*/
|
||||
this.autoResize = false;
|
||||
|
||||
/**
|
||||
* The width of the canvas view
|
||||
*
|
||||
* @property width
|
||||
* @type Number
|
||||
* @default 800
|
||||
*/
|
||||
this.width = game.width * game.resolution;
|
||||
|
||||
/**
|
||||
* The height of the canvas view
|
||||
*
|
||||
* @property height
|
||||
* @type Number
|
||||
* @default 600
|
||||
*/
|
||||
this.height = game.height * game.resolution;
|
||||
|
||||
/**
|
||||
* The canvas element that everything is drawn to.
|
||||
*
|
||||
* @property view
|
||||
* @type HTMLCanvasElement
|
||||
*/
|
||||
this.view = game.canvas;
|
||||
|
||||
/**
|
||||
* The canvas 2d context that everything is drawn with
|
||||
* @property context
|
||||
* @type CanvasRenderingContext2D
|
||||
*/
|
||||
this.context = this.view.getContext('2d', {
|
||||
alpha: this.transparent
|
||||
});
|
||||
|
||||
this.smoothProperty = Phaser.Canvas.getSmoothingPrefix(this.context);
|
||||
|
||||
this.roundPixels = false;
|
||||
|
||||
var so = 'source-over';
|
||||
|
||||
this.blendModes = [ so, 'lighter', so, so, so, so, so, so, so, so, so, so, so, so, so, so, so ];
|
||||
|
||||
this.currentBlendMode = 0;
|
||||
this.currentScaleMode = 0;
|
||||
|
||||
if (this.game.device.canUseMultiply)
|
||||
{
|
||||
this.mapBlendModes();
|
||||
}
|
||||
|
||||
this.resize(this.width, this.height);
|
||||
|
||||
// this.renderTypes = [];
|
||||
// this.renderTypes[Phaser.GROUP] = Phaser.Renderer.Canvas.GameObjects.Container;
|
||||
// this.renderTypes[Phaser.SPRITE] = Phaser.Renderer.Canvas.GameObjects.Sprite;
|
||||
|
||||
};
|
||||
|
||||
Phaser.Renderer.Canvas.GameObjects = {
|
||||
// Populated by the GameObjects classes
|
||||
};
|
||||
|
||||
Phaser.Renderer.Canvas.prototype.constructor = Phaser.Renderer.Canvas;
|
||||
|
||||
Phaser.Renderer.Canvas.prototype = {
|
||||
|
||||
/**
|
||||
* Maps Blend modes to Canvas blend modes.
|
||||
*
|
||||
* @method mapBlendModes
|
||||
* @private
|
||||
*/
|
||||
mapBlendModes: function ()
|
||||
{
|
||||
var modes = Phaser.blendModes;
|
||||
|
||||
this.blendModes[modes.MULTIPLY] = 'multiply';
|
||||
this.blendModes[modes.SCREEN] = 'screen';
|
||||
this.blendModes[modes.OVERLAY] = 'overlay';
|
||||
this.blendModes[modes.DARKEN] = 'darken';
|
||||
this.blendModes[modes.LIGHTEN] = 'lighten';
|
||||
this.blendModes[modes.COLOR_DODGE] = 'color-dodge';
|
||||
this.blendModes[modes.COLOR_BURN] = 'color-burn';
|
||||
this.blendModes[modes.HARD_LIGHT] = 'hard-light';
|
||||
this.blendModes[modes.SOFT_LIGHT] = 'soft-light';
|
||||
this.blendModes[modes.DIFFERENCE] = 'difference';
|
||||
this.blendModes[modes.EXCLUSION] = 'exclusion';
|
||||
this.blendModes[modes.HUE] = 'hue';
|
||||
this.blendModes[modes.SATURATION] = 'saturation';
|
||||
this.blendModes[modes.COLOR] = 'color';
|
||||
this.blendModes[modes.LUMINOSITY] = 'luminosity';
|
||||
|
||||
},
|
||||
|
||||
resize: function (width, height)
|
||||
{
|
||||
this.width = width * this.game.resolution;
|
||||
this.height = height * this.game.resolution;
|
||||
|
||||
this.view.width = this.width;
|
||||
this.view.height = this.height;
|
||||
|
||||
if (this.autoResize)
|
||||
{
|
||||
this.view.style.width = (this.width / this.game.resolution) + 'px';
|
||||
this.view.style.height = (this.height / this.game.resolution) + 'px';
|
||||
}
|
||||
|
||||
if (this.smoothProperty)
|
||||
{
|
||||
this.context[this.smoothProperty] = (this.scaleMode === Phaser.scaleModes.LINEAR);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Renders the Phaser.Stage to the canvas view, then iterates through its children.
|
||||
*
|
||||
* @method render
|
||||
* @param stage {Phaser.Stage}
|
||||
*/
|
||||
render: function (stage)
|
||||
{
|
||||
this.context.setTransform(1, 0, 0, 1, 0, 0);
|
||||
this.context.globalAlpha = 1;
|
||||
this.context.globalCompositeOperation = 'source-over';
|
||||
|
||||
this.currentBlendMode = 0;
|
||||
this.currentScaleMode = 0;
|
||||
|
||||
// Add Pre-render hook
|
||||
|
||||
// this.renderSession.currentBlendMode = 0;
|
||||
// this.renderSession.shakeX = this.game.camera._shake.x;
|
||||
// this.renderSession.shakeY = this.game.camera._shake.y;
|
||||
|
||||
// Is this needed any longer?
|
||||
/*
|
||||
if (navigator.isCocoonJS && this.view.screencanvas)
|
||||
{
|
||||
this.context.fillStyle = "black";
|
||||
this.context.clear();
|
||||
}
|
||||
*/
|
||||
|
||||
if (this.clearBeforeRender)
|
||||
{
|
||||
if (this.transparent)
|
||||
{
|
||||
this.context.clearRect(0, 0, this.width, this.height);
|
||||
}
|
||||
else if (stage._bgColor)
|
||||
{
|
||||
this.context.fillStyle = stage._bgColor.rgba;
|
||||
this.context.fillRect(0, 0, this.width , this.height);
|
||||
}
|
||||
}
|
||||
|
||||
stage.render(this, stage);
|
||||
|
||||
// Add Post-render hook
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* This method adds it to the current stack of masks.
|
||||
*
|
||||
* @method pushMask
|
||||
* @param maskData {Object} the maskData that will be pushed
|
||||
* @param renderSession {Object} The renderSession whose context will be used for this mask manager.
|
||||
*/
|
||||
pushMask: function (maskData)
|
||||
{
|
||||
this.context.save();
|
||||
|
||||
var cacheAlpha = maskData.alpha;
|
||||
var transform = maskData.worldTransform;
|
||||
|
||||
var resolution = this.game.resolution;
|
||||
|
||||
this.context.setTransform(
|
||||
transform.a * resolution,
|
||||
transform.b * resolution,
|
||||
transform.c * resolution,
|
||||
transform.d * resolution,
|
||||
transform.tx * resolution,
|
||||
transform.ty * resolution
|
||||
);
|
||||
|
||||
// PIXI.CanvasGraphics.renderGraphicsMask(maskData, context);
|
||||
|
||||
this.context.clip();
|
||||
|
||||
maskData.worldAlpha = cacheAlpha;
|
||||
|
||||
},
|
||||
|
||||
popMask: function ()
|
||||
{
|
||||
this.context.restore();
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes everything from the renderer and optionally removes the Canvas DOM element.
|
||||
*
|
||||
* @method destroy
|
||||
* @param [removeView=true] {boolean} Removes the Canvas element from the DOM.
|
||||
*/
|
||||
destroy: function ()
|
||||
{
|
||||
// CanvasPool
|
||||
|
||||
this.view = null;
|
||||
this.context = null;
|
||||
this.maskManager = null;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
49
src/renderer/canvas/gameobjects/Container.js
Normal file
49
src/renderer/canvas/gameobjects/Container.js
Normal file
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* Renders the object using the Canvas renderer
|
||||
*
|
||||
* @method _renderCanvas
|
||||
* @param renderSession {RenderSession}
|
||||
* @private
|
||||
*/
|
||||
Phaser.Renderer.Canvas.GameObjects.Container = {
|
||||
|
||||
render: function (renderer, source)
|
||||
{
|
||||
if (source.visible === false || source.alpha === 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// if (this._cacheAsBitmap)
|
||||
// {
|
||||
// this._renderCachedSprite(renderSession);
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (source._mask)
|
||||
{
|
||||
renderer.pushMask(source._mask);
|
||||
}
|
||||
|
||||
for (var i = 0; i < source.children.length; i++)
|
||||
{
|
||||
var child = source.children[i];
|
||||
|
||||
child.render(renderer, child);
|
||||
}
|
||||
|
||||
if (this._mask)
|
||||
{
|
||||
renderer.popMask();
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
renderCache: function (renderer, source)
|
||||
{
|
||||
// Do something
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
};
|
|
@ -6,138 +6,145 @@
|
|||
* @param {Matrix} [matrix] - Optional matrix. If provided the Display Object will be rendered using this matrix, otherwise it will use its worldTransform.
|
||||
* @private
|
||||
*/
|
||||
Phaser.CanvasRenderer.GameObjects.Sprite = function (src, renderSession, matrix) {
|
||||
Phaser.Renderer.Canvas.GameObjects.Sprite = {
|
||||
|
||||
// If the sprite is not visible or the alpha is 0 then no need to render this element
|
||||
if (!src.visible || src.alpha === 0 || !src.renderable || src.texture.crop.width <= 0 || src.texture.crop.height <= 0)
|
||||
render: function (renderer, source, matrix)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var wt = src.worldTransform;
|
||||
|
||||
// If they provided an alternative rendering matrix then use it
|
||||
if (matrix)
|
||||
{
|
||||
wt = matrix;
|
||||
}
|
||||
|
||||
if (src.blendMode !== renderSession.currentBlendMode)
|
||||
{
|
||||
renderSession.currentBlendMode = src.blendMode;
|
||||
renderSession.context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode];
|
||||
}
|
||||
|
||||
if (src._mask)
|
||||
{
|
||||
renderSession.maskManager.pushMask(src._mask, renderSession);
|
||||
}
|
||||
|
||||
// Ignore null sources
|
||||
if (!src.texture.valid)
|
||||
{
|
||||
// Update the children and leave
|
||||
for (var i = 0; i < src.children.length; i++)
|
||||
// If the sprite is not visible or the alpha is 0 then no need to render this element
|
||||
if (!source.visible || source.alpha === 0 || !source.renderable)
|
||||
{
|
||||
src.children[i]._renderCanvas(renderSession);
|
||||
return;
|
||||
}
|
||||
|
||||
if (src._mask)
|
||||
// Add back in: || src.texture.crop.width <= 0 || src.texture.crop.height <= 0
|
||||
|
||||
// If they provided an alternative rendering matrix then use it
|
||||
var wt = (matrix) ? matrix : source.worldTransform;
|
||||
|
||||
if (source.blendMode !== renderer.currentBlendMode)
|
||||
{
|
||||
renderSession.maskManager.popMask(renderSession);
|
||||
renderer.currentBlendMode = source.blendMode;
|
||||
renderer.context.globalCompositeOperation = Phaser.blendModesCanvas[renderer.currentBlendMode];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
// Check if the texture can be rendered
|
||||
|
||||
var resolution = src.texture.baseTexture.resolution / renderSession.resolution;
|
||||
|
||||
renderSession.context.globalAlpha = src.worldAlpha;
|
||||
|
||||
// If smoothingEnabled is supported and we need to change the smoothing property for src texture
|
||||
if (renderSession.smoothProperty && renderSession.scaleMode !== src.texture.baseTexture.scaleMode)
|
||||
{
|
||||
renderSession.scaleMode = src.texture.baseTexture.scaleMode;
|
||||
renderSession.context[renderSession.smoothProperty] = (renderSession.scaleMode === PIXI.scaleModes.LINEAR);
|
||||
}
|
||||
|
||||
// If the texture is trimmed we offset by the trim x/y, otherwise we use the frame dimensions
|
||||
var dx = (src.texture.trim) ? src.texture.trim.x - src.anchor.x * src.texture.trim.width : src.anchor.x * -src.texture.frame.width;
|
||||
var dy = (src.texture.trim) ? src.texture.trim.y - src.anchor.y * src.texture.trim.height : src.anchor.y * -src.texture.frame.height;
|
||||
|
||||
var tx = (wt.tx * renderSession.resolution) + renderSession.shakeX;
|
||||
var ty = (wt.ty * renderSession.resolution) + renderSession.shakeY;
|
||||
|
||||
var cw = src.texture.crop.width;
|
||||
var ch = src.texture.crop.height;
|
||||
|
||||
if (src.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 (renderSession.roundPixels)
|
||||
{
|
||||
renderSession.context.setTransform(wt.a, wt.b, wt.c, wt.d, tx | 0, ty | 0);
|
||||
dx |= 0;
|
||||
dy |= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
renderSession.context.setTransform(wt.a, wt.b, wt.c, wt.d, tx, ty);
|
||||
}
|
||||
|
||||
dx /= resolution;
|
||||
dy /= resolution;
|
||||
|
||||
if (src.tint !== 0xFFFFFF)
|
||||
{
|
||||
if (src.texture.requiresReTint || src.cachedTint !== src.tint)
|
||||
if (source._mask)
|
||||
{
|
||||
src.tintedTexture = PIXI.CanvasTinter.getTintedTexture(src, src.tint);
|
||||
|
||||
src.cachedTint = src.tint;
|
||||
src.texture.requiresReTint = false;
|
||||
renderer.pushMask(source._mask);
|
||||
}
|
||||
|
||||
renderSession.context.drawImage(src.tintedTexture, 0, 0, cw, ch, dx, dy, cw / resolution, ch / resolution);
|
||||
}
|
||||
else
|
||||
{
|
||||
var cx = src.texture.crop.x;
|
||||
var cy = src.texture.crop.y;
|
||||
// Ignore null sources
|
||||
/*
|
||||
if (!src.texture.valid)
|
||||
{
|
||||
// Update the children and leave
|
||||
for (var i = 0; i < src.children.length; i++)
|
||||
{
|
||||
src.children[i]._renderCanvas(renderSession);
|
||||
}
|
||||
|
||||
renderSession.context.drawImage(src.texture.baseTexture.source, cx, cy, cw, ch, dx, dy, cw / resolution, ch / resolution);
|
||||
}
|
||||
if (src._mask)
|
||||
{
|
||||
renderSession.maskManager.popMask(renderSession);
|
||||
}
|
||||
|
||||
for (var i = 0; i < src.children.length; i++)
|
||||
{
|
||||
src.children[i]._renderCanvas(renderSession);
|
||||
}
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
var resolution = source.texture.baseTexture.resolution / renderer.game.resolution;
|
||||
|
||||
renderer.context.globalAlpha = source.worldAlpha;
|
||||
|
||||
// If smoothingEnabled is supported and we need to change the smoothing property for src texture
|
||||
if (renderer.smoothProperty && renderer.currentScaleMode !== source.texture.baseTexture.scaleMode)
|
||||
{
|
||||
renderer.currentScaleMode = source.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 = (source.texture.trim) ? source.texture.trim.x - source.anchor.x * source.texture.trim.width : source.anchor.x * -source.texture.frame.width;
|
||||
var dy = (source.texture.trim) ? source.texture.trim.y - source.anchor.y * source.texture.trim.height : source.anchor.y * -source.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 = source.texture.crop.width;
|
||||
var ch = source.texture.crop.height;
|
||||
|
||||
if (source.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 (source.tint !== 0xFFFFFF)
|
||||
{
|
||||
if (source.texture.requiresReTint || source.cachedTint !== source.tint)
|
||||
{
|
||||
source.tintedTexture = PIXI.CanvasTinter.getTintedTexture(source, source.tint);
|
||||
|
||||
source.cachedTint = source.tint;
|
||||
source.texture.requiresReTint = false;
|
||||
}
|
||||
|
||||
renderer.context.drawImage(source.tintedTexture, 0, 0, cw, ch, dx, dy, cw / resolution, ch / resolution);
|
||||
}
|
||||
else
|
||||
{
|
||||
var cx = source.texture.crop.x;
|
||||
var cy = source.texture.crop.y;
|
||||
|
||||
renderer.context.drawImage(source.texture.baseTexture.source, cx, cy, cw, ch, dx, dy, cw / resolution, ch / resolution);
|
||||
}
|
||||
|
||||
for (var i = 0; i < source.children.length; i++)
|
||||
{
|
||||
var child = source.children[i];
|
||||
|
||||
child.render(renderer, child);
|
||||
}
|
||||
|
||||
if (source._mask)
|
||||
{
|
||||
renderer.popMask();
|
||||
}
|
||||
|
||||
if (src._mask)
|
||||
{
|
||||
renderSession.maskManager.popMask(renderSession);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -100,6 +100,9 @@ Phaser.TextureFrame = function (texture, name, sourceIndex, x, y, width, height)
|
|||
*/
|
||||
this.requiresReTint = false;
|
||||
|
||||
// Over-rides the Renderer setting? 0 = use Renderer Setting, 1 = No rounding, 2 = Round
|
||||
this.autoRound = 0;
|
||||
|
||||
/**
|
||||
* The un-modified source frame, trim and UV data.
|
||||
*
|
||||
|
|
|
@ -120,33 +120,6 @@ Phaser.Texture.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the base texture from the GPU, useful for managing resources on the GPU.
|
||||
* A texture is still 100% usable and will simply be re-uploaded if there is a sprite on screen that is using it.
|
||||
*
|
||||
* @method unloadFromGPU
|
||||
*/
|
||||
unloadFromGPU: function ()
|
||||
{
|
||||
this.dirty();
|
||||
|
||||
// delete the webGL textures if any.
|
||||
for (var i = this._glTextures.length - 1; i >= 0; i--)
|
||||
{
|
||||
var glTexture = this._glTextures[i];
|
||||
var gl = PIXI.glContexts[i];
|
||||
|
||||
if (gl && glTexture)
|
||||
{
|
||||
gl.deleteTexture(glTexture);
|
||||
}
|
||||
}
|
||||
|
||||
this._glTextures.length = 0;
|
||||
|
||||
this.dirty();
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroys this base texture
|
||||
*
|
||||
|
|
|
@ -185,6 +185,101 @@ Phaser.TextureManager.prototype = {
|
|||
|
||||
callback.apply(thisArg, args);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* TODO: This should move to the WebGL Renderer class.
|
||||
*
|
||||
* Removes the base texture from the GPU, useful for managing resources on the GPU.
|
||||
* A texture is still 100% usable and will simply be re-uploaded if there is a sprite on screen that is using it.
|
||||
*
|
||||
* @method unloadFromGPU
|
||||
*/
|
||||
unloadFromGPU: function ()
|
||||
{
|
||||
this.dirty();
|
||||
|
||||
// delete the webGL textures if any.
|
||||
for (var i = this._glTextures.length - 1; i >= 0; i--)
|
||||
{
|
||||
var glTexture = this._glTextures[i];
|
||||
var gl = PIXI.glContexts[i];
|
||||
|
||||
if (gl && glTexture)
|
||||
{
|
||||
gl.deleteTexture(glTexture);
|
||||
}
|
||||
}
|
||||
|
||||
this._glTextures.length = 0;
|
||||
|
||||
this.dirty();
|
||||
},
|
||||
|
||||
/**
|
||||
* TODO: This should move to the WebGL Renderer class.
|
||||
*
|
||||
* Updates and Creates a WebGL texture for the renderers context.
|
||||
*
|
||||
* @method updateTexture
|
||||
* @param texture {Texture} the texture to update
|
||||
* @return {boolean} True if the texture was successfully bound, otherwise false.
|
||||
*/
|
||||
loadToGPU: function (texture)
|
||||
{
|
||||
if (!texture.hasLoaded)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (texture.source.compressionAlgorithm)
|
||||
{
|
||||
return this.updateCompressedTexture(texture);
|
||||
}
|
||||
|
||||
var gl = this.gl;
|
||||
|
||||
if (!texture._glTextures[gl.id])
|
||||
{
|
||||
texture._glTextures[gl.id] = gl.createTexture();
|
||||
}
|
||||
|
||||
gl.activeTexture(gl.TEXTURE0 + texture.textureIndex);
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[gl.id]);
|
||||
|
||||
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultipliedAlpha);
|
||||
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);
|
||||
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST);
|
||||
|
||||
if (texture.mipmap && Phaser.Math.isPowerOfTwo(texture.width, texture.height))
|
||||
{
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST);
|
||||
gl.generateMipmap(gl.TEXTURE_2D);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST);
|
||||
}
|
||||
|
||||
if (!texture._powerOf2)
|
||||
{
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
|
||||
}
|
||||
|
||||
texture._dirty[gl.id] = false;
|
||||
|
||||
// return texture._glTextures[gl.id];
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue