#include "fbgfx.bi"
randomize timer
screenres 320,240,32
dim as FB.IMAGE ptr tbuffer = imagecreate(320,240)
type vec2f
as single x, y
end type
declare sub triangle_new( byref dst as fb.image ptr = 0, byref v1 as vec2f, byref v2 as vec2f, byref v3 as vec2f, byref colour as uinteger )
declare sub triangle_asm( byref dst as fb.image ptr = 0, byref v1 as vec2f, byref v2 as vec2f, byref v3 as vec2f, byval col as uinteger )
declare sub triangle_old( byref dst as fb.image ptr = 0, byref v1 as vec2f, byref v2 as vec2f, byref v3 as vec2f, byref colour as uinteger )
dim as integer mode = 1
dim as double ttime, ltime
dim as string fps_string
dim as integer fps
ttime = timer
do
ttime = timer
if ttime > ltime then
fps_string = "FPS " & fps
fps = 0
ltime = ttime+1
end if
fps+=1
if multikey(FB.SC_SPACE) then
mode +=1
if mode>3 then mode = 1
sleep 100,1
end if
screenlock
cls
if mode = 1 then
for x as integer = 0 to 500
triangle_new( 0, type(rnd*320,rnd*240), type(rnd*320,rnd*240), type(rnd*320,rnd*240), rgb( rnd*255, rnd*255, rnd*255) )
next
locate 1,1
print "new(integer) algo"
elseif mode = 2 then
for x as integer = 0 to 500
triangle_asm( 0, type(rnd*320,rnd*240), type(rnd*320,rnd*240), type(rnd*320,rnd*240), rgb( rnd*255, rnd*255, rnd*255) )
next
locate 1,1
print "asm(fpu) algo"
elseif mode = 3 then
for x as integer = 0 to 500
triangle_old( 0, type(rnd*320,rnd*240), type(rnd*320,rnd*240), type(rnd*320,rnd*240), rgb( rnd*255, rnd*255, rnd*255) )
next
locate 1,1
print "old fb(fpu) algo"
end if
print fps_String
screenunlock
sleep 1,1
loop until multikey(FB.SC_ESCAPE)
function min( byval a as integer, byval b as integer, byval c as integer ) as integer
if b<a then
swap a, b
end if
if c<a then
swap a, c
end if
return a
end function
function max( byval a as integer, byval b as integer, byval c as integer ) as integer
if c>b then
swap b, c
end if
if b>a then
swap a, b
end if
return a
end function
sub triangle_new( byref dst as fb.image ptr = 0, byref v1 as vec2f, byref v2 as vec2f, byref v3 as vec2f, byref colour as uinteger )
dim as uinteger ptr dptr
dim as integer tw
dim as integer th
if dst = 0 then
dptr = screenptr
screeninfo tw, th
else
dptr = cast(uinteger ptr, dst + 1 )
tw = dst->width
th = dst->height
end if
dim as integer y1 = cint(v1.y)*16
dim as integer y2 = cint(v2.y)*16
dim as integer y3 = cint(v3.y)*16
dim as integer x1 = cint(v1.x)*16
dim as integer x2 = cint(v2.x)*16
dim as integer x3 = cint(v3.x)*16
dim as integer DX12 = X1 - X2
dim as integer DX23 = X2 - X3
dim as integer DX31 = X3 - X1
dim as integer DY12 = Y1 - Y2
dim as integer DY23 = Y2 - Y3
dim as integer DY31 = Y3 - Y1
dim as integer FDX12 = DX12 shl 4
dim as integer FDX23 = DX23 shl 4
dim as integer FDX31 = DX31 shl 4
dim as integer FDY12 = DY12 shl 4
dim as integer FDY23 = DY23 shl 4
dim as integer FDY31 = DY31 shl 4
dim as integer minx
dim as integer maxx
dim as integer miny
dim as integer maxy
minx = (min( x1, x2, x3) +&hf) shr 4
miny = (min( y1, y2, y3) +&hf) shr 4
maxx = (max( x1, x2, x3) +&hf) shr 4
maxy = (max( y1, y2, y3) +&hf) shr 4
dim as integer q = 16
minx and = not(q-1)
miny and = not(q-1)
dim as integer C1 = DY12 * X1 - DX12 * Y1
dim as integer C2 = DY23 * X2 - DX23 * Y2
dim as integer C3 = DY31 * X3 - DX31 * Y3
if DY12 < 0 orelse (DY12 = 0 andalso DX12) > 0 then
C1+=1
end if
if DY23 < 0 orelse (DY23 = 0 andalso DX23) > 0 then
C2+=1
end if
if DY31 < 0 orelse (DY31 = 0 andalso DX31) > 0 then
C3+=1
end if
for y as integer = miny to maxy-1 step q
for x as integer = minx to maxx-1 step q
dim as integer x0 = x shl 4
dim as integer x1 = (x + q - 1) shl 4
dim as integer y0 = y shl 4
dim as integer y1 = (y + q - 1) shl 4
dim as integer a00 = -(C1 + DX12 * y0 - DY12 * x0 > 0)
dim as integer a10 = -(C1 + DX12 * y0 - DY12 * x1 > 0)
dim as integer a01 = -(C1 + DX12 * y1 - DY12 * x0 > 0)
dim as integer a11 = -(C1 + DX12 * y1 - DY12 * x1 > 0)
dim as integer a = (a00 shl 0) or (a10 shl 1) or (a01 shl 2) or (a11 shl 3)
dim as integer b00 = -(C2 + DX23 * y0 - DY23 * x0 > 0)
dim as integer b10 = -(C2 + DX23 * y0 - DY23 * x1 > 0)
dim as integer b01 = -(C2 + DX23 * y1 - DY23 * x0 > 0)
dim as integer b11 = -(C2 + DX23 * y1 - DY23 * x1 > 0)
dim as integer b = (b00 shl 0) or (b10 shl 1) or (b01 shl 2) or (b11 shl 3)
dim as integer c00 = -(C3 + DX31 * y0 - DY31 * x0 > 0)
dim as integer c10 = -(C3 + DX31 * y0 - DY31 * x1 > 0)
dim as integer c01 = -(C3 + DX31 * y1 - DY31 * x0 > 0)
dim as integer c11 = -(C3 + DX31 * y1 - DY31 * x1 > 0)
dim as integer c = (c00 shl 0) or (c10 shl 1) or (c01 shl 2) or (c11 shl 3)
if a = &h0 orelse b = &h0 orelse c = &h0 then
goto skipiteration
end if
if a = &h0 and b = &h0 and c = &h0 then
for iy as integer = 0 to q-1
for ix as integer = x to (x+q)-1
dptr[iy*tw+ix] = colour
next
next
else
dim as integer CY1 = C1 + DX12 * y0 - DY12 * x0
dim as integer CY2 = C2 + DX23 * y0 - DY23 * x0
dim as integer CY3 = C3 + DX31 * y0 - DY31 * x0
for iy as integer = y to (y+q)-1
dim as integer CX1 = CY1
dim as integer CX2 = CY2
dim as integer CX3 = CY3
for ix as integer = x to (x+q)-1
if CX1 > 0 and CX2 > 0 and CX3 > 0 then
dptr[iy*tw+ix] = colour
end if
CX1 -= FDY12
CX2 -= FDY23
CX3 -= FDY31
next
CY1 += FDX12
CY2 += FDX23
CY3 += FDX31
next
end if
skipiteration:
next x
next y
end sub
sub triangle_asm( byref dst as fb.image ptr = 0, byref v1 as vec2f, byref v2 as vec2f, byref v3 as vec2f, byval col as uinteger )
dim as any ptr dstptr
dim as integer dw, dh, dp
if dst = 0 then
dstptr = screenptr
screeninfo dw,dh
dp = dw * 4
else
dstptr = cast( any ptr, dst + 1 )
dw = dst->width
dh = dst->height
dp = dst->pitch
end if
dim as single x1 = v1.x
dim as single x2 = v2.x
dim as single x3 = v3.x
dim as single y1 = v1.y
dim as single y2 = v2.y
dim as single y3 = v3.y
if y2 < y1 then
swap y1, y2
swap x1, x2
end if
if y3 < y1 then
swap y3, y1
swap x3, x1
end if
if y3 < y2 then
swap y3, y2
swap x3, x2
end if
dim as single d1, d2, d3
scope
dim as integer dx1, dy1
dx1 = x2 - x1
dy1 = y2 - y1
if dy1 <> 0 then
d1 = dx1 / dy1
else
d1 = 0
end if
end scope
scope
dim as integer dx2, dy2
dx2 = x3 - x2
dy2 = y3 - y2
if dy2 <> 0 then
d2 = dx2 / dy2
else
d2 = 0
end if
end scope
scope
dim as integer dx3, dy3
dx3 = x1 - x3
dy3 = y1 - y3
if dy3 <> 0 then
d3 = dx3 / dy3
else
d3 = 0
end if
end scope
dim as single lx, rx
lx = x1
rx = x1
dim as single lx_incr = any
dim as single rx_incr = any
dim as integer y_start = any
dim as integer y_end = any
for t as integer = 0 to 1
if t = 0 then
lx_incr = d1
rx_incr = d3
y_start = y1
y_end = y2 - 1
else
lx_incr = d2
rx_incr = d3
y_start = y2
y_end = y3
lx = x2
end if
dim as any ptr __dstptr = dstptr + (y_start * dp)
if y_end >= dh then y_end = dh - 1
dim as integer y_draw_count = (y_end - y_start) + 1
if y_draw_count > 0 then
dim as integer y = any
asm
mov edx, dword ptr [y_draw_count]
mov eax, dword ptr [y_start]
mov dword ptr [y], eax
fld dword ptr [lx_incr]
fld dword ptr [rx_incr]
fld dword ptr [lx]
fld dword ptr [rx]
y_inner:
cmp dword ptr [y], -1
jle no_x_draw
sub esp, 4
fld st(1)
fistp dword ptr [esp]
mov esi, dword ptr [esp]
fist dword ptr [esp]
mov edi, dword ptr [esp]
add esp, 4
cmp esi, edi
jle no_swap
mov eax, esi
mov esi, edi
mov edi, eax
no_swap:
cmp esi, 0
jge no_clip_start_x
mov esi, 0
no_clip_start_x:
mov eax, dword ptr [dw]
cmp edi, eax
jl no_clip_end_x
dec eax
mov edi, eax
no_clip_end_x:
mov ebx, esi
shl ebx, 2
add ebx, dword ptr [__dstptr]
mov ecx, edi
sub ecx, esi
mov eax, dword ptr [col]
inc ecx
jle no_x_draw
x_inner:
mov dword ptr [ebx], eax
add ebx, 4
dec ecx
jnz x_inner
no_x_draw:
fld st(3)
faddp st(2), st(0)
fadd st(2)
mov eax, dword ptr [dp]
add dword ptr [__dstptr], eax
inc dword ptr [y]
y_test:
dec edx
jnz y_inner
fstp dword ptr [rx]
fstp dword ptr [lx]
emms
end asm
end if
next t
end sub
sub triangle_old( byref dst as fb.image ptr = 0, byref v1 as vec2f, byref v2 as vec2f, byref v3 as vec2f, byref col as uinteger )
dim as uinteger ptr dstptr
dim as integer x, y, dw, dh, dbpp, dp
dim as integer dx1, dx2, dx3, dy1, dy2, dy3, sx, ex
dim as single d1, d2, d3, lx, rx
dim as integer x1 = v1.x
dim as integer x2 = v2.x
dim as integer x3 = v3.x
dim as integer y1 = v1.y
dim as integer y2 = v2.y
dim as integer y3 = v3.y
if dst = 0 then
dstptr = screenptr
screeninfo dw,dh,,dbpp, dp
else
dstptr = cast( uinteger ptr, dst +1)
dw = dst->width
dh = dst->height
dp = dst->pitch
dbpp = dst->bpp
end if
if y2 < y1 then
swap y1, y2
swap x1, x2
end if
if y3 < y1 then
swap y3, y1
swap x3, x1
end if
if y3 < y2 then
swap y3, y2
swap x3, x2
end if
dx1 = x2 - x1
dy1 = y2 - y1
if dy1 <> 0 then
d1 = dx1 / dy1
else
d1 = 0
end if
dx2 = x3 - x2
dy2 = y3 - y2
if dy2 <> 0 then
d2 = dx2 / dy2
else
d2 = 0
end if
dx3 = x1 - x3
dy3 = y1 - y3
if dy3 <> 0 then
d3 = dx3 / dy3
else
d3 = 0
end if
lx = x1
rx = x1
for y = y1 to y2 - 1
if y>-1 and y<dh then
sx = lx
ex = rx
if sx>ex then swap sx,ex
if sx<0 then sx = 0
if ex>dw-1 then ex=dw-1
for x = sx to ex
*cast(uinteger ptr, cast(ubyte ptr, dstptr) + y * dp + x * dbpp) = col
next
end if
lx += d1
rx += d3
next
lx = x2
for y = y2 to y3
if y>-1 and y<dh then
sx = lx
ex = rx
if sx>ex then swap sx,ex
if sx<0 then sx = 0
if ex>dw-1 then ex=dw-1
for x = sx to ex
*cast(uinteger ptr, cast(ubyte ptr, dstptr) + y * dp + x * dbpp) = col
next
end if
lx += d2
rx += d3
next
end sub