Skip to main content
GameDev.net gamedev.net
🔒 Locked

Altering a 32 bit integer..

Started by mrmrcoleman Jan 14, 2005 at 6:39 PM 11 replies 1.3k views
Original Post
mrmrcoleman
mrmrcoleman
Hello, in my program I have a 32 bit integer which represents 4 8 bit values (Alpha, Red, Green, and Blue). AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB I need to be able to alter these values independetly, so for example, increase the Alpha by 10, or decrease the Red by 15. How do I do this? Thanks in advance. Kind regards. Mark Coleman
HarryW
HarryW
unsigned int colour = 0x12345678;unsigned char alpha = (colour & 0xFF000000) >> 24;unsigned char red =   (colour & 0x00FF0000) >> 16;unsigned char green = (colour & 0x0000FF00) >> 8;unsigned char blue =   colour & 0x000000FF;// changes come stuff then re-set colourcolour = (alpha << 24) || (red << 16) || (green << 8) || blue;
Harry.
ajas95
ajas95
struct argb{    union {        unsigned int num;        struct {            unsigned char b,g,r,a;        };    };};argb my_color;my_color.r = 0x88;my_color.g = 0x88;my_color.b = 0xff;my_color.a = 0xff;std::cout << my_color.num << std::endl;


There is a fair amount of ugliness in coding like this... but what you want to do is fairly ugly by nature, so this should be fine :)
mrmrcoleman
mrmrcoleman
Thanks for the feedback guys, I think I got it now!

Kind regards.

Mark Coleman
SnprBoB86
SnprBoB86
ajas95's solution isn't really that ugly. It uses one of the more advanced C++ features perfectly, but might not annonymous unions and annonymous structures might not have the best support from some compilers :-(

Reguardless, I would do it with the union technique, its just so simple...
silvermace
silvermace
just note that in the anon-struct inside the union the order of the unsigned char variables b,g,r,a this is important because you specified 'ARGB8888' color format thus, the integers higher bits (in the last byte) must be where the Alpha component is stored, and similarly for the other byte components.
Nemesis2k2
Nemesis2k2
Quote:
Hello, in my program I have a 32 bit integer which represents 4 8 bit values (Alpha, Red, Green, and Blue).

Why? Packing the data members together serves no purpose. They are seperate, so treat them as such. If there is some reason you need them packed in this form (eg, you're dealing with some outside library that has this limitation), then provide a function that packs them to send off to the library, or allows you to construct a color from a packed representation. You could also extend this class to support constructing from, or generating different packed representations, so you could use RGBA, ARGB, etc.

class Color{public:	Color(const unsigned char& argR, const unsigned char& argG, 	      const unsigned char& argB, const unsigned char& argA) 	      :r(argR), g(argG), b(argB), a(argA) {}	Color(const unsigned int& packedColor)	{		a = (packedColor & 0xFF000000) >> 24;		r = (packedColor & 0x00FF0000) >> 16;		g = (packedColor & 0x0000FF00) >> 8;		b = (packedColor & 0x000000FF);	}		unsigned int PackMembers() const	{		Unsigned int packedColor;		packedColor = a;		packedColor = (packedColor << 8) | r;		packedColor = (packedColor << 8) | g;		packedColor = (packedColor << 8) | b;		return packedColor;	}	unsigned char r, g, b, a;};


A real working color class would be done a bit differently to this. Personally, I'd probably store the color values as floating point numbers clamped within the range [0, 1], and I'd use an enumeration in the functions that deal with packed representations, to indicate which packed form you are working with, but the point is, you should be using a class to represent things like this. They are infinitely more flexible.
Genjix
Genjix
or use a function to return an int when provided with r,g,b,a chars.
Nemesis2k2
Nemesis2k2
You could, but I definately wouldn't recommend it, for many reasons. The function should be a member function of the color class. It's the logical choise, and the one that'll cause the least problems.
pTymN
pTymN
Quote:
A real working color class would be done a bit differently to this. Personally, I'd probably store the color values as floating point numbers clamped within the range [0, 1], and I'd use an enumeration in the functions that deal with packed representations, to indicate which packed form you are working with, but the point is, you should be using a class to represent things like this. They are infinitely more flexible.


Float=bad, integer=good.

Experience has shown me that classes do what they claim to do well, binding the data and the code together. That is not particularly more flexible than having disconnectioned functions/data.
 
Nemesis2k2
Nemesis2k2
Quote:
Float=bad, integer=good.

Depends on the application. For colors, generally, I'd agree, but in graphics, a lot of things require color data as floats, and if you supply them as ints, they'll have to convert for you behind the scenes. I prefer to keep them in the native types in which they're used.

Quote:
Experience has shown me that classes do what they claim to do well, binding the data and the code together. That is not particularly more flexible than having disconnectioned functions/data.

For the record, most of OOP is about seperation of data from code, not binding them together, but anyway. I'm not going to try and justify the logic behind OOP to support my argument. Implement it however you want. OOP has caught on in a big way pretty much everywhere though, for good reasons. I used to implement things such as this the way you describe when I was starting out in programming. Once I got a grasp for OOP, I never looked back. It is much more natural, logical, and flexible. Most importantly, it's just plain easier to do, and easier to modify later, there's just a bit more of a learning curve involved.
iMalc
iMalc
Quote:
Original post by Nemesis2k2
Quote:
Float=bad, integer=good.

Depends on the application. For colors, generally, I'd agree, but in graphics, a lot of things require color data as floats, and if you supply them as ints, they'll have to convert for you behind the scenes. I prefer to keep them in the native types in which they're used.
I am very surprised that you say many things require color data as floats. The only place I've seen that it would be appropriate to use floats is in a ray-tracer, and even then you can do without by using fixed-point.

Lets face it, the end result of a pixel on the screen is going to be in an integer ARGB or other format. So why go int -> float -> int. Those conversions are expensive per-pixel, when you can do without! IMHO it would be better to define a class that uses fixed-point numbers.

I'm looking at this from the perspective of having written a software 3D-engine btw.
Nemesis2k2
Nemesis2k2
It's by no means unusual. From the OpenGL 1.2 descrption for glColor:

"Current color values are stored in floating-point format, with unspecified mantissa and exponent sizes. Unsigned integer color components, when specified, are linearly mapped to floating-point values such that the largest representable value maps to 1.0 (full intensity), and 0 maps to 0.0 (zero intensity)...."

I think you'll find floats are pretty universal for colors.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.