var BlendModes = require('../../renderer/BlendModes'); var Camera = require('../../cameras/2d/BaseCamera'); var CanvasPool = require('../../display/canvas/CanvasPool'); var Class = require('../../utils/Class'); var Components = require('../components'); var CONST = require('../../const'); var Frame = require('../../textures/Frame'); var GameObject = require('../GameObject'); var Render = require('./RenderTextureRender'); var Utils = require('../../renderer/webgl/Utils'); var UUID = require('../../utils/string/UUID'); var RenderTexture = new Class({ Extends: GameObject, Mixins: [Components.Alpha, Components.BlendMode, Components.ComputedSize, Components.Crop, Components.Depth, Components.Flip, Components.GetBounds, Components.Mask, Components.Origin, Components.Pipeline, Components.ScaleMode, Components.ScrollFactor, Components.Tint, Components.Transform, Components.Visible, Render] , initialize: function RenderTexture(scene, x, y, width, height){ if (x === undefined) { x = 0; } if (y === undefined) { y = 0; } if (width === undefined) { width = 32; } if (height === undefined) { height = 32; } GameObject.call(this, scene, 'RenderTexture'); this.renderer = scene.sys.game.renderer; this.textureManager = scene.sys.textures; this.globalTint = 16777215; this.globalAlpha = 1; this.canvas = CanvasPool.create2D(this, width, height); this.context = this.canvas.getContext('2d'); this.framebuffer = null ; this._crop = this.resetCropObject(); this.texture = scene.sys.textures.addCanvas(UUID(), this.canvas); this.frame = this.texture.get(); this._saved = false ; this._eraseMode = false ; this.camera = new Camera(0, 0, width, height); this.dirty = false ; this.gl = null ; var renderer = this.renderer; if (renderer.type === CONST.WEBGL) { var gl = renderer.gl; this.gl = gl; this.drawGameObject = this.batchGameObjectWebGL; this.framebuffer = renderer.createFramebuffer(width, height, this.frame.source.glTexture, false ); } else if (renderer.type === CONST.CANVAS) { this.drawGameObject = this.batchGameObjectCanvas; } this.camera.setScene(scene); this.setPosition(x, y); this.setSize(width, height); this.setOrigin(0, 0); this.initPipeline(); } , setSize: function (width, height){ return this.resize(width, height); } , resize: function (width, height){ if (height === undefined) { height = width; } if (width !== this.width || height !== this.height) { this.canvas.width = width; this.canvas.height = height; if (this.gl) { var gl = this.gl; this.renderer.deleteTexture(this.frame.source.glTexture); this.renderer.deleteFramebuffer(this.framebuffer); this.frame.source.glTexture = this.renderer.createTexture2D(0, gl.NEAREST, gl.NEAREST, gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE, gl.RGBA, null , width, height, false ); this.framebuffer = this.renderer.createFramebuffer(width, height, this.frame.source.glTexture, false ); this.frame.glTexture = this.frame.source.glTexture; } this.frame.source.width = width; this.frame.source.height = height; this.camera.setSize(width, height); this.frame.setSize(width, height); this.width = width; this.height = height; } return this; } , setGlobalTint: function (tint){ this.globalTint = tint; return this; } , setGlobalAlpha: function (alpha){ this.globalAlpha = alpha; return this; } , saveTexture: function (key){ this.textureManager.renameTexture(this.texture.key, key); this._saved = true ; return this.texture; } , fill: function (rgb, alpha){ if (alpha === undefined) { alpha = 1; } var r = ((rgb >> 16) | 0) & 255; var g = ((rgb >> 8) | 0) & 255; var b = (rgb | 0) & 255; var gl = this.gl; if (gl) { var renderer = this.renderer; var bounds = this.getBounds(); renderer.setFramebuffer(this.framebuffer, true ); this.pipeline.drawFillRect(bounds.x, bounds.y, bounds.right, bounds.bottom, Utils.getTintFromFloats(r / 255, g / 255, b / 255, 1), alpha); renderer.setFramebuffer(null , true ); } else { this.context.fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + alpha + ')'; this.context.fillRect(0, 0, this.canvas.width, this.canvas.height); } return this; } , clear: function (){ if (this.dirty) { var gl = this.gl; if (gl) { var renderer = this.renderer; renderer.setFramebuffer(this.framebuffer, true ); gl.clearColor(0, 0, 0, 0); _AN_Call_clear('clear', gl, gl.COLOR_BUFFER_BIT); renderer.setFramebuffer(null , true ); } else { var ctx = this.context; ctx.save(); ctx.setTransform(1, 0, 0, 1, 0, 0); ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); ctx.restore(); } this.dirty = false ; } return this; } , erase: function (entries, x, y){ this._eraseMode = true ; var blendMode = this.renderer.currentBlendMode; this.renderer.setBlendMode(BlendModes.ERASE); this.draw(entries, x, y, 1, 16777215); this.renderer.setBlendMode(blendMode); this._eraseMode = false ; return this; } , draw: function (entries, x, y, alpha, tint){ if (alpha === undefined) { alpha = this.globalAlpha; } if (tint === undefined) { tint = (this.globalTint >> 16) + (this.globalTint & 65280) + ((this.globalTint & 255) << 16); } else { tint = (tint >> 16) + (tint & 65280) + ((tint & 255) << 16); } if (!Array.isArray(entries)) { entries = [entries] ; } var gl = this.gl; this.camera.preRender(1, 1); if (gl) { var cx = this.camera._cx; var cy = this.camera._cy; var cw = this.camera._cw; var ch = this.camera._ch; this.renderer.setFramebuffer(this.framebuffer, false ); this.renderer.pushScissor(cx, cy, cw, ch, ch); var pipeline = this.pipeline; pipeline.projOrtho(0, this.width, 0, this.height, -1000, 1000); this.batchList(entries, x, y, alpha, tint); pipeline.flush(); this.renderer.setFramebuffer(null , false ); this.renderer.popScissor(); pipeline.projOrtho(0, pipeline.width, pipeline.height, 0, -1000, 1000); } else { this.renderer.setContext(this.context); this.batchList(entries, x, y, alpha, tint); this.renderer.setContext(); } this.dirty = true ; return this; } , drawFrame: function (key, frame, x, y, alpha, tint){ if (x === undefined) { x = 0; } if (y === undefined) { y = 0; } if (alpha === undefined) { alpha = this.globalAlpha; } if (tint === undefined) { tint = (this.globalTint >> 16) + (this.globalTint & 65280) + ((this.globalTint & 255) << 16); } else { tint = (tint >> 16) + (tint & 65280) + ((tint & 255) << 16); } var gl = this.gl; var textureFrame = this.textureManager.getFrame(key, frame); if (textureFrame) { this.camera.preRender(1, 1); if (gl) { var cx = this.camera._cx; var cy = this.camera._cy; var cw = this.camera._cw; var ch = this.camera._ch; this.renderer.setFramebuffer(this.framebuffer, false ); this.renderer.pushScissor(cx, cy, cw, ch, ch); var pipeline = this.pipeline; pipeline.projOrtho(0, this.width, 0, this.height, -1000, 1000); pipeline.batchTextureFrame(textureFrame, x, y, tint, alpha, this.camera.matrix, null ); pipeline.flush(); this.renderer.setFramebuffer(null , false ); this.renderer.popScissor(); pipeline.projOrtho(0, pipeline.width, pipeline.height, 0, -1000, 1000); } else { this.batchTextureFrame(textureFrame, x, y, alpha, tint); } this.dirty = true ; } return this; } , batchList: function (children, x, y, alpha, tint){ for (var i = 0; i < (_AN_Read_length('length', children)); i++ ){ var entry = children[i]; if (!entry || entry === this) { continue ; } if (entry.renderWebGL || entry.renderCanvas) { this.drawGameObject(entry, x, y); } else if (entry.isParent || entry.list) { this.batchGroup(entry.getChildren(), x, y); } else if (typeof entry === 'string') { this.batchTextureFrameKey(entry, null , x, y, alpha, tint); } else if (entry instanceof Frame) { this.batchTextureFrame(entry, x, y, alpha, tint); } else if (Array.isArray(entry)) { this.batchList(entry, x, y, alpha, tint); } } } , batchGroup: function (children, x, y){ if (x === undefined) { x = 0; } if (y === undefined) { y = 0; } for (var i = 0; i < (_AN_Read_length('length', children)); i++ ){ var entry = children[i]; if (entry.willRender()) { var tx = entry.x + x; var ty = entry.y + y; this.drawGameObject(entry, tx, ty); } } } , batchGameObjectWebGL: function (gameObject, x, y){ if (x === undefined) { x = gameObject.x; } if (y === undefined) { y = gameObject.y; } var prevX = gameObject.x; var prevY = gameObject.y; if (!this._eraseMode) { this.renderer.setBlendMode(gameObject.blendMode); } gameObject.setPosition(x, y); gameObject.renderWebGL(this.renderer, gameObject, 0, this.camera, null ); gameObject.setPosition(prevX, prevY); } , batchGameObjectCanvas: function (gameObject, x, y){ if (x === undefined) { x = gameObject.x; } if (y === undefined) { y = gameObject.y; } var prevX = gameObject.x; var prevY = gameObject.y; if (this._eraseMode) { var blendMode = gameObject.blendMode; gameObject.blendMode = BlendModes.ERASE; } gameObject.setPosition(x, y); gameObject.renderCanvas(this.renderer, gameObject, 0, this.camera, null ); gameObject.setPosition(prevX, prevY); if (this._eraseMode) { gameObject.blendMode = blendMode; } } , batchTextureFrameKey: function (key, frame, x, y, alpha, tint){ var textureFrame = this.textureManager.getFrame(key, frame); if (textureFrame) { this.batchTextureFrame(textureFrame, x, y, alpha, tint); } } , batchTextureFrame: function (textureFrame, x, y, alpha, tint){ if (x === undefined) { x = 0; } if (y === undefined) { y = 0; } if (this.gl) { this.pipeline.batchTextureFrame(textureFrame, x, y, tint, alpha, this.camera.matrix, null ); } else { var ctx = this.context; var cd = textureFrame.canvasData; var source = textureFrame.source.image; var matrix = this.camera.matrix; ctx.globalAlpha = this.globalAlpha; ctx.setTransform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); ctx.drawImage(source, cd.x, cd.y, cd.width, cd.height, x, y, cd.width, cd.height); } } , preDestroy: function (){ if (!this._saved) { CanvasPool.remove(this.canvas); if (this.gl) { this.renderer.deleteFramebuffer(this.framebuffer); } this.texture.destroy(); this.camera.destroy(); this.canvas = null ; this.context = null ; this.framebuffer = null ; this.texture = null ; } } } ); module.exports = RenderTexture;