Jump to content
  • Advertisement
Sign in to follow this  
DarkMatter2008

Shading an RGB value

This topic is 3435 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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
Advertisement
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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!