Sign in to follow this  

Shading an RGB value

Recommended Posts

Hello All, I'm trying to shade and rgb value by a value
int red = sha << 16;
int green = sha<< 8;
int blue = sha;

color -= (red | green | blue);
This seems to work, until one of the colours reaches is lowest limit, i.e. when red is out it'll rollover and go bright green or blue. Is there some sort of fancy mask to prevent this? Thanks In advance.

Share this post

Link to post
Share on other sites
What Zipster said.

You could write a color class, which implements a subtraction operator (that is, if you are on c++, otherwise you would write a function "subtract()"), which internally does subtraction on three seperate values. Or if you rely on all components being in a single value, you have to decompose it first (using shifts and bitand's).

Upon subtraction, the easiest way is to convert each component into a signed integer of a bigger bitsize, perform a subtraction, clamp it to an upper/lower limit, and cast it back into the components/the color value.

Share this post

Link to post
Share on other sites
Bitwise ops, just revert what you have already used:
// your code
int red = sha << 16;
int green = sha << 8;
int blue = sha;

First, a struct could be handy:
// r,g,b are supposef to represent value between 0 and 0xFF.
// We have declared them as integers in order to take "over/under-flow"
// into account.
struct RGB {
int r, g, b;

Then, to get the components:
assert (sizeof (int) > 1); // But you can bet on that.

// How we would decompose:
RGB rgb = {
(sha >> 16) & 0xFF, // The value 0xFF is 11111111 in binary,
(sha >> 8) & 0xFF, // and with the bitand we filter out every bit
sha & 0xFF // that is on the "left" side

Now we are going to define a clamp function:
void clamp (RGB *rgb) {
assert (0 != rgb);
if (rgb->r < 0) rgb->r = 0;
else if (rgb->r > 0xFF) rgb->r = 0xFF;

if (rgb->g < 0) rgb->g = 0;
else if (rgb->g > 0xFF) rgb->g = 0xFF;

if (rgb->b < 0) rgb->b = 0;
else if (rgb->b > 0xFF) rgb->b = 0xFF;

Next, an example function to add colors (which will use the clamping function):
void clamp (RGB *target, const RGB *lhs, const RGB *rhs) {
assert (0 != target && 0 != lhs && 0 != rhs);
target->r = lhs->r + rhs->r;
target->g = lhs->g + rhs->g;
target->b = lhs->b + rhs->b;
clamp (target);

At last, you can use your three rgb values and shift up what you need:
RGB alpha, bravo, charlie;
add (&alpha, &bravo, &charlie);
uint32_t final = (alpha.r << 16) | (alpha.g << 8) | alpha.b;

Code is in plain C. Not tested.

Share this post

Link to post
Share on other sites
Thanks for that, it was really really help full.

I modified one of the functions because I don't really need so many stucts lying around.

void clamp (RGB *lhs, const int shade) {
lhs->r += shade;
lhs->g += shade;
lhs->b += shade;
clamp (lhs);

Thanks again :)

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this