Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

[RESOLVED] DP2.0: how about Invalidation of children without clearing cashed image
Started by eltromac Sep 07 2013 02:33 PM

12 replies to this topic
graphics 2.0 snapshot brush
[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

eltromac

[GLOBAL: userInfoPane.html]
eltromac
  • Observer

  • 13 posts
  • Corona SDK

Invalidation of children

Groups automatically detect when a child's properties have changed such as position. Thus, on the next render pass, the child will re-render.

Snapshots to not automatically detect when a child's properties have changed. You must clear the snapshot's cached image anytime you modify the child by calling snapshot:invalidate(). This invalidates the snapshot's image so it will be updated on the next render pass.

-------------------------------------------------------------------------------------

Above description means cached image will be cleared whenever invalidate() is called. But, what i'm wanting is that cached image is not cleared and draw just last added object when some function(like invalidate(false)) is called.

I'm just want to clear cached image when i want.

 

Thanks.

 

 



[TOPIC: post.html]
#2

rakoonic2

[GLOBAL: userInfoPane.html]
rakoonic2
  • Contributor

  • 503 posts
  • Corona SDK

Could you give an example of why this would be useful? Once you mark the snapshot as invalidated it will be redrawn completely, including the new image (ie so it will look the same anyway, just with the new image in it).

[TOPIC: post.html]
#3

eltromac

[GLOBAL: userInfoPane.html]
eltromac
  • Observer

  • 13 posts
  • Corona SDK

Let me give more detail explanation.

 

If you are making line drawing application like painter.

With corona sdk, you need to add display object(i,e, line, circle,..) whenever screen is touched and moved.

This will generate a lot of display objects and those are redrawn all at every invalidate() call.

And you can see performance degradation whenever line object is added.

 

Benefits what i think.

1. No performance degradation when adding lines even 10000 times display objects is already drawn.

2. can draw many lines by just reusing one display object.



[TOPIC: post.html]
#4

rakoonic2

[GLOBAL: userInfoPane.html]
rakoonic2
  • Contributor

  • 503 posts
  • Corona SDK

That is indeed a good example :)

Here's a possible solution (but you'll have to test as I don't know if it is possible):

Nested snapshots.

You'd have two snapshots in total. A working one and the previously drawn one.
Every time you want to add a new element (could be a single line etc, or a batch of them), you stick them in the working snapshot and behind you add the previous state snapshot. Invalidate the working snapshot (which should update to include everything), and then clear the previous state snapshot entirely of all children. Then just swap the two - IE the working one is now considered the precius state, and the old previous state one is now the working one (and is empty ready for it).

It all depends on whether you can nest snapshots and how exactly the render to texture works, but it *might* work, so I figure it is worth your time to quickly check :)

[TOPIC: post.html]
#5

walter

[GLOBAL: userInfoPane.html]
walter
  • Moderator

  • 726 posts
  • Alumni

Sounds like you want some way to "accumulate" drawing on a texture? So like a finger painting-style effect?

 

This is fairly different from what snapshot does (render to texture). The major expense of line objects is tessellation, and right now it looks like an append operation forces the old tessellation to get thrown out. I'll mark this as a performance request to see if we can do something more intelligent.



[TOPIC: post.html]
#6

eltromac

[GLOBAL: userInfoPane.html]
eltromac
  • Observer

  • 13 posts
  • Corona SDK

Yes, what i want is to accumulate drawing on a texture.

 

I think that just one option (which is prohibit to clear cached image) is needed like below.

- invalidate(true) --> clear cached image and redraw all and add(or draw) object 

- invalidate(false) --> don't clear cached image and add(or draw) object.

 

I think below link is good example about render to texture functions.

http://www.learn-cocos2d.com/2011/12/how-to-use-ccrendertexture-motion-blur-screenshots-drawing-sketches/#sketching



[TOPIC: post.html]
#7

rakoonic2

[GLOBAL: userInfoPane.html]
rakoonic2
  • Contributor

  • 503 posts
  • Corona SDK

Does that mean you aren't even going to try to see if my suggestion works? :s



[TOPIC: post.html]
#8

eltromac

[GLOBAL: userInfoPane.html]
eltromac
  • Observer

  • 13 posts
  • Corona SDK

I didn't try it what you suggest since snapshot has fundamental limitation when objects is added if snapshot have a lot of children.

 

Thanks



[TOPIC: post.html]
#9

rakoonic2

[GLOBAL: userInfoPane.html]
rakoonic2
  • Contributor

  • 503 posts
  • Corona SDK

I think you are misunderstanding my suggestion - as it stands it should work, but since I am not aware of the exact snapshot implementation, I can't say for sure it *will* work. I'll try to look into this myself tonight or tomorrow to see if it does in fact work as I hope (which would enable what you want to do).



[TOPIC: post.html]
#10

rakoonic2

[GLOBAL: userInfoPane.html]
rakoonic2
  • Contributor

  • 503 posts
  • Corona SDK

OK I tried out my idea and it works.

The only issue is how long you have to wait for the validation to take effect - in theory it is the next draw pass, but I had to insert a delay of 300 milliseconds between each update to actually have it kick in (or else it returned a blank texture).

 

Here's my code.

Every 300 milliseconds it creates 100 random lines, swaps the two snapshot objects, then clears all the lines.

The end result is it keeps filling up and filling up with lines overlaid.

 

Just copy and paste the following code into a fresh main.lua (no other files needed) and run it (on the iphone simulator for 'fullscreen', heh - can always just set the width and height to whatever device you prefer simulating on).

 

-- Set up status bar
display.setStatusBar( display.HiddenStatusBar )
 
--------------------------------------------------------------
-- Set up ----------------------------------------------------
 
local width  = 320
local height = 480
 
local snapshots = {
    active =  display.newSnapshot( width, height ),
    storage = display.newSnapshot( width, height ),
}
local drawGroup = display.newGroup()
local group     = drawGroup.parent
 
for k, v in pairs( snapshots ) do
    v.anchorX = 0
    v.anchorY = 0
end
 
group:insert( snapshots.active )
snapshots.active.x, snapshots.active.y = 0, 0
 
-- Place the storage group into the active group
snapshots.active:insert( snapshots.storage )
snapshots.storage.x, snapshots.storage.y = -width / 2, -height / 2
 
-- Place the draw group into the active group
snapshots.active:insert( drawGroup )
drawGroup.x, drawGroup.y = -width / 2, -height / 2
 
--------------------------------------------------------------
-- Run event -------------------------------------------------
 
local function drawLines()
 
    for i = 1, 100 do
        local line = display.newLine( drawGroup, math.random( 0, width ), math.random( 0, height ), math.random( 0, width ), math.random( 0, height ) )
        line.strokeWidth = math.random( 1,  10 )
        line:setStrokeColor( math.random( 0, 255 ) / 255, math.random( 0, 255 ) / 255, math.random( 0, 255 ) / 255 )
    end
    
end
 
local function toggleGroups()
 
    -- Swap snapshots
    snapshots.active, snapshots.storage = snapshots.storage, snapshots.active
 
    -- Kill the draw group (and hence everything in it) and recreate it
    drawGroup:removeSelf()
    drawGroup = display.newGroup()
 
    -- Place the active group into the group
    group:insert( snapshots.active )
    snapshots.active.x, snapshots.active.y = 0, 0
    
    -- Place the storage group into the active group
    snapshots.active:insert( snapshots.storage )
    snapshots.storage.x, snapshots.storage.y = -width / 2, -height / 2
 
    -- Place the draw group into the active group
    snapshots.active:insert( drawGroup )
    drawGroup.x, drawGroup.y = -width / 2, -height / 2
    
    -- Draw more lines
    drawLines()
    
    -- Update
    snapshots.active:invalidate()
 
end
 
-- Repeat 10000 times
timer.performWithDelay( 300, toggleGroups, 10000 )
 



[TOPIC: post.html]
#11

rakoonic2

[GLOBAL: userInfoPane.html]
rakoonic2
  • Contributor

  • 503 posts
  • Corona SDK

You can probably simplify the code above a bit - in particular the offsetting of everything cos I'm not really sure on the positioning etc - I just played with values until I saw what I expected.

Same goes for the draw group and parent group, these aren't likely needed, but after trying to access the numChildren of the snapshot and getting back a nil value, I figured I'd just chuck everything into actual display groups as at least I knew how to manipulate 'em.

 

eltromac - given the delay in the updating, I would probably not recommend the above swapping system constantly, just in natural breaks (eg the user draws into a normal group, lifts his finger, and in that instant you chuck the new lines into the active snapshot's drawgroup and update, ready for the next batch of drawing).



[TOPIC: post.html]
#12

eltromac

[GLOBAL: userInfoPane.html]
eltromac
  • Observer

  • 13 posts
  • Corona SDK

Thanks rakoonic,

Really appreciated.

 

But, i still want to get the solution as corona sdk platform level.



[TOPIC: post.html]
#13

eltromac

[GLOBAL: userInfoPane.html]
eltromac
  • Observer

  • 13 posts
  • Corona SDK


[topic_controls]
[/topic_controls]