Accelerating Object Drawing
Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller
Accelerating Object Drawing
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
Does anyone know about a method/script to draw an object faster than the "set the location of button ... " script? Thanks
Accelerating Object Drawing
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
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
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:
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:
call this handler on opencard. Then your drawObjects handler could look like this:
Hope that helps,
Malte
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
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
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
Malte
-
- Livecode Opensource Backer
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.
(typed on the fly and untested)
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
Accelerating Object Drawing
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.
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
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
Software Developer
Runtime Revolution
-
- Livecode Opensource Backer
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
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
Software Developer
Runtime Revolution
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
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
-
- Livecode Opensource Backer
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)
Code: Select all
put (endtime-starttime) & cr after URL ("file:" & "running_time.txt")
-
- Livecode Opensource Backer
Code: Select all
put the milliseconds into starttime
unlock screen
put the milliseconds into endtime
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
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
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
-
- Livecode Opensource Backer
I don't have a solution, sorry, just tried to test to see if I could find one
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
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.
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
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
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.
