Code: Select all
' ------ aadot 2017 Aug 13 - by dafhi
'
' calculation without sqr() in 2 zones:
' 1. blit corners
' 2. dot center max brightness)
' ------------------------------------
' ---------------
type imagevars '2017 July 3 - by dafhi
'1. quick reference for ScreenInfo & ImageInfo
'2. encapsulate standard metrics
'3. useful additional vars, subs
as integer w,h, bpp,bypp,pitch, rate
as string driver_name
as any ptr im
as any ptr pixels '' same address
as ulong ptr p32 ''
as single midx,midy
as integer pitchBy, wm = -1, hm = -1, ub = -1, is_screen
declare sub screen_init(w as integer=0, h as integer=0, bpp as integer=32, npages as integer=1, flags as integer=0)
declare sub create(w as integer=0, h as integer=0, col as ulong=&HFF000000)
declare sub get_info(im as any ptr=0)
declare destructor
private:
declare sub destroy
declare sub release
as any ptr hRelease
end type
Destructor.imagevars: release
End Destructor
sub imagevars.release '2016 Aug 30
w=0: h=0: bpp=0: bypp=0: im=0: pixels=0
If ImageInfo(hRelease) = 0 Then ImageDestroy hRelease: hRelease = 0
End Sub
sub imagevars.get_info(im as any ptr)
if im=0 then
ScreenInfo w,h, bpp, bypp, pitch, rate, driver_name: pixels=screenptr
is_screen = -1: im=0
elseif Imageinfo(im)=0 then
ImageInfo im, w, h, bypp, pitch, pixels: bpp = bypp * 8
this.im = im: is_screen = 0
endif: hRelease = im: p32=pixels
wm=w-1: midx=w/2: pitchBy=pitch/bypp '' crashes if \ and bypp = 0
hm=h-1: midy=h/2: ub = h*pitchBy - 1
end sub
sub imagevars.screen_init(w as integer, h as integer, bpp as integer, npages as integer, flags as integer)
release '2017 July 3
if w=0 or h=0 then get_info: w=this.w: h=this.h
screenres w,h,bpp,npages,flags: pixels = screenptr
get_info: if npages > 1 then screenset 0,1
end sub
sub imagevars.create(_w as integer, _h as integer, col as ulong)
release: get_info imagecreate(_w,_h,col)
End Sub
#Macro Alpha256(ret,back, fore, a256) '2017 Mar 26
ret=((_
(fore And &Hff00ff) * a256 + _
(back And &Hff00ff) * (256-a256) + &H800080) And &Hff00ff00 Or (_
(fore And &H00ff00) * a256 + _
(back And &H00ff00) * (256-a256) + &H008000) And &H00ff0000) Shr 8
#EndMacro
' ---------------------
'
type dotvars
as ulong col=-1
as single rad=1,slope=1
End Type
type AaDot
as dotvars o
as dotvars ptr p
declare sub render_target(byref buf as imagevars)
declare sub draw(x as single=0, y as single=0)
declare constructor
private:
as single dy,dxLeft,salpha,cone_h,coneSq,sq
as long x0,y0,x1,y1,alph,alpha_max
as imagevars ptr pim
end type
constructor.AaDot: p=@o
end constructor
sub AaDot.render_target(byref buf as imagevars)
pim = @buf
end sub
sub AaDot.draw(x as single, y as single)
salpha=(p->col shr 24)/255: alpha_max=salpha*256
var slope = p->slope
'slope = 1 .. 1 pixel aa edge
'slope = 2 .. 1/2 pixel (sharp)
'slope = 1/p->rad .. max blur
'slope < 1/p->rad .. rendering artifact
sq=1/p->rad '' clamp prevents artifact
slope=iif(slope<sq,sq,slope) ''
cone_h=slope*p->rad 'pre-inverted aadot imagined as side-viewed cone \/
coneSq=cone_h*cone_h 'avoid sqr() at blit corners
sq=(cone_h-1)*(cone_h-1)'avoid sqr() in dot center at max brightness
dim as long x0=x-p->rad: if x0<0 then x0=0
dim as long y0=y-p->rad: if y0<0 then y0=0
dim as long x1=x+p->rad: if x1>pim->wm then x1=pim->wm
dim as long y1=y+p->rad: if y1>pim->hm then y1=pim->hm
dy=(y0-y)*slope: dxLeft=(x0-x)*slope
for py as long ptr = @pim->p32[ y0*pim->pitchBy ] to @pim->p32[ y1*pim->pitchBy ] step pim->pitchBy
dim as single dx=dxleft, dySq=dy*dy
for px as ulong ptr = @py[x0] to @py[x1]
salpha = dx*dx+dySq
if salpha<sq then
Alpha256(*px,*px,p->col,alpha_max)
elseif salpha<=coneSq then
alph=(cone_h-sqr(salpha))*alpha_max
Alpha256(*px,*px,p->col,alph)
endif: dx+=slope
next: dy+=slope
next
end sub
sub Main
dim as imagevars buf
dim as aadot dot: dot.render_target buf
const GFX_FLAG_BORDERLESS = 8
buf.get_info: var scalar = 1 / 1.5
buf.screen_init buf.w*scalar, buf.h*scalar,,, GFX_FLAG_BORDERLESS '' no border
var t0=timer
do
#define r8 int(rnd*256)
for i as long = 1 to 2
dot.o.col = rgba(r8,r8,r8,r8)
dot.o.rad = 2+rnd*50
dot.o.slope = (1+5*rnd)/dot.o.rad
dot.draw rnd*buf.w, rnd*buf.h
screenlock
screenunlock
next
sleep 1
dim as string kstr = inkey
if kstr = chr(27) or timer-t0 > 5 then exit do
loop
? "demo finished. will now exit.."
sleep 2000
end sub
Main