FB II Compiler

PG PRO

Debugging

Memory

System

Mathematics

Resources

Disk I/O

Windows

Controls

Menus

Mouse

Keyboard

Text

Fonts

Drawing

Sound

Clipboard

Printing

Communication

ASM

Made with FB

DRAWING

Mix, saturate, lighten colours


Here are some functions for getting RGB colors that may be useful. Pass these functions the address of an RGB record and when the function returns the RGB record will hold the new RGB color.

1. FN getRGB(@RGBcolor,ang)
Pass this function an angle in degrees and you get back a fully saturated RGB color.
ang - Angle in degrees, range 0 to 360, 0=red, 45=yellow, 90=green, 135=bluegreen, etc.

2. FN deSaturate(@RGBcolor,sat)
Pass this function a fully saturated RGB color and a saturation level. A desaturated version of the color will be returned.
sat - Saturation, 0=mid gray, to 255 full intensity

3. FN lightness(@RGBcolor,lig)
Pass this function an RGB color and a lightness level and a lightened or darkened version of the color will be returned.
lig - Lightness, 0=black, 127=color, 255=white

4. FN mixColors(@RGB1,mix,@RGB2)
Pass this function the address of two RGB colors and a mixed version of them will be returned in RGB1.
mix - 0 = 100% of RGB1, 127 = 50%/50% mix of RGB1 and RGB2, 255=100% of RGB2

5. LOCAL FN getRGBcolor(RGBptr&,ang,sat,lig)
This combines all 3 color functions in one.

Here is a demo that uses these functions:

COMPILE 0,_caseinsensitive
GLOBALS
DIM gPlotHt(360)
END GLOBALS
'by Joe Lertola
'-----------
LOCAL FN getRGB(RGBptr&,ang)
'ang - Angle in degrees 0=red, 45=yellow, 90=green, 135=bluegreen, etc.
  ang= ang MOD 360 : IF ang<0 THEN ang=ang+360
  red%=0 : green%=0 : blue%=0

  SELECT 'red
    CASE (ang>=0 AND ang<=60) OR ang>=300 : red%=255
    CASE ang>60 AND ang<120 : i=60-(ang-60) : red%=i*255/60
    CASE ang>240 AND ang<300 : i=ang-240 : red%=i*255/60
  END SELECT
  SELECT 'green
    CASE ang>0 AND ang<60 : green%=ang*255/60
    CASE ang>=60 AND ang<=180 : green%=255
    CASE ang>180 AND ang<240 : i=60-(ang-180) : green%=i*255/60
  END SELECT
  SELECT 'blue
    CASE ang>120 AND ang<180 : i=ang-120 : blue%=ang*255/60
    CASE ang>=180 AND ang<=300 : blue%=255
    CASE ang>300 : i=60-(ang-300) : blue%=i*255/60
  END SELECT

  RGBptr&.red%=red%<<8 : RGBptr&.green%=green%<<8 : RGBptr&.blue%=blue%<<8
END FN
'-----------
LOCAL FN mixColors(RGB1&,mix,RGB2&)
  SELECT
    CASE mix>=255 'RGB1& is answer so do nothing
    CASE mix<=0 : BLOCKMOVE RGB2&, RGB1&, _rgbColor'RGB2& is answer
    CASE ELSE 'mix the two colors
      red1%=PEEK(@RGB1&.red%) : gre1%=PEEK(@RGB1&.green%) :blu1%=PEEK(@RGB1&.blue%)
      red2%=PEEK(@RGB2&.red%) : gre2%=PEEK(@RGB2&.green%) :blu2%=PEEK(@RGB2&.blue%)

      red1%=red1%*mix/255 : red2%=red2%*(255-mix)/255 : red1%=red1%+red2%
      gre1%=gre1%*mix/255 : gre2%=gre2%*(255-mix)/255 : gre1%=gre1%+gre2%
      blu1%=blu1%*mix/255 : blu2%=blu2%*(255-mix)/255 : blu1%=blu1%+blu2%

      RGB1&.red%=red1%<<8 : RGB1&.green%=gre1%<<8 : RGB1&.blue%=blu1%<<8
  END SELECT
END FN
'-----------
CLEAR LOCAL
  DIM RGBcol.rgbColor
'sat - Saturation, 0=mid grey, to 255 full intensity
LOCAL FN deSaturate(RGBptr&,sat) 'mix color with 50% grey
  RGBcol.red%=127<<8 : RGBcol.green%=127<<8 :RGBcol.blue%=127<<8
  FN mixColors(RGBptr&,sat,@RGBcol)
END FN
'-----------
CLEAR LOCAL
  DIM RGBcol.rgbColor
'lig - Lightness, 0=black, 127=color, 255=white
LOCAL FN lightness(RGBptr&,lig)
  IF lig>255 THEN lig=255
  IF lig<0 THEN lig=0
  LONG IF lig>127
    RGBcol.red%=255<<8 : RGBcol.green%=255<<8 :RGBcol.blue%=255<<8
    mix=(127-(lig-127))<<1
  XELSE
    RGBcol.red%=0 : RGBcol.green%=0 :RGBcol.blue%=0
    mix=lig<<1
  END IF
  FN mixColors(RGBptr&,mix,@RGBcol)
END FN
'-----------
CLEAR LOCAL
  DIM RGBcol.rgbColor
LOCAL FN getRGBcolor(RGBptr&,ang,sat,lig)
  FN getRGB(RGBptr&,ang)
  FN deSaturate(RGBptr&,sat)
  FN lightness(RGBptr&,lig)
END FN
'-----------
LOCAL FN fillArray(plotHtArea)
  FOR x= 0 TO 360
    rad#=x/57.29577951 : sinAngle# = SIN(rad#) '1 radian = about 57.29577951 deg
    p=sinAngle# * plotHtArea : gPlotHt(x)=p
  NEXT x
END FN
'-----------
LOCAL FN drawSinLines(lf,rt,tp,y,plotHtArea,z)
  FOR x=lf TO rt STEP 10
    scale=(plotHtArea-(y*2))
    i=((x*z)+y) MOD 360
    yht=gPlotHt(i)
    yht=yht*scale/plotHtArea
    yht=yht+plotHtArea+tp+y
    LONG IF x=lf
      PLOT x,yht
    XELSE
      PLOT TO x,yht
    END IF
  NEXT x
END FN
'-----------
CLEAR LOCAL
  DIM rect;8, RGBcol.rgbColor, RGBco2.rgbColor, RGBout.rgbColor
LOCAL FN ColorDemo
'make window
  wd = SYSTEM(_scrnWidth) : ht = SYSTEM(_scrnHeight)
  WINDOW 1, "", (0,0)-(wd-20,ht-50), _dialogFrame
'paint window background
  wd = WINDOW(_width) : ht = WINDOW(_height) : CALL SETRECT(rect,0,0,wd,ht)
  FN getRGBcolor(@RGBcol,225,255,64)
  CALL RGBFORECOLOR(#@RGBcol) : CALL PAINTRECT(rect)
'demo-set up variables
  SpaceBetDemos : TypLft=SpaceBetDemos : NumDemos=4
  DemoAreaY=(ht-(NumDemos+1)*SpaceBetDemos)/NumDemos
  lf=SpaceBetDemos : rt=wd-SpaceBetDemos
'setup a plot height table
  plotHtArea=DemoAreaY/3: FN fillArray(plotHtArea)
  DO
'do demo 1 - hue
    dem=0 'add 1 for each demo
    tp=dem*(DemoAreaY+SpaceBetDemos)+SpaceBetDemos : bo=tp+DemoAreaY
    CALL SETRECT(rect,lf,tp,rt,bo) : COLOR _zBlack : CALL PAINTRECT(rect)
    COLOR _zWhite : TypTop=tp-6 : z = RND(3) : rndAng=RND(360)
    PRINT %(TypLft,TypTop) "Hue demo - FN getRGB(@RGBcol,ang), press any key to exit";
    FOR y=0 TO plotHtArea-1
      ang=(y+rndAng)*360/plotHtArea
      FN getRGB(@RGBcol,ang) : CALL RGBFORECOLOR(#@RGBcol)
      FN drawSinLines(lf,rt,tp,y,plotHtArea,z)
    NEXT y

'do demo 2 - saturation
    dem=1
    tp=dem*(DemoAreaY+SpaceBetDemos)+SpaceBetDemos : bo=tp+DemoAreaY
    CALL SETRECT(rect,lf,tp,rt,bo) : COLOR _zBlack : CALL PAINTRECT(rect)
    COLOR _zWhite : TypTop=tp-6 : z = RND(3)
    PRINT %(TypLft,TypTop) "Saturation demo - FN deSaturate(@RGBcol,sat)"; rndCol=RND(360) : FN getRGB(@RGBout,rndCol)
    FOR y=0 TO plotHtArea-1
      sat=y*256/plotHtArea : RGBcol=RGBout
      FN deSaturate(@RGBcol,sat) : CALL RGBFORECOLOR(#@RGBcol)
      FN drawSinLines(lf,rt,tp,y,plotHtArea,z)
    NEXT y

'do demo 3 - lightness
    dem=2 'add 1 for each demo
    tp=dem*(DemoAreaY+SpaceBetDemos)+SpaceBetDemos : bo=tp+DemoAreaY
    CALL SETRECT(rect,lf,tp,rt,bo) : COLOR _zBlack : CALL PAINTRECT(rect)
    COLOR _zWhite : TypTop=tp-6 : z = RND(3)
    PRINT %(TypLft,TypTop) "Lightness demo - FN lightness(@RGBcol,lig)"; rndCol=RND(360) : FN getRGB(@RGBout,rndCol)
    FOR y=0 TO plotHtArea-1
      lig=y*256/plotHtArea : RGBcol=RGBout
      FN lightness(@RGBcol,lig) : CALL RGBFORECOLOR(#@RGBcol)
      FN drawSinLines(lf,rt,tp,y,plotHtArea,z)
    NEXT y

'do demo 4 - mix colors
    dem=3 'add 1 for each demo
    tp=dem*(DemoAreaY+SpaceBetDemos)+SpaceBetDemos : bo=tp+DemoAreaY
    CALL SETRECT(rect,lf,tp,rt,bo) : COLOR _zBlack : CALL PAINTRECT(rect)
    COLOR _zWhite : TypTop=tp-6 : z = RND(3)
    PRINT %(TypLft,TypTop) "Mix colors demo - FN mixColors(@RGBcol,mix,@RGBout)";
    rndCol=RND(360) : FN getRGB(@RGBcol,rndCol)
    rndCol=RND(360) : FN getRGB(@RGBco2,rndCol)
    FOR y=0 TO plotHtArea-1
      mix=y*256/plotHtArea : RGBcol=RGBout
       FN mixColors(@RGBcol,mix,@RGBco2) : CALL RGBFORECOLOR(#@RGBcol)
      FN drawSinLines(lf,rt,tp,y,plotHtArea,z)
    NEXT y

  UNTIL LEN(INKEY$)
END FN
'-----------

LOCAL FN doit
  FN ColorDemo
END FN

FN doit

Joe Lertola