Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
SetAlpha and ClearColor
#1
Messing around a bit with these two QB64 statements that can be used in SCREEN 0.

The below is a demo. The first simply shows how we can dim the background (screen). in QBasic, we could use the palette statement to change the background. Say it was set as palette 5, 63 so color 5 is changed to bright white. Changing the palette statement to a palette 5, 7 would darken that bright white background, but it would not change the intensity of the characters printed on that background. _SetAlpha can do that, and _ClearColor also gives us the option of making the background our characters appear on transparent.

So the first demo is simple. Press a key and watch the page dim. This is a nice effect if you want to add a popup, and bring it more in focus by diminishing the intensity of everything behind it.

Press the Tab or Esc key to go to the next and final demo...

The final demo allows us to pick screen colors, alpha intensity, and turn _ClearColor on or off. The number keys set the screen color as shown in the code. 0-7. Backspace returns us to the original screen. The space bar engages or disengages the _ClearColor statement. (You really need to switch to a different screen color to see that effect. It's too subtle with bright white. Use the arrow up and down keys to increase or decrease the alpha value; otherwise, press any other key to toggle the alpha on and off.

Note: This img file will be created in your local folder when you run the demo: temp14fe78.png
Code: (Select All)
s& = _NewImage(80, 25, 0)
Screen s&
Palette 5, 63 ' Use for a bright white background.
Cls , 5
For a = 1 To _Height ' Draw random colorful characters to the screen.
    Locate a, 1
    For i = 1 To _Width
        j = Int(Rnd * 14) + 1
        k = Int(Rnd * 25) + 1
        Color j, 5
        Print Chr$(k + 96);
    Next
Next
_SaveImage "temp14fe78.png"
temp& = _LoadImage("temp14fe78.png", 32)
img& = _CopyImage(temp&, 33)
Cls , _RGB(220, 220, 220)
_KeyClear
Do
    _Limit 30
    b$ = InKey$
    If Len(b$) Then
        If b$ = Chr$(27) Or b$ = Chr$(9) Then Exit Do
        sw = Not sw
If img& Then _FreeImage img& ' Free the image before the new image is copied.
        If sw Then
            _SetAlpha 90, , temp&: img& = _CopyImage(temp&, 33)
        Else
            _SetAlpha 255, , temp&: img& = _CopyImage(temp&, 33)
        End If
    End If
    _PutImage (0, 0), img&
    _Display
Loop
_FreeImage temp&
_FreeImage img&

_AutoDisplay
Screen 0
Cls , 0
Color 15, 0: Print "Press a key for Example #2..."
Sleep: _KeyClear

Screen 0
Palette 5, 63
Cls , 5
For a = 1 To _Height ' Draw random colorful characters to the screen.
    Locate a, 1
    For i = 1 To _Width
        j = Int(Rnd * 14) + 1
        k = Int(Rnd * 25) + 1
        Color j, 5
        Print Chr$(k + 96);
    Next
Next
_SaveImage "temp14fe78.png" ' Until _copyimage works in Screen 0, this will have to do.
temp& = _LoadImage("temp14fe78.png", 32) ' Load our Screen 0 image.
test& = _NewImage(640, 480, 32) ' Make a screen for our saved image.
_PutImage (0, 0), temp&, test& ' No need to _dest, just put the temp& source image to the test& destination screen.
_Source test& ' This is needed to dirsect the ClearColor variable to the correct source screen, test&
clr~& = Point(0, 0) 'Get the background color of the image. (Top left corner).
_Dest 0
_ClearColor clr~&, temp& ' Make the image background color transparent.
img& = _CopyImage(temp&, 33) ' Make a hardware copy of our Screen 0 page.
_FreeImage test&
c1 = 230: c2 = 230: c3 = 230
Cls , _RGB(c1, c2, c3) ' Won't work unless we do some sort of cls here.
alpha& = 128 ' Arbitrary starting point.
alpha$ = "Disengaged.": cclr$ = "Disengaged.": sw = 0
Do
    _Limit 30
    b$ = InKey$
    If Len(b$) Then
        trigger = -1 ' Values are: 0 to bypass special effects, -1 for screen color keys to bypass sw alpha flipping, and 1 for sw alpha flipping.
        Select Case b$
            Case Chr$(27): Exit Do ' Quit.
            Case Chr$(8): Cls , _RGB(c1, c2, c3) ' Original background color.
            Case "0": Cls , 0 ' Black background.
            Case "1": Cls , 1 ' Blue background.
            Case "2": Cls , 2 ' Green background.
            Case "3": Cls , 3 ' Teal background.
            Case "4": Cls , 4 ' Red background.
            Case "5": Cls , 5 ' White background because of palette.
            Case "6": Cls , 6 ' Orange background.
            Case "7": Cls , 7 ' Grey background.
            Case "8", "9": trigger = 0 ' No color options here.
            Case Chr$(0) + "H": If alpha& + 8 <= 255 Then sw = -1: If alpha& = 0 Then alpha& = 7 Else alpha& = alpha& + 8
            Case Chr$(0) + "P": If alpha& - 8 >= -1 Then sw = -1: alpha& = alpha& - 8: If alpha& < 0 Then alpha& = 0
            Case " ": If cclr$ = "Engaged." Then cclr$ = "Disengaged." Else cclr$ = "Engaged."
            Case Else: trigger = 1
        End Select
    End If
    If trigger Then
        If trigger = 1 Then sw = Not sw ' Flip bit unless color or alpha change was made.
If img& Then _FreeImage img& ' Free the image before the new image is copied.
        If sw Then
            _SetAlpha alpha&, , temp&: alpha$ = "Engaged." ' IMPORTANT: SetAlpha first, ClearColor second.
            If cclr$ = "Engaged." Then _ClearColor clr~&, temp& Else _ClearColor _None, temp&
            img& = _CopyImage(temp&, 33) ' Decreases the opacity.
        Else
            _SetAlpha 255, , temp&: alpha$ = "Disengaged." ' IMPORTANT: SetAlpha first, ClearColor second.
            If cclr$ = "Engaged." Then _ClearColor clr~&, temp& Else _ClearColor _None, temp&
            img& = _CopyImage(temp&, 33) ' Decreases the transparency.
        End If
        trigger = 0
    End If
    _PutImage (0, 16), img& ' Put the hardware copy on Screen 0.
    Color 14, 4: Locate 1, 1: Print Space$(_Width - 10);: Locate 1, _Width - 21: Print "Screen Color" + Chr$(26);
    Locate 1, 1: Print "Alpha ="; alpha&; alpha$; " ClearColor "; cclr$
    _Display
Loop
_FreeImage temp&
_FreeImage img&
System

So basically we put some characters on screen 0 then save that image to the local folder. We then load that image, find its background color so _ClearColor can make it transparent if desired, copy that image into memory so it becomes a hardware image, and then set the alpha value, _ClearColor effect or not, and put our hardware image on screen 0.

Edited to fix memory leak uncovered by Steve.

Pete
Reply
#2
Note the memory leak you have here: 

Code: (Select All)
s& = _NewImage(80, 25, 0)
Screen s&
Palette 5, 63 ' Use for a bright white background.
Cls , 5
For a = 1 To _Height ' Draw random colorful characters to the screen.
Locate a, 1
For i = 1 To _Width
j = Int(Rnd * 14) + 1
k = Int(Rnd * 25) + 1
Color j, 5
Print Chr$(k + 96);
Next
Next
_SaveImage "temp14fe78.png"
temp& = _LoadImage("temp14fe78.png", 32)
img& = _CopyImage(temp&, 33)
Cls , _RGB(220, 220, 220)
_KeyClear
Do
_Limit 30
b$ = InKey$
If Len(b$) Then
If b$ = Chr$(27) Or b$ = Chr$(9) Then Exit Do
sw = Not sw
If img& Then _FreeImage img& ' <<<--- Note that you have a memory leak here, if you don't free those copies
If sw Then
_SetAlpha 90, , temp&: img& = _CopyImage(temp&, 33) '<<--mem leak
Else
_SetAlpha 255, , temp&: img& = _CopyImage(temp&, 33) ' <<-- mem leak
End If
End If
_PutImage (0, 0), img&
_Display
Loop
_FreeImage temp&
_FreeImage img&

_AutoDisplay
Screen 0
Cls , 0
Color 15, 0: Print "Press a key for Example #2..."
Sleep: _KeyClear

Screen 0
Palette 5, 63
Cls , 5
For a = 1 To _Height ' Draw random colorful characters to the screen.
Locate a, 1
For i = 1 To _Width
j = Int(Rnd * 14) + 1
k = Int(Rnd * 25) + 1
Color j, 5
Print Chr$(k + 96);
Next
Next
_SaveImage "temp14fe78.png" ' Until _copyimage works in Screen 0, this will have to do.
temp& = _LoadImage("temp14fe78.png", 32) ' Load our Screen 0 image.
test& = _NewImage(640, 480, 32) ' Make a screen for our saved image.
_PutImage (0, 0), temp&, test& ' No need to _dest, just put the temp& source image to the test& destination screen.
_Source test& ' This is needed to dirsect the ClearColor variable to the correct source screen, test&
clr~& = Point(0, 0) 'Get the background color of the image. (Top left corner).
_Dest 0
_ClearColor clr~&, temp& ' Make the image background color transparent.
img& = _CopyImage(temp&, 33) ' Make a hardware copy of our Screen 0 page.
_FreeImage test&
c1 = 230: c2 = 230: c3 = 230
Cls , _RGB(c1, c2, c3) ' Won't work unless we do some sort of cls here.
alpha& = 128 ' Arbitrary starting point.
alpha$ = "Disengaged.": cclr$ = "Disengaged.": sw = 0
Do
_Limit 30
b$ = InKey$
If Len(b$) Then
trigger = -1 ' Values are: 0 to bypass special effects, -1 for screen color keys to bypass sw alpha flipping, and 1 for sw alpha flipping.
Select Case b$
Case Chr$(27): Exit Do ' Quit.
Case Chr$(8): Cls , _RGB(c1, c2, c3) ' Original background color.
Case "0": Cls , 0 ' Black background.
Case "1": Cls , 1 ' Blue background.
Case "2": Cls , 2 ' Green background.
Case "3": Cls , 3 ' Teal background.
Case "4": Cls , 4 ' Red background.
Case "5": Cls , 5 ' White background because of palette.
Case "6": Cls , 6 ' Orange background.
Case "7": Cls , 7 ' Grey background.
Case "8", "9": trigger = 0 ' No color options here.
Case Chr$(0) + "H": If alpha& + 8 <= 255 Then sw = -1: If alpha& = 0 Then alpha& = 7 Else alpha& = alpha& + 8
Case Chr$(0) + "P": If alpha& - 8 >= -1 Then sw = -1: alpha& = alpha& - 8: If alpha& < 0 Then alpha& = 0
Case " ": If cclr$ = "Engaged." Then cclr$ = "Disengaged." Else cclr$ = "Engaged."
Case Else: trigger = 1
End Select
End If
If trigger Then
If trigger = 1 Then sw = Not sw ' Flip bit unless color or alpha change was made.
If sw Then
_SetAlpha alpha&, , temp&: alpha$ = "Engaged." ' IMPORTANT: SetAlpha first, ClearColor second.
If cclr$ = "Engaged." Then _ClearColor clr~&, temp& Else _ClearColor _None, temp&
img& = _CopyImage(temp&, 33) ' Decreases the opacity.
Else
_SetAlpha 255, , temp&: alpha$ = "Disengaged." ' IMPORTANT: SetAlpha first, ClearColor second.
If cclr$ = "Engaged." Then _ClearColor clr~&, temp& Else _ClearColor _None, temp&
img& = _CopyImage(temp&, 33) ' Decreases the transparency.
End If
trigger = 0
End If
_PutImage (0, 16), img& ' Put the hardware copy on Screen 0.
Color 14, 4: Locate 1, 1: Print Space$(_Width - 10);: Locate 1, _Width - 21: Print "Screen Color" + Chr$(26);
Locate 1, 1: Print "Alpha ="; alpha&; alpha$; " ClearColor "; cclr$
_Display
Loop
_FreeImage temp&
_FreeImage img&
System
Reply
#3
By golly Oli, you're right. +1

I'm still not used to freeing images yet. I actually did this free before re-creating in a prior project post, and then missed it here.

I edited the above post. It needs your fix applied to both demos.

Thanks,  

Pete
Reply




Users browsing this thread: 1 Guest(s)