Author Topic: Triangle Rasteriser (with asm)  (Read 9932 times)

0 Members and 1 Guest are viewing this topic.

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Triangle Rasteriser (with asm)
« on: August 31, 2006 »
Here's the version with inline assembly language as promised (it's a bit quicker too).

[Edit, code removed because it didn't work properly, new listing added below... ~ SW.]
« Last Edit: September 02, 2006 by Shockwave »
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Triangle Rasteriser (with asm)
« Reply #1 on: August 31, 2006 »
Excellent!  Shockie writing asm!

One thing - you can do
Code: [Select]
asm
  cld
end asm
once at the start of your program.  Nothing will ever change it.  In fact I'd be surprised if it didn't default the direction flag to 0 anyway.

Another thing is this shows how shit the code optimisation is in freebasic.  The thing you did with *p, p=p+1 should have been only a small amount slower than rep stosd.  I've been pretty disappointed with the speed of the freebasic demos - sure, it's 10x faster than Blitz, but it's not competing with a decent C compiler.  I should try writing some comparisons.

Jim

Challenge Trophies Won:

Offline Rbz

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 2757
  • Karma: 493
    • View Profile
    • https://www.rbraz.com/
Re: Triangle Rasteriser (with asm)
« Reply #2 on: September 01, 2006 »
Nice work Shockie!

But I think there's something wrong with the asm version (or maybe my FB version), because it isn't working like the original version. If I replace the first function 'DBFTRI' (1st example code) with the DBFTRI asm version it just crash  Â :(
« Last Edit: September 01, 2006 by Rbraz »
Challenge Trophies Won:

Offline MrP

  • Atari ST
  • ***
  • Posts: 176
  • Karma: 18
    • View Profile
Re: Triangle Rasteriser (with asm)
« Reply #3 on: September 01, 2006 »
Sweet. didn't know about that rep stosd thingy. Just looked it up. Might come in handy that... Thanks for posting Shockwave, that learning curve keeps getting steeper and steeper. Better buy some climbing gear I think....

Offline relsoft

  • DBF Aficionado
  • ******
  • Posts: 3303
  • Karma: 47
    • View Profile
Re: Triangle Rasteriser (with asm)
« Reply #4 on: September 01, 2006 »
Excellent!  Shockie writing asm!

One thing - you can do
Code: [Select]
asm
  cld
end asm
once at the start of your program.  Nothing will ever change it.  In fact I'd be surprised if it didn't default the direction flag to 0 anyway.

Another thing is this shows how shit the code optimisation is in freebasic.  The thing you did with *p, p=p+1 should have been only a small amount slower than rep stosd.  I've been pretty disappointed with the speed of the freebasic demos - sure, it's 10x faster than Blitz, but it's not competing with a decent C compiler.  I should try writing some comparisons.

Jim



Don't forget that since .13b or so any emmiter based optimizatons has been ditched in preparation for the GCC backend move. 

The GCC move would enable FB with:
1. GCC speed
2. OO(classes etc)
3. Portability to any architecture GCC is ported to.
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Triangle Rasteriser (with asm)
« Reply #5 on: September 01, 2006 »
I didn't know that, thanks!  I hope that doesn't spell bad news for Windows people.  GCC is poorly supported there.
Sorry - OT - get back to talking 'bout triangles dammit!

Jim
Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Triangle Rasteriser (with asm)
« Reply #6 on: September 01, 2006 »
Lol, actually the triangle ratsriser above is broken :(
Most of the asm works though so at least you'll see a triangle, when you try and move it around bad things can happen. I'll need to fix it and put the working one up :)
Glad you liked it.
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Triangle Rasteriser (with asm)
« Reply #7 on: September 02, 2006 »
Ok, that version was horribly buggy, I have now re-coded it and it's very stable now. I've implimented some 2D clipping so this is pretty safe for anyone to use if they need a fast flatshader for their project. In fact this is probably about 40 % faster than my old flatshader so the speed increase is really significant.

You will need to have these variables;

XRES
YRES

And a screen buffer and you need to initialise a very small bit of asm before your main loop but that's all.

You can call the sub with;

FLAT_TRIANGLE( X1,Y1 , X2,Y2 , X3,Y3 , RGBCOLOUR )

The renderer will clip to the variables you define as your screen resolution.
Hope that you find it useful. :)

Code: [Select]
' Brand New Assembly Language Flatshaded Triangle Renderer
' Coded by Shockwave / DBF / S!P 2006 Use freely but credit Plz!
' Thanks to Stonemonkey and Jim Shaw for help with this technique.
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    OPTION STATIC
    OPTION EXPLICIT

    CONST XRES = 800
    CONST YRES = 600
   
    CONST HALFX = XRES/2
    CONST HALFY = YRES/2
   
    DIM SHARED BUFFER ( XRES * YRES ) AS UINTEGER
 
    DIM SHARED AS DOUBLE OLDTIME,GADD
    DIM SHARED AS UINTEGER TICKS,NEWTIME
 
    #define PTC_WIN       
    #Include Once "tinyptc.bi"
   
    DECLARE SUB DELTA()
    DECLARE SUB FLAT_TRIANGLE( BYVAL X1 AS INTEGER , BYVAL Y1 AS INTEGER, BYVAL X2 AS INTEGER , BYVAL Y2 AS INTEGER , BYVAL X3 AS INTEGER, BYVAL Y3 AS INTEGER , BYVAL TC AS INTEGER)
   
'-------------------------------------------------------------------------
' Open Screen.
'-------------------------------------------------------------------------

    If( ptc_open( "TRIANGLE ROUTINE WITH ASSEMBLY LANGUAGE RASTERISING BY SHOCKWAVE^S!P^DBF", XRES, YRES ) = 0 ) Then
    End -1
    End If

'-------------------------------------------------------------------------
'  YOU NEED TO DO THIS ONCE BEFORE THE MAIN LOOP OF THE PROGRAM;
'-------------------------------------------------------------------------
    asm
    cld
    end asm

    OLDTIME = TIMER
DO
    GADD=GADD+.005
    DELTA()
    FLAT_TRIANGLE(HALFX+500*SIN(GADD),HALFY+400*COS(GADD),HALFX+150*SIN(GADD*2),HALFY+200*COS(GADD*3),HALFX+300*SIN(GADD/2),HALFY+100*COS(GADD*5),&H88FF55)
    PTC_UPDATE@BUFFER(0)
    ERASE BUFFER
    TICKS=TICKS+1
   
LOOP UNTIL INKEY$ = CHR$(27)

SUB FLAT_TRIANGLE(BYVAL X1 AS INTEGER , BYVAL Y1 AS INTEGER, BYVAL X2 AS INTEGER , BYVAL Y2 AS INTEGER , BYVAL X3 AS INTEGER, BYVAL Y3 AS INTEGER , BYVAL TC AS INTEGER)
'-------------------------------------------------------------------------
' FLAT TRIANGLE RENDERER WITH ASSEMBLY LANGUAGE RASTERISING BY SHOCKWAVE ^ DBF ^ S!P 2006.
'-------------------------------------------------------------------------
'-------------------------------------------------------------------------
' WE NEED TO SORT THESE POINTS INTO ORDER FROM TOP TO BOTTOM, AN EXCHANGE SORT IS OK.
' AS WE ONLY HAVE GOT 3 POINTS TO ARRANGE.
'-------------------------------------------------------------------------
DIM AS INTEGER TEMPX,TEMPY,LO,LI
                DIM AS INTEGER PX(3)
                DIM AS INTEGER PY(3)
                DIM TFLAG AS INTEGER
                dim pp as uinteger PTR
                DIM AS INTEGER IL1,IL2,SLICE
                TFLAG=0
        PX(1)= X1
        PX(2)= X2
        PX(3)= X3
       
        PY(1)= Y1
        PY(2)= Y2
        PY(3)= Y3
FOR LO = 1 TO 2
    FOR LI =1 TO 2     
        IF PY(LI+1) <= PY(LI) THEN
        TEMPX = PX(LI) : TEMPY = PY(LI)
        PX(LI) = PX(LI+1)
        PY(LI) = PY(LI+1)
        PX(LI+1) = TEMPX
        PY(LI+1) = TEMPY
        END IF   
    NEXT LI
NEXT LO

        DIM AS DOUBLE XP1,XP2:' SCREEN POSITIONS.
        DIM AS DOUBLE XI1,XI2:' INTERPOLATIONS.
       
'***
'*** REGULAR TRIANGLE (Y1<Y2 Y2<Y3)
'***

IF PY(1)<PY(2) AND PY(2)<PY(3) THEN
    TFLAG=1
XP1 = PX(1)
XP2 = PX(1)
XI1 = (PX(1)-PX(2)) / (PY(2) - PY(1))
XI2 = (PX(1)-PX(3)) / (PY(3) - PY(1))

FOR LO = PY(1) TO PY(2)-1
   
IF LO>0 AND LO<YRES THEN

    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF
   
    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0

    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
   

END IF

XP1=XP1-XI1
XP2=XP2-XI2
NEXT

XI1 = (XP1-PX(3)) / (PY(3) - PY(2))

FOR LO = PY(2) TO PY(3)
IF LO>0 AND LO<YRES THEN
    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF

    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0

    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
END IF
XP1=XP1-XI1
XP2=XP2-XI2
NEXT




END IF

'***
'*** FLAT BOTTOMED TRIANGLE Y2 = Y3
'***

IF TFLAG=0 AND PY(2) = PY(3) THEN
   
        TFLAG=1
        XP1 = PX(1)
        XP2 = PX(1)
        XI1 = (PX(1)-PX(2)) / (PY(3) - PY(1))
        XI2 = (PX(1)-PX(3)) / (PY(3) - PY(1))
FOR LO = PY(1) TO PY(3)
IF LO>0 AND LO<YRES THEN
    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF

    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0


    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
END IF
    XP1=XP1-XI1
    XP2=XP2-XI2

NEXT
END IF

'***
'*** FLAT TOPPED TRIANGLE Y1=Y2
'***

IF TFLAG=0 AND PY(1) = PY(2) THEN
   
        TFLAG=1
        XP1 = PX(1)
        XP2 = PX(2)
        XI1 = (PX(1)-PX(3)) / (PY(3) - PY(1))
        XI2 = (PX(2)-PX(3)) / (PY(3) - PY(2))
FOR LO = PY(1) TO PY(3)
 IF LO>0 AND LO<YRES THEN
    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF
   
    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0
   
    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
END IF
    XP1=XP1-XI1
    XP2=XP2-XI2

NEXT
END IF
END SUB

'-------------------------------------------------------------------------
' TIMER MANAGEMENT;
'-------------------------------------------------------------------------
SUB DELTA()
    DIM Z AS UINTEGER
    IF TIMER-OLDTIME>=1 THEN
        NEWTIME = TICKS
        OLDTIME = TIMER
        PRINT "FPS:"+STR$(NEWTIME)
        TICKS =0
    END IF
END SUB
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: Triangle Rasteriser (with asm)
« Reply #8 on: September 02, 2006 »
Welldone dude :)
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Triangle Rasteriser (with asm)
« Reply #9 on: September 02, 2006 »
Thanks Clyde.. Here's how it looks with a vector routine attached to it, a new type of glenze effect..

Code: [Select]
' Brand New Assembly Language Flatshaded Triangle Renderer
' Coded by Shockwave / DBF / S!P 2006 Use freely but credit Plz!
' Thanks to Stonemonkey and Jim Shaw for help with this technique.
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    OPTION STATIC
    OPTION EXPLICIT

    CONST XRES = 640
    CONST YRES = 480
   
    CONST HALFX = XRES/2
    CONST HALFY = YRES/2
   
    DIM SHARED BUFFER ( XRES * YRES ) AS UINTEGER
    DIM SHARED BUFFER2( XRES * YRES ) AS UINTEGER
    DIM SHARED AS DOUBLE OLDTIME,GADD
    DIM SHARED AS UINTEGER TICKS,NEWTIME
 
    '#define PTC_WIN       
    #Include Once "tinyptc.bi"
    DECLARE SUB DELTA()
    DECLARE SUB FLAT_TRIANGLE( BYVAL X1 AS INTEGER , BYVAL Y1 AS INTEGER, BYVAL X2 AS INTEGER , BYVAL Y2 AS INTEGER , BYVAL X3 AS INTEGER, BYVAL Y3 AS INTEGER , BYVAL TC AS INTEGER)
   DECLARE SUB FLAT_TRIANGLE2( BYVAL X1 AS INTEGER , BYVAL Y1 AS INTEGER, BYVAL X2 AS INTEGER , BYVAL Y2 AS INTEGER , BYVAL X3 AS INTEGER, BYVAL Y3 AS INTEGER , BYVAL TC AS INTEGER)   
    DECLARE SUB CONSTRUCT()
    DECLARE SUB ROTATE()       

'---------------------------------------------------------
'            Define the necessary variables;
'---------------------------------------------------------
    DIM shared N AS DOUBLE
    dim shared vx1 as double
    dim shared vx2 as double
    dim shared vy1 as double
    dim shared vy2 as double


    DIM SHARED SIZE AS DOUBLE
    DIM SHARED POINTS AS INTEGER
    DIM SHARED FACES AS INTEGER

    DIM SHARED VXR as double
    dim shared VYR as double
    dim shared VZR AS double

    size=30
    points=14
    faces=24

    Dim SHARED Vx(points) AS DOUBLE
    Dim SHARED Vy(points) AS DOUBLE
    Dim SHARED Vz(points) AS DOUBLE
   
    Dim SHARED Vtx(points) AS INTEGER
    Dim SHARED Vty(points) AS INTEGER
    Dim SHARED Vtz(points) AS INTEGER
   
    Dim SHARED Vf1(faces) AS DOUBLE
    Dim SHARED Vf2(faces) AS DOUBLE
    Dim SHARED Vf3(faces) AS DOUBLE
    Dim SHARED Vf4(faces) AS DOUBLE
    Dim SHARED Vr(faces) AS DOUBLE
    Dim SHARED Vg(faces) AS DOUBLE
    Dim SHARED Vb(faces) AS DOUBLE

   
   
 
'---------------------------------------------------------
'               Read in the Object's points;
'---------------------------------------------------------
    dim A
    For a=1 To points
    Read Vx(a)
    read Vy(a)
    read Vz(a)
    Next

    For a=1 To faces
    Read Vf1(a)
    Read Vf2(a)
    Read Vf3(a)
    Read Vf4(a)
    Read Vr(a)
    READ Vg(a)
    READ Vb(a)
    Next

'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

   
'-------------------------------------------------------------------------
' Open Screen.
'-------------------------------------------------------------------------

    If( ptc_open( "GLENZE EFFECT BY SHOCKWAVE 2006!", XRES, YRES ) = 0 ) Then
    End -1
    End If

'-------------------------------------------------------------------------
'  YOU NEED TO DO THIS ONCE BEFORE THE MAIN LOOP OF THE PROGRAM;
'-------------------------------------------------------------------------
    asm
    cld
    end asm

    OLDTIME = TIMER
    DIM AS INTEGER LLX,LLY ,MMUL
DO

    DELTA()
    ROTATE()
    CONSTRUCT()
    FOR LLY=HALFY-150 TO HALFY+150
        MMUL=LLY*XRES
    FOR LLX=HALFX-150 TO HALFX+150
        BUFFER(MMUL+LLX)=BUFFER(MMUL+LLX)+BUFFER2(MMUL+LLX)
    NEXT
    NEXT

    'FOR A=1 TO XRES*YRES : BUFFER(A)=BUFFER(A) + BUFFER2(A) : NEXT
   
    PTC_UPDATE@BUFFER(0)
   
    ERASE BUFFER
    ERASE BUFFER2
   
    TICKS=TICKS+1
   
LOOP UNTIL INKEY$ = CHR$(27)

SUB FLAT_TRIANGLE(BYVAL X1 AS INTEGER , BYVAL Y1 AS INTEGER, BYVAL X2 AS INTEGER , BYVAL Y2 AS INTEGER , BYVAL X3 AS INTEGER, BYVAL Y3 AS INTEGER , BYVAL TC AS INTEGER)
'-------------------------------------------------------------------------
' FLAT TRIANGLE RENDERER WITH ASSEMBLY LANGUAGE RASTERISING BY SHOCKWAVE ^ DBF ^ S!P 2006.
'-------------------------------------------------------------------------
'-------------------------------------------------------------------------
' WE NEED TO SORT THESE POINTS INTO ORDER FROM TOP TO BOTTOM, AN EXCHANGE SORT IS OK.
' AS WE ONLY HAVE GOT 3 POINTS TO ARRANGE.
'-------------------------------------------------------------------------
DIM AS INTEGER TEMPX,TEMPY,LO,LI
                DIM AS INTEGER PX(3)
                DIM AS INTEGER PY(3)
                DIM TFLAG AS INTEGER
                dim pp as uinteger PTR
                DIM AS INTEGER IL1,IL2,SLICE
                TFLAG=0
        PX(1)= X1
        PX(2)= X2
        PX(3)= X3
       
        PY(1)= Y1
        PY(2)= Y2
        PY(3)= Y3
FOR LO = 1 TO 2
    FOR LI =1 TO 2     
        IF PY(LI+1) <= PY(LI) THEN
        TEMPX = PX(LI) : TEMPY = PY(LI)
        PX(LI) = PX(LI+1)
        PY(LI) = PY(LI+1)
        PX(LI+1) = TEMPX
        PY(LI+1) = TEMPY
        END IF   
    NEXT LI
NEXT LO

        DIM AS DOUBLE XP1,XP2:' SCREEN POSITIONS.
        DIM AS DOUBLE XI1,XI2:' INTERPOLATIONS.
       
'***
'*** REGULAR TRIANGLE (Y1<Y2 Y2<Y3)
'***

IF PY(1)<PY(2) AND PY(2)<PY(3) THEN
    TFLAG=1
XP1 = PX(1)
XP2 = PX(1)
XI1 = (PX(1)-PX(2)) / (PY(2) - PY(1))
XI2 = (PX(1)-PX(3)) / (PY(3) - PY(1))

FOR LO = PY(1) TO PY(2)-1
   
IF LO>0 AND LO<YRES THEN

    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF
   
    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0

    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
   

END IF

XP1=XP1-XI1
XP2=XP2-XI2
NEXT

XI1 = (XP1-PX(3)) / (PY(3) - PY(2))

FOR LO = PY(2) TO PY(3)
IF LO>0 AND LO<YRES THEN
    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF

    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0

    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
END IF
XP1=XP1-XI1
XP2=XP2-XI2
NEXT




END IF

'***
'*** FLAT BOTTOMED TRIANGLE Y2 = Y3
'***

IF TFLAG=0 AND PY(2) = PY(3) THEN
   
        TFLAG=1
        XP1 = PX(1)
        XP2 = PX(1)
        XI1 = (PX(1)-PX(2)) / (PY(3) - PY(1))
        XI2 = (PX(1)-PX(3)) / (PY(3) - PY(1))
FOR LO = PY(1) TO PY(3)
IF LO>0 AND LO<YRES THEN
    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF

    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0


    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
END IF
    XP1=XP1-XI1
    XP2=XP2-XI2

NEXT
END IF

'***
'*** FLAT TOPPED TRIANGLE Y1=Y2
'***

IF TFLAG=0 AND PY(1) = PY(2) THEN
   
        TFLAG=1
        XP1 = PX(1)
        XP2 = PX(2)
        XI1 = (PX(1)-PX(3)) / (PY(3) - PY(1))
        XI2 = (PX(2)-PX(3)) / (PY(3) - PY(2))
FOR LO = PY(1) TO PY(3)
 IF LO>0 AND LO<YRES THEN
    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF
   
    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0
   
    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
END IF
    XP1=XP1-XI1
    XP2=XP2-XI2

NEXT
END IF
END SUB

SUB FLAT_TRIANGLE2(BYVAL X1 AS INTEGER , BYVAL Y1 AS INTEGER, BYVAL X2 AS INTEGER , BYVAL Y2 AS INTEGER , BYVAL X3 AS INTEGER, BYVAL Y3 AS INTEGER , BYVAL TC AS INTEGER)
'-------------------------------------------------------------------------
' FLAT TRIANGLE RENDERER WITH ASSEMBLY LANGUAGE RASTERISING BY SHOCKWAVE ^ DBF ^ S!P 2006.
'-------------------------------------------------------------------------
'-------------------------------------------------------------------------
' WE NEED TO SORT THESE POINTS INTO ORDER FROM TOP TO BOTTOM, AN EXCHANGE SORT IS OK.
' AS WE ONLY HAVE GOT 3 POINTS TO ARRANGE.
'-------------------------------------------------------------------------
DIM AS INTEGER TEMPX,TEMPY,LO,LI
                DIM AS INTEGER PX(3)
                DIM AS INTEGER PY(3)
                DIM TFLAG AS INTEGER
                dim pp as uinteger PTR
                DIM AS INTEGER IL1,IL2,SLICE
                TFLAG=0
        PX(1)= X1
        PX(2)= X2
        PX(3)= X3
       
        PY(1)= Y1
        PY(2)= Y2
        PY(3)= Y3
FOR LO = 1 TO 2
    FOR LI =1 TO 2     
        IF PY(LI+1) <= PY(LI) THEN
        TEMPX = PX(LI) : TEMPY = PY(LI)
        PX(LI) = PX(LI+1)
        PY(LI) = PY(LI+1)
        PX(LI+1) = TEMPX
        PY(LI+1) = TEMPY
        END IF   
    NEXT LI
NEXT LO

        DIM AS DOUBLE XP1,XP2:' SCREEN POSITIONS.
        DIM AS DOUBLE XI1,XI2:' INTERPOLATIONS.
       
'***
'*** REGULAR TRIANGLE (Y1<Y2 Y2<Y3)
'***

IF PY(1)<PY(2) AND PY(2)<PY(3) THEN
    TFLAG=1
XP1 = PX(1)
XP2 = PX(1)
XI1 = (PX(1)-PX(2)) / (PY(2) - PY(1))
XI2 = (PX(1)-PX(3)) / (PY(3) - PY(1))

FOR LO = PY(1) TO PY(2)-1
   
IF LO>0 AND LO<YRES THEN

    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF
   
    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0

    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER2(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
   

END IF

XP1=XP1-XI1
XP2=XP2-XI2
NEXT

XI1 = (XP1-PX(3)) / (PY(3) - PY(2))

FOR LO = PY(2) TO PY(3)
IF LO>0 AND LO<YRES THEN
    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF

    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0

    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER2(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
END IF
XP1=XP1-XI1
XP2=XP2-XI2
NEXT




END IF

'***
'*** FLAT BOTTOMED TRIANGLE Y2 = Y3
'***

IF TFLAG=0 AND PY(2) = PY(3) THEN
   
        TFLAG=1
        XP1 = PX(1)
        XP2 = PX(1)
        XI1 = (PX(1)-PX(2)) / (PY(3) - PY(1))
        XI2 = (PX(1)-PX(3)) / (PY(3) - PY(1))
FOR LO = PY(1) TO PY(3)
IF LO>0 AND LO<YRES THEN
    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF

    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0


    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER2(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
END IF
    XP1=XP1-XI1
    XP2=XP2-XI2

NEXT
END IF

'***
'*** FLAT TOPPED TRIANGLE Y1=Y2
'***

IF TFLAG=0 AND PY(1) = PY(2) THEN
   
        TFLAG=1
        XP1 = PX(1)
        XP2 = PX(2)
        XI1 = (PX(1)-PX(3)) / (PY(3) - PY(1))
        XI2 = (PX(2)-PX(3)) / (PY(3) - PY(2))
FOR LO = PY(1) TO PY(3)
 IF LO>0 AND LO<YRES THEN
    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF
   
    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0
   
    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER2(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
END IF
    XP1=XP1-XI1
    XP2=XP2-XI2

NEXT
END IF
END SUB

'-------------------------------------------------------------------------
' TIMER MANAGEMENT;
'-------------------------------------------------------------------------
SUB DELTA()
    DIM Z AS UINTEGER
    IF TIMER-OLDTIME>=1 THEN
        NEWTIME = TICKS
        OLDTIME = TIMER
        PRINT "FPS:"+STR$(NEWTIME)
        TICKS =0
    END IF
END SUB

'---------------------------------------------------------
'                     Draw The Object;
'---------------------------------------------------------

SUB construct()
    DIM A
    DIM  AS DOUBLE N,RD,GR,BL

    For a=1 To faces

'---------------------------------------------------------
'              Draw A Face Of The Object;
'---------------------------------------------------------


  vx1= Vtx(Vf1(a))-Vtx(Vf2(a))
  vy1= Vty(Vf1(a))-Vty(Vf2(a))
  vx2= Vtx(Vf3(a))-Vtx(Vf2(a))
  vy2= Vty(Vf3(a))-Vty(Vf2(a))
  n=  vx1*vy2-vx2*vy1
 
If n>0 THEN

    n=(n/7000)
                        rd=Vr(a)*n : If rd>50 THEN rd=50
                        gr=Vg(a)*n : If gr>50 THEN gr=50
                        bl=Vb(a)*n : If bl>50 THEN bl=50
                        FLAT_TRIANGLE2(Vtx(Vf1(a)),Vty(Vf1(a)),Vtx(Vf2(a)),Vty(Vf2(a)),Vtx(Vf3(a)),Vty(Vf3(a)),RGB(RD,GR,BL))
                        FLAT_TRIANGLE2(Vtx(Vf1(a)),Vty(Vf1(a)),Vtx(Vf4(a)),Vty(Vf4(a)),Vtx(Vf3(a)),Vty(Vf3(a)),RGB(RD,GR,BL))
    End If
    NEXT


    For a=1 To faces

'---------------------------------------------------------
'              Draw A Face Of The Object;
'---------------------------------------------------------


  vx1= Vtx(Vf1(a))-Vtx(Vf2(a))
  vy1= Vty(Vf1(a))-Vty(Vf2(a))
  vx2= Vtx(Vf3(a))-Vtx(Vf2(a))
  vy2= Vty(Vf3(a))-Vty(Vf2(a))
  n=  vx1*vy2-vx2*vy1
 
If n<0 THEN

    n=-(n/2500)
                        rd=Vr(a)*n : If rd>200 THEN rd=200
                        gr=Vg(a)*n : If gr>200 THEN gr=200
                        bl=Vb(a)*n : If bl>200 THEN bl=200
                        FLAT_TRIANGLE(Vtx(Vf1(a)),Vty(Vf1(a)),Vtx(Vf2(a)),Vty(Vf2(a)),Vtx(Vf3(a)),Vty(Vf3(a)),RGB(RD,GR,BL))
                        FLAT_TRIANGLE(Vtx(Vf1(a)),Vty(Vf1(a)),Vtx(Vf4(a)),Vty(Vf4(a)),Vtx(Vf3(a)),Vty(Vf3(a)),RGB(RD,GR,BL))
    End If
    NEXT

END SUB


SUB ROTATE()
DIM A
    DIM VX1 AS DOUBLE
    dim VY1 AS DOUBLE
    dim VZ1 AS DOUBLE
   
    DIM VZZ AS DOUBLE   
    dim vxx as double
    dim vyy as double
   
    DIM VDV AS DOUBLE

'###############################################
'## Rotate And Scale Each Point! Store Result ##
'###############################################
 For a=1 To points

    VX1=Vx(a)
    VY1=Vy(a)
    VZ1=Vz(a)
   
'######################
'## X,Y,Z rotations! ##
'######################
  Vxx=Vx1
  Vyy=Vy1*cos(Vxr)+Vz1*sin(Vxr)
  Vzz=Vz1*cos(Vxr)-Vy1*sin(Vxr)
 
  Vy1=Vyy
  Vx1=Vxx*cos(Vyr)-Vzz*sin(Vyr)
  Vz1=Vxx*sin(Vyr)+Vzz*cos(Vyr)
 
  Vzz=Vz1
  Vxx=Vx1*cos(Vzr)-Vy1*sin(Vzr)
  Vyy=Vx1*sin(Vzr)+Vy1*cos(Vzr)
'########################
'## Apply Perspective! ##
'########################
  Vdv=(Vzz/40)+1

  Vxx=(size*(Vxx/Vdv))+HALFX
  Vyy=(size*(Vyy/Vdv))+HALFY
  Vtx(a)=Int(Vxx)
  Vty(a)=Int(Vyy)
  Vtz(a)=Int(Vzz)
 
 Next
        Vxr=Vxr+0.008
        Vyr=Vyr+0.007
        Vzr=Vzr+0.006
       
       
END SUB



'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
'   The Object Description As Data!
'   The Data Below Describes A Cube.
'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

'Points definition;
'~~~~~~~~~~~~~~~~~~
'Below are the points of the Object defined as x,y,z;

Data 5,-5,-5,5,5,-5,-5,5,-5,-5,-5,-5,0,0,-8,8,0,0,0
Data 8,0,-8,0,0,0,-8,0,5,-5,5,5,5,5,-5,5,5,-5,-5,5,0,0,8


'Connection definition;
'Below are the faces of the Object defined as vertice
'numbers, specified in clockwise order. These are followed
'by r,g,b values For the face And finally cell shaded
'parameter (0)=off (1)=on.

Data 10,9,13,13,5,2,2


Data 14,10,13,13,4,4,4
Data 14,13,12,12,2,5,2
Data 8,12,13,13,4,4,4
Data 4,8,13,13,2,2,5
Data 10,14,11,11,2,5,2
Data 10,11,6,6,4,4,4
Data 4,13,9,9,4,4,4

Data 1,4,9,9,5,2,2

Data 1,9,10,10,4,4,4

Data 6,1,10,10,5,1,5
Data 5,4,1,1,4,4,4
Data 8,4,3,3,4,4,4
Data 3,12,8,8,2,2,5
Data 3,4,5,5,1,5,5
Data 7,12,3,3,4,4,4
Data 14,12,11,11,4,4,4
Data 11,12,7,7,5,5,1
Data 6,11,2,2,5,1,5
Data 11,7,2,2,4,4,4
Data 1,6,2,2,4,4,4
Data 2,5,1,1,1,5,5
Data 2,7,3,3,5,5,1
Data 2,3,5,5,4,4,4

'===============================================================================
'                                     ***END***
'===============================================================================
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Rbz

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 2757
  • Karma: 493
    • View Profile
    • https://www.rbraz.com/
Re: Triangle Rasteriser (with asm)
« Reply #10 on: September 02, 2006 »
 :o  Fuc***g good dude, well done !
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Triangle Rasteriser (with asm)
« Reply #11 on: September 03, 2006 »
I've always liked your glenzes :)

You still have a problem though.  There is cracking caused by the bottom half of a normal triangle not being set up right.  Â In two places where you move from drawing the top half of the tri to the bottom half you have
Code: [Select]
XI1 = (XP1-PX(3)) / (PY(3) - PY(2))
The problem with that is that it assumes that XP1 has reached PX(2) by interpolation, and it doesn't always do that.  You should replace it with
Code: [Select]
XI1 = (PX(2)-PX(3)) / (PY(3) - PY(2))
XP1 = PX(2)
That makes sure you start the bottom half with the exact values.  If you don't do that, the bottom half of this triangle doesn't match with the top half of the joining triangle as they had different start and/or end points.

Tiny top clipping problem too
Code: [Select]
IF LO>0 AND LO<YRES THENshould be
Code: [Select]
IF LO>=0 AND LO<YRES THEN
I've done a bit of googling.  You defintiely don't need the 'asm cld' code.  Windows clears it at startup and expects it to be clear whenever it's called.

I have a question too.  Basically a normal triangle is just a flat-bottomed triangle on top of a flat-topped triangle.  Can't you take advantage of that and shrink about half of the code away?

Jim
« Last Edit: September 03, 2006 by Jim »
Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Triangle Rasteriser (with asm)
« Reply #12 on: September 03, 2006 »
Thank you for spotting that bug! I hadn't noticed it, I'll edit to include your suggestions, but in the meantime, here's the same code with another couple of effects thrown in for good measure and some delta timing..

This is actually going to be a S!P intro when it is finished.

Code: [Select]

'WORK IN PROGRESS..
' Coded by Shockwave / DBF / S!P 2006.
' Thanks to Stonemonkey and Jim Shaw for help with this technique.
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    OPTION STATIC
    OPTION EXPLICIT

    CONST XRES = 640
    CONST YRES = 480
   
    CONST HALFX = XRES/2
    CONST HALFY = YRES/2
   
    CONST PCLIP  = 18
   
    DIM SHARED BUFFER ( XRES * YRES ) AS UINTEGER
    DIM SHARED BUFFER2( XRES * YRES ) AS UINTEGER
    DIM SHARED AS DOUBLE OLDTIME,GADD,DELTAVALUE
    DIM SHARED AS UINTEGER TICKS,NEWTIME
    DIM SHARED AS DOUBLE GRADD
    DIM SHARED AS INTEGER GRID
    GRID=20
   
    DIM SHARED AS DOUBLE CHESS_GRIDX(GRID,GRID)
    DIM SHARED AS DOUBLE CHESS_GRIDZ(GRID,GRID)
    DIM SHARED CFM AS DOUBLE
    CFM=0
    '#define PTC_WIN       
    #Include Once "tinyptc.bi"
    DECLARE SUB DELTA()
    DECLARE SUB FLAT_TRIANGLE( BYVAL X1 AS INTEGER , BYVAL Y1 AS INTEGER, BYVAL X2 AS INTEGER , BYVAL Y2 AS INTEGER , BYVAL X3 AS INTEGER, BYVAL Y3 AS INTEGER , BYVAL TC AS INTEGER)
    DECLARE SUB FLAT_TRIANGLE2( BYVAL X1 AS INTEGER , BYVAL Y1 AS INTEGER, BYVAL X2 AS INTEGER , BYVAL Y2 AS INTEGER , BYVAL X3 AS INTEGER, BYVAL Y3 AS INTEGER , BYVAL TC AS INTEGER)   
    DECLARE SUB CONSTRUCT()
    DECLARE SUB ROTATE()       
    DECLARE SUB COPY_GLENZE()
    DECLARE SUB CHESS_SETUP()
    DECLARE SUB CHESS_FUNK()
    CHESS_SETUP()
   
'---------------------------------------------------------
'            Define the necessary variables;
'---------------------------------------------------------
    DIM shared N AS DOUBLE
    dim shared vx1 as double
    dim shared vx2 as double
    dim shared vy1 as double
    dim shared vy2 as double


    DIM SHARED SIZE AS DOUBLE
    DIM SHARED POINTS AS INTEGER
    DIM SHARED FACES AS INTEGER

    DIM SHARED VXR as double
    dim shared VYR as double
    dim shared VZR AS double

    size=24
    points=14
    faces=24

    Dim SHARED Vx(points) AS DOUBLE
    Dim SHARED Vy(points) AS DOUBLE
    Dim SHARED Vz(points) AS DOUBLE
   
    Dim SHARED Vtx(points) AS INTEGER
    Dim SHARED Vty(points) AS INTEGER
    Dim SHARED Vtz(points) AS INTEGER
   
    Dim SHARED Vf1(faces) AS DOUBLE
    Dim SHARED Vf2(faces) AS DOUBLE
    Dim SHARED Vf3(faces) AS DOUBLE
    Dim SHARED Vf4(faces) AS DOUBLE
    Dim SHARED Vr(faces) AS DOUBLE
    Dim SHARED Vg(faces) AS DOUBLE
    Dim SHARED Vb(faces) AS DOUBLE

   
   
 
'---------------------------------------------------------
'               Read in the Object's points;
'---------------------------------------------------------
    dim A
    For a=1 To points
    Read Vx(a)
    read Vy(a)
    read Vz(a)
    Next

    For a=1 To faces
    Read Vf1(a)
    Read Vf2(a)
    Read Vf3(a)
    Read Vf4(a)
    Read Vr(a)
    READ Vg(a)
    READ Vb(a)
    Next

'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

   
'-------------------------------------------------------------------------
' Open Screen.
'-------------------------------------------------------------------------

    If( ptc_open( "GLENZE EFFECT BY SHOCKWAVE 2006!", XRES, YRES ) = 0 ) Then
    End -1
    End If


'-------------------------------------------------------------------------
'  YOU NEED TO DO THIS ONCE BEFORE THE MAIN LOOP OF THE PROGRAM;
'-------------------------------------------------------------------------
    asm
    cld
    end asm


    OLDTIME = TIMER
    DELTAVALUE=100
    TICKS=80

DO

    DELTA()
    ROTATE()
    CHESS_FUNK()
    CONSTRUCT()
    COPY_GLENZE()       
   
    PTC_UPDATE@BUFFER(0)   
    ERASE BUFFER
    ERASE BUFFER2   
    TICKS=TICKS+1

LOOP UNTIL INKEY$ = CHR$(27)

SUB CHESS_FUNK()
    DIM CHYP AS INTEGER
    CHYP=350
    DIM AS INTEGER ZC,LX,LZ,TX1,TY1,TX2,TY2,TX3,TY3,TX4,TY4,FP,TOG,ML1,ML2
    TOG=0
    FP=1
    ZC=1
    FOR LZ=1 TO GRID-1
    FOR LX=FP TO GRID-1
    TX1=(CHESS_GRIDX(LX,LZ) / (CHESS_GRIDZ(LX,LZ)+CFM) ) + HALFX
    TY1=(CHYP / (CHESS_GRIDZ(LX,LZ)+CFM) ) + HALFY

    TX2=(CHESS_GRIDX(LX+1,LZ) / (CHESS_GRIDZ(LX+1,LZ)+CFM) ) + HALFX
    TY2=(CHYP / (CHESS_GRIDZ(LX+1,LZ)+CFM) ) + HALFY

    TX3=(CHESS_GRIDX(LX+1,LZ+1) / (CHESS_GRIDZ(LX+1,LZ+1)+CFM) ) + HALFX
    TY3=(CHYP / (CHESS_GRIDZ(LX+1,LZ+1)+CFM) ) + HALFY

    TX4=(CHESS_GRIDX(LX,LZ+1) / (CHESS_GRIDZ(LX,LZ+1)+CFM) ) + HALFX
    TY4=(CHYP / (CHESS_GRIDZ(LX,LZ+1)+CFM) ) + HALFY
    ZC=TY3-305
    ML1=RGB(ZC SHR 2,ZC SHR 2,ZC SHR 1)
    ML2=RGB(ZC SHR 3,ZC SHR 3,ZC SHR 2)
IF TOG=0 THEN
            FLAT_TRIANGLE(TX1,TY1,TX2,TY2,TX3,TY3,ML1)
            FLAT_TRIANGLE(TX3,TY3,TX4,TY4,TX1,TY1,ML1)
ELSE
            FLAT_TRIANGLE(TX1,TY1,TX2,TY2,TX3,TY3,ML2)
            FLAT_TRIANGLE(TX3,TY3,TX4,TY4,TX1,TY1,ML2)

END IF
TOG=TOG+1
IF TOG>1 THEN TOG=0
    NEXT
    FP=FP+1
    IF FP>2 THEN FP=1
    TOG=FP

    NEXT
        CFM=CFM-1/DELTAVALUE
        IF CFM<.4 THEN CFM=CFM+.4

END SUB


SUB CHESS_SETUP()
'
' THIS SUB INITIALISES A GRID FOR THE CHESSFUNK!
'
DIM AS DOUBLE CX,CZ,CSTX,CSTZ
DIM AS INTEGER LX,LZ

    CSTX = (50 / GRID)*2
    CSTZ = (1 / GRID)*2
    CZ=.3

    FOR LX = 1 TO GRID
    CX=-50
    FOR LZ = 1 TO GRID
        CHESS_GRIDX(LX,LZ)  = ( CX *  50)
        CHESS_GRIDZ(LX,LZ)  = ( CZ *  2)
        CX=CX+CSTX
    NEXT
        CZ=CZ+CSTZ
    NEXT


END SUB


SUB COPY_GLENZE()
    DIM AS INTEGER LLX,LLY ,MMUL
    GRADD=GRADD+250/DELTAVALUE
    SIZE=15+8*SIN(GRADD / 150)
    FOR LLY=HALFY-190 TO HALFY+190
    MMUL=LLY*XRES
    FOR LLX=HALFX-190 TO HALFX+190
        BUFFER(MMUL+LLX)=BUFFER(MMUL+LLX)+BUFFER2(MMUL+LLX)
    NEXT
    NEXT
    LLY=XRES-1
    FOR LLX=0 TO XRES-1
        MMUL = RGB(125+124*SIN((LLX+GRADD)/100),125+124*SIN((LLX+GRADD)/120),125+124*SIN((LLX+GRADD)/123))
        BUFFER(LLX+(PCLIP*XRES)) = MMUL
        BUFFER(LLY+((YRES-PCLIP)*XRES)) = MMUL
        LLY=LLY-1
    NEXT

END SUB

SUB FLAT_TRIANGLE(BYVAL X1 AS INTEGER , BYVAL Y1 AS INTEGER, BYVAL X2 AS INTEGER , BYVAL Y2 AS INTEGER , BYVAL X3 AS INTEGER, BYVAL Y3 AS INTEGER , BYVAL TC AS INTEGER)
'-------------------------------------------------------------------------
' FLAT TRIANGLE RENDERER WITH ASSEMBLY LANGUAGE RASTERISING BY SHOCKWAVE ^ DBF ^ S!P 2006.
'-------------------------------------------------------------------------
'-------------------------------------------------------------------------
' WE NEED TO SORT THESE POINTS INTO ORDER FROM TOP TO BOTTOM, AN EXCHANGE SORT IS OK.
' AS WE ONLY HAVE GOT 3 POINTS TO ARRANGE.
'-------------------------------------------------------------------------
DIM AS INTEGER TEMPX,TEMPY,LO,LI
                DIM AS INTEGER PX(3)
                DIM AS INTEGER PY(3)
                DIM TFLAG AS INTEGER
                dim pp as uinteger PTR
                DIM AS INTEGER IL1,IL2,SLICE
                TFLAG=0
        PX(1)= X1
        PX(2)= X2
        PX(3)= X3
       
        PY(1)= Y1
        PY(2)= Y2
        PY(3)= Y3
FOR LO = 1 TO 2
    FOR LI =1 TO 2     
        IF PY(LI+1) <= PY(LI) THEN
        TEMPX = PX(LI) : TEMPY = PY(LI)
        PX(LI) = PX(LI+1)
        PY(LI) = PY(LI+1)
        PX(LI+1) = TEMPX
        PY(LI+1) = TEMPY
        END IF   
    NEXT LI
NEXT LO

        DIM AS DOUBLE XP1,XP2:' SCREEN POSITIONS.
        DIM AS DOUBLE XI1,XI2:' INTERPOLATIONS.
       
'***
'*** REGULAR TRIANGLE (Y1<Y2 Y2<Y3)
'***

IF PY(1)<PY(2) AND PY(2)<PY(3) THEN
    TFLAG=1
XP1 = PX(1)
XP2 = PX(1)
XI1 = (PX(1)-PX(2)) / (PY(2) - PY(1))
XI2 = (PX(1)-PX(3)) / (PY(3) - PY(1))

FOR LO = PY(1) TO PY(2)-1
   
IF LO>PCLIP AND LO<YRES-PCLIP THEN

    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF
   
    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0

    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
   

END IF

XP1=XP1-XI1
XP2=XP2-XI2
NEXT

XI1 = (XP1-PX(3)) / (PY(3) - PY(2))

FOR LO = PY(2) TO PY(3)
IF LO>PCLIP AND LO<YRES-PCLIP THEN
    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF

    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0

    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
END IF
XP1=XP1-XI1
XP2=XP2-XI2
NEXT




END IF

'***
'*** FLAT BOTTOMED TRIANGLE Y2 = Y3
'***

IF TFLAG=0 AND PY(2) = PY(3) THEN
   
        TFLAG=1
        XP1 = PX(1)
        XP2 = PX(1)
        XI1 = (PX(1)-PX(2)) / (PY(3) - PY(1))
        XI2 = (PX(1)-PX(3)) / (PY(3) - PY(1))
FOR LO = PY(1) TO PY(3)
IF LO>PCLIP AND LO<YRES-PCLIP THEN
    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF

    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0


    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
END IF
    XP1=XP1-XI1
    XP2=XP2-XI2

NEXT
END IF

'***
'*** FLAT TOPPED TRIANGLE Y1=Y2
'***

IF TFLAG=0 AND PY(1) = PY(2) THEN
   
        TFLAG=1
        XP1 = PX(1)
        XP2 = PX(2)
        XI1 = (PX(1)-PX(3)) / (PY(3) - PY(1))
        XI2 = (PX(2)-PX(3)) / (PY(3) - PY(2))
FOR LO = PY(1) TO PY(3)
 IF LO>PCLIP AND LO<YRES-PCLIP THEN
    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF
   
    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0
   
    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
END IF
    XP1=XP1-XI1
    XP2=XP2-XI2

NEXT
END IF
END SUB

SUB FLAT_TRIANGLE2(BYVAL X1 AS INTEGER , BYVAL Y1 AS INTEGER, BYVAL X2 AS INTEGER , BYVAL Y2 AS INTEGER , BYVAL X3 AS INTEGER, BYVAL Y3 AS INTEGER , BYVAL TC AS INTEGER)
'-------------------------------------------------------------------------
' FLAT TRIANGLE RENDERER WITH ASSEMBLY LANGUAGE RASTERISING BY SHOCKWAVE ^ DBF ^ S!P 2006.
'-------------------------------------------------------------------------
'-------------------------------------------------------------------------
' WE NEED TO SORT THESE POINTS INTO ORDER FROM TOP TO BOTTOM, AN EXCHANGE SORT IS OK.
' AS WE ONLY HAVE GOT 3 POINTS TO ARRANGE.
'-------------------------------------------------------------------------
DIM AS INTEGER TEMPX,TEMPY,LO,LI
                DIM AS INTEGER PX(3)
                DIM AS INTEGER PY(3)
                DIM TFLAG AS INTEGER
                dim pp as uinteger PTR
                DIM AS INTEGER IL1,IL2,SLICE
                TFLAG=0
        PX(1)= X1
        PX(2)= X2
        PX(3)= X3
       
        PY(1)= Y1
        PY(2)= Y2
        PY(3)= Y3
FOR LO = 1 TO 2
    FOR LI =1 TO 2     
        IF PY(LI+1) <= PY(LI) THEN
        TEMPX = PX(LI) : TEMPY = PY(LI)
        PX(LI) = PX(LI+1)
        PY(LI) = PY(LI+1)
        PX(LI+1) = TEMPX
        PY(LI+1) = TEMPY
        END IF   
    NEXT LI
NEXT LO

        DIM AS DOUBLE XP1,XP2:' SCREEN POSITIONS.
        DIM AS DOUBLE XI1,XI2:' INTERPOLATIONS.
       
'***
'*** REGULAR TRIANGLE (Y1<Y2 Y2<Y3)
'***

IF PY(1)<PY(2) AND PY(2)<PY(3) THEN
    TFLAG=1
XP1 = PX(1)
XP2 = PX(1)
XI1 = (PX(1)-PX(2)) / (PY(2) - PY(1))
XI2 = (PX(1)-PX(3)) / (PY(3) - PY(1))

FOR LO = PY(1) TO PY(2)-1
   
IF LO>PCLIP AND LO<YRES-PCLIP THEN

    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF
   
    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0

    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER2(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
   

END IF

XP1=XP1-XI1
XP2=XP2-XI2
NEXT

XI1 = (XP1-PX(3)) / (PY(3) - PY(2))

FOR LO = PY(2) TO PY(3)
IF LO>PCLIP AND LO<YRES-PCLIP THEN
    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF

    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0

    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER2(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
END IF
XP1=XP1-XI1
XP2=XP2-XI2
NEXT




END IF

'***
'*** FLAT BOTTOMED TRIANGLE Y2 = Y3
'***

IF TFLAG=0 AND PY(2) = PY(3) THEN
   
        TFLAG=1
        XP1 = PX(1)
        XP2 = PX(1)
        XI1 = (PX(1)-PX(2)) / (PY(3) - PY(1))
        XI2 = (PX(1)-PX(3)) / (PY(3) - PY(1))
FOR LO = PY(1) TO PY(3)
IF LO>PCLIP AND LO<YRES-PCLIP THEN
    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF

    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0


    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER2(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
END IF
    XP1=XP1-XI1
    XP2=XP2-XI2

NEXT
END IF

'***
'*** FLAT TOPPED TRIANGLE Y1=Y2
'***

IF TFLAG=0 AND PY(1) = PY(2) THEN
   
        TFLAG=1
        XP1 = PX(1)
        XP2 = PX(2)
        XI1 = (PX(1)-PX(3)) / (PY(3) - PY(1))
        XI2 = (PX(2)-PX(3)) / (PY(3) - PY(2))
FOR LO = PY(1) TO PY(3)
 IF LO>PCLIP AND LO<YRES-PCLIP THEN
    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF
   
    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0
   
    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER2(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
END IF
    XP1=XP1-XI1
    XP2=XP2-XI2

NEXT
END IF
END SUB

'-------------------------------------------------------------------------
' TIMER MANAGEMENT;
'-------------------------------------------------------------------------
SUB DELTA()
    DIM Z AS UINTEGER
    IF TIMER-OLDTIME>=.1 THEN
        DELTAVALUE=(3*(TICKS*1.5))+1
        NEWTIME = TICKS
        OLDTIME = TIMER
        PRINT "FPS:"+STR$(NEWTIME*10)
        TICKS =0
    END IF
END SUB

'---------------------------------------------------------
'                     Draw The Object;
'---------------------------------------------------------

SUB construct()
    DIM A
    DIM  AS DOUBLE N,RD,GR,BL

    For a=1 To faces

'---------------------------------------------------------
'              Draw A Face Of The Object;
'---------------------------------------------------------


  vx1= Vtx(Vf1(a))-Vtx(Vf2(a))
  vy1= Vty(Vf1(a))-Vty(Vf2(a))
  vx2= Vtx(Vf3(a))-Vtx(Vf2(a))
  vy2= Vty(Vf3(a))-Vty(Vf2(a))
  n=  vx1*vy2-vx2*vy1
 
If n>0 THEN

    n=(n/8000)
                        rd=Vr(a)*n : If rd>85 THEN rd=85
                        gr=Vg(a)*n : If gr>85 THEN gr=85
                        bl=Vb(a)*n : If bl>85 THEN bl=85
                        FLAT_TRIANGLE2(Vtx(Vf1(a)),Vty(Vf1(a)),Vtx(Vf2(a)),Vty(Vf2(a)),Vtx(Vf3(a)),Vty(Vf3(a)),RGB(RD,GR,BL))
                        FLAT_TRIANGLE2(Vtx(Vf1(a)),Vty(Vf1(a)),Vtx(Vf4(a)),Vty(Vf4(a)),Vtx(Vf3(a)),Vty(Vf3(a)),RGB(RD,GR,BL))
    End If
    NEXT


    For a=1 To faces

'---------------------------------------------------------
'              Draw A Face Of The Object;
'---------------------------------------------------------


  vx1= Vtx(Vf1(a))-Vtx(Vf2(a))
  vy1= Vty(Vf1(a))-Vty(Vf2(a))
  vx2= Vtx(Vf3(a))-Vtx(Vf2(a))
  vy2= Vty(Vf3(a))-Vty(Vf2(a))
  n=  vx1*vy2-vx2*vy1
 
If n<0 THEN

    n=-(n/2000)
                        rd=Vr(a)*n : If rd>150 THEN rd=170
                        gr=Vg(a)*n : If gr>150 THEN gr=170
                        bl=Vb(a)*n : If bl>150 THEN bl=170
                        FLAT_TRIANGLE(Vtx(Vf1(a)),Vty(Vf1(a)),Vtx(Vf2(a)),Vty(Vf2(a)),Vtx(Vf3(a)),Vty(Vf3(a)),RGB(RD,GR,BL))
                        FLAT_TRIANGLE(Vtx(Vf1(a)),Vty(Vf1(a)),Vtx(Vf4(a)),Vty(Vf4(a)),Vtx(Vf3(a)),Vty(Vf3(a)),RGB(RD,GR,BL))
    End If
    NEXT

END SUB


SUB ROTATE()
DIM A
DIM XCUNT AS DOUBLE
XCUNT=5*SIN(GRADD/180)
    DIM VX1 AS DOUBLE
    dim VY1 AS DOUBLE
    dim VZ1 AS DOUBLE
   
    DIM VZZ AS DOUBLE   
    dim vxx as double
    dim vyy as double
   
    DIM VDV AS DOUBLE

'###############################################
'## Rotate And Scale Each Point! Store Result ##
'###############################################
 For a=1 To points

    VX1=Vx(a)+XCUNT
    VY1=Vy(a)
    VZ1=Vz(a)
   
'######################
'## X,Y,Z rotations! ##
'######################
  Vxx=Vx1
  Vyy=Vy1*cos(Vxr)+Vz1*sin(Vxr)
  Vzz=Vz1*cos(Vxr)-Vy1*sin(Vxr)
 
  Vy1=Vyy
  Vx1=Vxx*cos(Vyr)-Vzz*sin(Vyr)
  Vz1=Vxx*sin(Vyr)+Vzz*cos(Vyr)
 
  Vzz=Vz1
  Vxx=Vx1*cos(Vzr)-Vy1*sin(Vzr)
  Vyy=Vx1*sin(Vzr)+Vy1*cos(Vzr)
'########################
'## Apply Perspective! ##
'########################
  Vdv=(Vzz/40)+1

  Vxx=(size*(Vxx/Vdv))+HALFX
  Vyy=(size*(Vyy/Vdv))+HALFY
  Vtx(a)=Int(Vxx)
  Vty(a)=Int(Vyy)
  Vtz(a)=Int(Vzz)
 
 Next
        Vxr=Vxr+1/DELTAVALUE
        Vyr=Vyr+1/DELTAVALUE
        Vzr=Vzr+1/DELTAVALUE
       
       
END SUB



'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
'   The Object Description As Data!
'   The Data Below Describes A Cube.
'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

'Points definition;
'~~~~~~~~~~~~~~~~~~
'Below are the points of the Object defined as x,y,z;

Data 5,-5,-5,5,5,-5,-5,5,-5,-5,-5,-5,0,0,-8,8,0,0,0
Data 8,0,-8,0,0,0,-8,0,5,-5,5,5,5,5,-5,5,5,-5,-5,5,0,0,8


'Connection definition;
'Below are the faces of the Object defined as vertice
'numbers, specified in clockwise order. These are followed
'by r,g,b values For the face And finally cell shaded
'parameter (0)=off (1)=on.

Data 10,9,13,13,5,1,1


Data 14,10,13,13,4,4,4
Data 14,13,12,12,1,5,1
Data 8,12,13,13,4,4,4
Data 4,8,13,13,1,1,5
Data 10,14,11,11,1,5,1
Data 10,11,6,6,4,4,4
Data 4,13,9,9,4,4,4

Data 1,4,9,9,5,1,1

Data 1,9,10,10,4,4,4

Data 6,1,10,10,5,0,5
Data 5,4,1,1,4,4,4
Data 8,4,3,3,4,4,4
Data 3,12,8,8,2,2,5
Data 3,4,5,5,0,5,5
Data 7,12,3,3,4,4,4
Data 14,12,11,11,4,4,4
Data 11,12,7,7,5,5,0
Data 6,11,2,2,5,0,5
Data 11,7,2,2,4,4,4
Data 1,6,2,2,4,4,4
Data 2,5,1,1,0,5,5
Data 2,7,3,3,5,5,0
Data 2,3,5,5,4,4,4

'===============================================================================
'                                     ***END***
'===============================================================================
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Phoenix

  • C= 64
  • **
  • Posts: 99
  • Karma: 4
    • View Profile
Re: Triangle Rasteriser (with asm)
« Reply #13 on: September 03, 2006 »
That's completely awesome Shocky! Keep up the good work!

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Triangle Rasteriser (with asm)
« Reply #14 on: September 03, 2006 »
Cheers Phoenix :)
Hopefully when it's finished it will have a few more effects, as this is going to be my first intro for Surprise Productions I'd like to do a good job but I want to keep the oldschool feel too.
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Tetra

  • DBF Aficionado
  • ******
  • Posts: 2532
  • Karma: 83
  • Pirate Monkey!
    • View Profile
Re: Triangle Rasteriser (with asm)
« Reply #15 on: September 05, 2006 »
Great stuff, nice to see new ways of doing Triangle Rasteriser.  O0
 :||
Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Triangle Rasteriser (with asm)
« Reply #16 on: September 05, 2006 »
Takes us back to before when we were all talking about triangle rasterisers and when you were learning how to make your first gourad routine eh Tetra? You've moved forward and I'm still coding flatshaders :) Heheh. Tbh, I am very happy with this flatshader esp after I've implimented Jims bug fixes.
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: Triangle Rasteriser (with asm)
« Reply #17 on: September 06, 2006 »
Nice work Shockwave, I think there might be another slight problem with the clipping. The max values should be XRES-1 and YRES-1.

It's possible to take some things out of the loop too, in this:

Code: [Select]
FOR LO = PY(2) TO PY(3)
IF LO>PCLIP AND LO<YRES-PCLIP THEN
    IF XP1<=XP2 THEN
        IL1=XP1
        IL2=XP2
    ELSE
        IL1=XP2
        IL2=XP1
    END IF

    IF IL2>XRES THEN IL2=XRES
    IF IL1>XRES THEN IL1=XRES
    IF IL2<0 THEN IL2=0
    IF IL1<0 THEN IL1=0

    SLICE = IL2-IL1
    IF SLICE>0 THEN
    PP = @BUFFER(IL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
END IF
XP1=XP1-XI1
XP2=XP2-XI2
NEXT

You could try something like this although ive not tested it and you'd probably have to mess around a bit to get it working.

Code: [Select]
'clip top and bottom of tri
y_start=PY(2)
y_end=PY(3)
if y_start<PCLIP then y_start=PCLIP
if y_end>(YRES-PCLIP) then y_end=YRES-PCLIP

'swap the gradients of each side if they're the wrong way round so not having to do a swap for every scanline
if XI1>XI2 then
    temp=XI1
    XI1=XI2
    XI2=temp
end if

'if top is clipped then find the start and end of the scanlines at the point of clipping
dy=y_start-PY(2)
XP1+=XI1*dy
XP2+=XI2*dy

FOR LO = ystart TO yend

'you can do away with 2 of the tests here as the "IF SLICE>0 THEN" line will take care of that
    IF XL2>=XRES THEN IL2=XRES-1
'    IF XL1>=XRES THEN IL1=XRES-1
'    IF XL2<0 THEN XL2=0
    IF XL1<0 THEN XL1=0

    SLICE = XL2-XL1
    IF SLICE>0 THEN
    PP = @BUFFER(XL1+(LO*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    END IF
XP1=XP1-XI1
XP2=XP2-XI2
NEXT


Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Triangle Rasteriser (with asm)
« Reply #18 on: September 07, 2006 »
I think XRES is right.  Since he draws R-L pixels, so if L=0 and R=640 then it's 640-0 pixels drawn.  I checked it the other day and it looked OK.
I think YRES-1 is right though.  The for loop goes for y=0 to 480 and in freebasic that's 481 iterations, 1 too many.

Jim
Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Triangle Rasteriser (with asm)
« Reply #19 on: September 07, 2006 »
Thanks for the optimisations Stonemonkey :) and cheers for sorting the clipping bug both.
I'll be sure to post the fixed version for everyone who wants to use it as soon as I've fixed it.
Shockwave ^ Codigos
Challenge Trophies Won: