Author Topic: Triangle Rasteriser (with asm)  (Read 9919 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
Re: Triangle Rasteriser (with asm)
« Reply #20 on: September 07, 2006 »
I've implimented some (but not quite all) of the fixes. The code has been shrunk, some if thens have been ditched and a slight clipping bug fixed, also interpolation bug at the bottom of the triangle has been mended.

Thanks to Jim and Stonemonkey, here's the source with example. Feel free to use it;

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


    OLDTIME = TIMER
DO
    GADD=GADD+.002
    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)
    GADD=GADD+10
    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),&HFF88F55)
    GADD=GADD-10
    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) or (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<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 = (PX(2)-PX(3)) / (PY(3) - PY(2))
XP1 = PX(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<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<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: