So why is the color change "permanent"? - James D Jarvis - 04-24-2022
In the sample program attached I use a function to brighten the color of drawn elements. I noticed the color change is permanent even though I am not returning the color value to the color handle itself. Am I doing this wrong or is there something buggy in how color handles are passed that I don't understand? I figured out a work arround for the situation but I don't care for it. Any suggestions of comments would be welcome.
Code: (Select All) Sc& = _NewImage(800, 500, 32)
Screen Sc&
Dim klr&, klr2&, klr3&
klr& = _RGB(27, 27, 128)
klr2& = _RGB(27, 27, 128)
klr3& = _RGB(150, 26, 28)
For n = 1 To 40
Cls
_Limit 20
klr& = _RGB(27, 27, 128) 'if this line is commented out the color is permanently changed by the brighter function
orb 400, 250, n * 2, klr&, 1.5
' klr2& = _RGB(128, 227, 128) this one is commented out to show what would happen as above
orb 200, 250, n * 2, klr2&, 1.5
klr3& = _RGB(227, 26, 28) 'comment this out and the color changes
orb 600, 250, 40, klr3&, 7 'an orb that is the same size to serve as an example without the scaling to distract with the viewer
_Display
Next n
Function brighter& (ch&&, p)
r = _Red(ch&&)
b = _Blue(ch&&)
g = _Green(ch&&)
If p < 0 Then p = 0
If p > 100 Then p = 100
p = p / 100
rdif = 255 - r: rc = rdif * p: brr = Int(r + rc): If brr > 255 Then brr = 255
gdif = 255 - g: gc = gdif * p: bgg = Int(g + gc): If bgg > 255 Then bgg = 255
bdif = 255 - b: bc = bdif * p: bbb = Int(b + bc): If bbb > 255 Then bbb = 255
brighter& = _RGB(brr, bgg, bbb)
End Function
Sub orb (XX As Long, YY As Long, Rd As Long, KK As Long, brt As Integer)
'for false shaded 3-D look
'XX,YY arer screen position Rd is outermost radius of the orb KK is the startign color
'brt is the factor by which color will chnage it is the diffeence from KK to RGB(255,255,255)
'brt is applied each step so your orb will go to white if it is large or the brt value is high
ps = _Pi
p3 = _Pi / 3
p4 = _Pi / 4
rdc = p4 / Rd
If Rd < 10 Then ps = _Pi / 3 'so small radius orbs look cool too
For c = 0 To Int(Rd * .87) Step ps
KK = brighter&(KK, brt)
CircleFill XX, YY, Rd - (c), KK
XX = XX + rdc * (c * p3) ' could be fiddled with to move the center of the gradient
YY = YY - rdc * (c * 2 * p4) ' could be fiddled with to move the center of the gradient
Next c
End Sub
Sub CircleFill (CX As Long, CY As Long, R As Long, C As Long)
'sub by SMcNeill makes a filled circle without worrying about using the paint command to fill an empty circle
Dim Radius As Long, RadiusError As Long
Dim X As Long, Y As Long
Radius = Abs(R)
RadiusError = -Radius
X = Radius
Y = 0
If Radius = 0 Then PSet (CX, CY), C: Exit Sub
' Draw the middle span here so we don't draw it twice in the main loop,
' which would be a problem with blending turned on.
Line (CX - X, CY)-(CX + X, CY), C, BF
While X > Y
RadiusError = RadiusError + Y * 2 + 1
If RadiusError >= 0 Then
If X <> Y + 1 Then
Line (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
Line (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
End If
X = X - 1
RadiusError = RadiusError - X * 2
End If
Y = Y + 1
Line (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
Line (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
Wend
End Sub
RE: So why is the color change "permanent"? - bplus - 04-24-2022
I haven't check code yet but you might want to use _Unsigned Long for the Type to hold color values AND use _RGB32 instead of _RGB() which just matches to closest RGB value in an older screen mode ie NOT using _NewImage( wide, High, 32) to setup graphics screen.
OK you are using _NewImage so _RGB32() would be better, maybe I have I backwards don't use RGB32 with old screen modes? I just go by Rule if you use 32 to setup screen, use _RGB32.
OK I confess I don't understand what you are trying in Brighter& but suffix should be ~& to cover all colors including alpha.
I use this for gradually going (by fractions) from one color to another:
Code: (Select All) Function midInk~& (r1%, g1%, b1%, r2%, g2%, b2%, fr##)
midInk~& = _RGB32(r1% + (r2% - r1%) * fr##, g1% + (g2% - g1%) * fr##, b1% + (b2% - b1%) * fr##)
End Function
r1, g1, b1 is the RGB at the start when fraction fr## is 0 and r2, g2, b2 is the "Goal" color when fr## = 1 so anything between 0 and 1 for fr## is an in between color value eg fr## = .2 closer to start color r1,g1, b1 and fr ## = .8 closer to r2, g2, b2
The brightest color is _RGB32(255, 255, 255, 255) and & Type wont contain it.
RE: So why is the color change "permanent"? - James D Jarvis - 04-24-2022
So the color handle isn't just a pointer? Thinking that it is may be part of my issue.
The brighter function is just to get a lighter color of the original each iteration to do the shading look for the orbs.
RE: So why is the color change "permanent"? - bplus - 04-24-2022
(04-24-2022, 02:41 PM)James D Jarvis Wrote: So the color handle isn't just a pointer? Thinking that it is may be part of my issue.
The brighter function is just to get a lighter color of the original each iteration to do the shading look for the orbs.
Yes not a pointer, _RGB32 returns a very large integer best contained in the _Unsigned Long Type suffix ~&
Using _Red(), _Green32, _Blue32() is right, for getting a color converted to it's RGB elements and then using those to change gradually.
I worked up a little Demo of what I think you are trying here:
https://staging.qb64phoenix.com/showthread.php?tid=162
RE: So why is the color change "permanent"? - Gets - 04-24-2022
It looks like the color is being permanently changed here:
Quote:Sub orb (XX As Long, YY As Long, Rd As Long, KK As Long , brt As Integer)
KK = brighter&(KK, brt)
Values passed to a sub retain any changes made in that sub.
RE: So why is the color change "permanent"? - James D Jarvis - 04-24-2022
[quote pid="659" dateline="1650816800"]
Values passed to a sub retain any changes made in that sub.
[/quote]
Which I thought shouldn't happen unless the variables were explicitly shared or were returned as part of a function call. Darn it really has been ages since I used QB.
RE: So why is the color change "permanent"? - bplus - 04-24-2022
(04-24-2022, 04:50 PM)James D Jarvis Wrote: Quote:Values passed to a sub retain any changes made in that sub.
Which I thought shouldn't happen unless the variables were explicitly shared or were returned as part of a function call. Darn it really has been ages since I used QB.
That is new to QB64, arguments in a Sub or Function were passed by what they call ByValue in older versions of QB but QB64 does them ByRef. So if you are going to change a variable value it is best to copy the incoming value into a variable for the Sub to work with and leave the incoming variable alone after.
RE: So why is the color change "permanent"? - James D Jarvis - 04-24-2022
Not a complete best practices fix but a fix that solves the issue I was having.
i just added 2 lines :
Dim NK as long
NK=KK
and used NK instead of KK in following lines. It works exactly like I expected it to.
Code: (Select All) Sc& = _NewImage(800, 500, 32)
Screen Sc&
Dim klr&, klr2&, klr3&
klr& = _RGB(27, 27, 128)
klr2& = _RGB(27, 27, 128)
klr3& = _RGB(150, 26, 28)
For n = 1 To 40
Cls
_Limit 20
' klr& = _RGB(27, 27, 128) 'struck out but left for readibilty on the forum
orb 400, 250, n * 2, klr&, 1.5
' klr2& = _RGB(128, 227, 128) 'struck out but left for readibilty on the forum
orb 200, 250, n * 2, klr2&, 1.5
' klr3& = _RGB(227, 26, 28) 'struck out but left for readibilty on the forum
orb 600, 250, 80, klr3&, 7 'a orb that is the same size to serve as an example without the scaling to mess with the viewer
_Display
Next n
Function brighter& (ch&&, p)
r = _Red(ch&&)
b = _Blue(ch&&)
g = _Green(ch&&)
If p < 0 Then p = 0
If p > 100 Then p = 100
p = p / 100
rdif = 255 - r: rc = rdif * p: brr = Int(r + rc): If brr > 255 Then brr = 255
gdif = 255 - g: gc = gdif * p: bgg = Int(g + gc): If bgg > 255 Then bgg = 255
bdif = 255 - b: bc = bdif * p: bbb = Int(b + bc): If bbb > 255 Then bbb = 255
brighter& = _RGB(brr, bgg, bbb)
End Function
Sub orb (XX As Long, YY As Long, Rd As Long, KK As Long, brt As Integer)
'for false shaded 3-D look
'XX,YY arer screen position Rd is outermost radius of the orb KK is the startign color
'brt is the factor by which color will chnage it is the diffeence from KK to RGB(255,255,255)
'brt is applied each step so your orb will go to white if it is large or the brt value is high
Dim nk As Long
nk = KK ' this solves my problem along with changes to following lines to use nk instead of kk
ps = _Pi
p3 = _Pi / 3
p4 = _Pi / 4
If Rd < 10 Then ps = _Pi / 6 'so small radius orbs look cool too
rdc = p4 / Rd
For c = 0 To Int(Rd * .87) Step ps
nk = brighter&(nk, brt)
CircleFill XX, YY, Rd - (c), nk
XX = XX + rdc * (c * p3) ' could be fiddled with to move the center of the gradient
YY = YY - rdc * (c * 2 * p4) ' could be fiddled with to move the center of the gradient
Next c
End Sub
Sub CircleFill (CX As Long, CY As Long, R As Long, C As Long)
'sub by SMcNeill makes a filled circle without worrying about using the paint comamnd to fill an empty circle
Dim Radius As Long, RadiusError As Long
Dim X As Long, Y As Long
Radius = Abs(R)
RadiusError = -Radius
X = Radius
Y = 0
If Radius = 0 Then PSet (CX, CY), C: Exit Sub
' Draw the middle span here so we don't draw it twice in the main loop,
' which would be a problem with blending turned on.
Line (CX - X, CY)-(CX + X, CY), C, BF
While X > Y
RadiusError = RadiusError + Y * 2 + 1
If RadiusError >= 0 Then
If X <> Y + 1 Then
Line (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
Line (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
End If
X = X - 1
RadiusError = RadiusError - X * 2
End If
Y = Y + 1
Line (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
Line (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
Wend
End Sub
Thanks for the help !
RE: So why is the color change "permanent"? - bplus - 04-24-2022
@Admin Help! Where are those tag markings coming from in my post above? (The quotes and numbers and square brackets)
I am not seeing them in the edit screen.
RE: So why is the color change "permanent"? - James D Jarvis - 04-24-2022
I tried to trim the quotes to make it easier to read. I might have done that.
(04-24-2022, 04:56 PM)bplus Wrote: (04-24-2022, 04:50 PM)James D Jarvis Wrote: [quote pid="659" dateline="1650816800"]
Values passed to a sub retain any changes made in that sub.
Which I thought shouldn't happen unless the variables were explicitly shared or were returned as part of a function call. Darn it really has been ages since I used QB.
That is new to QB64, arguments in a Sub or Function were passed by what they call ByValue in older versions of QB but QB64 does them ByRef. So if you are going to change a variable value it is best to copy the incoming value into a variable for the Sub to work with and leave the incoming variable alone after.
[/quote]
OH... I hadn't noted that in documentation. That explains a few other subroutines and functions that have been driving me crazy the past few days. Well.... fixing those just got a heck of a lot easier too.
|