over time I've collected, what I consider *essentials* to work with FB's GFX-lib.
I've made it all, into an easy to include .bi file, which I want to share here.
Sources, other than my own stuff, are noted, however, limited to my memory.
(if I've made any mistakes, in quoting sources, please let me know ...)
Contains:
- constants: PI (Π), PI2 (double Π), GolderRatio -- others are used by macro's
- all Macro's are *single line*, aka: #Define (not listed, quite a few)
- two Function's: Contrast(), CContrast()
- updated: 2018-04-12 (added single alpha-/color-channel getters/setters)
Code: Select all
' GFX_MATH.bi -- mathematics for fbGFX (Singles only) -- 2016/18, MrSwiss
'
' update : 2017-05-06 changed: added Smap (renamed map to Imap)
' last update: 2018-04-11/12changed: added color-channel getters/setters
'
' some math const(s) + macro(s) + conrast Func's -- #Define = single line macro
'
' forum: https://www.freebasic.net/forum/viewtopic.php?f=7&t=25635&p=231423
#Ifndef __GFX_MATH_BI__
#Define __GFX_MATH_BI__
' from: FB-manual (maybe: Forum??)
Const As Single PI = Atn( 1f ) * 4f ' semi-circle, in RADians
Const As Single PI2 = Atn( 1f ) * 8f ' full-circle, RAD
' original, by bluatigro (I assume)
Const As Single GoldenRatio = ( Sqr(5f) - 1f ) / 2f
' original, by FB-manual
Const As Single D2R = pi / 180f ' conversion factor, DEG --> RAD
Const As Single R2D = 180f / pi ' conversion factor, RAD --> DEG
' original, by MrSwiss (I don't want to have to remember the Const's names!)
#Define RAD(d) ( CSng(d * D2R) ) ' conversion macro, DEG --> RAD
#Define DEG(r) ( CSng(r * R2D) ) ' conversion macro, RAD --> DEG
Randomize(Timer, 3) ' seed for Rnd(), Mersenne Twister (FB-default)
' original, by dodicat, modified for returning defined variable type, by MrSwiss
#Define LRange(l, h) ( CLng(Rnd() * (h - l) + l) ) ' general use, Long (32bit)
#Define LIRange(l, h) ( CLngInt(Rnd() * (h - l) + l) )' general use, LongInt (64bit)
#Define IRange(l, h) ( CInt(Rnd() * (h - l) + l) ) ' general use, Integer (FBC-bitness)
#Define SRange(l, h) ( CSng(Rnd() * (h - l) + l) ) ' general use, Single (GFX-Float, 32bit)
' original, by dodicat modified: MrSwiss (removed brackets around var's), added brackets _
#define Imap(a,b,x,c,d) ( (d - c) * (x - a) \ (b - a) + c ) ' around 'whole body' (readability)
#define Smap(a,b,x,c,d) ( (d - c) * (x - a) / (b - a) + c )
' -- all Color stuff, original, by MrSwiss --
#Define ClrRng(l, h) ( CULng(Rnd() * (h - l) + l) ) ' Color, aka: ULong
' random Color RGB range, ULong (full alpha, always)
#Define RndRGB ( CULng(Rnd() * &hFFFFFF + &hFF000000ul) )
' random Color ARGB range, ULong (random Alpha & Color)
#Define RndARGB ( CULng(Rnd() * &hFFFFFFFFul) )
' color inverter, not touching/changing of Alpha-Chan.
#Define InvClr(c) ( CULng(c Xor &h00FFFFFF) )
' color inverter, incl. Alpha
#Define InvAClr(c) ( CULng(c Xor &hFFFFFFFFul) )
' 2018-04-12, function like MACRO's (getters) for alpha-/color-channel's values (UByte, from 32-bit color)
#Define ga_ch(c) ( CULng(c) Shr 24 And 255 ) ' get alpha-channel
#Define gr_ch(c) ( CULng(c) Shr 16 And 255 ) ' get red-channel
#Define gg_ch(c) ( CULng(c) Shr 8 And 255 ) ' get green-channel
#Define gb_ch(c) ( CULng(c) And 255 ) ' get blue-channel
' 2018-04-11, function like MACRO's (setters) for alpha-/color-channel's (32-bit color, ULong)
#Define sa_ch(c,a) ( CULng(c) + ((a And 255) Shl 24) ) ' set alpha-channel
#Define sr_ch(c,r) ( CULng(c) + ((r And 255) Shl 16) ) ' set red-channel
#Define sg_ch(c,g) ( CULng(c) + ((g And 255) Shl 8) ) ' set green-channel
#Define sb_ch(c,b) ( CULng(c) + (b And 255) ) ' set blue-channel
' 2017-04-28, by MrSwiss (simplified version, of below Function: CContrast())
' reason: with CContrast() and, many diff. colors, it's too quickly Carnival-like!
Function Contrast ( ByVal cin As ULong _ ' param: 'in' ARGB-Color
) As ULong ' result: ARGB-Color (black or white)
' if NOT full alpha --> set it to full alpha (for easy evaluation)
If CPtr(UByte Ptr, @cin)[3] < 255 Then CPtr(UByte Ptr, @cin)[3] = 255
' bright half of RGB range --> return black
If cin > &hFF7F7F7F Then Return &hFF000000ul
' dark half of RGB range --> return white
Return &hFFFFFFFFul
End Function
' make one random colour over another different: original by dodicat, recoded: _
' 2017-04-28, by MrSwiss -- reason: more efficient code & independent of macro's
Function CContrast( ByVal cin As ULong _ ' param: 'in' ARGB-Color
) As ULong ' result: ARGB-Color
Dim As UByte a = CPtr(Ubyte Ptr, @cin)[3], _ ' save curr. alpha-chan
r = CPtr(Ubyte Ptr, @cin)[2], _ ' save curr. red-chan
g = CPtr(Ubyte Ptr, @cin)[1], _ ' save curr. green-chan
b = CPtr(Ubyte Ptr, @cin)[0], _ ' save curr. blue-chan
r2, g2, b2 ' temp. var's (uninit)
Dim As Boolean rf, gf, bf ' color channels flags
' minimal required difference from original: 127 / &h7F (aka: 50% of range)
While Not rf ' run's only: until new red val found
r2 = CUByte(Rnd() * 255) : If Abs(r - r2) > 126 Then rf = TRUE
Wend
While Not gf ' run's only: until new green val found
g2 = CUByte(Rnd() * 255) : If Abs(g - g2) > 126 Then gf = TRUE
Wend
While Not bf ' run's only: until new blue val found
b2 = CUByte(Rnd() * 255) : If Abs(b - b2) > 126 Then bf = TRUE
Wend
' got them all: return result
Return RGBA(r2, g2, b2, a) ' leave alpha unchanged (use saved original)
End Function
#EndIf ' __GFX_MATH_BI__
Code: Select all
' Demo1_GFX_MATH_bi.bas -- 2017-05-02, by MrSwiss
' last update: 2017-05-02 changed: nothing yet
' compile with: -s GUI
#Include "GFX_MATH.bi" ' see: https://freebasic.net/forum/viewtopic.php?f=7&t=25635
#Include Once "Grid.bas" ' see: https://freebasic.net/forum/viewtopic.php?f=7&t=24997
' NOTE: if only RGB() is used with GFX_ALPHA_PRIMITIVES, nothing is shown (alpha = 0)
Dim As ULong c1 = RGBA(255, 0, 0, 191), _ ' red 3/4 alpha = 1/4 transparent
c2 = RGBA(127, 127, 127, 255), _ ' grey 100% alpha = opaque (0% trans)
c3 = RGBA( 0, 0, 255, 191) ' blue (as red)
' for program execution control
Dim As Boolean quit = FALSE, sw = TRUE ' flags
' ===== MAIN =====
ScreenRes(641, 641, 32, 2, 64) ' GFX_ALPHA_PRIMITIVES = &h40 / 64 dec; double buffer
'Randomize(Timer, 3) ' seed for RND(), set in GFX_MATH.bi
c2 = RGBA(255, 255, 255, 255) ' redefine c2 to: white / opaque
Do
' cell size 68 (square), border 48 = cells: h/v = 8/8 (aka: chessboard)
Grid(640, 640, 68, 48,, c2) ' grid color = c2 (default = medium-gray)
For j As UInteger = 1 To 8 ' rows (cells vertical)
Var y = j * 68 + 24 ' calc. injection point y (paint, aka: flood-fill)
For i As UInteger = 1 To 8 ' columns (cells horizontal)
Var x = i * 68 + 24 ' calc. injection point x (paint)
If sw Then
Paint (x, y), ClrRng(&h7F7F7F7F, &hFFFFFFFF), c2 ' in GFX_MATH.bi
Else
' random color RGB range only (100% alpha always)
Paint (x, y), RndRGB, c2 ' in GFX_MATH.bi
EndIf
Next
If Len(InKey()) Then quit = TRUE : Exit For ' exit outer For loop (only)
sw = Not sw ' change macro used, every new row
Next
Flip
If quit Then Exit Do
Sleep 1500, 1 : Cls
Loop
' ===== END-MAIN ===== ' ----- EOF -----
Code: Select all
' GFX_MATH_Test2.bas -- 2017-05-06, by MrSwiss
' last update: 2017-05-06 changed: ---
' compile with: -s GUI
#Include Once "GFX_MATH.bi" ' see: https://freebasic.net/forum/viewtopic.php?f=7&p=231423#p231423
' for program execution control
Dim As Boolean quit = FALSE ' flag(s)
' ===== MAIN =====
ScreenRes(641, 641, 32, 2, 64) ' GFX_ALPHA_PRIMITIVES = &h40 / 64 dec; double buffer
Do
For j As UInteger = 0 To 10 ' rows (steps vertical)
Var y = j * 55 ' calc. y-axis pos.
For i As UInteger = 0 To 10 ' columns (steps horizontal)
Var x = i * 55 ' calc. x-axis pos.
Var h = IRange(25, 85) ' get a random height between 25 and 85
Var w = IRange(35, 150) ' get a random width between 35 and 150
Line (x, y)-Step(w, h), RndARGB, BF ' random color full ARGB range
Next
If Len(InKey()) Then quit = TRUE : Exit For ' exit outer For loop (only)
Next
Flip
If quit Then Exit Do ' end prog. (if quit = TRUE)
Sleep 1000, 1 : Cls ' give user some time, to 'look at it'
Loop
' ===== END-MAIN ===== ' ----- EOF -----