Added first pass at Video Game Object

This commit is contained in:
Richard Davey 2019-10-03 02:29:05 +01:00
parent de1034091e
commit 9429f66adb
7 changed files with 1007 additions and 1 deletions

View file

@ -39,6 +39,7 @@ var GameObjects = {
Text: require('./text/static/Text'),
TileSprite: require('./tilesprite/TileSprite'),
Zone: require('./zone/Zone'),
Video: require('./video/Video'),
// Shapes
@ -74,6 +75,7 @@ var GameObjects = {
Text: require('./text/static/TextFactory'),
TileSprite: require('./tilesprite/TileSpriteFactory'),
Zone: require('./zone/ZoneFactory'),
Video: require('./video/VideoFactory'),
// Shapes
Arc: require('./shape/arc/ArcFactory'),
@ -102,7 +104,8 @@ var GameObjects = {
StaticBitmapText: require('./bitmaptext/static/BitmapTextCreator'),
Text: require('./text/static/TextCreator'),
TileSprite: require('./tilesprite/TileSpriteCreator'),
Zone: require('./zone/ZoneCreator')
Zone: require('./zone/ZoneCreator'),
Video: require('./video/VideoCreator')
}
};

View file

@ -0,0 +1,839 @@
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2019 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
var Class = require('../../utils/Class');
var Components = require('../components');
var GameObject = require('../GameObject');
var UUID = require('../../utils/string/UUID');
var VideoRender = require('./VideoRender');
/**
* @classdesc
* A Video Game Object.
*
* @class Video
* @extends Phaser.GameObjects.GameObject
* @memberof Phaser.GameObjects
* @constructor
* @since 3.20.0
*
* @extends Phaser.GameObjects.Components.Alpha
* @extends Phaser.GameObjects.Components.BlendMode
* @extends Phaser.GameObjects.Components.Depth
* @extends Phaser.GameObjects.Components.Flip
* @extends Phaser.GameObjects.Components.GetBounds
* @extends Phaser.GameObjects.Components.Mask
* @extends Phaser.GameObjects.Components.Origin
* @extends Phaser.GameObjects.Components.Pipeline
* @extends Phaser.GameObjects.Components.ScrollFactor
* @extends Phaser.GameObjects.Components.Size
* @extends Phaser.GameObjects.Components.TextureCrop
* @extends Phaser.GameObjects.Components.Tint
* @extends Phaser.GameObjects.Components.Transform
* @extends Phaser.GameObjects.Components.Visible
*
* @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time.
* @param {number} x - The horizontal position of this Game Object in the world.
* @param {number} y - The vertical position of this Game Object in the world.
* @param {string} texture - The key of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|integer)} [frame] - An optional frame from the Texture this Game Object is rendering with.
*/
var Video = new Class({
Extends: GameObject,
Mixins: [
Components.Alpha,
Components.BlendMode,
Components.Depth,
Components.Flip,
Components.GetBounds,
Components.Mask,
Components.Origin,
Components.Pipeline,
Components.ScrollFactor,
Components.Size,
Components.TextureCrop,
Components.Tint,
Components.Transform,
Components.Visible,
VideoRender
],
initialize:
function Video (scene, x, y, key)
{
GameObject.call(this, scene, 'Video');
var textureKey = UUID();
this.snapshot = scene.sys.textures.createCanvas(textureKey, 8, 8);
/**
* @property {HTMLVideoElement} video - The HTML Video Element that is added to the document.
*/
this.video = null;
this.videoTexture = null;
this.videoTextureSource = null;
/**
* @property {boolean} touchLocked - true if this video is currently locked awaiting a touch event. This happens on some mobile devices, such as iOS.
* @default
*/
this.touchLocked = false;
/**
* Start playing the video when it's unlocked.
* @property {boolean} playWhenUnlocked
* @default
*/
this.playWhenUnlocked = true;
/**
* @property {integer} timeout - The amount of ms allowed to elapsed before the Video.onTimeout signal is dispatched while waiting for webcam access.
* @default
*/
this.timeout = 15000;
/**
* @property {integer} _timeOutID - setTimeout ID.
* @private
*/
this._timeOutID = null;
/**
* @property {MediaStream} videoStream - The Video Stream data. Only set if this Video is streaming from the webcam via `startMediaStream`.
*/
this.videoStream = null;
/**
* @property {boolean} isStreaming - Is there a streaming video source? I.e. from a webcam.
*/
this.isStreaming = false;
/**
* When starting playback of a video Phaser will monitor its readyState using a setTimeout call.
* The setTimeout happens once every `Video.retryInterval` ms. It will carry on monitoring the video
* state in this manner until the `retryLimit` is reached and then abort.
* @property {integer} retryLimit
* @default
*/
this.retryLimit = 20;
/**
* @property {integer} retry - The current retry attempt.
* @default
*/
this.retry = 0;
/**
* @property {integer} retryInterval - The number of ms between each retry at monitoring the status of a downloading video.
* @default
*/
this.retryInterval = 500;
/**
* @property {integer} _retryID - The callback ID of the retry setTimeout.
* @private
*/
this._retryID = null;
/**
* @property {boolean} _codeMuted - Internal mute tracking var.
* @private
* @default
*/
this._codeMuted = false;
/**
* @property {boolean} _muted - Internal mute tracking var.
* @private
* @default
*/
this._muted = false;
/**
* @property {boolean} _codePaused - Internal paused tracking var.
* @private
* @default
*/
this._codePaused = false;
/**
* @property {boolean} _paused - Internal paused tracking var.
* @private
* @default
*/
this._paused = false;
/**
* @property {boolean} _pending - Internal var tracking play pending.
* @private
* @default
*/
this._pending = false;
/**
* @property {boolean} _pendingChangeSource - Internal var tracking play pending.
* @private
* @default
*/
this._pendingChangeSource = false;
/**
* @property {boolean} _autoplay - Internal var tracking autoplay when changing source.
* @private
* @default
*/
this._autoplay = false;
/**
* @property {function} _endCallback - The addEventListener ended function.
* @private
*/
this._endCallback = null;
/**
* @property {function} _playCallback - The addEventListener playing function.
* @private
*/
this._playCallback = null;
/**
* The internal crop data object, as used by `setCrop` and passed to the `Frame.setCropUVs` method.
*
* @name Phaser.GameObjects.Image#_crop
* @type {object}
* @private
* @since 3.11.0
*/
this._crop = this.resetCropObject();
// if (this.game.device.needsTouchUnlock())
// {
// this.setTouchLock();
// }
// else if (_video)
// {
// _video.locked = false;
// }
this.setTexture(textureKey);
this.setPosition(x, y);
this.setSizeToFrame();
this.setOrigin(0.5, 0.5);
this.initPipeline();
var ctx = this.texture.context;
ctx.fillStyle = '#ff0000';
ctx.fillRect(0, 0, 8, 8);
this.texture.refresh();
},
/**
* Starts this video playing.
*
* If the video is already playing, or has been queued to play with `changeSource` then this method just returns.
*
* @method Phaser.Video#play
* @param {boolean} [loop=false] - Should the video loop automatically when it reaches the end? Please note that at present some browsers (i.e. Chrome) do not support *seamless* video looping.
* @param {number} [playbackRate=1] - The playback rate of the video. 1 is normal speed, 2 is x2 speed, and so on. You cannot set a negative playback rate.
* @return {Phaser.Video} This Video object for method chaining.
*/
play: function (loop, playbackRate)
{
if (loop === undefined) { loop = false; }
if (playbackRate === undefined) { playbackRate = 1; }
if (this._pendingChangeSource)
{
return this;
}
// if (this.game.sound.onMute)
// {
// this.game.sound.onMute.add(this.setMute, this);
// this.game.sound.onUnMute.add(this.unsetMute, this);
// if (this.game.sound.mute)
// {
// this.setMute();
// }
// }
// this.game.onPause.add(this.setPause, this);
// this.game.onResume.add(this.setResume, this);
this._endCallback = this.complete.bind(this);
this.video.addEventListener('ended', this._endCallback, true);
this.video.addEventListener('webkitendfullscreen', this._endCallback, true);
if (loop)
{
this.video.loop = 'loop';
}
else
{
this.video.loop = '';
}
this.video.playbackRate = playbackRate;
if (this.touchLocked)
{
this._pending = true;
}
else
{
this._pending = false;
if (this.key !== null)
{
if (this.video.readyState !== 4)
{
this.retry = this.retryLimit;
this._retryID = window.setTimeout(this.checkVideoProgress.bind(this), this.retryInterval);
}
else
{
this._playCallback = this.playHandler.bind(this);
this.video.addEventListener('playing', this._playCallback, true);
}
}
this.video.play();
// this.onPlay.dispatch(this, loop, playbackRate);
}
return this;
},
/**
* Called when the video starts to play. Updates the texture.
*
* @method Phaser.Video#playHandler
* @private
*/
playHandler: function ()
{
this.video.removeEventListener('playing', this._playCallback, true);
this.updateTexture();
},
/**
* Stops the video playing.
*
* This removes all locally set signals.
*
* If you only wish to pause playback of the video, to resume at a later time, use `Video.paused = true` instead.
* If the video hasn't finished downloading calling `Video.stop` will not abort the download. To do that you need to
* call `Video.destroy` instead.
*
* If you are using a video stream from a webcam then calling Stop will disconnect the MediaStream session and disable the webcam.
*
* @method Phaser.Video#stop
* @return {Phaser.Video} This Video object for method chaining.
*/
stop: function ()
{
// if (this.game.sound.onMute)
// {
// this.game.sound.onMute.remove(this.setMute, this);
// this.game.sound.onUnMute.remove(this.unsetMute, this);
// }
// this.game.onPause.remove(this.setPause, this);
// this.game.onResume.remove(this.setResume, this);
// Stream or file?
if (this.isStreaming)
{
if (this.video.mozSrcObject)
{
this.video.mozSrcObject.stop();
this.video.src = null;
}
else if (this.video.srcObject)
{
this.video.srcObject.stop();
this.video.src = null;
}
else
{
this.video.src = '';
if (this.videoStream.active)
{
this.videoStream.active = false;
}
else
if (this.videoStream.getTracks)
{
this.videoStream.getTracks().forEach(function (track)
{
track.stop();
});
}
else
{
this.videoStream.stop();
}
}
this.videoStream = null;
this.isStreaming = false;
}
else
{
this.video.removeEventListener('ended', this._endCallback, true);
this.video.removeEventListener('webkitendfullscreen', this._endCallback, true);
this.video.removeEventListener('playing', this._playCallback, true);
if (this.touchLocked)
{
this._pending = false;
}
else
{
this.video.pause();
}
}
return this;
},
/**
* Creates a new Video element from the given URL.
*
* @method Phaser.Video#createVideoFromURL
* @param {string} url - The URL of the video.
* @param {boolean} [autoplay=false] - Automatically start the video?
* @return {Phaser.Video} This Video object for method chaining.
*/
createVideoFromURL: function (url, autoplay)
{
if (autoplay === undefined) { autoplay = false; }
this.video = document.createElement('video');
this.video.controls = false;
if (autoplay)
{
this.video.setAttribute('autoplay', 'autoplay');
}
this.video.src = url;
this.video.canplay = true;
this.video.load();
this.retry = this.retryLimit;
this._retryID = window.setTimeout(this.checkVideoProgress.bind(this), this.retryInterval);
return this;
},
/**
* Internal callback that monitors the download progress of a video after changing its source.
*
* @method Phaser.Video#checkVideoProgress
* @private
*/
checkVideoProgress: function ()
{
if (this.video.readyState === 4)
{
this._pendingChangeSource = false;
// We've got enough data to update the texture for playback
this.updateTexture();
}
else
{
this.retry--;
if (this.retry > 0)
{
this._retryID = window.setTimeout(this.checkVideoProgress.bind(this), this.retryInterval);
}
else
{
console.warn('Phaser.Video: Unable to start downloading video in time', this.isStreaming);
}
}
},
/**
* Called automatically if the video source changes and updates the internal texture dimensions.
* Then dispatches the onChangeSource signal.
*
* @method Phaser.Video#updateTexture
* @param {object} [event] - The event which triggered the texture update.
* @param {integer} [width] - The new width of the video. If undefined `video.videoWidth` is used.
* @param {integer} [height] - The new height of the video. If undefined `video.videoHeight` is used.
*/
updateTexture: function (event, width, height)
{
var newSize = false;
if (width === undefined || width === null) { width = this.video.videoWidth; newSize = true; }
if (height === undefined || height === null) { height = this.video.videoHeight; }
// First we'll update our current CanvasTexture
if (newSize)
{
this.texture.setSize(width, height);
}
if (!this.videoTexture)
{
this.videoTexture = this.scene.sys.textures.create(UUID(), this.video, width, height);
this.videoTextureSource = this.videoTexture.source[0];
this.videoTexture.add('__BASE', 0, 0, 0, width, height);
}
else
{
var textureSource = this.videoTextureSource;
textureSource.source = this.video;
textureSource.width = width;
textureSource.height = height;
}
// Swap out the canvas texture for the video texture
// this.canvasTexture = this.texture;
// this.canvasFrame = this.frame;
this.texture = this.videoTexture;
this.frame = this.videoTexture.get();
this.setSizeToFrame();
this.setOriginFromFrame();
if (this._autoplay)
{
this.video.play();
}
},
preUpdate: function ()
{
if (this.videoTextureSource && this.playing)
{
this.videoTextureSource.update();
}
},
/**
* @name Phaser.Video#currentTime
* @property {number} currentTime - The current time of the video in seconds. If set the video will attempt to seek to that point in time.
*/
getCurrentTime: function ()
{
return (this.video) ? this.video.currentTime : 0;
},
setCurrentTime: function (value)
{
if (this.video)
{
this.video.currentTime = value;
}
return this;
},
/**
* @name Phaser.Video#duration
* @property {number} duration - The duration of the video in seconds.
* @readOnly
*/
getDuration: function ()
{
return (this.video) ? this.video.duration : 0;
},
/**
* @name Phaser.Video#progress
* @property {number} progress - The progress of this video. This is a value between 0 and 1, where 0 is the start and 1 is the end of the video.
* @readOnly
*/
getProgress: function ()
{
return (this.video) ? (this.video.currentTime / this.video.duration) : 0;
},
isMuted: function ()
{
return this._muted;
},
setMute: function (value)
{
if (value === undefined) { value = true; }
if (value)
{
if (!this._muted)
{
this._muted = true;
this._codeMuted = true;
if (this.video)
{
this.video.muted = true;
}
}
}
else
{
// eslint-disable-next-line no-lonely-if
if (this._muted)
{
this._muted = false;
this._codeMuted = false;
if (this.video)
{
this.video.muted = false;
}
}
}
return this;
},
pause: function ()
{
if (this._paused || this.touchLocked)
{
return this;
}
this._codePaused = true;
this._paused = true;
if (this.video)
{
this.video.pause();
}
return this;
},
resume: function ()
{
if (!this._paused || this._codePaused || this.touchLocked)
{
return this;
}
this._codePaused = false;
this._paused = false;
if (this.video && !this.video.ended)
{
this.video.play();
}
return this;
},
getVolume: function ()
{
return (this.video) ? this.video.volume : 1;
},
/**
* @name Phaser.Video#volume
* @property {number} volume - Gets or sets the volume of the Video, a value between 0 and 1. The value given is clamped to the range 0 to 1.
*/
setVolume: function (value)
{
if (value === undefined) { value = 1; }
if (value < 0)
{
value = 0;
}
else if (value > 1)
{
value = 1;
}
if (this.video)
{
this.video.volume = value;
}
return this;
},
getPlaybackRate: function ()
{
return (this.video) ? this.video.playbackRate : 1;
},
/**
* @name Phaser.Video#playbackRate
* @property {number} playbackRate - Gets or sets the playback rate of the Video. This is the speed at which the video is playing.
*/
setPlaybackRate: function (rate)
{
if (this.video)
{
this.video.playbackRate = rate;
}
return this;
},
getLoop: function ()
{
return (this.video) ? this.video.loop : false;
},
/**
* Gets or sets if the Video is set to loop.
* Please note that at present some browsers (i.e. Chrome) do not support *seamless* video looping.
* If the video isn't yet set this will always return false.
*
* @name Phaser.Video#loop
* @property {boolean} loop
*/
setLoop: function (value)
{
if (value === undefined) { value = true; }
if (this.video)
{
this.video.loop = (value) ? 'loop' : '';
}
return this;
},
/**
* @name Phaser.Video#playing
* @property {boolean} playing - True if the video is currently playing (and not paused or ended), otherwise false.
* @readOnly
*/
isPlaying: function ()
{
return (this.video) ? !(this.video.paused && this.video.ended) : false;
},
/**
* Grabs the current frame from the Video or Video Stream and renders it to the Video.snapshot BitmapData.
*
* You can optionally set if the BitmapData should be cleared or not, the alpha and the blend mode of the draw.
*
* If you need more advanced control over the grabbing them call `Video.snapshot.copy` directly with the same parameters as BitmapData.copy.
*
* @method Phaser.Video#grab
* @param {boolean} [clear=false] - Should the BitmapData be cleared before the Video is grabbed? Unless you are using alpha or a blend mode you can usually leave this set to false.
* @param {number} [alpha=1] - The alpha that will be set on the video before drawing. A value between 0 (fully transparent) and 1, opaque.
* @param {string} [blendMode=null] - The composite blend mode that will be used when drawing. The default is no blend mode at all. This is a Canvas globalCompositeOperation value such as 'lighter' or 'xor'.
* @return {Phaser.BitmapData} A reference to the Video.snapshot BitmapData object for further method chaining.
*/
grab: function (clear, alpha, blendMode)
{
if (clear === undefined) { clear = false; }
if (alpha === undefined) { alpha = 1; }
if (blendMode === undefined) { blendMode = null; }
if (clear)
{
this.snapshot.clear();
}
// Set globalAlpha
// Set blendMode
this.snapshot.draw(0, 0, this.video);
return this.snapshot;
},
/**
* Removes the Video element from the DOM by calling parentNode.removeChild on itself.
* Also removes the autoplay and src attributes and nulls the reference.
*
* @method Phaser.Video#removeVideoElement
*/
removeVideoElement: function ()
{
if (!this.video)
{
return;
}
if (this.video.parentNode)
{
this.video.parentNode.removeChild(this.video);
}
while (this.video.hasChildNodes())
{
this.video.removeChild(this.video.firstChild);
}
this.video.removeAttribute('autoplay');
this.video.removeAttribute('src');
this.video = null;
},
/**
* Destroys the Video object. This calls `Video.stop` and then `Video.removeVideoElement`.
* If any Sprites are using this Video as their texture it is up to you to manage those.
*
* @method Phaser.Video#destroy
*/
destroy: function ()
{
this.stop();
this.removeVideoElement();
// if (this.touchLocked)
// {
// this.game.input.removeTouchLockCallback(this.unlock, this);
// }
if (this._retryID)
{
window.clearTimeout(this._retryID);
}
},
/**
* @name Phaser.Video#playing
* @property {boolean} playing - True if the video is currently playing (and not paused or ended), otherwise false.
* @readOnly
*/
playing: {
get: function ()
{
return (this.video) ? !(this.video.paused && this.video.ended) : false;
}
}
});
module.exports = Video;

View file

@ -0,0 +1,27 @@
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2019 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
/**
* Renders this Game Object with the Canvas 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.Image#renderCanvas
* @since 3.0.0
* @private
*
* @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer.
* @param {Phaser.GameObjects.Image} src - The Game Object being rendered in this call.
* @param {number} interpolationPercentage - Reserved for future use and custom pipelines.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
*/
var VideoCanvasRenderer = function (renderer, src, interpolationPercentage, camera, parentMatrix)
{
renderer.batchSprite(src, src.frame, camera, parentMatrix);
};
module.exports = VideoCanvasRenderer;

View file

@ -0,0 +1,44 @@
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2019 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
var BuildGameObject = require('../BuildGameObject');
var GameObjectCreator = require('../GameObjectCreator');
var GetAdvancedValue = require('../../utils/object/GetAdvancedValue');
var Video = require('./Video');
/**
* Creates a new Image Game Object and returns it.
*
* Note: This method will only be available if the Image Game Object has been built into Phaser.
*
* @method Phaser.GameObjects.GameObjectCreator#image
* @since 3.0.0
*
* @param {object} 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('video', function (config, addToScene)
{
if (config === undefined) { config = {}; }
var key = GetAdvancedValue(config, 'key', null);
var frame = GetAdvancedValue(config, 'frame', null);
var image = new Video(this.scene, 0, 0, key, frame);
if (addToScene !== undefined)
{
config.add = addToScene;
}
BuildGameObject(this.scene, image, config);
return image;
});
// When registering a factory function 'this' refers to the GameObjectCreator context.

View file

@ -0,0 +1,41 @@
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2019 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
var Video = require('./Video');
var GameObjectFactory = require('../GameObjectFactory');
/**
* Creates a new Image Game Object and adds it to the Scene.
*
* Note: This method will only be available if the Image Game Object has been built into Phaser.
*
* @method Phaser.GameObjects.GameObjectFactory#video
* @since 3.20.0
*
* @param {number} x - The horizontal position of this Game Object in the world.
* @param {number} y - The vertical position of this Game Object in the world.
* @param {string} texture - The key of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|integer)} [frame] - An optional frame from the Texture this Game Object is rendering with.
*
* @return {Phaser.GameObjects.Image} The Game Object that was created.
*/
GameObjectFactory.register('video', function (x, y, videoURL)
{
var video = new Video(this.scene, x, y, videoURL);
this.displayList.add(video);
this.updateList.add(video);
return video;
});
// 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

View file

@ -0,0 +1,25 @@
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2019 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
var renderWebGL = require('../../utils/NOOP');
var renderCanvas = require('../../utils/NOOP');
if (typeof WEBGL_RENDERER)
{
renderWebGL = require('./VideoWebGLRenderer');
}
if (typeof CANVAS_RENDERER)
{
renderCanvas = require('./VideoCanvasRenderer');
}
module.exports = {
renderWebGL: renderWebGL,
renderCanvas: renderCanvas
};

View file

@ -0,0 +1,27 @@
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2019 Photon Storm Ltd.
* @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.Image#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 {number} interpolationPercentage - Reserved for future use and custom pipelines.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
*/
var VideoWebGLRenderer = function (renderer, src, interpolationPercentage, camera, parentMatrix)
{
this.pipeline.batchSprite(src, camera, parentMatrix);
};
module.exports = VideoWebGLRenderer;