Page 1 of 1

Accelerating Object Drawing

Posted: Wed Jan 10, 2007 11:58 pm
by andres
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

Posted: Thu Jan 11, 2007 8:27 am
by malte
hi andres,

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

All the best,

Malte

Accelerating Object Drawing

Posted: Fri Jan 12, 2007 2:12 am
by andres
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

Posted: Fri Jan 12, 2007 8:47 am
by malte
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

Posted: Sun Jan 14, 2007 3:25 pm
by marielle
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)

Accelerating Object Drawing

Posted: Sun Jan 14, 2007 3:36 pm
by andres
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.

Posted: Tue Jan 16, 2007 11:13 am
by oliverk
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

Posted: Tue Jan 16, 2007 1:45 pm
by marielle
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?

Posted: Tue Jan 16, 2007 6:11 pm
by oliverk
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

Posted: Sun Feb 18, 2007 7:49 am
by andres
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

Posted: Sun Feb 18, 2007 11:54 am
by marielle
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.

Posted: Sun Feb 18, 2007 11:58 am
by marielle

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?

Posted: Sun Feb 18, 2007 4:15 pm
by andres
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

Posted: Sun Feb 18, 2007 4:46 pm
by marielle
This is weird indeed. I have no idea what the explanation (if any) might be.

Posted: Sun Feb 18, 2007 5:00 pm
by Bill
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. :?