This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
HPWebcamAble's profile picture

Disable Window API

Started by HPWebcamAble, 26 April 2015 - 02:22 AM
HPWebcamAble #1
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?
Bomb Bloke #2
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
HPWebcamAble #3
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
Bomb Bloke #4
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.
HPWebcamAble #5
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?
Bomb Bloke #6
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.
MKlegoman357 #7
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.
CrazedProgrammer #8
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
HPWebcamAble #9
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
CrazedProgrammer #10
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!