Accelerating Object Drawing

Visuals, audio, animation. Blended, not stirred. If LiveCode is part of your rich media production toolbox, this is the forum for you.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
andres
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 68
Joined: Thu Jan 04, 2007 2:24 am

Accelerating Object Drawing

Post by andres » Wed Jan 10, 2007 11:58 pm

Hello, I am developing a game with many graphic objects (buttons) being redrawn at 30fps but I cannot increase the number of objects or frame/rate (there is a low limit).

Does anyone know about a method/script to draw an object faster than the "set the location of button ... " script? Thanks

malte
Posts: 1098
Joined: Thu Feb 23, 2006 8:34 pm
Contact:

Post by malte » Thu Jan 11, 2007 8:27 am

hi andres,

could you post the relevant script? It is easier to judge if it could be optimized then.

All the best,

Malte

andres
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 68
Joined: Thu Jan 04, 2007 2:24 am

Accelerating Object Drawing

Post by andres » Fri Jan 12, 2007 2:12 am

Hello Malte

It will be to much code to post but I guess the simplest way to put it is as follows....

on DrawObjects
repeat for i = 1 to N #Number of Objects
-- Mathematical equations to calculate each object's position
set the location of button ("Button"&i) to CalculatedPosition[i]
end repeat
send "DrawObjects" to me in 0.03 seconds
end DrawObjects

I have found that the numerical calculations do not take time, instead what is taking too much time in this loop is the "set location" script.

Does this make any sense?

Thanks again

Andres

malte
Posts: 1098
Joined: Thu Feb 23, 2006 8:34 pm
Contact:

Post by malte » Fri Jan 12, 2007 8:47 am

Hi Andres,

yes, what you encounter makes sense. Each time you set the loc of an object the screen gets redrawn. To speed it up you might try the following:

Code: Select all

on DrawObjects
lock screen
repeat for i = 1 to N #Number of Objects
-- Mathematical equations to calculate each object's position
  set the location of button ("Button"&i) to CalculatedPosition[i]
end repeat
unlock screen
send "DrawObjects" to me in 0.03 seconds
end DrawObjects
This should speed it up. Also I found that using a repeat for each loop can increase speed a bit. Store the names of your buttons in a custom property or a global var, each name on a line.

example:

Code: Select all

global gButtonList

on createButtonList
  repeat with i=1 to n
    put the short name of btn ("button"&i) & cr after gButtonList
  end repeat
  delete char -1 of gButtonList
end create buttonList
call this handler on opencard. Then your drawObjects handler could look like this:

Code: Select all

global gButtonList

on DrawObjects
lock screen
repeat for each line theObject in gButtonList
-- Mathematical equations to calculate each object's position
  set the location of button theObject to CalculatedPosition[i]
end repeat
unlock screen
send "DrawObjects" to me in 0.03 seconds
end DrawObjects
Hope that helps,

Malte

marielle
Livecode Opensource Backer
Livecode Opensource Backer

Post by marielle » Sun Jan 14, 2007 3:25 pm

Globals can often be avoided. Custom Props can be accessed from anywhere within the script, the same way as globals, but they have the advantage to be attached to a given object... so you don't have the risk to mistakenly overwrite it in any other part of the script.

Then storing the object full reference (full id) rather than the object short names allows you to make you script a lot more flexible. You are then free to reposition fields as well as buttons.

Code: Select all


### Initialization ############

on initialize
   set the button_list of me to createButtonList()
end initialize

### Data ############

getProp button_list
  put the button_list of me into tValue
  if tValue is not empty then return tValue
  --- button list is empty ... we forgot to initialize the script properly ----
  return createButtonList()
end button_list

### Processing ############

on DrawObjects 
  lock screen 
  put the button_list of me into tButtonList
  repeat for each line tCtlRef in tButtonList 
    -- Mathematical equations to calculate each object's position 
    set the location of tCtlRef to CalculatedPosition[i] 
  end repeat 
  unlock screen 
  send "DrawObjects" to me in 0.03 seconds 
end DrawObjects 

function createButtonList
 put empty into tButtonList
  repeat with tCtlNb=1 to (the number of controls on this card)
    put the long id of control tCtlNb of this card into tCtlRef
    if word 1 of tCtlRef is "button" then
        put tCtlRef & cr after tButtonList
    end if
  end repeat
  delete char -1 of tButtonList
  return tButtonList
end createButtonList

(typed on the fly and untested)

andres
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 68
Joined: Thu Jan 04, 2007 2:24 am

Accelerating Object Drawing

Post by andres » Sun Jan 14, 2007 3:36 pm

Thanks Marielle. Please tell me why would I want to avoid global variables? I use them very often and if possible I preffer to have a more efficiennt code. Rgds, Andres.

oliverk
Site Admin
Site Admin
Posts: 53
Joined: Mon Feb 27, 2006 2:16 pm

Post by oliverk » Tue Jan 16, 2007 11:13 am

Hi Andreas,

I agree with Marielle that using custom properties is preferable to global variables.

The main reasons for minimising the use of global variables are to make your code easier to understand and less prone to errors. This is very important for any application.

Personally I have not needed to use a global variable in a single one of the many projects I have worked on in Revolution, and there is no significant speed loss in using custom properties instead. Any slow downs can be easily optmized by using local variables to store values anyway.

Just my thoughts, hope it was some help.

Regards

Oliver
Oliver Kenyon
Software Developer
Runtime Revolution

marielle
Livecode Opensource Backer
Livecode Opensource Backer

Post by marielle » Tue Jan 16, 2007 1:45 pm

oliverk wrote:Any slow downs can be easily optmized by using local variables to store values anyway.
Can you let us know more about this?

oliverk
Site Admin
Site Admin
Posts: 53
Joined: Mon Feb 27, 2006 2:16 pm

Post by oliverk » Tue Jan 16, 2007 6:11 pm

Hi Marielle,

Perhaps I didn't word that in the best way, there is no way of getting around the fact that setting / getting a custom property takes a more time than setting / getting a global variable.

What I meant to say is that it is unlikely that setting and getting custom properties will be the limiting factor in the speed of a CPU intensive application as these are relatively fast operations and the data can be structured in such a way to optimize access to it

Regards

Oliver
Oliver Kenyon
Software Developer
Runtime Revolution

andres
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 68
Joined: Thu Jan 04, 2007 2:24 am

Post by andres » Sun Feb 18, 2007 7:49 am

Hello

Thanks to all of you for your comments. I implemented the majority of them. But one special piece is making me crazy.

[code]
on DrawObjects
lock screen
repeat for i = 1 to N #Number of Objects
-- Mathematical equations to calculate each object's position
set the location of button ("Button"&i) to CalculatedPosition[i]
end repeat
put the milliseconds into starttime
unlock screen
put the milliseconds into endtime
put (endtime-starttime)
send "DrawObjects" to me in 0.03 seconds
end DrawObjects
[/code]

My problem now is that the "unlock screen" command sometimes takes too much time to be executed. It takes a few millisec per moved object, and everything works fine when objects move fast. However, on slow motion, and even with just one object moving the "unlock screen" command takes more than 100 millisecs to be executed.

Any clue what may be causing this?

Regards,
Andres

marielle
Livecode Opensource Backer
Livecode Opensource Backer

Post by marielle » Sun Feb 18, 2007 11:54 am

andres wrote:Any clue what may be causing this?

Code: Select all

put the milliseconds into endtime
put (endtime-starttime)

In your script, you get to write the time in each iteration. Writing stuff in the message box takes a lot of time. Can you not store the value in a variable?

An obvious option is :

Code: Select all

set the running_time of  me to (endtime-starttime)
Another one is :

Code: Select all

put (endtime-starttime) & cr after URL ("file:" & "running_time.txt")
I find that storing data in a custom property or sending data to a file rather than write it on the message box takes less time.

marielle
Livecode Opensource Backer
Livecode Opensource Backer

Post by marielle » Sun Feb 18, 2007 11:58 am

Code: Select all

put the milliseconds into starttime
unlock screen 
put the milliseconds into endtime
Okay, I am rereading it more carefully. A problem there is that you assume that the only thing that happens is an unlock screen. However it may be that the starttime is being stored when the processing of the repeat loop is not finished yet. If you take a player object, for instance, and put some "answer something" right after the play command, you will see the dialog box pop when the video has only started to play.

What gets me think that way is the fact that you say "the unlock screen takes a few millisec per moved object". This shouldn't be the case. The unlock screen shouldn't be affected by the number of objects that have been moved.

So the first thing is to make sure that it is really the unlock screen taking that much time. What if you put something else like put 1 into tTest?

Code: Select all

put the milliseconds into starttime
put 1 into tTest
put the milliseconds into endtime
Does it still take that much time?

andres
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 68
Joined: Thu Jan 04, 2007 2:24 am

Post by andres » Sun Feb 18, 2007 4:15 pm

Thanks Marielle

I have made hundreds of measurements and believeme... the unlock screen takes a few millisec per moved object. I tried your siggestion and the difference in time is 0 millisec.

What I forgot to mention and makes the case even more weird is that the compiled versions for OSX and Win behave different. The Windows application was greatly improved by the lock-unlock method, but the OSX just a little on regular motion and worst on slow motion.

Another thing I forgot to mention is that the execution of the Unlock command not always is greater than 100 millisecs, on 10 samples measured at slow-mo there are 6 samples this long, the others are normal.

Is it possible that when the "Unlock Screen" is called, the application or OS processes other stuff ?

Regards,
Andres

marielle
Livecode Opensource Backer
Livecode Opensource Backer

Post by marielle » Sun Feb 18, 2007 4:46 pm

This is weird indeed. I have no idea what the explanation (if any) might be.

Bill
Posts: 57
Joined: Sat Apr 08, 2006 8:22 pm

Post by Bill » Sun Feb 18, 2007 5:00 pm

I don't have a solution, sorry, just tried to test to see if I could find one

Code: Select all

on mouseUp
  repeat with n = 1 to 100
lock screen
  put the loc of me into xy
  add 1 to item 1 of xy
  set the loc of me to xy
  put the milliseconds into tstarttime 
put 1 into tTest 
put the milliseconds into tendtime 
put abs(tstarttime-tendtime) &comma after alltime
put alltime
unlock screen
end repeat
end mouseUp
Very very jumpy erattic movement, with or without lock/unlock, there is not much of a diffference.

Note I changed the name of those variables, starttime and endtime seem to be player object properties, seeing red in a variable name was..a red flag ha!
The difference in milliseconds is 0, however
change your millseconds to the long seconds and you'll get a value something in the order of : 0.000002,0.000002,0.000002,0.000001,0.000001,0.000002,....etc

Its hard to imagine the human eye would notice that kind of difference in time.

Whoa, just removed the lock/unlock in the long seconds test and the values are like so: 0.000008,0.000002,0.000002,0.000002,0.000002,0.000003,0.000004,0.000003,0.000008

I suddenly have newfound appreciation for lock/unlock screen.

The following values are totals added into variable alltime, while viewing
the data as it is performed different ways.

Writing a message to the message box slows things down for sure.
set the label of me to alltime
reveals between 0.000074 and 0.000092
similiar results with write alltime to stderr

writing to message box gets numbers between 0.000167 to 0.000486

Code: Select all

 set the moveSpeed to 1
  put the loc me into xy
  add 100 to item 1 of xy
  move me to xy in 30 ticks
This is much much smoother by far.
I think perhaps you should give your objects destinations and let revs engine handle the move, so its not "plopping" it down into the spot on an each iteration.

Wouldn't hurt to try, too much. :?

Post Reply