possible problem with off screen culling

Is there a flag on a display object that can reveal if it is being culled? 

I’m having an issue where display objects that had their alpha adjusted while off screen are not being displayed when they move onscreen.  This did not occur until I upgraded to the public release with graphics 2.0 last week.

I’m trying to create an isolated case to submit as a bug but have not been able to create an isolated case.  Of course, this means that it may not be caused by off screen culling, it might just be a coincidence that the affected tiles are always off screen when the error occurs.

What I have is a large tile map made of square display objects that are .png images.   It looks like a tile floor. The map is bigger than the screen can display so you can slide it around with your finger to see the parts that begin off screen.  When the map is first created all of the tiles appear as expected.  However, there are events where all the tiles go to alpha 0 and then back to visible.  If the floor tile is off screen when this happens, it is doesn’t come back.  In exploring the problem, I used a touch listener to confirm that the tile is still there and its alpha is set to 1 and that isVisible is set to true, but it still doesn’t appear on the screen.  I’m trying to figure out why.

I created a test app that just creates a floor that you can move around and a button to cycle the alpha of the tiles.  I’m not getting the same results with the test app so whatever the problem is, it is more edge case than simply cycling the alpha of the display object while it is off screen.  Thus my original question, how can I tell if it is being culled?

Also, I’ve seen some code pasted into posts that retains its formating, how do I do that?

OK, got my proof.  If you run this code it will show you the problem.

  1. The map appears up and left, drag it down toward the middle of the screen.

  2. press the red button

  3. drag the map back to the middle of the screen and you will see that part of it does not reappear, presumably from culling

The key to this error is that the tile was on screen when it’s alpha was set to 0, then shifted off screen, then it’s alpha was set back to 1.  If you simply cycle the alpha the error doesn’t occur.

tileSize = 40 homeX, homeY = -400, -400 function createMap() -- create a display group local floorTiles = display.newGroup() local colors = {{.25, .25, .25},{.50,.50,.50}} local startX, finishX, deltaX = 0, 800, 40 local startY, finishY, deltaY = 0, 800, 40 local currentColor = 1 for i=startX, finishX, deltaX do for j=startY, finishY, deltaY do local tileGroup = display.newGroup() tileGroup.anchorChildren = true local thisTile = display.newRect( i,j, 40, 40 ) thisTile:setFillColor(unpack(colors[currentColor])) tileGroup:insert(thisTile) floorTiles:insert(tileGroup) tileGroup.x, tileGroup.y = i, j if currentColor == 1 then currentColor = 2 else currentColor = 1 end -- checkerboard so we can see what is going on end end floorTiles.x, floorTiles.y = homeX, homeY function dragMap(event) local self = event.target if event.phase == "began" then --set touch focus display.getCurrentStage():setFocus(self) self.isFocus = true self.markX = self.x -- store x location of object self.markY = self.y -- store y location of object elseif self.isFocus then local deltaX = event.x - event.xStart local deltaY = event.y - event.yStart if event.phase == "moved" then self.x, self.y = self.markX + deltaX, self.markY + deltaY elseif event.phase == "ended" or event.phase == "cancelled" then self.x, self.y = self.markX + deltaX, self.markY + deltaY -- reset touch focus display.getCurrentStage():setFocus(nil) self.isFocus = nil end end return true end floorTiles:addEventListener( "touch", dragMap) return floorTiles end function createButton(floorTiles) local button = display.newRect(display.contentCenterX, display.contentCenterY, 80, 80) button:setFillColor(.75, 0, 0) function restoreAlpha(thisTile) return function() floorTiles.x, floorTiles.y = homeX, homeY thisTile.alpha = 1 end end function cycleAlpha(event) local self = event.target if event.phase == "began" then --set touch focus display.getCurrentStage():setFocus(self) self.isFocus = true elseif self.isFocus then if event.phase == "ended" or event.phase == "cancelled" then for i= 1, floorTiles.numChildren do local thisTile = floorTiles[i] transition.to(thisTile, {time = 500, alpha = 0, onComplete = restoreAlpha(thisTile)}) end -- reset touch focus display.getCurrentStage():setFocus(nil) self.isFocus = nil end end return true end button:addEventListener("touch", cycleAlpha) end floorTiles = createMap() createButton(floorTiles)

I just submitted this as a bug report.

Also, I’ve seen some code pasted into posts that retains its formating, how do I do that?

Using the browser interface you should see a toolbar at the top of your editing viewport.

Choose the Code-symbol (looks like “<>”) which will open a popup where you can paste your code.

Sample:

-- main.lua local t = display.newText{text="Testing...", font=native.systemFont, fontSize=16}; t:setFillColor(1); t.x, t.y = display.contentCenterX, display.contentCenterY;

Not for nothing, but native Corona off-screen culling has never been all that effective, at least from tests I’ve conducted. I figured this was just the nature of the beast, as the onus of intelligent culling and resource management has been on the developer, but if you’re saying it worked and now it doesn’t, I’m excited to see progress made here.

Keep us posted!

Thanks for the help on formatting, I fixed my earlier post of code.

This bug took my 8 hours to track down including time to create an app that Corona would accept as proof of a bug…  At first I was just observing that “sometimes some of the floor tiles are missing”.

If any of you have time to load up this code and confirm the bug I would appreciate it.  The recreation steps are pretty simple.

The key to seeing the bug is the map/checkerboard needs to be moved out of it’s home position.  If you run the code a checkerboard appears in the upper left corner of the screen but you are only seeing about 1/4 of it.  Drag it down into the middle of the screen, then press the red button.  The red button causes a series of events: the alpha of all the tiles are set to 0, all the tiles are shifted back to the starting position, and then the alpha on all tiles is set back to 1.

After the alpha of the tiles cycle, drag the map/checkerboard back into the middle of the viewing area and you will see that a bunch of the tiles are no longer visible.  Specifically, any tile that was in the viewing area when it went to alpha = 0 and then moved out of the viewing area before returning to alpha = 1.

If you just load the app and press the red button you won’t see the bug.

Tom was able to confirm the bug and has sent it to engineering.  Thank you Tom!!

Thanks Mark and Tom!

Sounds like the same issue we’ve been watching for a while, which seems to have dropped off the face of the earth:

http://forums.coronalabs.com/topic/42281-graphics-20-display-object-transparency-issue/page-2#entry221093

Does this sound like the same issue to you all?

This bug has made my app development come to a standstill…

I didn’t find that thread before you referenced it, but I would believe they are connected.  It seems a lot more people chimed in on that thread, I hope my test case will help them diagnose the problem and that your thread will help them prioritize solving it.

I’m able to keep working while this problem exists, but I’m not going to be able to ship until it is solved one way or another.

Thanks, Mark.  I hope they can get to it soon… it holds up shipment for me!

I just  got a message that this issue is resolved in daily build 2126.  I’m not in a good spot in coding to verify.  I will let you know as soon as I have verified the fix.

Now do I use a daily build?  I see a .dmg file a .msi file and a .zip file but I don’t see instructions as to what to do with them.  I assume this is explained somewhere but I couldn’t find it, if someone has a link I’d appreciate it.

The DMG file is for Macs and the MSI file is for Windows. The ZIP file is the updated documentation that you can unzip to any location you want on your drive.

Installation:

I can only speak for Mac though where you just open the DMG file and drag the Corona bundle to your Applications folder (Replace All when asked). For Windows I assume that you just open the MSI file and re-install and overwrite the Corona installation.

Sweet!  The bug is fixed!

Thanks for the help on understanding the file extentions, Ingemar.  I’m guessing that MSI stands for microsoft installer.  I will remember it that way anyway.

OK, got my proof.  If you run this code it will show you the problem.

  1. The map appears up and left, drag it down toward the middle of the screen.

  2. press the red button

  3. drag the map back to the middle of the screen and you will see that part of it does not reappear, presumably from culling

The key to this error is that the tile was on screen when it’s alpha was set to 0, then shifted off screen, then it’s alpha was set back to 1.  If you simply cycle the alpha the error doesn’t occur.

tileSize = 40 homeX, homeY = -400, -400 function createMap() -- create a display group local floorTiles = display.newGroup() local colors = {{.25, .25, .25},{.50,.50,.50}} local startX, finishX, deltaX = 0, 800, 40 local startY, finishY, deltaY = 0, 800, 40 local currentColor = 1 for i=startX, finishX, deltaX do for j=startY, finishY, deltaY do local tileGroup = display.newGroup() tileGroup.anchorChildren = true local thisTile = display.newRect( i,j, 40, 40 ) thisTile:setFillColor(unpack(colors[currentColor])) tileGroup:insert(thisTile) floorTiles:insert(tileGroup) tileGroup.x, tileGroup.y = i, j if currentColor == 1 then currentColor = 2 else currentColor = 1 end -- checkerboard so we can see what is going on end end floorTiles.x, floorTiles.y = homeX, homeY function dragMap(event) local self = event.target if event.phase == "began" then --set touch focus display.getCurrentStage():setFocus(self) self.isFocus = true self.markX = self.x -- store x location of object self.markY = self.y -- store y location of object elseif self.isFocus then local deltaX = event.x - event.xStart local deltaY = event.y - event.yStart if event.phase == "moved" then self.x, self.y = self.markX + deltaX, self.markY + deltaY elseif event.phase == "ended" or event.phase == "cancelled" then self.x, self.y = self.markX + deltaX, self.markY + deltaY -- reset touch focus display.getCurrentStage():setFocus(nil) self.isFocus = nil end end return true end floorTiles:addEventListener( "touch", dragMap) return floorTiles end function createButton(floorTiles) local button = display.newRect(display.contentCenterX, display.contentCenterY, 80, 80) button:setFillColor(.75, 0, 0) function restoreAlpha(thisTile) return function() floorTiles.x, floorTiles.y = homeX, homeY thisTile.alpha = 1 end end function cycleAlpha(event) local self = event.target if event.phase == "began" then --set touch focus display.getCurrentStage():setFocus(self) self.isFocus = true elseif self.isFocus then if event.phase == "ended" or event.phase == "cancelled" then for i= 1, floorTiles.numChildren do local thisTile = floorTiles[i] transition.to(thisTile, {time = 500, alpha = 0, onComplete = restoreAlpha(thisTile)}) end -- reset touch focus display.getCurrentStage():setFocus(nil) self.isFocus = nil end end return true end button:addEventListener("touch", cycleAlpha) end floorTiles = createMap() createButton(floorTiles)

I just submitted this as a bug report.

Also, I’ve seen some code pasted into posts that retains its formating, how do I do that?

Using the browser interface you should see a toolbar at the top of your editing viewport.

Choose the Code-symbol (looks like “<>”) which will open a popup where you can paste your code.

Sample:

-- main.lua local t = display.newText{text="Testing...", font=native.systemFont, fontSize=16}; t:setFillColor(1); t.x, t.y = display.contentCenterX, display.contentCenterY;

Not for nothing, but native Corona off-screen culling has never been all that effective, at least from tests I’ve conducted. I figured this was just the nature of the beast, as the onus of intelligent culling and resource management has been on the developer, but if you’re saying it worked and now it doesn’t, I’m excited to see progress made here.

Keep us posted!

Thanks for the help on formatting, I fixed my earlier post of code.

This bug took my 8 hours to track down including time to create an app that Corona would accept as proof of a bug…  At first I was just observing that “sometimes some of the floor tiles are missing”.

If any of you have time to load up this code and confirm the bug I would appreciate it.  The recreation steps are pretty simple.

The key to seeing the bug is the map/checkerboard needs to be moved out of it’s home position.  If you run the code a checkerboard appears in the upper left corner of the screen but you are only seeing about 1/4 of it.  Drag it down into the middle of the screen, then press the red button.  The red button causes a series of events: the alpha of all the tiles are set to 0, all the tiles are shifted back to the starting position, and then the alpha on all tiles is set back to 1.

After the alpha of the tiles cycle, drag the map/checkerboard back into the middle of the viewing area and you will see that a bunch of the tiles are no longer visible.  Specifically, any tile that was in the viewing area when it went to alpha = 0 and then moved out of the viewing area before returning to alpha = 1.

If you just load the app and press the red button you won’t see the bug.

Tom was able to confirm the bug and has sent it to engineering.  Thank you Tom!!