Composer and Qiso rendering problem

In connection to the topic discuss here, where Richard stated:

Qiso creates a display group on initiation and all rendering is done to that group, so as long as you initiate before creating other display groups, those groups should naturally sit on top and adding your UI elements to those groups should in turn sit them on top of Qiso.

but Rob also stated 

Display objects that are not part of the parent scene  or part of the overlay scene (i.e. you did not insert them into the scene group)  are always on top of composer managed objects.

I have made a really simple app where the problem can be reproduced.

The code can be found below:

local composer = require( "composer" ) local scene = composer.newScene() local widget = require("widget") local qiso = require "plugin.qisoengine" qiso.setAssetsFolder("assets") -- Enable zooming when the screen is pinched qiso.enablePinchZoom() -- Enable camera panning when the screen is dragged qiso.enableCameraPan() -- Enable the main Qiso loop to render/update our world qiso.activate() -- Load a Lua formatted Tiled Map Editor tilemap into a Qiso map. qiso.loadTiledMap("map2") qiso.setZoomLevel(2) qiso.setMaxZoomLevel(3) print('Qiso stuff') ----------------------------------------------------------------------------------- -- Scene event functions -- ----------------------------------------------------------------------------------- -- create() function scene:create( event ) local sceneGroup = self.view -- Code here runs when the scene is first created but has not yet appeared on screen end -- scene:create() -- show() function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is still off screen (but is about to come on screen) local toolbarGroup = display.newGroup() -- Creates a new display group for the toolbar bar icons -- toolbarGroup.alpha = 1 -- Displays the toolbar -- Delete button to remove an item from the map local deleteButton = widget.newButton( { width = 150, height = 150, defaultFile = "images/delete.png" } ) deleteButton.x = 75 deleteButton.y = display.contentHeight-75 toolbarGroup:insert( deleteButton ) -- Inserts button into toolbar group sceneGroup:insert( toolbarGroup ) -- Inserts button into SceneGroup print('Insert in sceneGroup') elseif ( phase == "did" ) then -- Code here runs when the scene is entirely on screen end end -- hide() function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then -- Code here runs immediately after the scene goes entirely off screen end end -- destroy() function scene:destroy( event ) local sceneGroup = self.view -- Code here runs prior to the removal of scene's view end -- ----------------------------------------------------------------------------------- -- Scene event function listeners -- ----------------------------------------------------------------------------------- scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) -- ----------------------------------------------------------------------------------- return scene 

When debugging I can see that Qiso is called first, with the console displaying:

Qiso stuff

Insert in sceneGroup

Still, the map is displayed on top of the button as you can see from the attached snapshot.

So I’m looking into a way to insert my display objects into the SceneGroup but keep them at the top, this should work out-of-the-box IMO.

Maybe I need to insert the map in sceneGroup as well? If so, maybe Richard can guide me on how to to that? (i.e. how can I retrieve the group Qiso has created?).

Thanks!

Move this chunk into your scene:create routine and you should be ok:

local qiso = require "plugin.qisoengine" qiso.setAssetsFolder("assets") -- Enable zooming when the screen is pinched qiso.enablePinchZoom() -- Enable camera panning when the screen is dragged qiso.enableCameraPan() -- Enable the main Qiso loop to render/update our world qiso.activate() -- Load a Lua formatted Tiled Map Editor tilemap into a Qiso map. qiso.loadTiledMap("map2") qiso.setZoomLevel(2) qiso.setMaxZoomLevel(3) print('Qiso stuff')

Note also that you should be calling qiso.activate() after setting everything up really, i.e. as the last line in the above code rather than in the middle. It’ll work just fine regardless, but activate() is basically invoking the renderer which you just don’t need to do until everything is set up - a good habit to get into for when you’re working on something bigger where squeezing every bit of performance out of it might be more worthwhile.

Let me know if you come across any further problems with that code moved into the scene:create routine. I had a Composer demo set up a while ago but can’t seem to find it now - happy to create another if need be.

Thanks Richard, unfortunately the button remains behind the map after moving the code into the scene:create routine.

Well noted for the qiso.activate, I will move it to the end in my project.

Ah, sorry, turns out the Composer demo I had was based around an old toBack() hack I’d been playing with that wasn’t in the released plugin, and that wasn’t a very elegant way of doing it anyway!

Implemented a new function into Qiso now, setParentGroup(). Just pass another group to Qiso via this function and it’ll insert the rendering layer into that group. I’ve included a basic Composer example in the documentation, but this will work with any group management system, not just Composer:

https://qiso.qweb.co.uk/documentation/graphics/rendering/functions/setparentgroup

Note that the example calls setParentGroup() and activate() within the scene:create function, so rendering will start before the Composer transition effect moves the group into view, meaning that the Qiso map will inherit that same transition effect. If you don’t want this, you might want to experiment with calling these up in the scene:show if(phase == “did”) routine instead. Just note that anything added to the scene group before calling setParentGroup() will still show behind Qiso unless you then do toFront() calls on those elements.

The new function is pushed live, but it might take up to an hour for the Corona build servers to synchronise.

Actually, I’ve amended the example slightly, to show activate() within the scene:show and deactivate() within scene:hide. This should be work better with how Composer is intended to be used, because your world would effectively pause while not on screen.

Now it works as described in your example! Thanks!

I hope I can send you my app in a couple of weeks so you can see what I’m working on with Qiso.

That’d be brilliant :grin:

Move this chunk into your scene:create routine and you should be ok:

local qiso = require "plugin.qisoengine" qiso.setAssetsFolder("assets") -- Enable zooming when the screen is pinched qiso.enablePinchZoom() -- Enable camera panning when the screen is dragged qiso.enableCameraPan() -- Enable the main Qiso loop to render/update our world qiso.activate() -- Load a Lua formatted Tiled Map Editor tilemap into a Qiso map. qiso.loadTiledMap("map2") qiso.setZoomLevel(2) qiso.setMaxZoomLevel(3) print('Qiso stuff')

Note also that you should be calling qiso.activate() after setting everything up really, i.e. as the last line in the above code rather than in the middle. It’ll work just fine regardless, but activate() is basically invoking the renderer which you just don’t need to do until everything is set up - a good habit to get into for when you’re working on something bigger where squeezing every bit of performance out of it might be more worthwhile.

Let me know if you come across any further problems with that code moved into the scene:create routine. I had a Composer demo set up a while ago but can’t seem to find it now - happy to create another if need be.

Thanks Richard, unfortunately the button remains behind the map after moving the code into the scene:create routine.

Well noted for the qiso.activate, I will move it to the end in my project.

Ah, sorry, turns out the Composer demo I had was based around an old toBack() hack I’d been playing with that wasn’t in the released plugin, and that wasn’t a very elegant way of doing it anyway!

Implemented a new function into Qiso now, setParentGroup(). Just pass another group to Qiso via this function and it’ll insert the rendering layer into that group. I’ve included a basic Composer example in the documentation, but this will work with any group management system, not just Composer:

https://qiso.qweb.co.uk/documentation/graphics/rendering/functions/setparentgroup

Note that the example calls setParentGroup() and activate() within the scene:create function, so rendering will start before the Composer transition effect moves the group into view, meaning that the Qiso map will inherit that same transition effect. If you don’t want this, you might want to experiment with calling these up in the scene:show if(phase == “did”) routine instead. Just note that anything added to the scene group before calling setParentGroup() will still show behind Qiso unless you then do toFront() calls on those elements.

The new function is pushed live, but it might take up to an hour for the Corona build servers to synchronise.

Actually, I’ve amended the example slightly, to show activate() within the scene:show and deactivate() within scene:hide. This should be work better with how Composer is intended to be used, because your world would effectively pause while not on screen.

Now it works as described in your example! Thanks!

I hope I can send you my app in a couple of weeks so you can see what I’m working on with Qiso.

That’d be brilliant :grin: