Author Topic: Fast line rout!  (Read 14711 times)

0 Members and 1 Guest are viewing this topic.

Offline jace_stknights

  • Amiga 1200
  • ****
  • Posts: 399
  • Karma: 32
  • PEEK & POKE are not MOVEM!
    • View Profile
    • ST Knights WebSite
Fast line rout!
« on: September 29, 2011 »
  • Draw 2*2 pixels for zooming
  • Run in windowed or fulscreen mode
  • Run as quick as possible for "old" computer

Here is my code for the drawing (using Purebasic and my favorite POKEQ !):
Code: [Select]
Procedure LigneRetro(x1,y1,x2,y2,couleur)
  coul.q = couleur<<32 + couleur
  If Abs(x2-x1) > Abs(y2-y1)
    If x1>x2
      Swap x1,x2
      Swap y1,y2
    EndIf
    y.f = y1
    inc.f = ((y2-y1)/Abs(x2-x1))
    For j = x1 To x2
      PokeQ(*ecran + Int(y)*lgEcran*2 + j*8 , coul)                   ; 2 pixels up
      PokeQ(*ecran + Int(y)*lgEcran*2 + lgEcran + j*8 , coul)   ; 2 pixels down
      y = y + inc
    Next     
  Else
    If Abs(x2-x1) = Abs(y2-y1)
      If x1>x2
        Swap x1,x2
        Swap y1,y2
      EndIf
      y.f = y1
      inc = ((y2-y1)*1)/(Abs(x2-x1)*1)
      For j = x1 To x2
        PokeQ(*ecran + Int(y)*lgEcran*2 + j*8 , coul)
        PokeQ(*ecran + Int(y)*lgEcran*2 + lgEcran + j*8 , coul)
        y = y + inc
      Next
     Else
       If y1>y2
        Swap x1,x2
        Swap y1,y2
       EndIf
       x.f = x1
       inc.f = ((x2-x1)/Abs(y2-y1))
       For j = y1 To y2
         PokeQ(*ecran + j*lgEcran*2 + Int(x)*8 , coul)
         PokeQ(*ecran + j*lgEcran*2 + lgEcran + Int(x)*8 , coul)
         x = x + inc
       Next
    EndIf
  EndIf
EndProcedure

This is a simple conversion of my 68k line rout (the original is a -bit- faster and use jmp to opcode).

THE QUESTIONS ARE:
  • Does anybody have a fast line rout technique using hardware acceleration??? (I thought about a technique using a 2 pixels Sprite3D distored and zoomed to 2*LineSize, and rotated at the good angle for drawing but It won't get the 2*2 pixels aliasing)
  • Should I use assembly ::) (The compilers are good today, but who knows ???)
  • Is my code above good, as I'm pretty new in PureBasic...

Thanx to all...
« Last Edit: September 29, 2011 by jace_stknights »
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Fast line rout!
« Reply #1 on: September 29, 2011 »
There are a few things that are totally, totally killing this code, which is otherwise OK.
Code: [Select]
For j = y1 To y2
         PokeQ(*ecran + j*lgEcran*2 + Int(x)*8 , coul)
         PokeQ(*ecran + j*lgEcran*2 + lgEcran + Int(x)*8 , coul)
         x = x + inc
       Next
First thing is that x is not an integer, so doing Int(x) is going to be really expensive.
Second thing is that most of the expression in the PokeQ is either constant or changes by a fixed amount each pixel.

So you could rewrite this code (I'm not totally familiar with PB so bear with me)
Code: [Select]
xp.i = 0
 xi.i = Int(inc*65536)
 ecran2 = ecran + y1*lgEcran*2 + Int(x)*8
 For j = y1 To y2
         PokeQ(*ecran2 + (xp>>16)<<3 , coul)
         PokeQ(*ecran2 + lgEcran + (xp>>16)<<3, coul)
         xp = xp + xi
         ecran2 = ecran2 + lgEcran*2
Next

I think it's possible to optimize this some more, to get rid of the <<3.  But I think the asm for this will be OK.  Can PB output the asm?

Jim

Challenge Trophies Won:

Offline jace_stknights

  • Amiga 1200
  • ****
  • Posts: 399
  • Karma: 32
  • PEEK & POKE are not MOVEM!
    • View Profile
    • ST Knights WebSite
Re: Fast line rout!
« Reply #2 on: September 29, 2011 »
So you could rewrite this code (I'm not totally familiar with PB so bear with me)
Code: [Select]
xp.i = 0
 xi.i = Int(inc*65536)
 ecran2 = ecran + y1*lgEcran*2 + Int(x)*8
 For j = y1 To y2
         PokeQ(*ecran2 + (xp>>16)<<3 , coul)
         PokeQ(*ecran2 + lgEcran + (xp>>16)<<3, coul)
         xp = xp + xi
         ecran2 = ecran2 + lgEcran*2
Next

I think it's possible to optimize this some more, to get rid of the <<3.  But I think the asm for this will be OK.  Can PB output the asm?

Jim

Yep you're right! In my original 68000 rout i'm using this way of incremental! I must admit that I'm not so good at converting assembly to hight level language  :P

I'm gonna try it right now... Thank you for the trick!
« Last Edit: September 29, 2011 by jace_stknights »
Challenge Trophies Won:

Offline jace_stknights

  • Amiga 1200
  • ****
  • Posts: 399
  • Karma: 32
  • PEEK & POKE are not MOVEM!
    • View Profile
    • ST Knights WebSite
Re: Fast line rout!
« Reply #3 on: September 29, 2011 »
Hum... I've made the changes. And it's running at same speed!  :o

But I've cleaned the code -> I was still using StartDrawing() and StopDrawing() before each call of linerout, coz I was testing the speed between my rout and LineXY()...

Damn it runs now at 60FPS on my PC!!!  :bfuck2:

Challenge Trophies Won:

Offline maracuja

  • C= 64
  • **
  • Posts: 31
  • Karma: 4
    • View Profile
Re: Fast line rout!
« Reply #4 on: September 29, 2011 »
Hmm What don't you use direct3d acceleration ? You will just think on the useful task like 3d matrix operations ?

Offline maracuja

  • C= 64
  • **
  • Posts: 31
  • Karma: 4
    • View Profile
Re: Fast line rout!
« Reply #5 on: September 29, 2011 »
Hum... I've made the changes. And it's running at same speed!  :o

But I've cleaned the code -> I was still using StartDrawing() and StopDrawing() before each call of linerout, coz I was testing the speed between my rout and LineXY()...

Damn it runs now at 60FPS on my PC!!!  :bfuck2:

Congrats ! :=)

Offline jace_stknights

  • Amiga 1200
  • ****
  • Posts: 399
  • Karma: 32
  • PEEK & POKE are not MOVEM!
    • View Profile
    • ST Knights WebSite
Re: Fast line rout!
« Reply #6 on: September 29, 2011 »
Hmm What don't you use direct3d acceleration ? You will just think on the useful task like 3d matrix operations ?

Because of the aliasing!!! 3D functions doesn't make 2*2 display!!! So I've got to remake all "by hand"...
Challenge Trophies Won:

Offline va!n

  • Pentium
  • *****
  • Posts: 1432
  • Karma: 109
    • View Profile
    • http://www.secretly.de
Re: Fast line rout!
« Reply #7 on: September 29, 2011 »
Here is my personal purebasic version i did in 2002 - http://forums.purebasic.com/english/viewtopic.php?t=3653

Code: [Select]
;--------------------------------------------
;
; PureBasic - How does a Line() command work
; by va!n
;
;--------------------------------------------
;
    Procedure MyLine(x1,y1,x2,y2)
        ;
        x = x1
        y = y1
        StartDrawing(ScreenOutput())       ; ### START DRAWING ###
          Plot (x,y)                       ; Hopefully faster DXPlot() for DirectX support soon :wink:
        StopDrawing()                      ; ### STOP DRAWING ###         
        f = 0
        ;
        Repeat
            f1 = f + Abs(x2 - x1)
            f2 = f - Abs(y2 - y1)
            ;
            ;------------------------
            ;
            If Abs(f1) >= Abs(f2)
               f = f2
               x = x + Sgn(x2 - x1)       ; Still miss Sgn() math command as standard function in PureBasic!
            Else
               f = f1
               y = y + Sgn(y2 - y1)
            EndIf
            ;
            ;------------------------
            ;
            Plot x,y
        Until x = x2 And y = y2
        ;
    End Procedure
;   
;--------------------------------------------
- hp EliteBook 8540p, 4 GB RAM, Windows 8.1 x64
- Asus P5Q, Intel Q8200, 6 GB DDR2, Radeon 4870, Windows 8.1 x64
http://www.secretly.de
Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Re: Fast line rout!
« Reply #8 on: September 30, 2011 »
3D functions doesn't make 2*2 display!!! So I've got to remake all "by hand"...
I've no idea about PureBasic but can't you work in the native resolution (320x200) and just double the pixels for display?
In a couple of years we'll probably use 16384x9216 screens and you don't want to fix all your drawing routines to poke 16x16 pixels, do you?

Here is my personal purebasic version i did in 2002
At work we call such code "suited for educational purposes" (which means it's very elegant but terribly slow) :)
« Last Edit: September 30, 2011 by hellfire »
Challenge Trophies Won:

Offline jace_stknights

  • Amiga 1200
  • ****
  • Posts: 399
  • Karma: 32
  • PEEK & POKE are not MOVEM!
    • View Profile
    • ST Knights WebSite
Re: Fast line rout!
« Reply #9 on: September 30, 2011 »
I've no idea about PureBasic but can't you work in the native resolution (320x200) and just double the pixels for display?
In a couple of years we'll probably use 16384x9216 screens and you don't want to fix all your drawing routines to poke 16x16 pixels, do you?
Yep but this is ONLY for retro-remake!!! That's why I'm doing my own routine! have to work in 640*480 or 800*600 (if I want simulate the Atari border).
Yes, I could use a 320*200 sprite and the effects inside at this resolution and finally clip it to the screen... that an idea  ;)!!

Here is my personal purebasic version i did in 2002
At work we call such code "suited for educational purposes" (which means it's very elegant but terribly slow) :)
;)
For this moment, mine runs fine ! This was the startdrawing() and stopdrawing() wich were making all so slowwww!
Challenge Trophies Won:

Offline energy

  • Amiga 1200
  • ****
  • Posts: 280
  • Karma: 25
    • View Profile
Re: Fast line rout!
« Reply #10 on: October 02, 2011 »
perhaps it's possible to precalc all lines before the mainloop routine, i case of all
that calc/ and convert routines, which are slowing down all that stuff.

Quote
Should I use assembly  (The compilers are good today, but who knows )

If yu are similar with asm (i case of PB with fasm) yu are able to use the inline asm.


coding: jwasm,masm
hobby: www.scd2003.de

Offline jace_stknights

  • Amiga 1200
  • ****
  • Posts: 399
  • Karma: 32
  • PEEK & POKE are not MOVEM!
    • View Profile
    • ST Knights WebSite
Re: Fast line rout!
« Reply #11 on: October 02, 2011 »
I didn't make any x86 code since 1997 (or 1998), but I think I will try to make a test. It is a good way also to return back to the roots...

Will post the final result  ;)
Challenge Trophies Won:

Offline energy

  • Amiga 1200
  • ****
  • Posts: 280
  • Karma: 25
    • View Profile
Re: Fast line rout!
« Reply #12 on: October 02, 2011 »
super. it will be from interrest.  :D
coding: jwasm,masm
hobby: www.scd2003.de

Offline jace_stknights

  • Amiga 1200
  • ****
  • Posts: 399
  • Karma: 32
  • PEEK & POKE are not MOVEM!
    • View Profile
    • ST Knights WebSite
Re: Fast line rout!
« Reply #13 on: October 03, 2011 »
Hu hu, I've found my old books of x86...  :clap: But I must admit that after a quick look, I definitely think that 68k, arm, and even PPC assembly are more "beautifull" than this ugly intel mnemonics...  :whack:

Pfewwww...
Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17409
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Fast line rout!
« Reply #14 on: October 03, 2011 »
Very true :)
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Fast line rout!
« Reply #15 on: October 04, 2011 »
But soooo many instructions to choose from! ;)

Jim
Challenge Trophies Won:

Offline jace_stknights

  • Amiga 1200
  • ****
  • Posts: 399
  • Karma: 32
  • PEEK & POKE are not MOVEM!
    • View Profile
    • ST Knights WebSite
Re: Fast line rout!
« Reply #16 on: October 04, 2011 »
But soooo many instructions to choose from! ;)

Jim

That's why I prefer arm! Never made anything on this processor, but remember the time I wanted to buy a Risc PC. An old mate from Archimedes gave me docs and code examples, to make me dream of it! An it was very nice... :-*

But the time where all pc will run onto Arm processor comes soon!!!  :updance:
Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Re: Fast line rout!
« Reply #17 on: October 04, 2011 »
I don't think you'll gain much when converting the loop (referring to Jim's snippet) into assembly.
The code should translate 1:1 to assembly - unless the compiler is total crap.
Asm is only useful if you can make use of things, the compiler doesn't know about.
The only thing I can imagine here is using the carry-flag to avoid the shift...
Maybe you can also add special cases for small increments and optimize them separately.
« Last Edit: October 04, 2011 by hellfire »
Challenge Trophies Won:

Offline energy

  • Amiga 1200
  • ****
  • Posts: 280
  • Karma: 25
    • View Profile
Re: Fast line rout!
« Reply #18 on: October 04, 2011 »
One stupid question:
are the lines changing/morphing?
If not, would it be ok for a  remake, if yu save that modell as a texture and them arround?  :-\

coding: jwasm,masm
hobby: www.scd2003.de

Offline Hotshot

  • DBF Aficionado
  • ******
  • Posts: 2114
  • Karma: 91
    • View Profile
Re: Fast line rout!
« Reply #19 on: October 04, 2011 »
Quote
This was the startdrawing() and stopdrawing() wich were making all so slowwww!

I hate those commands as if you had own Purebasic Framework without using these would be Great!!!