957 posts
Location
Web Development
Posted 26 April 2015 - 04:22 AM
Long story short, the new version of my Simple Screen Maker causes major screen flicker when redrawing the screen
At this point, I'd like to try disabling the Window API when it starts to see if that helps at all.
If that doesn't work, I have a few more ideas, but first I'd like to try this
I vaguely remember that the Window API really slows down rendering on Advanced Computers
If this isn't actually the case, I guess disabling it wouldn't help…
So how would I go about disabling it, then enabling when the program finishes?
7083 posts
Location
Tasmania (AU)
Posted 26 April 2015 - 04:32 AM
You don't want to disable it so much as you want to bypass it.
Redirect to term.native(). Use term.current() to keep track of what the "initial" term was so you can go back to it later.
Edit:
That said, if you rigged your "drawObject" function to clear each line before drawing it - or even just the parts of each line that need to be cleared! - as opposed to clearing the whole display then drawing the lines one at a time, that'd help no end.
Edited on 26 April 2015 - 02:35 AM
957 posts
Location
Web Development
Posted 26 April 2015 - 06:28 AM
- Snip -
Works perfectly, it stops all the flickering
I guessed it was flickering because of my drawing of the screen (Well duh)
I use a buffer, which could be used to redraw everything without having to recalculate the positions of anything
Thing is, when you drag something around, it has to clear and reset the buffer, then redraw the screen… for every mouse_drag event
Is there a better way?
I need the buffer, I want to be able to color text based on the background of the pixel its being drawn on
Oh, also I'm using CCEmuRedux, so I can only imagine any flicker or lag will be amplified in-game
Edited on 26 April 2015 - 04:29 AM
7083 posts
Location
Tasmania (AU)
Posted 26 April 2015 - 06:40 AM
It may be that it's faster to build a new buffer than it is to clear the existing one, or perhaps you could simply get away with overwriting the contents of the old buffer. It may also be the case that you don't need to redraw the entire display; try figuring out the bounds of the area that could've actually changed, and just redraw that.
Sometimes making a script more efficient means making it a lot longer, so that it can handle individual scenarios better.
957 posts
Location
Web Development
Posted 26 April 2015 - 06:57 AM
Well, the actual clearing of the buffer is really quick:
buffer = {}
Its a table, and to clear it I just make it a blank table
Would it be more efficient to see if every pixel changed, and only draw each if it did?
Or is it better to just overwrite it anyway?
Basically what I'm asking is which is faster; drawing a pixel OR comparing two buffers and drawing only the necessary pixels?
7083 posts
Location
Tasmania (AU)
Posted 26 April 2015 - 07:11 AM
That depends on how many pixels you're changing, and on how you're doing your comparisons.
My general tactic is to figure out the bounds within which things might be changing, then redraw just that area of the screen.
1140 posts
Location
Kaunas, Lithuania
Posted 26 April 2015 - 10:42 AM
In CC environment it is a lot faster to do some ifs than to redraw every pixel one after another. Take a look at the already existing buffers and how they manage drawing.
546 posts
Location
Wageningen, The Netherlands
Posted 26 April 2015 - 11:25 AM
You can use my
Surface API if you want, which is highly optimized to remove flickering, even with the Window API enabled.
It doesn't change colors for every pixel, instead it checks if the next pixel has a different color and if so, it writes the last pixels and changes the color.
It uses the least amount of draw calls possible.
You can also look at the
code yourself (note that this comes straight out of the Surface API):
Spoiler
local cmd = { }
local str = ""
local backcolor = 0
local textcolor = 0
for j=sy1,sy2,1 do
cmd[#cmd + 1] = 1
cmd[#cmd + 1] = y + j - sy1
for i=sx1,sx2,1 do
if surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 2] ~= backcolor then
backcolor = surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 2]
if str ~= "" then
cmd[#cmd + 1] = 4
cmd[#cmd + 1] = str
str = ""
end
cmd[#cmd + 1] = 2
cmd[#cmd + 1] = backcolor
end
if surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 3] ~= textcolor then
textcolor = surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 3]
if str ~= "" then
cmd[#cmd + 1] = 4
cmd[#cmd + 1] = str
str = ""
end
cmd[#cmd + 1] = 3
cmd[#cmd + 1] = textcolor
end
str = str..(surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 1] or "\0")
end
cmd[#cmd + 1] = 4
cmd[#cmd + 1] = str
str = ""
end
for i=1,#cmd/2,1 do
local c = cmd[(i - 1) * 2 + 1]
local a = cmd[(i - 1) * 2 + 2]
if c == 1 then
display.setCursorPos(x, a)
elseif c == 2 then
display.setBackgroundColor(a or 32768)
elseif c == 3 then
display.setTextColor(a or 1)
elseif c == 4 then
display.write(a)
end
end
Edited on 26 April 2015 - 09:26 AM
957 posts
Location
Web Development
Posted 26 April 2015 - 05:12 PM
My general tactic is to figure out the bounds within which things might be changing, then redraw just that area of the screen.
I'll see if I can get this working, I considered it earlier but decided against it. Probably the most efficient.
In CC environment it is a lot faster to do some ifs than to redraw every pixel one after another
I might use this method if I can't get the first to work
You can use my
Surface API if you want, which is highly optimized to remove flickering, even with the Window API enabled.
It doesn't change colors for every pixel, instead it checks if the next pixel has a different color and if so, it writes the last pixels and changes the color.
It uses the least amount of draw calls possible.
You can also look at the
code yourself (note that this comes straight out of the Surface API):
I might end up using a slightly modified version of your API if I can't get one of the first two working
PS On your forum post for it, some of the links for the function documentation aren't working
546 posts
Location
Wageningen, The Netherlands
Posted 26 April 2015 - 06:04 PM
I might end up using a slightly modified version of your API if I can't get one of the first two working
PS On your forum post for it, some of the links for the function documentation aren't working
I've fixed the broken link (
surf:render), thanks for the report!