Skip to content

Commit f420bc8

Browse files
authored
Merge pull request phaserjs#4074 from TadejZupancic/master
Create RenderTexture from existing texture/frame
2 parents 19c0b47 + 7c0645c commit f420bc8

3 files changed

Lines changed: 131 additions & 55 deletions

File tree

src/gameobjects/rendertexture/RenderTexture.js

Lines changed: 124 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ var UUID = require('../../utils/string/UUID');
5454
* @param {number} [y=0] - The vertical position of this Game Object in the world.
5555
* @param {integer} [width=32] - The width of the Render Texture.
5656
* @param {integer} [height=32] - The height of the Render Texture.
57+
* @property {string} [key] - The texture key to make the RenderTexture from.
58+
* @property {string} [frame] - the frame to make the RenderTexture from.
5759
*/
5860
var RenderTexture = new Class({
5961

@@ -79,7 +81,7 @@ var RenderTexture = new Class({
7981

8082
initialize:
8183

82-
function RenderTexture (scene, x, y, width, height)
84+
function RenderTexture (scene, x, y, width, height, key, frame)
8385
{
8486
if (x === undefined) { x = 0; }
8587
if (y === undefined) { y = 0; }
@@ -133,16 +135,7 @@ var RenderTexture = new Class({
133135
* @type {HTMLCanvasElement}
134136
* @since 3.2.0
135137
*/
136-
this.canvas = CanvasPool.create2D(this, width, height);
137-
138-
/**
139-
* A reference to the Rendering Context belonging to the Canvas Element this Render Texture is drawing to.
140-
*
141-
* @name Phaser.GameObjects.RenderTexture#context
142-
* @type {CanvasRenderingContext2D}
143-
* @since 3.2.0
144-
*/
145-
this.context = this.canvas.getContext('2d');
138+
this.canvas = null;
146139

147140
/**
148141
* A reference to the GL Frame Buffer this Render Texture is drawing to.
@@ -154,6 +147,15 @@ var RenderTexture = new Class({
154147
*/
155148
this.framebuffer = null;
156149

150+
/**
151+
* Is this Render Texture dirty or not? If not it won't spend time clearing or filling itself.
152+
*
153+
* @name Phaser.GameObjects.RenderTexture#dirty
154+
* @type {boolean}
155+
* @since 3.12.0
156+
*/
157+
this.dirty = false;
158+
157159
/**
158160
* The internal crop data object, as used by `setCrop` and passed to the `Frame.setCropUVs` method.
159161
*
@@ -171,7 +173,7 @@ var RenderTexture = new Class({
171173
* @type {Phaser.Textures.Texture}
172174
* @since 3.12.0
173175
*/
174-
this.texture = scene.sys.textures.addCanvas(UUID(), this.canvas);
176+
this.texture = null;
175177

176178
/**
177179
* The Frame corresponding to this Render Texture.
@@ -180,8 +182,8 @@ var RenderTexture = new Class({
180182
* @type {Phaser.Textures.Frame}
181183
* @since 3.12.0
182184
*/
183-
this.frame = this.texture.get();
184-
185+
this.frame = null;
186+
185187
/**
186188
* Internal saved texture flag.
187189
*
@@ -192,6 +194,42 @@ var RenderTexture = new Class({
192194
*/
193195
this._saved = false;
194196

197+
if (key === undefined)
198+
{
199+
this.canvas = CanvasPool.create2D(this, width, height);
200+
201+
// Create a new Texture for this Text object
202+
this.texture = scene.sys.textures.addCanvas(UUID(), this.canvas);
203+
204+
// Get the frame
205+
this.frame = this.texture.get();
206+
}
207+
else
208+
{
209+
this.texture = scene.sys.textures.get(key);
210+
211+
// Get the frame
212+
if (frame === undefined) { frame = '__BASE'; }
213+
this.frame = this.texture.get(frame);
214+
215+
this.canvas = this.frame.source.image;
216+
this._saved = true;
217+
218+
this.dirty = true;
219+
220+
this.width = this.frame.cutWidth;
221+
this.height = this.frame.cutHeight;
222+
}
223+
224+
/**
225+
* A reference to the Rendering Context belonging to the Canvas Element this Render Texture is drawing to.
226+
*
227+
* @name Phaser.GameObjects.RenderTexture#context
228+
* @type {CanvasRenderingContext2D}
229+
* @since 3.2.0
230+
*/
231+
this.context = this.canvas.getContext('2d');
232+
195233
/**
196234
* Internal erase mode flag.
197235
*
@@ -213,15 +251,6 @@ var RenderTexture = new Class({
213251
*/
214252
this.camera = new Camera(0, 0, width, height);
215253

216-
/**
217-
* Is this Render Texture dirty or not? If not it won't spend time clearing or filling itself.
218-
*
219-
* @name Phaser.GameObjects.RenderTexture#dirty
220-
* @type {boolean}
221-
* @since 3.12.0
222-
*/
223-
this.dirty = false;
224-
225254
/**
226255
* A reference to the WebGL Rendering Context.
227256
*
@@ -250,7 +279,7 @@ var RenderTexture = new Class({
250279
this.camera.setScene(scene);
251280

252281
this.setPosition(x, y);
253-
this.setSize(width, height);
282+
if (key === undefined) { this.setSize(width, height); }
254283
this.setOrigin(0, 0);
255284
this.initPipeline();
256285
},
@@ -273,7 +302,11 @@ var RenderTexture = new Class({
273302

274303
/**
275304
* Resizes the Render Texture to the new dimensions given.
305+
*
306+
* If Render Texture was created from specific frame, only the size of the frame will be changed. The size of the source
307+
* texture will not change.
276308
*
309+
* If Render Texture was not created from specific frame, the following will happen:
277310
* In WebGL it will destroy and then re-create the frame buffer being used by the Render Texture.
278311
* In Canvas it will resize the underlying canvas element.
279312
* Both approaches will erase everything currently drawn to the Render Texture.
@@ -294,31 +327,45 @@ var RenderTexture = new Class({
294327

295328
if (width !== this.width || height !== this.height)
296329
{
297-
this.canvas.width = width;
298-
this.canvas.height = height;
299-
300-
if (this.gl)
330+
331+
if (this.frame.name === '__BASE') // resize the texture
301332
{
302-
var gl = this.gl;
303333

304-
this.renderer.deleteTexture(this.frame.source.glTexture);
305-
this.renderer.deleteFramebuffer(this.framebuffer);
334+
this.canvas.width = width;
335+
this.canvas.height = height;
306336

307-
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);
308-
this.framebuffer = this.renderer.createFramebuffer(width, height, this.frame.source.glTexture, false);
337+
if (this.gl)
338+
{
339+
var gl = this.gl;
309340

310-
this.frame.glTexture = this.frame.source.glTexture;
311-
}
341+
this.renderer.deleteTexture(this.frame.source.glTexture);
342+
this.renderer.deleteFramebuffer(this.framebuffer);
312343

313-
this.frame.source.width = width;
314-
this.frame.source.height = height;
344+
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);
345+
this.framebuffer = this.renderer.createFramebuffer(width, height, this.frame.source.glTexture, false);
315346

316-
this.camera.setSize(width, height);
347+
this.frame.glTexture = this.frame.source.glTexture;
348+
}
317349

318-
this.frame.setSize(width, height);
350+
this.frame.source.width = width;
351+
this.frame.source.height = height;
319352

320-
this.width = width;
321-
this.height = height;
353+
this.camera.setSize(width, height);
354+
355+
this.frame.setSize(width, height);
356+
357+
this.width = width;
358+
this.height = height;
359+
360+
}
361+
}
362+
else // resize the frame
363+
{
364+
var baseFrame = this.texture.getSourceImage();
365+
if (this.frame.cutX + width > baseFrame.width) { width = baseFrame.width - this.frame.cutX; }
366+
if (this.frame.cutY + height > baseFrame.height) { height = baseFrame.height - this.frame.cutY; }
367+
368+
this.frame.setSize(width, height, this.frame.cutX, this.frame.cutY);
322369
}
323370

324371
return this;
@@ -406,12 +453,20 @@ var RenderTexture = new Class({
406453
*
407454
* @param {number} rgb - The color to fill the Render Texture with.
408455
* @param {number} [alpha=1] - The alpha value used by the fill.
456+
* @param {number} [x=0] - The left coordinate of the fill rectangle.
457+
* @param {number} [y=0] - The top coordinate of the fill rectangle.
458+
* @param {number} [width=this.frame.cutWidth] - The width of the fill rectangle.
459+
* @param {number} [height=this.frame.cutHeight] - The height of the fill rectangle.
409460
*
410461
* @return {this} This Render Texture instance.
411462
*/
412-
fill: function (rgb, alpha)
463+
fill: function (rgb, alpha, x, y, width, height)
413464
{
414465
if (alpha === undefined) { alpha = 1; }
466+
if (x === undefined) { x = 0; }
467+
if (y === undefined) { y = 0; }
468+
if (width === undefined) { width = this.frame.cutWidth; }
469+
if (height === undefined) { height = this.frame.cutHeight; }
415470

416471
var r = ((rgb >> 16) | 0) & 0xff;
417472
var g = ((rgb >> 8) | 0) & 0xff;
@@ -423,22 +478,34 @@ var RenderTexture = new Class({
423478
{
424479
var renderer = this.renderer;
425480

481+
var gl = this.gl;
482+
426483
var bounds = this.getBounds();
427484

428485
renderer.setFramebuffer(this.framebuffer, true);
429486

487+
if (width !== this.frame.source.width || height !== this.frame.source.height)
488+
{
489+
gl.scissor(x + this.frame.cutX, y + this.frame.cutY, width, height);
490+
}
491+
430492
this.pipeline.drawFillRect(
431493
bounds.x, bounds.y, bounds.right, bounds.bottom,
432494
Utils.getTintFromFloats(r / 255, g / 255, b / 255, 1),
433495
alpha
434496
);
435497

436-
renderer.setFramebuffer(null, true);
498+
if (width !== this.frame.source.width || height !== this.frame.source.height)
499+
{
500+
gl.scissor(0, 0, this.frame.source.width, this.frame.source.height);
501+
}
502+
503+
this.renderer.setFramebuffer(null, true);
437504
}
438505
else
439506
{
440-
this.context.fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + alpha + ')';
441-
this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);
507+
this.context.fillStyle = 'rgba(' + ur + ',' + ug + ',' + ub + ',' + alpha + ')';
508+
this.context.fillRect(x + this.frame.cutX, y + this.frame.cutY, width, height);
442509
}
443510

444511
return this;
@@ -463,6 +530,11 @@ var RenderTexture = new Class({
463530
var renderer = this.renderer;
464531

465532
renderer.setFramebuffer(this.framebuffer, true);
533+
534+
if (this.frame.cutWidth !== this.canvas.width || this.frame.cutHeight !== this.canvas.height)
535+
{
536+
gl.scissor(this.frame.cutX, this.frame.cutY, this.frame.cutWidth, this.frame.cutHeight);
537+
}
466538

467539
gl.clearColor(0, 0, 0, 0);
468540
gl.clear(gl.COLOR_BUFFER_BIT);
@@ -475,7 +547,7 @@ var RenderTexture = new Class({
475547

476548
ctx.save();
477549
ctx.setTransform(1, 0, 0, 1, 0, 0);
478-
ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
550+
ctx.clearRect(this.frame.cutX, this.frame.cutY, this.frame.cutWidth, this.frame.cutHeight);
479551
ctx.restore();
480552
}
481553

@@ -636,9 +708,9 @@ var RenderTexture = new Class({
636708

637709
var pipeline = this.pipeline;
638710

639-
pipeline.projOrtho(0, this.width, 0, this.height, -1000.0, 1000.0);
711+
pipeline.projOrtho(0, this.texture.width, 0, this.texture.height, -1000.0, 1000.0);
640712

641-
this.batchList(entries, x, y, alpha, tint);
713+
this.batchList(entries, x + this.frame.cutX, y + this.frame.cutY, alpha, tint);
642714

643715
pipeline.flush();
644716

@@ -652,7 +724,7 @@ var RenderTexture = new Class({
652724
{
653725
this.renderer.setContext(this.context);
654726

655-
this.batchList(entries, x, y, alpha, tint);
727+
this.batchList(entries, x + this.frame.cutX, y + this.frame.cutY, alpha, tint);
656728

657729
this.renderer.setContext();
658730
}
@@ -727,9 +799,9 @@ var RenderTexture = new Class({
727799

728800
var pipeline = this.pipeline;
729801

730-
pipeline.projOrtho(0, this.width, 0, this.height, -1000.0, 1000.0);
802+
pipeline.projOrtho(0, this.texture.width, 0, this.texture.height, -1000.0, 1000.0);
731803

732-
pipeline.batchTextureFrame(textureFrame, x, y, tint, alpha, this.camera.matrix, null);
804+
pipeline.batchTextureFrame(textureFrame, x + this.frame.cutX, y + this.frame.cutY, tint, alpha, this.camera.matrix, null);
733805

734806
pipeline.flush();
735807

@@ -741,7 +813,7 @@ var RenderTexture = new Class({
741813
}
742814
else
743815
{
744-
this.batchTextureFrame(textureFrame, x, y, alpha, tint);
816+
this.batchTextureFrame(textureFrame, x + this.frame.cutX, y + this.frame.cutY, alpha, tint);
745817
}
746818

747819
this.dirty = true;

src/gameobjects/rendertexture/RenderTextureCreator.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ GameObjectCreator.register('renderTexture', function (config, addToScene)
3030
var y = GetAdvancedValue(config, 'y', 0);
3131
var width = GetAdvancedValue(config, 'width', 32);
3232
var height = GetAdvancedValue(config, 'height', 32);
33+
var key = GetAdvancedValue(config, 'key', undefined);
34+
var frame = GetAdvancedValue(config, 'frame', undefined);
3335

34-
var renderTexture = new RenderTexture(this.scene, x, y, width, height);
36+
var renderTexture = new RenderTexture(this.scene, x, y, width, height, key, frame);
3537

3638
if (addToScene !== undefined)
3739
{

src/gameobjects/rendertexture/RenderTextureFactory.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@ var RenderTexture = require('./RenderTexture');
2323
* @param {number} y - The vertical position of this Game Object in the world.
2424
* @param {integer} [width=32] - The width of the Render Texture.
2525
* @param {integer} [height=32] - The height of the Render Texture.
26+
* @property {string} [key] - The texture key to make the RenderTexture from.
27+
* @property {string} [frame] - the frame to make the RenderTexture from.
2628
*
2729
* @return {Phaser.GameObjects.RenderTexture} The Game Object that was created.
2830
*/
29-
GameObjectFactory.register('renderTexture', function (x, y, width, height)
31+
GameObjectFactory.register('renderTexture', function (x, y, width, height, key, frame)
3032
{
31-
return this.displayList.add(new RenderTexture(this.scene, x, y, width, height));
33+
return this.displayList.add(new RenderTexture(this.scene, x, y, width, height, key, frame));
3234
});

0 commit comments

Comments
 (0)