Color by Percent (static lib) 32/64bit (pure FB-code)

Headers, Bindings, Libraries for use with FreeBASIC, Please include example of use to help ensure they are tested and usable.
Post Reply
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Color by Percent (static lib) 32/64bit (pure FB-code)

Post by MrSwiss »

Hi all,

this is an attempt to simplify the *workings* with Color (24/32 bit) especially, with what I call:
Color-Channels (the separate UBytes contained in a ULong = *aarrggbb* in HEX).

The range of: 0 to 255 (UByte range) seems to be confusing to some. Mainly to find the correct
math. to go with it (from within: e.g. a loop or similar). This then may go as far, as a program-
crash (worst case scenario) or simply, not work *as expected*.

The idea behind it is really simple:
  • reduce the range to: 0 to 100 (percent, being familiar to all)
  • put a range check into all the setters (crash prevention!)
  • making it as fast as possible (more detail on that below)
  • compatible with all of FBC 32/64, independent of OS used
Speed issues, where addressed as follows:
  • on multiple set/get and *programmable* single set/get a Union is used
  • to get the math. out of Sub's/Function's: *LUT's are used
  • on single channel set/get as well as GBR_RGB, Pointer access used
*LUT = look up table (containing: pre-calculated values) filled at start-up (once).

Let's start with the include file (aka: .bi):

Code: Select all

' ColorLUTbyPercent.bi -- 2017-04-30, by MrSwiss
' last update: 2017-04-30   changed: nothing yet

#Ifndef __ColorLUTbyPercent__
#Define __ColorLUTbyPercent__

' FB to WIN: red/blue swap / WIN to FB blue/red swap, works both ways!
Declare Function BGR_RGB    ( ByVal As ULong ) As ULong ' for 24/32bit color only!
' multi channel: setters/getters ... using Union access
Declare Function PSetRGB    ( ByVal As UByte = 0, ByVal As UByte = 0, ByVal As UByte = 0 ) As ULong
Declare Sub      PGetRGB    ( ByVal As ULong, ByRef As UByte = 0, ByRef As UByte = 0, ByRef As UByte = 0 )
Declare Function PSetARGB   ( ByVal As UByte = 0, ByVal As UByte = 0, ByVal As UByte = 0, ByVal As UByte = 0 ) As ULong
Declare Sub      PGetARGB   ( ByVal As ULong, ByRef As UByte = 0, ByRef As UByte = 0, ByRef As UByte = 0, ByRef As UByte = 0 )
' single channel setter ... using Union access (any one channel)
Declare Function PSet_Chan  ( ByVal As ULong, ByVal As UByte, ByRef As String ) As ULong
' single channel getter ... using Union access (any one channel)
Declare Function PGet_Chan  ( ByVal As ULong, ByRef As String ) As UByte
' all remaining: single channel getters/setters ... using Ptr access 
Declare Function PSet_A     ( ByVal As ULong, ByVal As UByte ) As ULong
Declare Function PSet_R     ( ByVal As ULong, ByVal As UByte ) As ULong
Declare Function PSet_G     ( ByVal As ULong, ByVal As UByte ) As ULong
Declare Function PSet_B     ( ByVal As ULong, ByVal As UByte ) As ULong
Declare Function PGet_A     ( ByVal As ULong ) As UByte
Declare Function PGet_R     ( ByVal As ULong ) As UByte
Declare Function PGet_G     ( ByVal As ULong ) As UByte 
Declare Function PGet_B     ( ByVal As ULong ) As UByte 

#Ifdef __FB_64BIT__
  #Inclib "ColorLUTbyPercent64"
#Else
  #Inclib "ColorLUTbyPercent32"
#EndIf  ' __FB_64BIT__


#EndIf  ' __ColorLUTbyPercent__
Secondly, the code of the lib itself:

Code: Select all

' ColorLUTbyPercent32.bas -- 2017-04-21, by MrSwiss
' last update: 2017-04-30   changed: nothing yet ...

Union colour        ' BE since, AE: Color is a FB-keyword
    As ULong clr    ' UINT(32), fixed size, 4 x UByte
    Type            ' we are on 'little endian' CPU's (Intel/AMD etc.)
        As UByte b  ' LSB - blue  channel (= CPtr(UByte Ptr, ULong Ptr)[0]) ' only if ptr exists, else: use below method
        As UByte g  '       green channel (= CPtr(UByte Ptr, @ULong)[1])    ' no defined Ptr needed here (address of variable)
        As UByte r  '       red   channel (= CPtr(UByte Ptr, @ULong)[2])    ' more often used (than 'Long Ptr' method)
        As UByte a  ' MSB - alpha channel (= CPtr(UByte Ptr, @ULong)[3])
    End Type
End Union


' GLOBAL fixed size arrays used here, to be accessible from all code
Dim Shared As UByte PCCA(100), RCCA(255)' pre computed LUT's [L]ook-[U]p-[T]able

' converts from: percent channel val, to: real channel val
For i As UInteger = 0 To 100
    PCCA(i) = CUByte(i * 2.55)          ' init LUT1 with values (once only)
Next

' converts from: real channel val, to: percent channel val
For i As UInteger = 0 To 255
    RCCA(i) = CUByte(i / 2.55)          ' init LUT2 with values (once only)
Next


' multi channel getters/setters
Function BGR_RGB( ByVal clr As ULong ) As ULong ' for 24/32bit color only!
    ' FB to WIN: red/blue swap / WIN to FB blue/red swap, works both ways!
    Swap CPtr(UByte Ptr, @clr)[0], CPtr(UByte Ptr, @clr)[2]
    Return clr
End Function

Function PSetRGB( ByVal rpc As UByte = 0, _ ' red chan. (in percent)
                  ByVal gpc As UByte = 0, _ ' green chan. (as above)
                  ByVal bpc As UByte = 0 _  ' blue chan. (as above)
                 ) As ULong                 ' return: color(32bit)
    ' param. range check: 0..100% (all else => QUIT proc.)
    If rpc > 100 OrElse gpc > 100 OrElse bpc > 100 Then Exit Function
    Static As colour ret    ' using the Union

    With ret
        .r = PCCA(rpc)  ' set red using LUT
        .g = PCCA(gpc)  ' set green
        .b = PCCA(bpc)  ' set blue
    End With

    Return ret.clr
End Function

Sub PGetRGB( ByVal clr As ULong, _      ' param. mandatory: color
             ByRef rpc As UByte = 0, _  ' return: red chan. (in percent)
             ByRef gpc As UByte = 0, _  ' return: green chan.
             ByRef bpc As UByte = 0 )   ' return: blue chan.
    Static As colour ret

    With ret
        .clr = clr      ' load current color (all channels)
        rpc = RCCA(.r)  ' get red using LUT
        gpc = RCCA(.g)  ' get green ...
        bpc = RCCA(.b)  ' get blue
    End With 
End Sub

Function PSetARGB( ByVal apc As UByte = 0, _    ' alpha chan. (in percent)
                   ByVal rpc As UByte = 0, _    ' all else: as PSetRGB()
                   ByVal gpc As UByte = 0, _
                   ByVal bpc As UByte = 0 _
                  ) As ULong                    ' return: color(32bit)
    ' param. range check: 0..100% (all else => QUIT proc.)
    If apc > 100 OrElse rpc > 100 OrElse gpc > 100 OrElse bpc > 100 Then Exit Function
    Static As colour ret

    With ret
        .a = PCCA(apc) : .r = PCCA(rpc)
        .g = PCCA(gpc) : .b = PCCA(bpc)
    End With

    Return ret.clr
End Function

Sub PGetARGB( ByVal clr As ULong, _     ' see: PGetRGB()
              ByRef apc As UByte = 0, _ ' alpha chan. (in percent)
              ByRef rpc As UByte = 0, _ ' all else: as PGetRGB()
              ByRef gpc As UByte = 0, _
              ByRef bpc As UByte = 0 )
    Static As colour ret

    With ret
        .clr = clr      ' load current color (all channels)
        apc = RCCA(.a)
        rpc = RCCA(.r)  ' get channels using LUT
        gpc = RCCA(.g)
        bpc = RCCA(.b)
    End With
End Sub

' single channel setter ... using Union access (any one channel)
Function PSet_Chan( ByVal clr As ULong, _       ' color 24/32 bit
                    ByVal ccv As UByte, _       ' value to set (in percent)
                    ByRef chn As String _       ' char (a, r, g, b) = channel to set
                   ) As ULong                   ' return: channel val. in percent
    Static As Colour ret
    
    With ret
        .clr = clr      ' load current color (all channels)
        Select Case As Const Asc(UCase(chn), 1) ' we only want to check upper case
            Case 65 : .a = PCCA(ccv)            ' 65 = Asc("A"), but faster
            Case 82 : .r = PCCA(ccv)            ' 82 = Asc("R"), as above
            Case 71 : .g = PCCA(ccv)            ' 71 = Asc("G"), as above
            Case 66 : .b = PCCA(ccv)            ' 66 = Acs("B"), as above
            Case Else
                chn = "?"   ' error return "?" in chn
                Exit Function
        End Select
    
        Return .clr
    End With
End Function

' single channel getter ... using Union access (any one channel)
Function PGet_Chan( ByVal clr As ULong, _       ' color 24/32 bit
                    ByRef chn As String _       ' char (a, r, g, b) = channel to get
                   ) As UByte                   ' return: channel val. in percent
    Static As Colour ret
    ret.clr = clr

    Select Case As Const Asc(UCase(chn), 1)     ' we only want to check upper case
        Case 65 : Return RCCA(ret.a)            ' 65 = Asc("A"), but faster
        Case 82 : Return RCCA(ret.r)            ' 82 = Asc("R"), as above
        Case 71 : Return RCCA(ret.g)            ' 71 = Asc("G"), as above
        Case 66 : Return RCCA(ret.b)            ' 66 = Acs("B"), as above
        Case Else
            chn = "?"   ' error return "?" in chn
            Exit Function
    End Select
End Function

' all remaining: single channel getter/setter ... using Ptr access 
Function PSet_A ( ByVal clr As ULong, _         ' color 32 bit only!
                  ByVal apc As UByte _          ' ALPHA (in percent)
                 ) As ULong                     ' return: changed ALPHA (in ULong)
    If apc > 100 Then Exit Function             ' range check: 0%..100%
    CPtr(UByte Ptr, @clr)[3] = PCCA(apc)        ' apply using LUT
    Return clr
End Function

Function PSet_R ( ByVal clr As ULong, _         ' color 24/32 bit
                  ByVal rpc As UByte _          ' RED in percent
                 ) As ULong                     ' all else: as above
    If rpc > 100 Then Exit Function
    CPtr(UByte Ptr, @clr)[2] = PCCA(rpc)
    Return clr
End Function

Function PSet_G ( ByVal clr As ULong, _         ' color 24/32 bit
                  ByVal gpc As UByte _          ' GREEN in percent
                 ) As ULong
    If gpc > 100 Then Exit Function             ' all else: as above
    CPtr(UByte Ptr, @clr)[1] = PCCA(gpc)
    Return clr
End Function

Function PSet_B ( ByVal clr As ULong, _         ' color 24/32 bit
                  ByVal bpc As UByte _          ' BLUE in percent
                 ) As ULong
    If bpc > 100 Then Exit Function             ' all else: as above
    CPtr(UByte Ptr, @clr)[0] = PCCA(bpc)
    Return clr
End Function

Function PGet_A ( ByVal clr As ULong ) As UByte ' color 24/32 bit 
    Return RCCA(CPtr(UByte Ptr, @clr)[3])       ' Alpha
End Function

Function PGet_R ( ByVal clr As ULong ) As UByte ' color 24/32 bit 
    Return RCCA(CPtr(UByte Ptr, @clr)[2])       ' red
End Function

Function PGet_G ( ByVal clr As ULong ) As UByte ' color 24/32 bit 
    Return RCCA(CPtr(UByte Ptr, @clr)[1])       ' green
End Function

Function PGet_B ( ByVal clr As ULong ) As UByte ' color 24/32 bit 
    Return RCCA(CPtr(UByte Ptr, @clr)[0])       ' blue
End Function
This is for the FBC-32bit version. For the FBC-64bit version:
simply rename it and save it again (the code is identical for both). However from doing DLL's:
it's better to proceed this way, because a simple (later) name-change, doesn't work! This may
not be relevant to static lib's, but I prefer to be *on the safe side*, also called *good practice*.

If you are only using one FBC, save the file once (with correct bit-ness appended):
e.g. ColorLUTbyPercent32.bas or ColorLUTbyPercent64.bas (name is taken over into .a file!).

After compiling the lib (one or two) you'll have to put the files into the correct folders/dirs:
  • .bi goes to (all used compilers) <FBC-DIR>/inc/
    the libColorLUTbyPercent<nn>.a goes to: <FBC-DIR>/lib/<OS>/
where: <nn> = bitness, <OS> = WIN<nn>, LIN<nn> ...

Examples follow in the next post ...
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Color by Percent (static lib) 32/64bit (pure FB-code)

Post by MrSwiss »

As promised, the first two Examples.
1) only console (and proof, that lib loads without hassles), main aim:
show the LUT's values and, how they're accessed (lib internal, otherwise)
2) fbgfx, doing some graphics, to show the SETTER's mainly ...

here goes 1):

Code: Select all

' C_LUT_P_Demo1_set.bas -- 2017-04-30, by MrSwiss
' last update: 2017-04-30   changed: nothing yet ...

#Include "ColorLUTbyPercent.bi" ' just a test for: load lib successfully

' even if below is also declared/used in the lib (no access from here!)
' below two Lut's are: identical copies from the lib (aka: lib NOT at all used!)
Dim As UByte PCCA(100), RCCA(255)       ' pre computed LUT's [L]ook-[U]p-[T]able

' converts from: percent channel val, to: real channel val (setters)
For i As UInteger = 0 To 100
    PCCA(i) = CUByte(i * 2.55)          ' init LUT1 with values (once only)
Next

' converts from: real channel val, to: percent channel val (getters)
For i As UInteger = 0 To 255
    RCCA(i) = CUByte(i / 2.55)          ' init LUT2 with values (once only)
Next

Dim As UInteger row = 5, col, tb        ' define start row of 'table'-LUT1
Dim As Boolean  rsw                     ' [R]ow[SW]itch, default: FALSE
Dim As String   title, uline

title = "Color-Channel by Percent DEMO: set/get using LUT's, ranges: UByte or %"
uline = String(Len(title), "~")         ' titles underline

' ===== MAIN =====
' A try to explain the inner workings of translation to/from percent values,
' to/from the 'real' values, used later by the color channels setters/getters.
Width 80, 50                            ' console setting
Locate ,, 0                             ' cursor = OFF

Print title
Print uline
Print : Print "LUT1: conv. % to real UByte value:"

For i As UInteger = 0 To 100            ' LUT1: UByte-Array (101 elements)
    tb = i Mod 10                       ' do the math 'once only', per run
    If tb > 0 Then col = tb * 8 Else col = 1    ' set col position
    If col = 72 Then rsw = TRUE         ' at --EOL-- set flag
    Locate row, col : Print PCCA(i);    ' show LUT values ... (NO LF!)
    If rsw Then row += 1 : rsw = FALSE  ' if flag: incr row | reset flag
Next

Locate CsrLin + 2, 1 : Print "LUT2: conv. real UByte value to %:"
row = CsrLin                            ' pre-set row, for next 'table'-LUT2

For i As UInteger = 0 To 255            ' LUT2: UByte-Array (256 elements)
    tb = i Mod 10                       ' do the math 'once only', per run
    If tb > 0 Then col = tb * 8 Else col = 1    ' set col position
    If col = 72 Then rsw = TRUE         ' at --EOL-- set flag
    Locate row, col : Print RCCA(i);    ' show LUT values ... (NO LF!)
    If rsw Then row += 1 : rsw = FALSE  ' if flag: incr row | reset flag
Next

Locate CsrLin + 3, 1, 1                 ' cursor = ON (again)
Print "any user action --> QUIT! ";

Sleep
' ===== END-MAIN =====  ' ----- EOF -----
and 2):

Code: Select all

' C_LUT_P_Demo2_set.bas -- 2017-05-01, by MrSwiss
' last update: 2017-05-01   changed: nothing yet ...

#Include "ColorLUTbyPercent.bi" ' declares & load lib (depending on FBC: 32/64 bit)


Const As ULong  red = &hFFFF0000, green = &hFF00FF00, blue = &hFF0000FF, _
                white = &hFFFFFFFF, black = &hFF000000, grey = &hFF7F7F7F, _
                wid = 640, hei = 480, sx = 20, sy = 20, v = 319

' ===== MAIN =====
ScreenRes(wid, hei, 32, 2, 96)  ' 32 bit, double buff, Alpha-primit. & always on top
Color(white, black) : Cls       ' primary colors: white(fg) on black(bg)

Dim As ULong    x, y, h         ' positioning var's (aka: offsets from consts)
Dim As String   StrA(3) = { "RED-Channel modified", "GREEN-Channel modified", _
                            "BLUE-Channel modified", "ALPHA-Channel modified" } 

Line (10, 255)-Step(619, 194), white, BF    ' white background (below grey)

For i As UInteger = 0 To 100    ' color channel val (in percent)
    ' y = vertical offset, of start pixel (sy)
    ' -Step(5, 25) means: 6px wide, 26px high (it's relative, to start pixel)
    y = 0   : Line (sx + x, sy + y)-Step(5, 25), PSet_R(red, i), BF
    y = 40  : Line (sx + x, sy + y)-Step(5, 25), PSet_G(green, i), BF
    y = 80  : Line (sx + x, sy + y)-Step(5, 25), PSet_B(blue, i), BF
    y = 160 : Line (sx + x, sy + y)-Step(5, 25), PSet_A(white, i), BF
    y = 200 : Line (sx + x, sy + y)-Step(5, 25), PSet_A(grey, i), BF
    y = 240 : Line (sx + x, sy + y)-Step(5, 25), PSet_A(black, i), BF
    y = 320 : Line (sx + x, sy + y)-Step(5, 25), PSet_B(blue, i), BF
    y = 360 : Line (sx + x, sy + y)-Step(5, 25), PSet_G(green, i), BF
    y = 400 : Line (sx + x, sy + y)-Step(5, 25), PSet_R(red, i), BF
    x += 6  ' horizontal move (increment by x-size, of block)
Next
' add description: red, green and blue
x = v - (Len(StrA(0)) * 4) : y = sy + 9 : h = y + 3 ' all calc. 'out of param.'
Draw String (x, y), StrA(0), BGR_RGB(Point(v, h))   ' invert red/blue
x = v - (Len(StrA(1)) * 4) : y = sy + 49 ' : h = y + 3 not needed, see below
Draw String (x, y), StrA(1), white  ' BGR_RGB(Point(v, h)) is useless on green
x = v - (Len(StrA(2)) * 4) : y = sy + 89 : h = y + 3
Draw String (x, y), StrA(2), BGR_RGB(Point(v, h))   ' invert blue/red
' add description: white, grey and black
x = v - (Len(StrA(3)) * 4) : y = sy + 169 ' string 'centered' on x-axis
Draw String (x, y), StrA(3), black
y = sy + 209    ' if the string stays the same length: only new y is needed
Draw String (x, y), StrA(3), white
y = sy + 249
Draw String (x, y), StrA(3), PSetARGB(100, 100, 100, 0) ' yellow
' add description: blue, green and red
x = v - (Len(StrA(2)) * 4) : y = sy + 329
Draw String (x, y), StrA(2), PSetARGB(100, 100, 50, 0)  ' orange
x = v - (Len(StrA(1)) * 4) : y = sy + 369
Draw String (x, y), StrA(1), PSetARGB(100, 100, 0, 100) ' magic-pink
x = v - (Len(StrA(0)) * 4) : y = sy + 409
Draw String (x, y), StrA(0), white

Flip    ' show it all

Sleep
' ===== MAIN =====  ' ----- EOF -----
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Color by Percent (static lib) 32/64bit (pure FB-code)

Post by MrSwiss »

Two more tests, with the lib:
1) console, shows it's use ... and 2) graphics, shows use in loops etc.

Code: Select all

' Test1_ColorLUTbyPercent.bas -- 2017-05-02, by MrSwiss
' last update: 2017-05-02   changed: nothing yet

' compile with: -s console

#Include "ColorLUTbyPercent.bi"


Dim As ULong    c1 = PSetARGB(100, 50, 50, 50), _   ' set ARGB in percent, mid-grey
                c2 = PSetRGB(25, 50, 75), _         ' set RGB in percent, blue(ish)-grey
                c3 = &hFF0000FF                     ' direct, blue 'fully opaque'
Dim As UByte    ba, br, bg, bb                      ' single color channels 'receivers'
Dim As String   err_                                ' for: error checking Get_ChanP(,)
Dim As String   title = "Color setters/getters all in %, range: 0..100%"

' ===== MAIN =====
Print title : Print String(Len(title), "~") : Print
Print "c1:"; Hex(c1, 8), "c2:"; Hex(c2, 8), "c3:"; Hex(c3, 8), "in HEX" : Print
Print "c1, getting each channel individually, in %" ' get color channel in percent (below)
Print PGet_Chan(c1, "a"), PGet_Chan(c1, "R"), PGet_Chan(c1, "g"), PGet_Chan(c1, "B")
Print
Print "c3, getting all channel's, one shot, in %"   '(inp.)color; alpha  red    green  blue(4 x outp.)
PGetARGB(c3, ba, br, bg, bb)    ' get ARGB in percent: Sub(ByVal, ByRef, ByRef, ByRef, ByRef)
Print ba, br, bg, bb            ' show it
Print
Print "c3, setting green channel to 25% :",
err_ = "G"  ' pre-set channel to 'get', only: channel specifiers accepted!, as first letter (any case)
c3 = PSet_G(c3, 25)             ' set green channel to 25% (in c3)
Print PGet_Chan(c3, err_), "and prove it! PGet_Chan()"   ' with error checking! "?" = error
If err_ = "?" Then Print "PGet_Chan(), ERROR: unrecognised Char in: 'err_' !"   ' test for error
' but, no real error handling (as abort prog. etc., it's after all, an example only!)
print
Print "c2, getting alpha channel :      ", PGet_Chan(c2, "a"), "PSetRGB() was used for init!"
Locate CsrLin + 3, 10 : Print "any user action --> EXIT! ";
Sleep
' ===== END-MAIN ===== ' ----- EOF -----

Code: Select all

' Test2_ColorLUTbyPercent.bas -- 2017-04-26, by MrSwiss
' last update: 2017-05-01   changed: adapted to new lib

' compile with: -s GUI

#Include "ColorArrByPercent.bi" ' see: https://freebasic.net/forum/viewtopic.php?f=14&t=25631

' use color by percent lib (as initializer, here first)
' NOTE: if only PSetRGB() is used with GFX_ALPHA_PRIMITIVES, nothing is shown (alpha = 0)
Dim As ULong    c1 = PSetARGB(100, 100, 0, 0), _    ' red 'full alpha' = opaque
                c2 = PSetARGB(100, 0, 100, 0), _    ' green (as above)
                c3 = PSetARGB(100, 0, 0, 100)       ' blue  (as above)
' for program execution control
Dim As Boolean  quit = FALSE, sw = TRUE             ' flags

' ===== MAIN =====
ScreenRes(650, 650, 32, 2, 64)  ' GFX_ALPHA_PRIMITIVES = &h40 / 64 dec; double buffer

Do
    For i As UInteger = 0 To 100 Step 10
        If Len(InKey()) Then quit = TRUE : Exit For ' most likely place, to catch it: 'key press'
        If sw Then                                  ' depending on state: circles or squares
            Var xy = 15 + i * 5, r = 8 + i          ' math. taken out of parameters (except: offsets)
            Circle (xy, xy), r + 1, BGR_RGB(c3)     ' switch blue/red channel
            Circle (xy, xy), r, PSet_A(c2, i),,,, F ' ALPHA channel change: 'transparency' setting
        Else
            Var xy = 15+i*3, sl = 5+i*3, inv = 100-i    ' different from circles! even: xy
            Line (xy-1, xy-1)-Step(sl+2, sl+2), c3, B   ' c3 unswitched, aka: 'as set'
            Line (xy, xy)-Step(sl, sl), PSetARGB(i, i, inv, inv), BF    ' multi channel set
        End If
        Flip                                        ' screen-copy (work- to visible-page)
        Sleep 200, 1                                ' pause for 0.2 Sec. (no user interrupt)
    Next
    If quit Then Exit Do                            ' exit do/loop as well as program
    Sleep 750, 1 : Cls : sw = Not sw                ' change state of: sw
Loop
' ===== END-MAIN ===== ' ----- EOF -----
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Color by Percent (static lib) 32/64bit (pure FB-code)

Post by MrSwiss »

Just finished Test4 ... :

Code: Select all

' Test4_ColorLUTbyPercent.bas -- 2017-05-04, by MrSwiss
' last update: 2017-05-04   changed: adapted to new lib

' compile with: -s GUI

#Include "ColorLUTbyPercent.bi" ' see: https://freebasic.net/forum/viewtopic.php?f=14&t=25631
#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

' use color by percent lib (as initializer, here first)
' NOTE: if only PSetRGB() is used with GFX_ALPHA_PRIMITIVES, nothing is shown (alpha = 0)
Dim As ULong    c1 = PSetARGB( 75, 100,   0,   0), _    ' red 3/4 alpha = 1/4 transparent
                c2 = PSetARGB(100,  50,  50,  50), _    ' grey 100% alpha = opaque (0% trans)
                c3 = PSetARGB(100,   0,   0,  67), x, y ' dark-blue, x, y (later use)
' 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
Color(c3, c2) : Cls
c2 = PSetARGB( 50, 100, 100, 100)   ' redefine c2 to: white / 50% opaque / 50% transparent
                                    ' can't be used for Grid (try it, change c1 to c2, 3x)
Do                                  ' the problem seems to be with paint (only opaque?)
    ' cell size 68 (square), border 48 = cells: h/v = 8/8 (aka: chessboard)
    Grid(640, 640, 68, 48,, c1)     ' grid color = c2 (default = medium-gray)
    For j As UInteger = 1 To 8      ' rows (cells vertical)
        y = j * 68 + 48 - 34        ' calc. injection point y (paint, aka: flood-fill)
        For i As UInteger = 1 To 8  ' columns (cells horizontal)
            x = i * 68 + 48 - 34    ' calc. injection point x (paint)
            If sw Then
                ' randon color from range = bright 75% & 25..100% alpha
                Paint (x, y), ClrRng(&h3F3F3F3F, &hFFFFFFFF), c1    ' in GFX_MATH.bi
            Else
                ' random color / opaque (alpha = 100%)
                Paint (x, y), RndRGB, c1    ' in ColorLUTbyPercent | GFX_MATH.bi
            EndIf
        Next
        If Len(InKey()) Then quit = TRUE : Exit For ' exit outer For loop (only)
    Next
    Draw String (20, 20), UCase(Str(sw)), c3        ' show current sw state
    sw = Not sw                                     ' change macro used, every new run
    Draw String (72, 78), Str(x), Contrast(Point(78, 78))   ' last injection point x
    Draw String (72, 146), Str(y), Contrast(Point(78, 146)) ' last injection point y
    c1 = PSet_A(CContrast(Point(558, 558)), 100)    ' CContrast + Alpha set to 100%
    Circle (558, 558), 16, c1 : Circle (558, 558), 1, c1,,,, F  ' mark last injecton point
    Flip
    If quit Then Exit Do
    Sleep 1250, 1 : Cls
Loop
' ===== END-MAIN =====  ' ----- EOF -----
Post Reply