Help! RGB to R,G,B

Previous topic - Next topic

PeeJay

I'm having a total mental block on this one.

I use GETPIXEL to get the RGB value, but I can't remember the formula to convert it into the separate red, green and blue components.

Thanks in advance
www.peejays-remakes.co.uk
For games, remakes, and GL Basic Tutorials
Artificial Intelligence is no match for Natural Stupidity

Quentin

Code (glbasic) Select
 
  color = RGB(250, 13, 56)
  red = bAND(color, 255)
  green = bAND(color / 256, 255)
  blue = bAND(color / 256 * 256), 255)
this is also in one of the samples delivered with GLBasic I think but I don't know the exact location.

PeeJay

thanks Quentin, I was just having a total mental block. I did end up with formulae involving INTEGERS and MODS, but I knew there was a simpler way of doing it! Thanks again
www.peejays-remakes.co.uk
For games, remakes, and GL Basic Tutorials
Artificial Intelligence is no match for Natural Stupidity

Moru

(Explanation why the code above works :-)

The RGB code is just a hexadecimal number 0 - FF grouped in three sections (for 24 bit anyway)

Red, Green, Blue
FF, FF, FF

To single them out, bAND the colourcode with FF (256) and you get the rightmost number.
Then you move the whole thing to the right, removing decimals ( colourcode / 256 ) and start all over again with the bAND.

kamakazieturtle

Just found this little snippet, so useful. But I thought I would add that the there was a small error in the fourth line. The left parentheses was missing before the first 256.

Code (glbasic) Select

color = RGB(250, 13, 56)
red = bAND(color, 255)
green = bAND(color / 256, 255)
blue = bAND(color / (256 * 256), 255)
                    ^

MrTAToad

I use this :

Code (glbasic) Select
FUNCTION RGBR%:colour%
INLINE
return (DGNat) colour & 255;
ENDINLINE
ENDFUNCTION

FUNCTION RGBG%:colour%
INLINE
return (DGNat) ((colour>>8) & 255);
ENDINLINE
ENDFUNCTION

FUNCTION RGBB%:colour%
INLINE
return (DGNat) ((colour>>16) & 255);
ENDINLINE
ENDFUNCTION

erico

sometimes for collision, I do a little black/white map (top down) and check for black free, white collision, so get pixel comes into play. Does anyone know if this is a fast command on i-plataforms/pc/mac?

MrTAToad

I don't think GETPIXEL is terribly fast - although, of course, you would put the map into a 2D array and access that :)

Ian Price

It's fast enough on all platforms (depending on number of checks), but be aware that PC gfx cards vary and values for the same colour can differ by a significant amount (IIRC Gernot quoted as much as 16%). So black on one gfx card may be (0,0,0) but on another they might be (0,0,1). Other platforms should be much more predictable.
I came. I saw. I played.

Marmor

ERICO

why not create an collisionsarray from the map ?

erico

Quote from: Marmor on 2011-Jul-02
ERICO
why not create an collisionsarray from the map ?

yep, like mr. tatoad said, that is another solution, the best one.
Fact is that I learned how to use arrays a couple years ago, before that,
I would try everything to reach the goal.

That getpixel solution was used on a app to wander on a 3d apartment, like doom.
I didn´t want to use 3d collisions at the time,
so I went by creating a B/W 1bit top map image of the apartment, have a cursor/point for camera position and check that point , if black no collision, if white, collision. It was quite troublesome to get (diagonal) movements after collision working...

These thoughts come to mind now as I´m working on a sort of pong/puck game(2D). The board is displayed in perspective and I don´t think working collisions and all inside the diagonal board would be a good idea. I´m working an array to be the top down representation of the board where everything happens, then a routine reads this array and a few other variables and draw the diagonal thing. A 2 player split screen game would read this routine twice.

Does it make any sense?

Ian Price

2D map arrays are indeed faster than GETPIXEL, however they may not be totally accurate, especially if there are slopes or odd shapes within the array. Sometimes you have to use more than just arrays and/or multiple checks on the areas surrounding the player.
I came. I saw. I played.

Slydog

If it is top-down only, and looks '2D' from the top, you could always add Box2D physics.
Then you define polygon collision areas and let the engine handle the collision detection for you.

Oh, and using hex makes the colour separation code cleaner, IMO:
Code (glbasic) Select
r = bAND(colour,         0xff)
g = bAND(colour/0x100,   0xff)
b = bAND(colour/0x10000, 0xff)

My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Slydog

Ha, or use this new TYPE I just whipped up:
(Not sure if it's useful to anybody!)
VERY UNTESTED!

Code (glbasic) Select
TYPE TColour
colour%

FUNCTION Set%: r%, g%, b%
self.colour = RGB(r, g, b)
ENDFUNCTION

FUNCTION R%:
RETURN bAND(self.colour, 0xff)
ENDFUNCTION

FUNCTION G%:
RETURN bAND(self.colour/0x100, 0xff)
ENDFUNCTION

FUNCTION B%:
RETURN bAND(self.colour/0x10000, 0xff)
ENDFUNCTION

// Untested . . .
FUNCTION Alpha%:
RETURN bAND(self.colour/0x1000000, 0xff)
ENDFUNCTION

FUNCTION Brightness%: amount%
LOCAL r%, g%, b%, percent#
    percent = amount / 100.0
r = self.R()
g = self.G()
b = self.B()
    IF percent >= 0
    r = INTEGER((255 - r) * percent + r)
    g = INTEGER((255 - g) * percent + g)
    b = INTEGER((255 - b) * percent + b)
    ELSE
    r = INTEGER(r * ABS(-1 - percent))
    g = INTEGER(g * ABS(-1 - percent))
    b = INTEGER(b * ABS(-1 - percent))
    ENDIF
    RETURN RGB(r, g, b)
ENDFUNCTION
ENDTYPE


Usage:
Code (glbasic) Select

LOCAL rgb_tree AS TColour
LOCAL rgb_sky AS TColour
LOCAL rgb_sky_dark AS TColour

rgb_sky.Set(0, 220, 250) // Using internal 'Set()' member function
rgb_tree.colour = RGB(0, 200, 0) // Directly setting 'colour' works too
rgb_sky_dark.colour = rgb_sky.Brightness(-40) // Sets the 'rgb_sky_dark' to a 40% darker version of 'rgb_sky'

LOCAL green%
green = rgb_tree.G() // Access to the individual colour components
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]