Nick Posted October 26, 2014 Share Posted October 26, 2014 I've come across a few issues in WebGL after upgrading to 2.1.3 which I've tracked down to the Phaser State Transition Plugin. 1. Stage is drawn upside down. The State Transition Plugin makes a copy of the stage to a renderTexture like so:this._texture = new Phaser.RenderTexture(this.game, this.game.width, this.game.height, 'cover');/* Draw the current world to the render */this._texture.renderXY(this.game.stage, -this.game.camera.x, -this.game.camera.y); This results in the RenderTexture displaying the drawn stage upside down. 2. Error is thrown when the plugin adds a Sprite to the game which uses the new RenderTexture. // Create a new sprite which uses the texture.this._cover = new Phaser.Sprite(this.game, 0, 0, this._texture);// More code to position the sprite...this.game.state.states[state]['create'] = function() { _create.call(_this.game.state.states[state]); // This line here fires the error... _this.game.add.existing(_this._cover); _animateCover.call(_this);}this.game.state.start(state);Once the sprite is added to the game world via add.existing() the following error fires. Uncaught TypeError: Failed to execute 'texImage2D' on 'WebGLRenderingContext': No function was found that matched the signature provided. One thing to note is that Canvas mode still works as expected. I noticed that Phaser.RenderTexture.render now uses either renderWebGL() or renderCanvas() depending on the renderer type so the problems are specific to the WebGL implementation of renderTextures. At this stage I'm not able to shed any more light on it that that Link to comment Share on other sites More sharing options...
rich Posted October 26, 2014 Share Posted October 26, 2014 RenderTextures now need a matrix instead of a point object to define how they are transformed. The x/y values form the tx/ty translate values - this is handled by Phaser for drawing simple display objects, but the enter Stage may provide different. You may want to try creating a PIXI RenderTexture directly and manipulating the matrix as needed (or over-riding the Phaser render method and changing the matrix property first) as that is almost certainly the root of the issue (the matrix set-up). Link to comment Share on other sites More sharing options...
valueerror Posted October 29, 2014 Share Posted October 29, 2014 any news on that? how to fix this issue? Link to comment Share on other sites More sharing options...
MichaelD Posted October 31, 2014 Share Posted October 31, 2014 Looking forward for a fix also Link to comment Share on other sites More sharing options...
Nick Posted November 2, 2014 Author Share Posted November 2, 2014 Sorry all. I've been away for a few days. Thanks for the suggestions Rich. I'll be taking a look in the next couple days and will post an update here. Update: I've tried creating a PIXI RenderTexture directly using the following code:/* If there's no texture create one */if (!this._texture) { this._texture = new PIXI.RenderTexture(this.game.width, this.game.height, this.game.renderer);}this._matrix = new PIXI.Matrix();this._matrix.translate(-this.game.camera.x, -this.game.camera.y);this._texture.render(this.game.stage, this._matrix);Again this works correctly when Canvas is the renderer but WebGL behaves the same as it did using the Phaser methods. So as far as I can tell the matrix set up is okay. valueerror 1 Link to comment Share on other sites More sharing options...
valueerror Posted November 6, 2014 Share Posted November 6, 2014 hmm.. can't you just work around and catch the case where webgl is used and flip the texture? do you change anything related to the world bounds in this plugin? i am zooming in/out a lot in my game and change the bounds of the world from state to state and the camera bounds - using the plugin (change back to the menu for example) in a zoomed state results in weird bounds - not showing everything on the screen btw. thank you very much for this plugin - i wish i could use it in my game.. i really like the zoom out effect on every state transition.. maybe i'll find some time on this weekend to make myself familiar with the code of the plugin.. i don't know if can help but i will try thx for your work!! Link to comment Share on other sites More sharing options...
Nick Posted November 7, 2014 Author Share Posted November 7, 2014 Just to be clear I'm not the author of this plugin Link to comment Share on other sites More sharing options...
valueerror Posted November 7, 2014 Share Posted November 7, 2014 it's crazy.. i played a little bit with the code of the plugin and found out that this line is turning the whole stage upside downthis._texture.renderXY(this.game.stage, this.game.camera.x, this.game.camera.y, true);to test this i just added these two lines to my game menu:texture = new Phaser.RenderTexture(game,game.width, game.height);texture.renderXY(game.stage, game.camera.x, game.camera.y, true);aaaand.. everything is upside down.. not just the image.. the whole stage, physicsbodies. mouse movement... everything is mirrored along the y - axis.. same goes btw. for this approach:texture = new PIXI.RenderTexture(game.width, game.height, game.renderer);matrix = new PIXI.Matrix();matrix.translate(game.camera.x, -game.camera.y);texture.render(game.stage, matrix);rendering the game.stage on the texture flips everything WTH ? as far as i understand these lines create a new empty texture and then render the current stage on this texture.. why is this altering the stage ? Link to comment Share on other sites More sharing options...
valueerror Posted November 7, 2014 Share Posted November 7, 2014 rendering a phaser group on the texture for example does nothing... that means it works .. in my game i add everything on the stage to a group called "stageGroup" (except the game UI) for scalingso i tried giving the render function the "stageGroup" instead of the "game.stage" it still throws the same error in the console : Error: WebGL: texImage2D: null ImageData but it works nevertheless.. it is still unusable for me because not everything is on the stageGroup and it doesn't take the current zoom state of the stageGroup into account and therefore looks weird. Link to comment Share on other sites More sharing options...
valueerror Posted November 7, 2014 Share Posted November 7, 2014 uh.. using this.game.worldinstead ofthis.game.stageworks flawlessly !!(almost)the only problem that remains is that the current scale factor of the world is NOT taken into account ... hmmm... any ideas on that? Link to comment Share on other sites More sharing options...
valueerror Posted November 7, 2014 Share Posted November 7, 2014 this code works even with my always changing zoom factors if (!this._texture) { this._texture = new PIXI.RenderTexture(this.game.width, this.game.height, this.game.renderer);}this._matrix = new PIXI.Matrix();this._matrix.translate(-this.game.camera.x, -this.game.camera.y);this._texture.render(this.game.world, this._matrix); Link to comment Share on other sites More sharing options...
valueerror Posted November 7, 2014 Share Posted November 7, 2014 this line still throws the old error on webGL_this.game.add.existing(_this._cover);the actual line in phaser.js is : 6234 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);maybe we should file a github issue so @rich can read this ?? Link to comment Share on other sites More sharing options...
valueerror Posted November 10, 2014 Share Posted November 10, 2014 unfortunately the tween that zooms the created "cover" is not always visible on my mobile device.. the first time it is not there most of the time.. i do not understand how a tween can be skipped or just not shown but the oncomplete function is still called. Link to comment Share on other sites More sharing options...
efusien Posted November 27, 2014 Share Posted November 27, 2014 Maybe you could propose a fork on the Github repo: https://github.com/cristianbote/phaser-state-transition.Seems nothing changed since 8 months... Link to comment Share on other sites More sharing options...
valueerror Posted December 1, 2014 Share Posted December 1, 2014 well i found out how to make the code work and i even found a workaround for the tween on slow devices (so it's always visible) i am using it in my current game without any problems.. actually i am using just the necessary code - not the plugin.. if you need something - just tell me Link to comment Share on other sites More sharing options...
efusien Posted December 1, 2014 Share Posted December 1, 2014 Yes, can you show your working code so I can test it on my side?Thanks Link to comment Share on other sites More sharing options...
valueerror Posted December 2, 2014 Share Posted December 2, 2014 well ... here it is..create: function () { game.add.existing(cover); // add the cover for the transition effect as early as possible //other creation stuff here cover.bringToTop(); // bring the cover for the stateTransition to top game.time.events.add(0, fadeIn); // start the fade out of the cover and therefore the fade in of the current state}function fadeOut(target){ texture = new PIXI.RenderTexture(game.width, game.height, game.renderer); matrix = new PIXI.Matrix(); matrix.translate(-game.camera.x, -game.camera.y); texture.render(game.world, matrix); cover = new Phaser.Sprite(game, 0, 0, texture); cover.fixedToCamera = true; cover.anchor.setTo(0.5,0.5); cover.cameraOffset.x = game.width / 2; cover.cameraOffset.y = game.height / 2; game.state.start(''+target+''); }function fadeIn() { if (!cover) {return;} // catch a very rare error where the cover is not created for some reason tween1 = this.game.add.tween(cover).to({alpha: 0}, 1000,Phaser.Easing.Exponential.InOut, true); tween2 = this.game.add.tween(cover.scale).to({ x: 1.5, y: 1.5 }, 1000,Phaser.Easing.Exponential.InOut, true); tween2.onComplete.addOnce(destroyCover, this);}function destroyCover() { cover&&cover.destroy(); cover = null; texture&&texture.destroy(); texture = null;}so to change from one state to another (or to start a state when pressing a button) i usefadeOut('somestate');this creates the rendertexture and the "cover" and starts the given state..the state then adds the existing "cover" (onTop) and starts the cover-zoom-fade Tween... thats it.i start the tween through a game.time.event because that way it waits for the new state creation process to finish - otherwise the tween would run between those creation processes and probably lag or not show at all.. efusien 1 Link to comment Share on other sites More sharing options...
efusien Posted December 2, 2014 Share Posted December 2, 2014 Thanks for the post. I have a small flickering effect when the create function add the cover on the game.We can prevent this flickering effect by adding the cover before state creation: in the init() state function. So we can move the line below:game.add.existing(cover); // add the cover for the transition effect as early as possibleto the init function:init: function () { game.add.existing(cover); // add the cover for the transition effect as early as possible}Just for other people information, the code below could not work depending on when we create our display objects (keep in mind groups order).We need to have the cover at the top, so it depends on your layers order.cover.bringToTop();If I have some time I'll post an updated version of the plugin in order to give everyone a working copy ;-) Link to comment Share on other sites More sharing options...
efusien Posted December 2, 2014 Share Posted December 2, 2014 Ok, so the plugin function _draw looks like this code:/* Draw the world state */function _draw(state) {var texture;var matrix;/* Pause the game at first */this.game.paused = true;/* If there's a sprite there, destroy it */if (this._cover) {this._cover.destroy();}/* If there's a state as a parameter change the state and do the dew */if (state) {texture = new PIXI.RenderTexture(game.width, game.height, game.renderer);matrix = new PIXI.Matrix();matrix.translate(-game.camera.x, -game.camera.y);texture.render(game.world, matrix);var _init = this.game.state.states[state]['init'];var _create = this.game.state.states[state]['create'];var _this = this;this._cover = new Phaser.Sprite(game, 0, 0, texture);this._cover.fixedToCamera = true;this._cover.anchor.setTo(0.5);//Instead of x/y we need to set the cameraOffset point */this._cover.cameraOffset.x = this.game.width / 2;this._cover.cameraOffset.y = this.game.height / 2;this.game.state.states[state]['init'] = function() {_init.call(_this.game.state.states[state]);_this.game.add.existing(_this._cover);};this.game.state.states[state]['create'] = function() {_create.call(_this.game.state.states[state]);_animateCover.call(_this);};this.game.state.start(state);}/* Resume the game */this.game.paused = false;}I just added the init function call and your previously code with PIXI texture.If anyone can test it on his own game. Sounds good on my side. Link to comment Share on other sites More sharing options...
valueerror Posted December 3, 2014 Share Posted December 3, 2014 interesting.. i can't see any flickering in my game but moving the cover to init sounds like a good idea nevertheless.. btw. i have no idea why the game is paused in the plugin.. do you? i tried several ways to accomplish the zoom/fade effect and game.pause didn't do anything good .. Link to comment Share on other sites More sharing options...
efusien Posted December 3, 2014 Share Posted December 3, 2014 I think it depends on your purposes. I made my own version because I need a specific behavior. For the texture, I saw yesterday this code seems to do the same things as yours: texture = new PIXI.RenderTexture(game.width, game.height, game.renderer);//matrix = new PIXI.Matrix();//matrix.translate(-game.camera.x, -game.camera.y);texture.render(game.world/*, matrix*/);So I'm asking if it's necessary to add the matrix? Maybe I'm wrong? Link to comment Share on other sites More sharing options...
valueerror Posted December 3, 2014 Share Posted December 3, 2014 for a game world where the world is as big as the camera view and you are not moving the camera focus nor scaling your game world at some point (and maybe then - in the scaled mode - trigger the transition) - the matrix is not necessary.. in every other (more complex) game it's definitely necessary i can't really describe what it does without those lines.. lets say the cover position is in no way predictable... Link to comment Share on other sites More sharing options...
Nick Posted December 5, 2014 Author Share Posted December 5, 2014 For anyone using Phaser 2.2, the stage manager is no longer throwing a WebGL error in this version. The stage was still being drawn to the renderTexture upside down, but changing to draw the game world instead works as expected ( Thanks @valueerror for finding this previously ). I've created a pull request for the author here: https://github.com/cristianbote/phaser-state-transition/pull/8 If anyone wants to use my fork in the meantime, it's here: https://github.com/nickryall/phaser-state-transition/tree/phaser-2.2-fix Link to comment Share on other sites More sharing options...
valueerror Posted December 5, 2014 Share Posted December 5, 2014 perfect.. so i'd say.. case closed and mark it as solved? Link to comment Share on other sites More sharing options...
aaccurso Posted December 16, 2014 Share Posted December 16, 2014 Hi there, I've created a new repository with a refactored state transition plugin => https://github.com/aaccurso/phaser-state-transition-pluginIt's registered on bower and npm. Thanks for your contributions! Link to comment Share on other sites More sharing options...
Recommended Posts