mirror of
https://github.com/photonstorm/phaser
synced 2024-11-22 12:43:26 +00:00
Move ImageGPULayer to plugin.
This commit is contained in:
parent
affee47879
commit
a58f6d0f0c
17 changed files with 0 additions and 2273 deletions
|
@ -1,77 +0,0 @@
|
|||
/**
|
||||
* @author Benjamin D. Richards <benjamindrichards@gmail.com>
|
||||
* @copyright 2013-2024 Phaser Studio Inc.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Easing function identifiers.
|
||||
*
|
||||
* @ignore
|
||||
*/
|
||||
var EasingEncoding = {
|
||||
None: 0,
|
||||
|
||||
Power0: 1,
|
||||
Power1: 10,
|
||||
Power2: 20,
|
||||
Power3: 30,
|
||||
Power4: 40,
|
||||
Linear: 1,
|
||||
|
||||
Quad: 10,
|
||||
'Quad.easeOut': 10,
|
||||
'Quad.easeIn': 11,
|
||||
'Quad.easeInOut': 12,
|
||||
|
||||
Cubic: 20,
|
||||
'Cubic.easeOut': 20,
|
||||
'Cubic.easeIn': 21,
|
||||
'Cubic.easeInOut': 22,
|
||||
|
||||
Quart: 30,
|
||||
'Quart.easeOut': 30,
|
||||
'Quart.easeIn': 31,
|
||||
'Quart.easeInOut': 32,
|
||||
|
||||
Quint: 40,
|
||||
'Quint.easeOut': 40,
|
||||
'Quint.easeIn': 41,
|
||||
'Quint.easeInOut': 42,
|
||||
|
||||
Sine: 50,
|
||||
'Sine.easeOut': 50,
|
||||
'Sine.easeIn': 51,
|
||||
'Sine.easeInOut': 52,
|
||||
|
||||
Expo: 60,
|
||||
'Expo.easeOut': 60,
|
||||
'Expo.easeIn': 61,
|
||||
'Expo.easeInOut': 62,
|
||||
|
||||
Circ: 70,
|
||||
'Circ.easeOut': 70,
|
||||
'Circ.easeIn': 71,
|
||||
'Circ.easeInOut': 72,
|
||||
|
||||
// // Elastic requires extra parameters, so we skip it.
|
||||
// Elastic: 80,
|
||||
// 'Elastic.easeOut': 80,
|
||||
// 'Elastic.easeIn': 81,
|
||||
// 'Elastic.easeInOut': 82,
|
||||
|
||||
Back: 90,
|
||||
'Back.easeOut': 90,
|
||||
'Back.easeIn': 91,
|
||||
'Back.easeInOut': 92,
|
||||
|
||||
Bounce: 100,
|
||||
'Bounce.easeOut': 100,
|
||||
'Bounce.easeIn': 101,
|
||||
'Bounce.easeInOut': 102,
|
||||
|
||||
// Stepped could require extra parameters, but we assume just 2.
|
||||
Stepped: 110
|
||||
};
|
||||
|
||||
module.exports = EasingEncoding;
|
|
@ -1,757 +0,0 @@
|
|||
/**
|
||||
* @author Benjamin D. Richards <benjamindrichards@gmail.com>
|
||||
* @copyright 2013-2024 Phaser Studio Inc.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
var Class = require('../../utils/Class');
|
||||
var Utils = require('../../renderer/webgl/Utils.js');
|
||||
var SubmitterImageGPULayer = require('../../renderer/webgl/renderNodes/submitter/SubmitterImageGPULayer');
|
||||
var Components = require('../components');
|
||||
var GameObject = require('../GameObject');
|
||||
var EasingEncoding = require('./EasingEncoding');
|
||||
var ImageGPULayerRender = require('./ImageGPULayerRender');
|
||||
|
||||
var getTint = Utils.getTintAppendFloatAlpha;
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* An ImageGPULayer GameObject. This is a WebGL only GameObject.
|
||||
* It is optimized for rendering very large numbers of quads
|
||||
* following simple tween animations.
|
||||
* It is suited to complex backgrounds with animation.
|
||||
*
|
||||
* An ImageGPULayer is a composite object that contains a collection of
|
||||
* ImageGPULayerMember objects. It stores the rendering data for these
|
||||
* objects in a GPU buffer, and renders them in a single draw call.
|
||||
* Because it only updates the GPU buffer when necessary,
|
||||
* it is up to 100 times faster than rendering the objects individually.
|
||||
* Avoid changing the contents of the ImageGPULayer frequently, as this
|
||||
* requires the whole buffer to be updated.
|
||||
*
|
||||
* The layer can generally perform well with a million small quads.
|
||||
* The exact performance will depend on the device and the size of the quads.
|
||||
* If the quads are large, the layer will be fill-rate limited.
|
||||
* Try to avoid drawing more than a few million pixels per frame.
|
||||
*
|
||||
* When populating the ImageGPULayer, use `addMember` to add a new member
|
||||
* to the top of the layer. You should populate the layer all at once,
|
||||
* and leave it unchanged, rather than frequently adding and removing members,
|
||||
* because it is expensive to update the buffer.
|
||||
*
|
||||
* Rather than create a new `ImageGPULayer.Member` object for each `addMember` call,
|
||||
* you can reuse the same object. This is more efficient,
|
||||
* because creating millions of objects has a major performance cost
|
||||
* and may cause garbage collection issues.
|
||||
*
|
||||
* @class ImageGPULayer
|
||||
* @extends Phaser.GameObjects.GameObject
|
||||
* @memberof Phaser.GameObjects
|
||||
* @webglOnly
|
||||
*
|
||||
* @extends Phaser.GameObjects.Components.Alpha
|
||||
* @extends Phaser.GameObjects.Components.BlendMode
|
||||
* @extends Phaser.GameObjects.Components.Lighting
|
||||
* @extends Phaser.GameObjects.Components.Mask
|
||||
* @extends Phaser.GameObjects.Components.PostPipeline
|
||||
* @extends Phaser.GameObjects.Components.RenderNode
|
||||
* @extends Phaser.GameObjects.Components.TextureCrop
|
||||
* @extends Phaser.GameObjects.Components.Visible
|
||||
*
|
||||
* @constructor
|
||||
* @since 3.90.0
|
||||
* @param {Phaser.Scene} scene - The Scene to which this ImageGPULayer belongs.
|
||||
* @param {Phaser.Textures.Texture} texture - The texture that will be used to render the ImageGPULayer.
|
||||
* @param {number} size - The maximum number of quads that this ImageGPULayer will hold. This can be increased later if necessary.
|
||||
*/
|
||||
var ImageGPULayer = new Class({
|
||||
Extends: GameObject,
|
||||
|
||||
Mixins: [
|
||||
Components.Alpha,
|
||||
Components.BlendMode,
|
||||
Components.Lighting,
|
||||
Components.Mask,
|
||||
Components.PostPipeline,
|
||||
Components.RenderNode,
|
||||
Components.TextureCrop,
|
||||
Components.Visible,
|
||||
ImageGPULayerRender
|
||||
],
|
||||
|
||||
initialize: function ImageGPULayer (scene, texture, size)
|
||||
{
|
||||
GameObject.call(this, scene, 'ImageGPULayer');
|
||||
|
||||
/**
|
||||
* The number of quad members in the ImageGPULayer.
|
||||
*
|
||||
* @name Phaser.GameObjects.ImageGPULayer#memberCount
|
||||
* @type {number}
|
||||
* @since 3.90.0
|
||||
*/
|
||||
this.memberCount = 0;
|
||||
|
||||
/**
|
||||
* The maximum number of quad members that can be in the ImageGPULayer.
|
||||
* This value is read-only. Change buffer size with `resize`.
|
||||
*
|
||||
* @name Phaser.GameObjects.ImageGPULayer#size
|
||||
* @type {number}
|
||||
* @since 3.90.0
|
||||
* @readonly
|
||||
*/
|
||||
this.size = Math.max(size, 0);
|
||||
|
||||
/**
|
||||
* Whether the GPU buffer needs to be updated.
|
||||
* The update will occur on the next render.
|
||||
*
|
||||
* @name Phaser.GameObjects.ImageGPULayer#needsUpdate
|
||||
* @type {boolean}
|
||||
* @since 3.90.0
|
||||
*/
|
||||
this.needsUpdate = false;
|
||||
|
||||
/**
|
||||
* The time elapsed since timer initialization.
|
||||
* This drives the animation of the ImageGPULayer.
|
||||
*
|
||||
* @name Phaser.GameObjects.ImageGPULayer#timeElapsed
|
||||
* @type {number}
|
||||
* @since 3.90.0
|
||||
*/
|
||||
this.timeElapsed = 0;
|
||||
|
||||
/**
|
||||
* Whether the ImageGPULayer is paused.
|
||||
*
|
||||
* @name Phaser.GameObjects.ImageGPULayer#timePaused
|
||||
* @type {boolean}
|
||||
* @since 3.90.0
|
||||
* @default false
|
||||
*/
|
||||
this.timePaused = false;
|
||||
|
||||
/**
|
||||
* Values for valid easing functions that can be assigned to
|
||||
* the `ease` property of an ImageGPULayerMemberAnimation.
|
||||
*
|
||||
* @name Phaser.GameObjects.ImageGPULayer#EASE
|
||||
* @type {object}
|
||||
* @since 3.90.0
|
||||
* @readonly
|
||||
*/
|
||||
this.EASE = EasingEncoding;
|
||||
|
||||
this.setTexture(texture);
|
||||
this.initRenderNodes('ImageGPULayer');
|
||||
this.initPostPipeline(true);
|
||||
|
||||
/**
|
||||
* The SubmitterImageGPULayer RenderNode for this ImageGPULayer.
|
||||
*
|
||||
* This handles rendering the ImageGPULayer to the GPU.
|
||||
* It is created automatically when the ImageGPULayer is initialized.
|
||||
* Most RenderNodes are singletons stored in the RenderNodeManager,
|
||||
* but because this one holds very specific data,
|
||||
* it is stored in the ImageGPULayer itself.
|
||||
*
|
||||
* @name Phaser.GameObjects.ImageGPULayer#submitterNode
|
||||
* @type {Phaser.Renderer.WebGL.RenderNodes.SubmitterImageGPULayer}
|
||||
* @since 3.90.0
|
||||
*/
|
||||
this.submitterNode = new SubmitterImageGPULayer(scene.renderer.renderNodes, {}, this);
|
||||
|
||||
this.defaultRenderNodes['Submitter'] = this.submitterNode;
|
||||
this.renderNodeData[this.submitterNode.name] = {};
|
||||
|
||||
this.resize(this.size);
|
||||
|
||||
/**
|
||||
* A temporary buffer used to store member data before it is added to the GPU buffer.
|
||||
*
|
||||
* @name Phaser.GameObjects.ImageGPULayer#_tempMember
|
||||
* @type {ArrayBuffer}
|
||||
* @private
|
||||
* @since 3.90.0
|
||||
*/
|
||||
this._tempMember = new ArrayBuffer(this.submitterNode.instanceBufferLayout.layout.stride);
|
||||
|
||||
/**
|
||||
* A Float32Array view of the temporary member buffer.
|
||||
*
|
||||
* @name Phaser.GameObjects.ImageGPULayer#_tempMemberF32
|
||||
* @type {Float32Array}
|
||||
* @private
|
||||
* @since 3.90.0
|
||||
*/
|
||||
this._tempMemberF32 = new Float32Array(this._tempMember);
|
||||
|
||||
/**
|
||||
* A Uint32Array view of the temporary member buffer.
|
||||
* This is used to write 32-bit integer data to the buffer.
|
||||
* It is used for color data.
|
||||
*
|
||||
* @name Phaser.GameObjects.ImageGPULayer#_tempMemberU32
|
||||
* @type {Uint32Array}
|
||||
* @private
|
||||
* @since 3.90.0
|
||||
*/
|
||||
this._tempMemberU32 = new Uint32Array(this._tempMember);
|
||||
},
|
||||
|
||||
// Overrides Game Object method
|
||||
addedToScene: function ()
|
||||
{
|
||||
this.scene.sys.updateList.add(this);
|
||||
},
|
||||
|
||||
// Overrides Game Object method
|
||||
removedFromScene: function ()
|
||||
{
|
||||
this.scene.sys.updateList.remove(this);
|
||||
},
|
||||
|
||||
preUpdate: function (time, delta)
|
||||
{
|
||||
this.updateTimer(time, delta);
|
||||
},
|
||||
|
||||
/**
|
||||
* Resizes the ImageGPULayer buffer to a new size.
|
||||
* Optionally, clears the buffer.
|
||||
*
|
||||
* @method Phaser.GameObjects.ImageGPULayer#resize
|
||||
* @since 3.90.0
|
||||
* @param {number} count - The new number of members in the ImageGPULayer.
|
||||
* @param {boolean} [clear=false] - Whether to clear the buffer.
|
||||
* @returns {this} This ImageGPULayer object.
|
||||
*/
|
||||
resize: function (count, clear)
|
||||
{
|
||||
var layout = this.submitterNode.instanceBufferLayout;
|
||||
var buffer = layout.buffer;
|
||||
var u8 = buffer.viewU8;
|
||||
var targetByteSize = count * layout.layout.stride;
|
||||
|
||||
this.size = count;
|
||||
this.needsUpdate = true;
|
||||
|
||||
buffer.resize(targetByteSize);
|
||||
|
||||
if (clear)
|
||||
{
|
||||
this.memberCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy data from the old buffer to the new buffer.
|
||||
var newBuffer = buffer.viewU8;
|
||||
newBuffer.set(u8.subarray(0, Math.min(newBuffer.byteLength, targetByteSize)));
|
||||
this.memberCount = Math.min(this.memberCount, count);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds data to the ImageGPULayer buffer.
|
||||
*
|
||||
* This is mostly used internally by the ImageGPULayer.
|
||||
* It takes raw data as a buffer, which is very efficient,
|
||||
* but not easy to use. It is recommended to use the
|
||||
* `addMember` method instead.
|
||||
*
|
||||
* @method Phaser.GameObjects.ImageGPULayer#addData
|
||||
* @since 3.90.0
|
||||
* @param {Float32Array} member - The raw data to add to the buffer.
|
||||
* @returns {this} This ImageGPULayer object.
|
||||
*/
|
||||
addData: function (member)
|
||||
{
|
||||
if (this.memberCount >= this.size)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
var layout = this.submitterNode.instanceBufferLayout;
|
||||
var f32 = layout.buffer.viewF32;
|
||||
var offset = this.memberCount * layout.layout.stride;
|
||||
|
||||
f32.set(member, offset / f32.BYTES_PER_ELEMENT);
|
||||
|
||||
this.memberCount++;
|
||||
this.needsUpdate = true;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a member to the ImageGPULayer.
|
||||
*
|
||||
* @method Phaser.GameObjects.ImageGPULayer#addMember
|
||||
* @since 3.90.0
|
||||
* @param {Partial<Phaser.Types.GameObjects.ImageGPULayer.Member>} [member] - The member to add to the ImageGPULayer.
|
||||
* @returns {this} This ImageGPULayer object.
|
||||
*/
|
||||
addMember: function (member)
|
||||
{
|
||||
if (this.memberCount >= this.size)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
var f32 = this._tempMemberF32;
|
||||
var u32 = this._tempMemberU32;
|
||||
|
||||
if (!member)
|
||||
{
|
||||
member = {};
|
||||
}
|
||||
|
||||
var frame = member.frame || this.frame;
|
||||
|
||||
var offset = 0;
|
||||
|
||||
this._setAnimatedValue(member.x, offset);
|
||||
offset += 4;
|
||||
|
||||
this._setAnimatedValue(member.y, offset);
|
||||
offset += 4;
|
||||
|
||||
this._setAnimatedValue(member.rotation, offset);
|
||||
offset += 4;
|
||||
|
||||
this._setAnimatedValue(member.scaleX, offset, 1, frame.width);
|
||||
offset += 4;
|
||||
|
||||
this._setAnimatedValue(member.scaleY, offset, 1, frame.height);
|
||||
offset += 4;
|
||||
|
||||
f32[offset++] = member.originX || 0.5;
|
||||
f32[offset++] = member.originY || 0.5;
|
||||
|
||||
f32[offset++] = member.tintFill ? 1 : 0;
|
||||
|
||||
this._setAnimatedValue(member.scrollFactorX, offset, 1);
|
||||
offset += 4;
|
||||
|
||||
this._setAnimatedValue(member.scrollFactorY, offset, 1);
|
||||
offset += 4;
|
||||
|
||||
f32[offset++] = frame.u0;
|
||||
f32[offset++] = frame.v0;
|
||||
f32[offset++] = frame.u1;
|
||||
f32[offset++] = frame.v1;
|
||||
|
||||
this._setAnimatedValue(member.tintBlend, offset, 1);
|
||||
offset += 4;
|
||||
|
||||
var tintBottomLeft = member.tintBottomLeft === undefined ? 0xffffff : member.tintBottomLeft;
|
||||
var tintTopLeft = member.tintTopLeft === undefined ? 0xffffff : member.tintTopLeft;
|
||||
var tintBottomRight = member.tintBottomRight === undefined ? 0xffffff : member.tintBottomRight;
|
||||
var tintTopRight = member.tintTopRight === undefined ? 0xffffff : member.tintTopRight;
|
||||
|
||||
var alphaBottomLeft = member.alphaBottomLeft === undefined ? 1 : member.alphaBottomLeft;
|
||||
var alphaTopLeft = member.alphaTopLeft === undefined ? 1 : member.alphaTopLeft;
|
||||
var alphaBottomRight = member.alphaBottomRight === undefined ? 1 : member.alphaBottomRight;
|
||||
var alphaTopRight = member.alphaTopRight === undefined ? 1 : member.alphaTopRight;
|
||||
|
||||
u32[offset++] = getTint(
|
||||
tintBottomLeft,
|
||||
alphaBottomLeft
|
||||
);
|
||||
u32[offset++] = getTint(
|
||||
tintTopLeft,
|
||||
alphaTopLeft
|
||||
);
|
||||
u32[offset++] = getTint(
|
||||
tintBottomRight,
|
||||
alphaBottomRight
|
||||
);
|
||||
u32[offset++] = getTint(
|
||||
tintTopRight,
|
||||
alphaTopRight
|
||||
);
|
||||
|
||||
this._setAnimatedValue(member.alpha, offset, 1);
|
||||
offset += 4;
|
||||
|
||||
this.addData(this._tempMemberF32);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Edits a member of the ImageGPULayer.
|
||||
* This will update the member's data in the GPU buffer.
|
||||
* This is an expensive operation, as it requires the whole buffer to be updated.
|
||||
*
|
||||
* @method Phaser.GameObjects.ImageGPULayer#editMember
|
||||
* @since 3.90.0
|
||||
* @param {number} index - The index of the member to edit.
|
||||
* @param {Partial<Phaser.Types.GameObjects.ImageGPULayer.Member>} member - The new member data.
|
||||
* @returns {this} This ImageGPULayer object.
|
||||
*/
|
||||
editMember: function (index, member)
|
||||
{
|
||||
if (index < 0 || index >= this.memberCount)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
var currentMemberCount = this.memberCount;
|
||||
this.memberCount = index;
|
||||
this.addMember(member);
|
||||
this.memberCount = currentMemberCount + 1;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a member of the ImageGPULayer.
|
||||
*
|
||||
* This returns an object copied from the buffer.
|
||||
* Editing it will not change anything in the ImageGPULayer.
|
||||
* The object will be functionally identical to the data used to
|
||||
* create the buffer, but some values may be different.
|
||||
*
|
||||
* - Animation easing values will be presented as numbers (the values
|
||||
* in `this.EASE`).
|
||||
* - Animation offset values will be normalized to the duration,
|
||||
* e.g. an offset of 150 with a duration of 100 will return 50.
|
||||
* - Some rounding may occur due to floating point precision.
|
||||
*
|
||||
* @method Phaser.GameObjects.ImageGPULayer#getMember
|
||||
* @since 3.90.0
|
||||
* @param {number} index - The index of the member to get.
|
||||
* @returns {?Phaser.Types.GameObjects.ImageGPULayer.Member} The member data, or null if the index is out of bounds.
|
||||
*/
|
||||
getMember: function (index)
|
||||
{
|
||||
if (index < 0 || index >= this.memberCount)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var layout = this.submitterNode.instanceBufferLayout;
|
||||
var buffer = layout.buffer;
|
||||
var stride = layout.layout.stride;
|
||||
var byteOffset = index * stride;
|
||||
var f32 = buffer.viewF32;
|
||||
var u32 = buffer.viewU32;
|
||||
|
||||
var member = {};
|
||||
|
||||
var offset = byteOffset;
|
||||
|
||||
member.x = this._getAnimatedValue(offset);
|
||||
offset += 4;
|
||||
|
||||
member.y = this._getAnimatedValue(offset);
|
||||
offset += 4;
|
||||
|
||||
member.rotation = this._getAnimatedValue(offset);
|
||||
offset += 4;
|
||||
|
||||
member.scaleX = this._getAnimatedValue(offset);
|
||||
offset += 4;
|
||||
|
||||
member.scaleY = this._getAnimatedValue(offset);
|
||||
offset += 4;
|
||||
|
||||
member.originX = f32[offset++];
|
||||
member.originY = f32[offset++];
|
||||
member.tintFill = !!f32[offset++];
|
||||
|
||||
member.scrollFactorX = this._getAnimatedValue(offset);
|
||||
offset += 4;
|
||||
|
||||
member.scrollFactorY = this._getAnimatedValue(offset);
|
||||
offset += 4;
|
||||
|
||||
member.frame = {
|
||||
u0: f32[offset++],
|
||||
v0: f32[offset++],
|
||||
u1: f32[offset++],
|
||||
v1: f32[offset++]
|
||||
};
|
||||
|
||||
// Use frame data to revert scale values.
|
||||
var width = this.texture.source[0].width * (member.frame.u1 - member.frame.u0);
|
||||
if (typeof member.scaleX === 'object')
|
||||
{
|
||||
member.scaleX.base /= width;
|
||||
member.scaleX.amplitude /= width;
|
||||
}
|
||||
else
|
||||
{
|
||||
member.scaleX /= width;
|
||||
}
|
||||
var height = this.texture.source[0].height * (member.frame.v1 - member.frame.v0);
|
||||
if (typeof member.scaleY === 'object')
|
||||
{
|
||||
member.scaleY.base /= height;
|
||||
member.scaleY.amplitude /= height;
|
||||
}
|
||||
else
|
||||
{
|
||||
member.scaleY /= height;
|
||||
}
|
||||
|
||||
member.tintBlend = this._getAnimatedValue(offset);
|
||||
offset += 4;
|
||||
|
||||
member.tintBottomLeft = u32[offset++];
|
||||
member.tintTopLeft = u32[offset++];
|
||||
member.tintBottomRight = u32[offset++];
|
||||
member.tintTopRight = u32[offset++];
|
||||
member.alphaBottomLeft = (member.tintBottomLeft >>> 24) / 255;
|
||||
member.alphaTopLeft = (member.tintTopLeft >>> 24) / 255;
|
||||
member.alphaBottomRight = (member.tintBottomRight >>> 24) / 255;
|
||||
member.alphaTopRight = (member.tintTopRight >>> 24) / 255;
|
||||
member.tintBottomLeft &= 0xffffff;
|
||||
member.tintTopLeft &= 0xffffff;
|
||||
member.tintBottomRight &= 0xffffff;
|
||||
member.tintTopRight &= 0xffffff;
|
||||
|
||||
member.alpha = this._getAnimatedValue(offset);
|
||||
offset += 4;
|
||||
|
||||
return member;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes a member or a number of members from the ImageGPULayer.
|
||||
* This will update the GPU buffer.
|
||||
* This is an expensive operation, as it requires the whole buffer to be updated.
|
||||
*
|
||||
* The buffer is not resized.
|
||||
*
|
||||
* @method Phaser.GameObjects.ImageGPULayer#removeMember
|
||||
* @since 3.90.0
|
||||
* @param {number} index - The index of the member to remove.
|
||||
* @param {number} [count=1] - The number of members to remove, default 1.
|
||||
* @returns {this} This ImageGPULayer object.
|
||||
*/
|
||||
removeMember: function (index, count)
|
||||
{
|
||||
if (index < 0 || index >= this.memberCount)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
if (count === undefined)
|
||||
{
|
||||
count = 1;
|
||||
}
|
||||
|
||||
count = Math.min(count, this.memberCount - index);
|
||||
|
||||
var layout = this.submitterNode.instanceBufferLayout;
|
||||
var buffer = layout.buffer;
|
||||
var stride = layout.layout.stride;
|
||||
var byteOffset = index * stride;
|
||||
var byteLength = count * stride;
|
||||
|
||||
// Create temporary buffer containing a copy of the information
|
||||
// which comes after the removed members.
|
||||
var u8 = buffer.viewU8;
|
||||
var u8After = u8.subarray(byteOffset + byteLength);
|
||||
var newU8 = new Uint8Array(u8After.length);
|
||||
newU8.set(u8After);
|
||||
|
||||
// Copy the temporary buffer back to the original buffer,
|
||||
// overwriting the removed members.
|
||||
u8.set(newU8, byteOffset);
|
||||
|
||||
// Update layer properties.
|
||||
this.memberCount -= count;
|
||||
this.needsUpdate = true;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the values of an animation for a member of this ImageGPULayer.
|
||||
* The values are set on the temporary buffer, used internally.
|
||||
*
|
||||
* @method Phaser.GameObjects.ImageGPULayer#_setAnimatedValue
|
||||
* @since 3.90.0
|
||||
* @private
|
||||
* @param {undefined|number|Phaser.Types.GameObjects.ImageGPULayer.MemberAnimation} value - The value to set.
|
||||
* @param {number} index - The offset in the temporary buffer to write to.
|
||||
* @param {number} [defaultValue=0] - A default value to use if `value` is undefined.
|
||||
* @param {factor} [factor=1] - A factor to multiply the base value and amplitude by.
|
||||
*/
|
||||
_setAnimatedValue: function (value, index, defaultValue, factor)
|
||||
{
|
||||
var f32 = this._tempMemberF32;
|
||||
|
||||
if (defaultValue === undefined)
|
||||
{
|
||||
defaultValue = 0;
|
||||
}
|
||||
|
||||
if (factor === undefined)
|
||||
{
|
||||
factor = 1;
|
||||
}
|
||||
|
||||
if (typeof value === 'number')
|
||||
{
|
||||
f32[index++] = value * factor;
|
||||
f32[index++] = 0;
|
||||
f32[index++] = 0;
|
||||
f32[index++] = 0;
|
||||
}
|
||||
else if (value === undefined)
|
||||
{
|
||||
f32[index++] = defaultValue * factor;
|
||||
f32[index++] = 0;
|
||||
f32[index++] = 0;
|
||||
f32[index++] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
var base = value.base || 0;
|
||||
var ease = value.ease || 0;
|
||||
var amplitude = value.amplitude || 0;
|
||||
var duration = Math.abs(value.duration || 0);
|
||||
var offset = value.offset || 0;
|
||||
var yoyo = value.yoyo !== undefined ? value.yoyo : true;
|
||||
|
||||
if (typeof ease === 'string')
|
||||
{
|
||||
ease = this.EASE[ease] || 0;
|
||||
}
|
||||
|
||||
// Normalize offset.
|
||||
offset = (offset / duration) % 1;
|
||||
if (offset < 0)
|
||||
{
|
||||
offset += 1;
|
||||
}
|
||||
|
||||
// Add an integer to encode the type.
|
||||
offset += ease;
|
||||
|
||||
// Encode yoyo in the sign of duration, which must be positive.
|
||||
if (yoyo)
|
||||
{
|
||||
duration = -duration;
|
||||
}
|
||||
|
||||
f32[index++] = base * factor;
|
||||
f32[index++] = amplitude * factor;
|
||||
f32[index++] = duration;
|
||||
f32[index++] = offset;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the values of an animation for a member of this ImageGPULayer
|
||||
* in the buffer.
|
||||
*
|
||||
* @method Phaser.GameObjects.ImageGPULayer#_getAnimatedValue
|
||||
* @since 3.90.0
|
||||
* @private
|
||||
* @param {number} index - The index where the animation begins in the buffer.
|
||||
* @returns {number|Phaser.Types.GameObjects.ImageGPULayer.MemberAnimation} The animation values.
|
||||
*/
|
||||
_getAnimatedValue: function (index)
|
||||
{
|
||||
var f32 = this.submitterNode.instanceBufferLayout.buffer.viewF32;
|
||||
|
||||
var base = f32[index++];
|
||||
var amplitude = f32[index++];
|
||||
var duration = f32[index++];
|
||||
var offset = f32[index++];
|
||||
|
||||
if (duration === 0)
|
||||
{
|
||||
return base;
|
||||
}
|
||||
|
||||
var yoyo = duration < 0;
|
||||
if (yoyo)
|
||||
{
|
||||
duration = -duration;
|
||||
}
|
||||
|
||||
// Evaluate ease after duration, so duration has the correct sign.
|
||||
|
||||
var ease = Math.floor(offset);
|
||||
offset -= ease;
|
||||
offset *= duration;
|
||||
|
||||
return {
|
||||
base: base,
|
||||
ease: ease,
|
||||
amplitude: amplitude,
|
||||
duration: duration,
|
||||
offset: offset,
|
||||
yoyo: yoyo
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Pauses or resumes the animation timer for this ImageGPULayer.
|
||||
*
|
||||
* @method Phaser.GameObjects.ImageGPULayer#setTimerPaused
|
||||
* @since 3.90.0
|
||||
* @param {boolean} [paused] - Pause state (`true` to pause, `false` to unpause). If not specified, the timer will unpause.
|
||||
* @return {this} This ImageGPULayer object.
|
||||
*/
|
||||
setTimerPaused: function (paused)
|
||||
{
|
||||
this.timePaused = !!paused;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Reset the animation timer for this ImageGPULayer.
|
||||
*
|
||||
* @method Phaser.GameObjects.ImageGPULayer#resetTimer
|
||||
* @since 3.90.0
|
||||
* @param {number} [ms=0] - The time to reset the timer to.
|
||||
* @return {this} This ImageGPULayer object.
|
||||
*/
|
||||
resetTimer: function (ms)
|
||||
{
|
||||
if (ms === undefined) { ms = 0; }
|
||||
this.timeElapsed = ms;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the timer for this ImageGPULayer.
|
||||
* This is called automatically by the preUpdate method.
|
||||
* The timer drives the animation of the ImageGPULayer members.
|
||||
*
|
||||
* Override this method to create more advanced time management,
|
||||
* or set it to a NOOP function to disable the timer update.
|
||||
* If you want to control animations with a tween or input system,
|
||||
* disabling the timer update could be useful.
|
||||
*
|
||||
* @method Phaser.GameObjects.ImageGPULayer#updateTimer
|
||||
* @since 3.90.0
|
||||
* @param {number} time - The current time in milliseconds.
|
||||
* @param {number} delta - The time since the last update, in milliseconds.
|
||||
* @return {this} This ImageGPULayer object.
|
||||
*/
|
||||
updateTimer: function (time, delta)
|
||||
{
|
||||
if (!this.timePaused)
|
||||
{
|
||||
this.timeElapsed += delta;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = ImageGPULayer;
|
|
@ -1,57 +0,0 @@
|
|||
/**
|
||||
* @author Benjamin D. Richards <benjamindrichards@gmail.com>
|
||||
* @copyright 2013-2024 Phaser Studio Inc.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
var BlendModes = require('../../renderer/BlendModes');
|
||||
var GameObjectCreator = require('../GameObjectCreator');
|
||||
var GetAdvancedValue = require('../../utils/object/GetAdvancedValue');
|
||||
var ImageGPULayer = require('./ImageGPULayer');
|
||||
|
||||
/**
|
||||
* Creates a new ImageGPULayer Game Object and returns it.
|
||||
*
|
||||
* Note: This method will only be available if the ImageGPULayer Game Object
|
||||
* has been built into Phaser.
|
||||
*
|
||||
* @method Phaser.GameObjects.GameObjectCreator#image
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param {Phaser.Types.GameObjects.Sprite.SpriteConfig & { size: number }} config - The configuration object this Game Object will use to create itself.
|
||||
* @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object.
|
||||
*
|
||||
* @return {Phaser.GameObjects.Image} The Game Object that was created.
|
||||
*/
|
||||
GameObjectCreator.register('imageGPULayer', function (config, addToScene)
|
||||
{
|
||||
if (config === undefined) { config = {}; }
|
||||
|
||||
var key = GetAdvancedValue(config, 'key', null);
|
||||
var size = GetAdvancedValue(config, 'size', 1);
|
||||
|
||||
var imageGPULayer = new ImageGPULayer(this.scene, key, size);
|
||||
|
||||
if (addToScene !== undefined)
|
||||
{
|
||||
config.add = addToScene;
|
||||
}
|
||||
|
||||
// Alpha
|
||||
imageGPULayer.alpha = GetAdvancedValue(config, 'alpha', 1);
|
||||
|
||||
// Blend Mode
|
||||
imageGPULayer.blendMode = GetAdvancedValue(config, 'blendMode', BlendModes.NORMAL);
|
||||
|
||||
// Visible
|
||||
imageGPULayer.visible = GetAdvancedValue(config, 'visible', true);
|
||||
|
||||
if (addToScene)
|
||||
{
|
||||
this.scene.sys.displayList.add(imageGPULayer);
|
||||
}
|
||||
|
||||
return imageGPULayer;
|
||||
});
|
||||
|
||||
// When registering a factory function 'this' refers to the GameObjectCreator context.
|
|
@ -1,34 +0,0 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@phaser.io>
|
||||
* @copyright 2013-2024 Phaser Studio Inc.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
var ImageGPULayer = require('./ImageGPULayer');
|
||||
var GameObjectFactory = require('../GameObjectFactory');
|
||||
|
||||
/**
|
||||
* Creates a new ImageGPULayer Game Object and adds it to the Scene.
|
||||
*
|
||||
* Note: This method will only be available if the ImageGPULayer Game Object has been built into Phaser.
|
||||
*
|
||||
* @method Phaser.GameObjects.GameObjectFactory#imagegpulayer
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param {(string|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager.
|
||||
* @param {number} [size] - The number of members the ImageGPULayer will accommodate. Default 1.
|
||||
*
|
||||
* @return {Phaser.GameObjects.ImageGPULayer} The Game Object that was created.
|
||||
*/
|
||||
GameObjectFactory.register('imageGPULayer', function (texture, size)
|
||||
{
|
||||
return this.displayList.add(new ImageGPULayer(this.scene, texture, size));
|
||||
});
|
||||
|
||||
// When registering a factory function 'this' refers to the GameObjectFactory context.
|
||||
//
|
||||
// There are several properties available to use:
|
||||
//
|
||||
// this.scene - a reference to the Scene that owns the GameObjectFactory
|
||||
// this.displayList - a reference to the Display List the Scene owns
|
||||
// this.updateList - a reference to the Update List the Scene owns
|
|
@ -1,21 +0,0 @@
|
|||
/**
|
||||
* @author Benjamin D. Richards <benjamindrichards@gmail.com>
|
||||
* @copyright 2013-2024 Phaser Studio Inc.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
var NOOP = require('../../utils/NOOP');
|
||||
var renderWebGL = NOOP;
|
||||
var renderCanvas = NOOP;
|
||||
|
||||
if (typeof WEBGL_RENDERER)
|
||||
{
|
||||
renderWebGL = require('./ImageGPULayerWebGLRenderer');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
renderWebGL: renderWebGL,
|
||||
renderCanvas: renderCanvas
|
||||
|
||||
};
|
|
@ -1,33 +0,0 @@
|
|||
/**
|
||||
* @author Benjamin D. Richards <benjamindrichards@gmail.com>
|
||||
* @copyright 2013-2024 Phaser Studio Inc.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Renders this Game Object with the WebGL Renderer to the given Camera.
|
||||
* The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
|
||||
* This method should not be called directly. It is a utility function of the Render module.
|
||||
*
|
||||
* @method Phaser.GameObjects.ImageGPULayer#renderWebGL
|
||||
* @since 3.0.0
|
||||
* @private
|
||||
*
|
||||
* @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer.
|
||||
* @param {Phaser.GameObjects.Image} src - The Game Object being rendered in this call.
|
||||
* @param {Phaser.Renderer.WebGL.DrawingContext} drawingContext - The current drawing context.
|
||||
* @param {Phaser.GameObjects.Components.TransformMatrix} [parentMatrix] - This transform matrix is defined if the game object is nested.
|
||||
*/
|
||||
var ImageWebGLRenderer = function (renderer, src, drawingContext, parentMatrix)
|
||||
{
|
||||
drawingContext.camera.addToRenderList(src);
|
||||
|
||||
var customRenderNodes = src.customRenderNodes;
|
||||
var defaultRenderNodes = src.defaultRenderNodes;
|
||||
|
||||
(customRenderNodes.Submitter || defaultRenderNodes.Submitter).run(
|
||||
drawingContext
|
||||
);
|
||||
};
|
||||
|
||||
module.exports = ImageWebGLRenderer;
|
|
@ -1,26 +0,0 @@
|
|||
/**
|
||||
* @typedef {object} Phaser.Types.GameObjects.ImageGPULayer.Member
|
||||
* @since 3.90.0
|
||||
*
|
||||
* @property {number|Phaser.Types.GameObjects.ImageGPULayer.MemberAnimation} x - The x position of the member.
|
||||
* @property {number|Phaser.Types.GameObjects.ImageGPULayer.MemberAnimation} y - The y position of the member.
|
||||
* @property {number|Phaser.Types.GameObjects.ImageGPULayer.MemberAnimation} rotation - The rotation of the member.
|
||||
* @property {number|Phaser.Types.GameObjects.ImageGPULayer.MemberAnimation} scaleX - The x scale of the member.
|
||||
* @property {number|Phaser.Types.GameObjects.ImageGPULayer.MemberAnimation} scaleY - The y scale of the member.
|
||||
* @property {number} originX - The originX of the member (0-1).
|
||||
* @property {number} originY - The originY of the member (0-1).
|
||||
* @property {boolean} tintFill - Whether the member should be filled with the tint color. If false, the member texture will be multiplied by the tint. If true, the member will use the texture alpha and the tint color.
|
||||
* @property {number|Phaser.Types.GameObjects.ImageGPULayer.MemberAnimation} scrollFactorX - The horizontal camera scroll factor of the member.
|
||||
* @property {number|Phaser.Types.GameObjects.ImageGPULayer.MemberAnimation} scrollFactorY - The vertical camera scroll factor y of the member.
|
||||
* @property {{u0: number, v0: number, u1: number, v1: number}} frame - The frame of the member. You can pass a `Phaser.Types.Textures.Frame` object or an object with `u0`, `v0`, `u1`, and `v1` properties.
|
||||
* @property {number|Phaser.Types.GameObjects.ImageGPULayer.MemberAnimation} tintBlend - The tint blend mode of the member. 0 is no tint (equivalent to white), 1 is full tint. Use this to animate tint values, which are otherwise too complex to animate.
|
||||
* @property {number} tintBottomLeft - The bottom-left tint color of the member, as a 24-bit RGB value.
|
||||
* @property {number} tintTopLeft - The top-left tint color of the member, as a 24-bit RGB value.
|
||||
* @property {number} tintBottomRight - The bottom-right tint color of the member, as a 24-bit RGB value.
|
||||
* @property {number} tintTopRight - The top-right tint color of the member, as a 24-bit RGB value.
|
||||
* @property {number} alphaBottomLeft - The bottom-left alpha value of the member, in the range 0-1.
|
||||
* @property {number} alphaTopLeft - The top-left alpha value of the member, in the range 0-1.
|
||||
* @property {number} alphaBottomRight - The bottom-right alpha value of the member, in the range 0-1.
|
||||
* @property {number} alphaTopRight - The top-right alpha value of the member, in the range 0-1.
|
||||
* @property {number|Phaser.Types.GameObjects.ImageGPULayer.MemberAnimation} alpha - The alpha value of the member, in the range 0-1. This multiplies all four corner alpha values, and can be animated.
|
||||
*/
|
|
@ -1,11 +0,0 @@
|
|||
/**
|
||||
* @typedef {object} Phaser.Types.GameObjects.ImageGPULayer.MemberAnimation
|
||||
* @since 3.90.0
|
||||
*
|
||||
* @property {number} [base=0] - The base value of the animation.
|
||||
* @property {number|string} [ease=0] - The ease value of the animation. This must be a key or value of `ImageGPULayer.EASE`, e.g. 'Linear', 'Quad.easeIn', etc.
|
||||
* @property {number} [amplitude=0] - The amplitude of the animation.
|
||||
* @property {number} [duration=0] - The duration of the animation, in milliseconds. Must be non-negative.
|
||||
* @property {number} [offset=0] - The offset of the animation, in milliseconds.
|
||||
* @property {boolean} [yoyo=true] - Whether the animation runs backwards when it completes. If false, it starts over from the beginning.
|
||||
*/
|
|
@ -12,7 +12,6 @@ var DefaultBitmapTextNodes = require('./defaults/DefaultBitmapTextNodes');
|
|||
var DefaultBlitterNodes = require('./defaults/DefaultBlitterNodes');
|
||||
var DefaultGraphicsNodes = require('./defaults/DefaultGraphicsNodes');
|
||||
var DefaultImageNodes = require('./defaults/DefaultImageNodes');
|
||||
var DefaultImageGPULayerNodes = require('./defaults/DefaultImageGPULayerNodes');
|
||||
var DefaultNineSliceNodes = require('./defaults/DefaultNineSliceNodes');
|
||||
var DefaultParticleEmitterNodes = require('./defaults/DefaultParticleEmitterNodes');
|
||||
var DefaultPointLightNodes = require('./defaults/DefaultPointLightNodes');
|
||||
|
@ -118,7 +117,6 @@ var RenderNodeManager = new Class({
|
|||
Blitter: DefaultBlitterNodes,
|
||||
Graphics: DefaultGraphicsNodes,
|
||||
Image: DefaultImageNodes,
|
||||
ImageGPULayer: DefaultImageGPULayerNodes,
|
||||
NineSlice: DefaultNineSliceNodes,
|
||||
ParticleEmitter: DefaultParticleEmitterNodes,
|
||||
PointLight: DefaultPointLightNodes,
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
/**
|
||||
* @author Benjamin D. Richards <benjamindrichards@gmail.com>
|
||||
* @copyright 2013-2024 Phaser Studio Inc.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
var Map = require('../../../../structs/Map');
|
||||
|
||||
var DefaultImageGPULayerNodes = new Map([]);
|
||||
|
||||
module.exports = DefaultImageGPULayerNodes;
|
|
@ -29,7 +29,6 @@ var RenderNodes = {
|
|||
RebindContext: require('./RebindContext'),
|
||||
RenderNode: require('./RenderNode'),
|
||||
StrokePath: require('./StrokePath'),
|
||||
SubmitterImageGPULayer: require('./submitter/SubmitterImageGPULayer'),
|
||||
SubmitterQuad: require('./submitter/SubmitterQuad'),
|
||||
SubmitterQuadLight: require('./submitter/SubmitterQuadLight'),
|
||||
SubmitterTileSprite: require('./submitter/SubmitterTileSprite'),
|
||||
|
|
|
@ -1,433 +0,0 @@
|
|||
/**
|
||||
* @author Benjamin D. Richards <benjamindrichards@gmail.com>
|
||||
* @copyright 2013-2024 Phaser Studio Inc.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
var TransformMatrix = require('../../../../gameobjects/components/TransformMatrix');
|
||||
var Class = require('../../../../utils/Class');
|
||||
var Merge = require('../../../../utils/object/Merge');
|
||||
var ShaderSourceFS = require('../../shaders/ImageBakedLayer-frag');
|
||||
var ShaderSourceVS = require('../../shaders/ImageBakedLayer-vert');
|
||||
var WebGLVertexBufferLayoutWrapper = require('../../wrappers/WebGLVertexBufferLayoutWrapper');
|
||||
var RenderNode = require('../RenderNode');
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* This RenderNode handles rendering of a single ImageGPULayer object.
|
||||
* A new instance of the RenderNode should be created for each ImageGPULayer object,
|
||||
* as it stores the shader program and vertex buffer data for the object.
|
||||
*
|
||||
* It is a Stand Alone Render, meaning that it does not batch.
|
||||
* It is best suited to rendering highly complex objects.
|
||||
*
|
||||
* @class SubmitterImageGPULayer
|
||||
* @extends Phaser.Renderer.WebGL.RenderNodes.RenderNode
|
||||
* @memberof Phaser.Renderer.WebGL.RenderNodes
|
||||
* @constructor
|
||||
* @since 3.90.0
|
||||
* @param {Phaser.Renderer.WebGL.RenderNodes.RenderNodeManager} manager - The manager that owns this RenderNode.
|
||||
* @param {object} [config] - The configuration object for this handler.
|
||||
* @param {string} [config.name='SubmitterImageGPULayer'] - The name of this RenderNode.
|
||||
* @param {string} [config.vertexSource] - The vertex shader source.
|
||||
* @param {string} [config.fragmentSource] - The fragment shader source.
|
||||
*/
|
||||
var SubmitterImageGPULayer = new Class({
|
||||
Extends: RenderNode,
|
||||
|
||||
initialize: function SubmitterImageGPULayer (manager, config, gameObject)
|
||||
{
|
||||
var renderer = manager.renderer;
|
||||
|
||||
var finalConfig = Merge(config || {}, this.defaultConfig);
|
||||
var name = finalConfig.name;
|
||||
this._completeLayout(finalConfig);
|
||||
|
||||
RenderNode.call(this, name, manager);
|
||||
|
||||
/**
|
||||
* The ImageGPULayer GameObject this RenderNode is rendering.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.SubmitterImageGPULayer#gameObject
|
||||
* @type {Phaser.GameObjects.ImageGPULayer}
|
||||
* @since 3.90.0
|
||||
* @readonly
|
||||
*/
|
||||
this.gameObject = gameObject;
|
||||
|
||||
/**
|
||||
* The WebGL program used to render GameObjects.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.SubmitterImageGPULayer#program
|
||||
* @type {Phaser.Renderer.WebGL.Wrappers.WebGLProgramWrapper}
|
||||
* @since 3.90.0
|
||||
* @readonly
|
||||
*/
|
||||
this.program = renderer.createProgram(
|
||||
finalConfig.vertexSource,
|
||||
finalConfig.fragmentSource
|
||||
);
|
||||
|
||||
// Set texture sampler uniform.
|
||||
this.program.setUniform(
|
||||
'uMainSampler',
|
||||
0
|
||||
);
|
||||
|
||||
/**
|
||||
* The instance buffer layout for this RenderNode.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.SubmitterImageGPULayer#instanceBufferLayout
|
||||
* @type {Phaser.Renderer.WebGL.WebGLVertexBufferLayoutWrapper}
|
||||
* @since 3.90.0
|
||||
* @readonly
|
||||
*/
|
||||
this.instanceBufferLayout = new WebGLVertexBufferLayoutWrapper(
|
||||
renderer,
|
||||
this.program,
|
||||
finalConfig.instanceBufferLayout,
|
||||
null
|
||||
);
|
||||
|
||||
/**
|
||||
* The vertex buffer layout for this RenderNode.
|
||||
*
|
||||
* This consists of 4 bytes, 0-3, forming corners of a quad instance.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.SubmitterImageGPULayer#vertexBufferLayout
|
||||
* @type {Phaser.Renderer.WebGL.WebGLVertexBufferLayoutWrapper}
|
||||
* @since 3.90.0
|
||||
* @readonly
|
||||
*/
|
||||
this.vertexBufferLayout = new WebGLVertexBufferLayoutWrapper(
|
||||
renderer,
|
||||
this.program,
|
||||
finalConfig.vertexBufferLayout,
|
||||
null
|
||||
);
|
||||
|
||||
// Set up vertex buffer.
|
||||
var vertexBuffer = this.vertexBufferLayout.buffer;
|
||||
var vertexBufferViewU8 = vertexBuffer.viewU8;
|
||||
vertexBufferViewU8[0] = 0;
|
||||
vertexBufferViewU8[1] = 1;
|
||||
vertexBufferViewU8[2] = 2;
|
||||
vertexBufferViewU8[3] = 3;
|
||||
vertexBuffer.update();
|
||||
|
||||
/**
|
||||
* The Vertex Array Object (VAO) for this RenderNode.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.SubmitterImageGPULayer#vao
|
||||
* @type {Phaser.Renderer.WebGL.Wrappers.WebGLVAOWrapper}
|
||||
* @since 3.90.0
|
||||
* @readonly
|
||||
*/
|
||||
this.vao = renderer.createVAO(null, [
|
||||
this.instanceBufferLayout,
|
||||
this.vertexBufferLayout
|
||||
]);
|
||||
|
||||
/**
|
||||
* A matrix used for temporary calculations.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.SubmitterImageGPULayer#_calcMatrix
|
||||
* @type {Phaser.GameObjects.Components.TransformMatrix}
|
||||
* @since 3.90.0
|
||||
*/
|
||||
this._calcMatrix = new TransformMatrix();
|
||||
},
|
||||
|
||||
/**
|
||||
* Default configuration of this RenderNode.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.SubmitterImageGPULayer#defaultConfig
|
||||
* @type {object}
|
||||
* @since 3.90.0
|
||||
* @readonly
|
||||
* @property {string} name - The name of this RenderNode.
|
||||
* @property {string} vertexSource - The vertex shader source.
|
||||
* @property {string} fragmentSource - The fragment shader source.
|
||||
*/
|
||||
defaultConfig: {
|
||||
name: 'SubmitterImageGPULayer',
|
||||
count: 0,
|
||||
vertexSource: ShaderSourceVS,
|
||||
fragmentSource: ShaderSourceFS,
|
||||
instanceBufferLayout: {
|
||||
usage: 'STATIC_DRAW',
|
||||
instanceDivisor: 1,
|
||||
layout: [
|
||||
{
|
||||
name: 'inPositionX',
|
||||
size: 4
|
||||
},
|
||||
{
|
||||
name: 'inPositionY',
|
||||
size: 4
|
||||
},
|
||||
{
|
||||
name: 'inRotation',
|
||||
size: 4
|
||||
},
|
||||
{
|
||||
name: 'inScaleX',
|
||||
size: 4
|
||||
},
|
||||
{
|
||||
name: 'inScaleY',
|
||||
size: 4
|
||||
},
|
||||
{
|
||||
name: 'inOriginAndTintFill',
|
||||
size: 3
|
||||
},
|
||||
{
|
||||
name: 'inScrollFactorX',
|
||||
size: 4
|
||||
},
|
||||
{
|
||||
name: 'inScrollFactorY',
|
||||
size: 4
|
||||
},
|
||||
{
|
||||
name: 'inFrameUVs',
|
||||
size: 4
|
||||
},
|
||||
{
|
||||
name: 'inTintBlend',
|
||||
size: 4
|
||||
},
|
||||
{
|
||||
name: 'inTintBL',
|
||||
size: 4,
|
||||
type: 'UNSIGNED_BYTE',
|
||||
normalized: true
|
||||
},
|
||||
{
|
||||
name: 'inTintTL',
|
||||
size: 4,
|
||||
type: 'UNSIGNED_BYTE',
|
||||
normalized: true
|
||||
},
|
||||
{
|
||||
name: 'inTintBR',
|
||||
size: 4,
|
||||
type: 'UNSIGNED_BYTE',
|
||||
normalized: true
|
||||
},
|
||||
{
|
||||
name: 'inTintTR',
|
||||
size: 4,
|
||||
type: 'UNSIGNED_BYTE',
|
||||
normalized: true
|
||||
},
|
||||
{
|
||||
name: 'inAlpha',
|
||||
size: 4
|
||||
}
|
||||
]
|
||||
},
|
||||
vertexBufferLayout: {
|
||||
usage: 'STATIC_DRAW',
|
||||
count: 4,
|
||||
layout: [
|
||||
{
|
||||
// The vertex index, 0-3.
|
||||
name: 'inVertex',
|
||||
type: 'UNSIGNED_BYTE'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Fill out the configuration object with default values where needed.
|
||||
*
|
||||
* @method Phaser.Renderer.WebGL.RenderNodes.SubmitterImageGPULayer#_completeConfig
|
||||
* @since 3.90.0
|
||||
* @param {object} config - The configuration object to complete.
|
||||
*/
|
||||
_completeLayout: function (config)
|
||||
{
|
||||
// Set up vertex buffer layout.
|
||||
var layoutSource = config.vertexBufferLayout;
|
||||
config.vertexBufferLayout = {};
|
||||
config.vertexBufferLayout.usage = layoutSource.usage;
|
||||
config.vertexBufferLayout.count = layoutSource.count;
|
||||
config.vertexBufferLayout.layout = [];
|
||||
var remove = config.vertexBufferLayoutRemove || [];
|
||||
|
||||
for (var i = 0; i < layoutSource.layout.length; i++)
|
||||
{
|
||||
var sourceAttr = layoutSource.layout[i];
|
||||
if (remove.indexOf(sourceAttr.name) !== -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
config.vertexBufferLayout.layout[i] = {
|
||||
name: sourceAttr.name,
|
||||
size: sourceAttr.size || 1,
|
||||
type: sourceAttr.type || 'FLOAT',
|
||||
normalized: sourceAttr.normalized || false
|
||||
};
|
||||
}
|
||||
|
||||
if (config.vertexBufferLayoutAdd)
|
||||
{
|
||||
var add = config.vertexBufferLayoutAdd || [];
|
||||
for (i = 0; i < add.length; i++)
|
||||
{
|
||||
var addAttr = add[i];
|
||||
config.vertexBufferLayout.layout.push({
|
||||
name: addAttr.name,
|
||||
size: addAttr.size || 1,
|
||||
type: addAttr.type || 'FLOAT',
|
||||
normalized: addAttr.normalized || false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Set up instance buffer layout.
|
||||
layoutSource = config.instanceBufferLayout;
|
||||
config.instanceBufferLayout = {};
|
||||
config.instanceBufferLayout.usage = layoutSource.usage;
|
||||
config.instanceBufferLayout.instanceDivisor = layoutSource.instanceDivisor;
|
||||
config.instanceBufferLayout.layout = [];
|
||||
remove = config.instanceBufferLayoutRemove || [];
|
||||
|
||||
for (i = 0; i < layoutSource.layout.length; i++)
|
||||
{
|
||||
sourceAttr = layoutSource.layout[i];
|
||||
if (remove.indexOf(sourceAttr.name) !== -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
config.instanceBufferLayout.layout[i] = {
|
||||
name: sourceAttr.name,
|
||||
size: sourceAttr.size || 1,
|
||||
type: sourceAttr.type || 'FLOAT',
|
||||
normalized: sourceAttr.normalized || false
|
||||
};
|
||||
}
|
||||
|
||||
if (config.instanceBufferLayoutAdd)
|
||||
{
|
||||
add = config.instanceBufferLayoutAdd || [];
|
||||
for (i = 0; i < add.length; i++)
|
||||
{
|
||||
addAttr = add[i];
|
||||
config.instanceBufferLayout.layout.push({
|
||||
name: addAttr.name,
|
||||
size: addAttr.size || 1,
|
||||
type: addAttr.type || 'FLOAT',
|
||||
normalized: addAttr.normalized || false
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called at the start of the `run` method.
|
||||
*
|
||||
* @method Phaser.Renderer.WebGL.RenderNodes.SubmitterImageGPULayer#onRunBegin
|
||||
* @since 3.90.0
|
||||
* @param {Phaser.Renderer.WebGL.DrawingContext} drawingContext - The current drawing context.
|
||||
*/
|
||||
onRunBegin: function (drawingContext)
|
||||
{
|
||||
var camera = drawingContext.camera;
|
||||
|
||||
this.program.setUniform(
|
||||
'uRoundPixels',
|
||||
camera.roundPixels
|
||||
);
|
||||
|
||||
this.program.setUniform(
|
||||
'uResolution',
|
||||
[ drawingContext.width, drawingContext.height ]
|
||||
);
|
||||
|
||||
drawingContext.renderer.setProjectionMatrix(
|
||||
drawingContext.width,
|
||||
drawingContext.height
|
||||
);
|
||||
this.program.setUniform(
|
||||
'uProjectionMatrix',
|
||||
drawingContext.renderer.projectionMatrix.val
|
||||
);
|
||||
|
||||
var cm = camera.matrix;
|
||||
this.program.setUniform(
|
||||
'uViewMatrix',
|
||||
[
|
||||
cm.a, cm.b, 0,
|
||||
cm.c, cm.d, 0,
|
||||
cm.tx, cm.ty, 1
|
||||
]
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Render an ImageGPULayer object.
|
||||
*
|
||||
* @method Phaser.Renderer.WebGL.RenderNodes.SubmitterImageGPULayer#run
|
||||
* @since 3.90.0
|
||||
* @param {Phaser.Renderer.WebGL.DrawingContext} drawingContext - The current drawing context.
|
||||
*/
|
||||
run: function (drawingContext)
|
||||
{
|
||||
var layer = this.gameObject;
|
||||
|
||||
if (layer.memberCount === 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.manager.startStandAloneRender();
|
||||
|
||||
this.onRunBegin(drawingContext);
|
||||
|
||||
if (layer.needsUpdate)
|
||||
{
|
||||
this.instanceBufferLayout.buffer.update();
|
||||
layer.needsUpdate = false;
|
||||
}
|
||||
|
||||
// Set game object derived uniforms.
|
||||
var camera = drawingContext.camera;
|
||||
this.program.setUniform(
|
||||
'uCameraScrollAndAlpha',
|
||||
[
|
||||
camera.scrollX,
|
||||
camera.scrollY,
|
||||
camera.alpha * layer.alpha
|
||||
]
|
||||
);
|
||||
|
||||
this.program.setUniform(
|
||||
'uTime',
|
||||
layer.timeElapsed
|
||||
);
|
||||
|
||||
// Assemble textures.
|
||||
var textures = [
|
||||
layer.frame.source.glTexture
|
||||
];
|
||||
|
||||
// Render instances.
|
||||
this.manager.renderer.drawInstancedArrays(
|
||||
drawingContext,
|
||||
textures,
|
||||
this.program,
|
||||
this.vao,
|
||||
0,
|
||||
4,
|
||||
layer.memberCount
|
||||
);
|
||||
|
||||
this.onRunEnd(drawingContext);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = SubmitterImageGPULayer;
|
|
@ -1,23 +0,0 @@
|
|||
module.exports = [
|
||||
'#define SHADER_NAME PHASER_IMAGE_BAKED_LAYER_FS',
|
||||
'#ifdef GL_FRAGMENT_PRECISION_HIGH',
|
||||
'precision highp float;',
|
||||
'#else',
|
||||
'precision mediump float;',
|
||||
'#endif',
|
||||
'uniform sampler2D uMainSampler;',
|
||||
'varying vec2 outTexCoord;',
|
||||
'varying float outTintEffect;',
|
||||
'varying vec4 outTint;',
|
||||
'void main ()',
|
||||
'{',
|
||||
' vec4 texture = texture2D(uMainSampler, outTexCoord);',
|
||||
' vec4 texel = vec4(outTint.bgr * outTint.a, outTint.a);',
|
||||
' vec4 color = texture * texel;',
|
||||
' if (outTintEffect == 1.0)',
|
||||
' {',
|
||||
' color.rgb = mix(texture.rgb, texel.rgb, texture.a);',
|
||||
' }',
|
||||
' gl_FragColor = color;',
|
||||
'}',
|
||||
].join('\n');
|
|
@ -1,344 +0,0 @@
|
|||
module.exports = [
|
||||
'#define SHADER_NAME PHASER_IMAGE_BAKED_LAYER_VS',
|
||||
'precision mediump float;',
|
||||
'uniform mat4 uProjectionMatrix;',
|
||||
'uniform mat3 uViewMatrix;',
|
||||
'uniform vec3 uCameraScrollAndAlpha;',
|
||||
'uniform int uRoundPixels;',
|
||||
'uniform vec2 uResolution;',
|
||||
'uniform float uTime;',
|
||||
'attribute float inVertex;',
|
||||
'attribute vec4 inPositionX;',
|
||||
'attribute vec4 inPositionY;',
|
||||
'attribute vec4 inRotation;',
|
||||
'attribute vec4 inScaleX;',
|
||||
'attribute vec4 inScaleY;',
|
||||
'attribute vec3 inOriginAndTintFill;',
|
||||
'attribute vec4 inScrollFactorX;',
|
||||
'attribute vec4 inScrollFactorY;',
|
||||
'attribute vec4 inFrameUVs;',
|
||||
'attribute vec4 inTintBlend;',
|
||||
'attribute vec4 inTintTL;',
|
||||
'attribute vec4 inTintTR;',
|
||||
'attribute vec4 inTintBL;',
|
||||
'attribute vec4 inTintBR;',
|
||||
'attribute vec4 inAlpha;',
|
||||
'varying vec2 outTexCoord;',
|
||||
'varying float outTintEffect;',
|
||||
'varying vec4 outTint;',
|
||||
'const float PI = 3.14159265359;',
|
||||
'const float HALF_PI = PI / 2.0;',
|
||||
'const float BOUNCE_OVERSHOOT = 1.70158;',
|
||||
'const float BOUNCE_OVERSHOOT_PLUS = BOUNCE_OVERSHOOT + 1.0;',
|
||||
'const float BOUNCE_OVERSHOOT_IN_OUT = BOUNCE_OVERSHOOT * 1.525;',
|
||||
'const float BOUNCE_OVERSHOOT_IN_OUT_PLUS = BOUNCE_OVERSHOOT_IN_OUT + 1.0;',
|
||||
'float animate (vec4 anim)',
|
||||
'{',
|
||||
' float value = anim.x;',
|
||||
' float a = anim.y;',
|
||||
' float b = anim.z;',
|
||||
' float c = anim.w;',
|
||||
' int type = int(floor(c));',
|
||||
' if (type == 0 || a == 0.0 || b == 0.0)',
|
||||
' {',
|
||||
' return value;',
|
||||
' }',
|
||||
' float duration = b;',
|
||||
' float offset = mod(c, 1.0) * b;',
|
||||
' bool yoyo = b < 0.0;',
|
||||
' float rawTime = uTime / duration + offset;',
|
||||
' float time = mod(rawTime, 1.0);',
|
||||
' if (yoyo && mod(rawTime, 2.0) > 1.0)',
|
||||
' {',
|
||||
' time = 1.0 - time;',
|
||||
' }',
|
||||
' if (type == 1)',
|
||||
' {',
|
||||
' return value + a * time;',
|
||||
' }',
|
||||
' else if (type == 10)',
|
||||
' {',
|
||||
' return value + a * time * (2.0 - time);',
|
||||
' }',
|
||||
' else if (type == 11)',
|
||||
' {',
|
||||
' return value + a * time * time;',
|
||||
' }',
|
||||
' else if (type == 12)',
|
||||
' {',
|
||||
' time *= 2.0;',
|
||||
' if (time < 1.0)',
|
||||
' {',
|
||||
' return value + a * time * time * 0.5;',
|
||||
' }',
|
||||
' time -= 1.0;',
|
||||
' return value + a * -0.5 * (time * (time - 2.0) - 1.0);',
|
||||
' }',
|
||||
' else if (type == 20)',
|
||||
' {',
|
||||
' time -= 1.0;',
|
||||
' return value + a * (time * time * time + 1.0);',
|
||||
' }',
|
||||
' else if (type == 21)',
|
||||
' {',
|
||||
' return value + a * time * time * time;',
|
||||
' }',
|
||||
' else if (type == 22)',
|
||||
' {',
|
||||
' time *= 2.0;',
|
||||
' if (time < 1.0)',
|
||||
' {',
|
||||
' return value + a * time * time * time * 0.5;',
|
||||
' }',
|
||||
' time -= 2.0;',
|
||||
' return value + a * 0.5 * (time * time * time + 2.0);',
|
||||
' }',
|
||||
' else if (type == 30)',
|
||||
' {',
|
||||
' time -= 1.0;',
|
||||
' return value + a * (1.0 - time * time * time * time);',
|
||||
' }',
|
||||
' else if (type == 31)',
|
||||
' {',
|
||||
' return value + a * time * time * time * time;',
|
||||
' }',
|
||||
' else if (type == 32)',
|
||||
' {',
|
||||
' time *= 2.0;',
|
||||
' if (time < 1.0)',
|
||||
' {',
|
||||
' return value + a * time * time * time * time * 0.5;',
|
||||
' }',
|
||||
' time -= 2.0;',
|
||||
' return value + a * -0.5 * (time * time * time * time - 2.0);',
|
||||
' }',
|
||||
' else if (type == 40)',
|
||||
' {',
|
||||
' time -= 1.0;',
|
||||
' return value + a * (time * time * time * time * time + 1.0);',
|
||||
' }',
|
||||
' else if (type == 41)',
|
||||
' {',
|
||||
' return value + a * time * time * time * time * time;',
|
||||
' }',
|
||||
' else if (type == 42)',
|
||||
' {',
|
||||
' time *= 2.0;',
|
||||
' if (time < 1.0)',
|
||||
' {',
|
||||
' return value + a * time * time * time * time * time * 0.5;',
|
||||
' }',
|
||||
' time -= 2.0;',
|
||||
' return value + a * 0.5 * (time * time * time * time * time + 2.0);',
|
||||
' }',
|
||||
' else if (type == 50)',
|
||||
' {',
|
||||
' return value + a * sin(time * HALF_PI);',
|
||||
' }',
|
||||
' else if (type == 51)',
|
||||
' {',
|
||||
' return value + a * (1.0 - cos(time * HALF_PI));',
|
||||
' }',
|
||||
' else if (type == 52)',
|
||||
' {',
|
||||
' return value + a * 0.5 * (1.0 - cos(PI * time));',
|
||||
' }',
|
||||
' else if (type == 60)',
|
||||
' {',
|
||||
' return value + a * (1.0 - pow(2.0, -10.0 * time));',
|
||||
' }',
|
||||
' else if (type == 61)',
|
||||
' {',
|
||||
' return value + a * pow(2.0, 10.0 * (time - 1.0) - 0.001);',
|
||||
' }',
|
||||
' else if (type == 62)',
|
||||
' {',
|
||||
' time *= 2.0;',
|
||||
' if (time < 1.0)',
|
||||
' {',
|
||||
' return value + a * 0.5 * pow(2.0, 10.0 * (time - 1.0));',
|
||||
' }',
|
||||
' time -= 1.0;',
|
||||
' return value + a * 0.5 * (2.0 - pow(2.0, -10.0 * (time - 1.0)));',
|
||||
' }',
|
||||
' else if (type == 70)',
|
||||
' {',
|
||||
' time -= 1.0;',
|
||||
' return value + a * sqrt(1.0 - time * time);',
|
||||
' }',
|
||||
' else if (type == 71)',
|
||||
' {',
|
||||
' return value + a * (1.0 - sqrt(1.0 - time * time));',
|
||||
' }',
|
||||
' else if (type == 72)',
|
||||
' {',
|
||||
' time *= 2.0;',
|
||||
' if (time < 1.0)',
|
||||
' {',
|
||||
' return value + a * -0.5 * (sqrt(1.0 - time * time) - 1.0);',
|
||||
' }',
|
||||
' time -= 2.0;',
|
||||
' return value + a * 0.5 * (sqrt(1.0 - time * time) + 1.0);',
|
||||
' }',
|
||||
' else if (type == 90)',
|
||||
' {',
|
||||
' time -= 1.0;',
|
||||
' return value + a * (time * time * (BOUNCE_OVERSHOOT_PLUS * time + BOUNCE_OVERSHOOT) + 1.0);',
|
||||
' }',
|
||||
' else if (type == 91)',
|
||||
' {',
|
||||
' return value + a * time * time * (BOUNCE_OVERSHOOT_PLUS * time - BOUNCE_OVERSHOOT);',
|
||||
' }',
|
||||
' else if (type == 92)',
|
||||
' {',
|
||||
' time *= 2.0;',
|
||||
' if (time < 1.0)',
|
||||
' {',
|
||||
' return value + a * 0.5 * (time * time * (BOUNCE_OVERSHOOT_IN_OUT_PLUS * time - BOUNCE_OVERSHOOT_IN_OUT));',
|
||||
' }',
|
||||
' time -= 2.0;',
|
||||
' return value + a * 0.5 * (time * time * (BOUNCE_OVERSHOOT_IN_OUT_PLUS * time + BOUNCE_OVERSHOOT_IN_OUT) + 2.0);',
|
||||
' }',
|
||||
' else if (type == 100)',
|
||||
' {',
|
||||
' if (time < 1.0 / 2.75)',
|
||||
' {',
|
||||
' return value + a * (7.5625 * time * time);',
|
||||
' }',
|
||||
' else if (time < 2.0 / 2.75)',
|
||||
' {',
|
||||
' time -= 1.5 / 2.75;',
|
||||
' return value + a * (7.5625 * time * time + 0.75);',
|
||||
' }',
|
||||
' else if (time < 2.5 / 2.75)',
|
||||
' {',
|
||||
' time -= 2.25 / 2.75;',
|
||||
' return value + a * (7.5625 * time * time + 0.9375);',
|
||||
' }',
|
||||
' else',
|
||||
' {',
|
||||
' time -= 2.625 / 2.75;',
|
||||
' return value + a * (7.5625 * time * time + 0.984375);',
|
||||
' }',
|
||||
' }',
|
||||
' else if (type == 101)',
|
||||
' {',
|
||||
' time = 1.0 - time;',
|
||||
' if (time < 1.0 / 2.75)',
|
||||
' {',
|
||||
' return value + a * (1.0 - 7.5625 * time * time);',
|
||||
' }',
|
||||
' else if (time < 2.0 / 2.75)',
|
||||
' {',
|
||||
' time -= 1.5 / 2.75;',
|
||||
' return value + a * (1.0 - (7.5625 * time * time + 0.75));',
|
||||
' }',
|
||||
' else if (time < 2.5 / 2.75)',
|
||||
' {',
|
||||
' time -= 2.25 / 2.75;',
|
||||
' return value + a * (1.0 - (7.5625 * time * time + 0.9375));',
|
||||
' }',
|
||||
' else',
|
||||
' {',
|
||||
' time -= 2.625 / 2.75;',
|
||||
' return value + a * (1.0 - (7.5625 * time * time + 0.984375));',
|
||||
' }',
|
||||
' }',
|
||||
' else if (type == 102)',
|
||||
' {',
|
||||
' bool reverse = false;',
|
||||
' if (time < 0.5)',
|
||||
' {',
|
||||
' time = 1.0 - time * 2.0;',
|
||||
' reverse = true;',
|
||||
' }',
|
||||
' if (time < 1.0 / 2.75)',
|
||||
' {',
|
||||
' time = 7.5625 * time * time;',
|
||||
' }',
|
||||
' else if (time < 2.0 / 2.75)',
|
||||
' {',
|
||||
' time -= 1.5 / 2.75;',
|
||||
' time = 7.5625 * time * time + 0.75;',
|
||||
' }',
|
||||
' else if (time < 2.5 / 2.75)',
|
||||
' {',
|
||||
' time -= 2.25 / 2.75;',
|
||||
' time = 7.5625 * time * time + 0.9375;',
|
||||
' }',
|
||||
' else',
|
||||
' {',
|
||||
' time -= 2.625 / 2.75;',
|
||||
' time = 7.5625 * time * time + 0.984375;',
|
||||
' }',
|
||||
' if (reverse)',
|
||||
' {',
|
||||
' return value + a * (1.0 - time) * 0.5;',
|
||||
' }',
|
||||
' return value + a * time * 0.5 + 0.5;',
|
||||
' }',
|
||||
' else if (type == 110)',
|
||||
' {',
|
||||
' return value + a * floor(time + 0.5);',
|
||||
' }',
|
||||
' return value;',
|
||||
'}',
|
||||
'void main ()',
|
||||
'{',
|
||||
' float positionX = animate(inPositionX);',
|
||||
' float positionY = animate(inPositionY);',
|
||||
' float rotation = animate(inRotation);',
|
||||
' float scaleX = animate(inScaleX);',
|
||||
' float scaleY = animate(inScaleY);',
|
||||
' float scrollFactorX = animate(inScrollFactorX);',
|
||||
' float scrollFactorY = animate(inScrollFactorY);',
|
||||
' float tintBlend = animate(inTintBlend);',
|
||||
' float alpha = animate(inAlpha);',
|
||||
' vec2 origin = inOriginAndTintFill.xy;',
|
||||
' float tintFill = inOriginAndTintFill.z;',
|
||||
' float x = -origin.x;',
|
||||
' float y = -origin.y;',
|
||||
' float u = inFrameUVs.x;',
|
||||
' float v = inFrameUVs.y;',
|
||||
' vec4 tint = inTintTL;',
|
||||
' if (inVertex == 0.0)',
|
||||
' {',
|
||||
' y = 1.0 - origin.y;',
|
||||
' v = inFrameUVs.w;',
|
||||
' tint = inTintBL;',
|
||||
' }',
|
||||
' else if (inVertex == 2.0)',
|
||||
' {',
|
||||
' x = 1.0 - origin.x;',
|
||||
' y = 1.0 - origin.y;',
|
||||
' u = inFrameUVs.z;',
|
||||
' v = inFrameUVs.w;',
|
||||
' tint = inTintBR;',
|
||||
' }',
|
||||
' else if (inVertex == 3.0)',
|
||||
' {',
|
||||
' x = 1.0 - origin.x;',
|
||||
' u = inFrameUVs.z;',
|
||||
' tint = inTintTR;',
|
||||
' }',
|
||||
' vec3 position = vec3(x * scaleX, y * scaleY, 1.0);',
|
||||
' float sine = sin(rotation);',
|
||||
' float cosine = cos(rotation);',
|
||||
' mat3 transformMatrix = mat3(',
|
||||
' cosine, sine, 0.0,',
|
||||
' -sine, cosine, 0.0,',
|
||||
' positionX - uCameraScrollAndAlpha.x * scrollFactorX, positionY - uCameraScrollAndAlpha.y * scrollFactorY, 1.0',
|
||||
' );',
|
||||
' position = uViewMatrix * transformMatrix * position;',
|
||||
' alpha *= uCameraScrollAndAlpha.z;',
|
||||
' tint.a *= alpha;',
|
||||
' gl_Position = uProjectionMatrix * vec4(position.xy, 1.0, 1.0);',
|
||||
' if (uRoundPixels == 1)',
|
||||
' {',
|
||||
' gl_Position.xy = floor(((gl_Position.xy + 1.0) * 0.5 * uResolution) + 0.5) / uResolution * 2.0 - 1.0;',
|
||||
' }',
|
||||
' outTexCoord = vec2(u, v);',
|
||||
' outTint = mix(vec4(1.0, 1.0, 1.0, tint.a), tint, tintBlend);',
|
||||
' outTintEffect = tintFill;',
|
||||
'}',
|
||||
].join('\n');
|
|
@ -35,8 +35,6 @@ module.exports = {
|
|||
FlatFrag: require('./Flat-frag.js'),
|
||||
FlatVert: require('./Flat-vert.js'),
|
||||
FlatLightFrag: require('./FlatLight-frag.js'),
|
||||
ImageBakedLayerFrag: require('./ImageBakedLayer-frag.js'),
|
||||
ImageBakedLayerVert: require('./ImageBakedLayer-vert.js'),
|
||||
LightFrag: require('./Light-frag.js'),
|
||||
LightShadowFrag: require('./LightShadow-frag.js'),
|
||||
LinearBlendFrag: require('./LinearBlend-frag.js'),
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
#define SHADER_NAME PHASER_IMAGE_BAKED_LAYER_FS
|
||||
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
precision highp float;
|
||||
#else
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform sampler2D uMainSampler;
|
||||
|
||||
varying vec2 outTexCoord;
|
||||
varying float outTintEffect;
|
||||
varying vec4 outTint;
|
||||
|
||||
void main ()
|
||||
{
|
||||
vec4 texture = texture2D(uMainSampler, outTexCoord);
|
||||
|
||||
vec4 texel = vec4(outTint.bgr * outTint.a, outTint.a);
|
||||
|
||||
// Multiply texture tint
|
||||
vec4 color = texture * texel;
|
||||
|
||||
if (outTintEffect == 1.0)
|
||||
{
|
||||
// Solid color + texture alpha
|
||||
color.rgb = mix(texture.rgb, texel.rgb, texture.a);
|
||||
}
|
||||
|
||||
gl_FragColor = color;
|
||||
}
|
|
@ -1,410 +0,0 @@
|
|||
#define SHADER_NAME PHASER_IMAGE_BAKED_LAYER_VS
|
||||
|
||||
precision mediump float;
|
||||
|
||||
uniform mat4 uProjectionMatrix;
|
||||
uniform mat3 uViewMatrix;
|
||||
uniform vec3 uCameraScrollAndAlpha;
|
||||
uniform int uRoundPixels;
|
||||
uniform vec2 uResolution;
|
||||
uniform float uTime;
|
||||
|
||||
// Vertex buffer attributes
|
||||
|
||||
// 0 - BL, 1 - TL, 2 - BR, 3 - TR
|
||||
attribute float inVertex;
|
||||
|
||||
// Instance buffer attributes
|
||||
attribute vec4 inPositionX;
|
||||
attribute vec4 inPositionY;
|
||||
attribute vec4 inRotation;
|
||||
attribute vec4 inScaleX;
|
||||
attribute vec4 inScaleY;
|
||||
attribute vec3 inOriginAndTintFill;
|
||||
attribute vec4 inScrollFactorX;
|
||||
attribute vec4 inScrollFactorY;
|
||||
attribute vec4 inFrameUVs;
|
||||
attribute vec4 inTintBlend;
|
||||
attribute vec4 inTintTL;
|
||||
attribute vec4 inTintTR;
|
||||
attribute vec4 inTintBL;
|
||||
attribute vec4 inTintBR;
|
||||
attribute vec4 inAlpha;
|
||||
|
||||
varying vec2 outTexCoord;
|
||||
varying float outTintEffect;
|
||||
varying vec4 outTint;
|
||||
|
||||
const float PI = 3.14159265359;
|
||||
const float HALF_PI = PI / 2.0;
|
||||
const float BOUNCE_OVERSHOOT = 1.70158;
|
||||
const float BOUNCE_OVERSHOOT_PLUS = BOUNCE_OVERSHOOT + 1.0;
|
||||
const float BOUNCE_OVERSHOOT_IN_OUT = BOUNCE_OVERSHOOT * 1.525;
|
||||
const float BOUNCE_OVERSHOOT_IN_OUT_PLUS = BOUNCE_OVERSHOOT_IN_OUT + 1.0;
|
||||
|
||||
float animate (vec4 anim)
|
||||
{
|
||||
float value = anim.x;
|
||||
float a = anim.y;
|
||||
float b = anim.z;
|
||||
float c = anim.w;
|
||||
|
||||
int type = int(floor(c));
|
||||
|
||||
if (type == 0 || a == 0.0 || b == 0.0)
|
||||
{
|
||||
// None
|
||||
return value;
|
||||
}
|
||||
|
||||
float duration = b;
|
||||
float offset = mod(c, 1.0) * b;
|
||||
bool yoyo = b < 0.0;
|
||||
|
||||
float rawTime = uTime / duration + offset;
|
||||
float time = mod(rawTime, 1.0);
|
||||
if (yoyo && mod(rawTime, 2.0) > 1.0)
|
||||
{
|
||||
time = 1.0 - time;
|
||||
}
|
||||
|
||||
if (type == 1)
|
||||
{
|
||||
// Linear
|
||||
return value + a * time;
|
||||
}
|
||||
else if (type == 10)
|
||||
{
|
||||
// Quad.easeOut
|
||||
return value + a * time * (2.0 - time);
|
||||
}
|
||||
else if (type == 11)
|
||||
{
|
||||
// Quad.easeIn
|
||||
return value + a * time * time;
|
||||
}
|
||||
else if (type == 12)
|
||||
{
|
||||
// Quad.easeInOut
|
||||
time *= 2.0;
|
||||
if (time < 1.0)
|
||||
{
|
||||
return value + a * time * time * 0.5;
|
||||
}
|
||||
time -= 1.0;
|
||||
return value + a * -0.5 * (time * (time - 2.0) - 1.0);
|
||||
}
|
||||
else if (type == 20)
|
||||
{
|
||||
// Cubic.easeOut
|
||||
time -= 1.0;
|
||||
return value + a * (time * time * time + 1.0);
|
||||
}
|
||||
else if (type == 21)
|
||||
{
|
||||
// Cubic.easeIn
|
||||
return value + a * time * time * time;
|
||||
}
|
||||
else if (type == 22)
|
||||
{
|
||||
// Cubic.easeInOut
|
||||
time *= 2.0;
|
||||
if (time < 1.0)
|
||||
{
|
||||
return value + a * time * time * time * 0.5;
|
||||
}
|
||||
time -= 2.0;
|
||||
return value + a * 0.5 * (time * time * time + 2.0);
|
||||
}
|
||||
else if (type == 30)
|
||||
{
|
||||
// Quart.easeOut
|
||||
time -= 1.0;
|
||||
return value + a * (1.0 - time * time * time * time);
|
||||
}
|
||||
else if (type == 31)
|
||||
{
|
||||
// Quart.easeIn
|
||||
return value + a * time * time * time * time;
|
||||
}
|
||||
else if (type == 32)
|
||||
{
|
||||
// Quart.easeInOut
|
||||
time *= 2.0;
|
||||
if (time < 1.0)
|
||||
{
|
||||
return value + a * time * time * time * time * 0.5;
|
||||
}
|
||||
time -= 2.0;
|
||||
return value + a * -0.5 * (time * time * time * time - 2.0);
|
||||
}
|
||||
else if (type == 40)
|
||||
{
|
||||
// Quint.easeOut
|
||||
time -= 1.0;
|
||||
return value + a * (time * time * time * time * time + 1.0);
|
||||
}
|
||||
else if (type == 41)
|
||||
{
|
||||
// Quint.easeIn
|
||||
return value + a * time * time * time * time * time;
|
||||
}
|
||||
else if (type == 42)
|
||||
{
|
||||
// Quint.easeInOut
|
||||
time *= 2.0;
|
||||
if (time < 1.0)
|
||||
{
|
||||
return value + a * time * time * time * time * time * 0.5;
|
||||
}
|
||||
time -= 2.0;
|
||||
return value + a * 0.5 * (time * time * time * time * time + 2.0);
|
||||
}
|
||||
else if (type == 50)
|
||||
{
|
||||
// Sine.easeOut
|
||||
return value + a * sin(time * HALF_PI);
|
||||
}
|
||||
else if (type == 51)
|
||||
{
|
||||
// Sine.easeIn
|
||||
return value + a * (1.0 - cos(time * HALF_PI));
|
||||
}
|
||||
else if (type == 52)
|
||||
{
|
||||
// Sine.easeInOut
|
||||
return value + a * 0.5 * (1.0 - cos(PI * time));
|
||||
}
|
||||
else if (type == 60)
|
||||
{
|
||||
// Expo.easeOut
|
||||
return value + a * (1.0 - pow(2.0, -10.0 * time));
|
||||
}
|
||||
else if (type == 61)
|
||||
{
|
||||
// Expo.easeIn
|
||||
return value + a * pow(2.0, 10.0 * (time - 1.0) - 0.001);
|
||||
}
|
||||
else if (type == 62)
|
||||
{
|
||||
// Expo.easeInOut
|
||||
time *= 2.0;
|
||||
if (time < 1.0)
|
||||
{
|
||||
return value + a * 0.5 * pow(2.0, 10.0 * (time - 1.0));
|
||||
}
|
||||
time -= 1.0;
|
||||
return value + a * 0.5 * (2.0 - pow(2.0, -10.0 * (time - 1.0)));
|
||||
}
|
||||
else if (type == 70)
|
||||
{
|
||||
// Circ.easeOut
|
||||
time -= 1.0;
|
||||
return value + a * sqrt(1.0 - time * time);
|
||||
}
|
||||
else if (type == 71)
|
||||
{
|
||||
// Circ.easeIn
|
||||
return value + a * (1.0 - sqrt(1.0 - time * time));
|
||||
}
|
||||
else if (type == 72)
|
||||
{
|
||||
// Circ.easeInOut
|
||||
time *= 2.0;
|
||||
if (time < 1.0)
|
||||
{
|
||||
return value + a * -0.5 * (sqrt(1.0 - time * time) - 1.0);
|
||||
}
|
||||
time -= 2.0;
|
||||
return value + a * 0.5 * (sqrt(1.0 - time * time) + 1.0);
|
||||
}
|
||||
else if (type == 90)
|
||||
{
|
||||
// Back.easeOut
|
||||
time -= 1.0;
|
||||
return value + a * (time * time * (BOUNCE_OVERSHOOT_PLUS * time + BOUNCE_OVERSHOOT) + 1.0);
|
||||
}
|
||||
else if (type == 91)
|
||||
{
|
||||
// Back.easeIn
|
||||
return value + a * time * time * (BOUNCE_OVERSHOOT_PLUS * time - BOUNCE_OVERSHOOT);
|
||||
}
|
||||
else if (type == 92)
|
||||
{
|
||||
// Back.easeInOut
|
||||
time *= 2.0;
|
||||
if (time < 1.0)
|
||||
{
|
||||
return value + a * 0.5 * (time * time * (BOUNCE_OVERSHOOT_IN_OUT_PLUS * time - BOUNCE_OVERSHOOT_IN_OUT));
|
||||
}
|
||||
time -= 2.0;
|
||||
return value + a * 0.5 * (time * time * (BOUNCE_OVERSHOOT_IN_OUT_PLUS * time + BOUNCE_OVERSHOOT_IN_OUT) + 2.0);
|
||||
}
|
||||
else if (type == 100)
|
||||
{
|
||||
// Bounce.easeOut
|
||||
if (time < 1.0 / 2.75)
|
||||
{
|
||||
return value + a * (7.5625 * time * time);
|
||||
}
|
||||
else if (time < 2.0 / 2.75)
|
||||
{
|
||||
time -= 1.5 / 2.75;
|
||||
return value + a * (7.5625 * time * time + 0.75);
|
||||
}
|
||||
else if (time < 2.5 / 2.75)
|
||||
{
|
||||
time -= 2.25 / 2.75;
|
||||
return value + a * (7.5625 * time * time + 0.9375);
|
||||
}
|
||||
else
|
||||
{
|
||||
time -= 2.625 / 2.75;
|
||||
return value + a * (7.5625 * time * time + 0.984375);
|
||||
}
|
||||
}
|
||||
else if (type == 101)
|
||||
{
|
||||
// Bounce.easeIn
|
||||
time = 1.0 - time;
|
||||
if (time < 1.0 / 2.75)
|
||||
{
|
||||
return value + a * (1.0 - 7.5625 * time * time);
|
||||
}
|
||||
else if (time < 2.0 / 2.75)
|
||||
{
|
||||
time -= 1.5 / 2.75;
|
||||
return value + a * (1.0 - (7.5625 * time * time + 0.75));
|
||||
}
|
||||
else if (time < 2.5 / 2.75)
|
||||
{
|
||||
time -= 2.25 / 2.75;
|
||||
return value + a * (1.0 - (7.5625 * time * time + 0.9375));
|
||||
}
|
||||
else
|
||||
{
|
||||
time -= 2.625 / 2.75;
|
||||
return value + a * (1.0 - (7.5625 * time * time + 0.984375));
|
||||
}
|
||||
}
|
||||
else if (type == 102)
|
||||
{
|
||||
bool reverse = false;
|
||||
// Bounce.easeInOut
|
||||
if (time < 0.5)
|
||||
{
|
||||
time = 1.0 - time * 2.0;
|
||||
reverse = true;
|
||||
}
|
||||
|
||||
if (time < 1.0 / 2.75)
|
||||
{
|
||||
time = 7.5625 * time * time;
|
||||
}
|
||||
else if (time < 2.0 / 2.75)
|
||||
{
|
||||
time -= 1.5 / 2.75;
|
||||
time = 7.5625 * time * time + 0.75;
|
||||
}
|
||||
else if (time < 2.5 / 2.75)
|
||||
{
|
||||
time -= 2.25 / 2.75;
|
||||
time = 7.5625 * time * time + 0.9375;
|
||||
}
|
||||
else
|
||||
{
|
||||
time -= 2.625 / 2.75;
|
||||
time = 7.5625 * time * time + 0.984375;
|
||||
}
|
||||
|
||||
if (reverse)
|
||||
{
|
||||
return value + a * (1.0 - time) * 0.5;
|
||||
}
|
||||
return value + a * time * 0.5 + 0.5;
|
||||
}
|
||||
else if (type == 110)
|
||||
{
|
||||
// Stepped
|
||||
return value + a * floor(time + 0.5);
|
||||
}
|
||||
|
||||
// Default (should not happen)
|
||||
return value;
|
||||
}
|
||||
|
||||
void main ()
|
||||
{
|
||||
float positionX = animate(inPositionX);
|
||||
float positionY = animate(inPositionY);
|
||||
float rotation = animate(inRotation);
|
||||
float scaleX = animate(inScaleX);
|
||||
float scaleY = animate(inScaleY);
|
||||
float scrollFactorX = animate(inScrollFactorX);
|
||||
float scrollFactorY = animate(inScrollFactorY);
|
||||
float tintBlend = animate(inTintBlend);
|
||||
float alpha = animate(inAlpha);
|
||||
|
||||
vec2 origin = inOriginAndTintFill.xy;
|
||||
float tintFill = inOriginAndTintFill.z;
|
||||
|
||||
float x = -origin.x;
|
||||
float y = -origin.y;
|
||||
float u = inFrameUVs.x;
|
||||
float v = inFrameUVs.y;
|
||||
vec4 tint = inTintTL;
|
||||
|
||||
if (inVertex == 0.0)
|
||||
{
|
||||
// Bottom-left
|
||||
y = 1.0 - origin.y;
|
||||
v = inFrameUVs.w;
|
||||
tint = inTintBL;
|
||||
}
|
||||
// 1.0 is top-left and uses the initial values.
|
||||
else if (inVertex == 2.0)
|
||||
{
|
||||
// Bottom-right
|
||||
x = 1.0 - origin.x;
|
||||
y = 1.0 - origin.y;
|
||||
u = inFrameUVs.z;
|
||||
v = inFrameUVs.w;
|
||||
tint = inTintBR;
|
||||
}
|
||||
else if (inVertex == 3.0)
|
||||
{
|
||||
// Top-right
|
||||
x = 1.0 - origin.x;
|
||||
u = inFrameUVs.z;
|
||||
tint = inTintTR;
|
||||
}
|
||||
|
||||
vec3 position = vec3(x * scaleX, y * scaleY, 1.0);
|
||||
|
||||
// Create and initialize the transform matrix.
|
||||
float sine = sin(rotation);
|
||||
float cosine = cos(rotation);
|
||||
mat3 transformMatrix = mat3(
|
||||
cosine, sine, 0.0,
|
||||
-sine, cosine, 0.0,
|
||||
positionX - uCameraScrollAndAlpha.x * scrollFactorX, positionY - uCameraScrollAndAlpha.y * scrollFactorY, 1.0
|
||||
);
|
||||
|
||||
// Transform the position.
|
||||
position = uViewMatrix * transformMatrix * position;
|
||||
|
||||
// Alpha handling.
|
||||
alpha *= uCameraScrollAndAlpha.z;
|
||||
tint.a *= alpha;
|
||||
|
||||
gl_Position = uProjectionMatrix * vec4(position.xy, 1.0, 1.0);
|
||||
|
||||
if (uRoundPixels == 1)
|
||||
{
|
||||
gl_Position.xy = floor(((gl_Position.xy + 1.0) * 0.5 * uResolution) + 0.5) / uResolution * 2.0 - 1.0;
|
||||
}
|
||||
|
||||
outTexCoord = vec2(u, v);
|
||||
outTint = mix(vec4(1.0, 1.0, 1.0, tint.a), tint, tintBlend);
|
||||
outTintEffect = tintFill;
|
||||
}
|
Loading…
Reference in a new issue