Advertisement

the % in color

Started by March 19, 2000 01:53 AM
16 comments, last by Zipster 24 years, 11 months ago
ooooooooooooh, i realized my mistake. if you want to use 24-bit color ranges (i.e 0 to 255) in 16-bit mode, then the modulus equation is used. however, if you prefer to stick with values between 0 and 31, and 0 and 63, then the bitshift equation is used.
its a all a matter of preference then!!
why didn't anyone explain that?
(SiCrane partially explained that, but he don't say the difference between the two)

Edited by - Zipster on 3/19/00 1:30:01 PM
Zipster:

You aren''t listening to anyone else''s posts. With 565 16-bit color, you NEED to have the following ranges:

red: 0 through 31
green: 0 through 63
blue: 0 through 31

Trying to stuff the number 247 into 5 bits for red ISN''T GOING TO WORK and will give you bizarre colors. 5 bits can only hold the number 0 through 31 -- NOT 247. If you tried to use 247 without making sure it was in the range, you would send the wrong number to the pixel blitter, and get colors that looked NOTHING like what you wanted.

It is definitely NOT a matter of preference. If you are trying to use 16-bit color, you need to verify that the numbers fall within the ranges -- otherwise, the following can happen:

red = 24
green = 52
blue = 85

Since the blue element can only be in the range of 0 through 31, if you add it at this point, portions of the blue element will spill into the green element.

If you don''t understand how this works, I recommend that you read up on bit math. I have a hunch that you don''t understand exactly what you''re doing.

-Chris

---<<>>---
Chris Rouillard
Software Engineer
crouilla@hotmail.com
---<<>>--- Chris Rouillard Software Engineercrouilla@hotmail.com
Advertisement
Speaking of these modulus operators... I believe that they are pretty much useless for creating RGB values in 16-bit mode EVEN IF YOU WANT TO NORMALIZE A 24-BIT COLOR. The reason for this is that you really want to save the most significant bits of each 8-bit component, not the least significant as the modulus operator will do.

You would be much better off making sure your initial components are between 0-255 (just program it that way and use assertions or something to make sure its true, don''t try using % to force values into this range.)

Then, use division (or simply bit shifting) to remove the right most bits and achive the propper length:

RGB16 = ((red >> 3) << 11) + ((green >> 2) << 5) + ((blue >> 3))

The reason for this additional shifting becomes clear after considering a couple special examples...

A fairly dark green: 00111111 would become bright green: 111111 using the % operator which is clearly not correct. Using the >> operator whe get 001111 which is scaled corectly to the new range.

A meduim green: 10000000 would become black: 000000 using the % operator! This is certainly incorrect, but with the >> operator you get 100000 which is *still* medium green in the new color range.

Hope this helps.
Oh, and one more thing... Zipster, % always means modulus (unless you have overloaded it) The real question here is "Does the modulus operator do what I want in this situation?" And the answer to that is no (as you have observed.)

Remember, % does not work for namalizing... its only good for forcing random numbers into a range and for getting the least significant bits (although a bitmast should be faster in any case where you are moding by a power of 2.)
i know EXACTLY what im doing. the red and blue bits in 5.6.5 only support up to 31, and green only up to 63. when i said "a matter of preference", i meant that if you want to pass values from 0 to 255 through a function (because you''re used to them from 8-bit mode), use the modulus macro to cut them down into appropiate numbers (0 to 31, 0 to 63), but if you want to be a good sport and just pass the values as 0 to 63 or 0 to 31, then use the pure bitshift macro. so it could be considerend preference on how you pass the values.

anyways, i dont personally use 16-bit (becuase of the previous arguments), and since 24-bit isn''t supported on most video cards, i just program in 32-bit (which is the fasted form of memory addressing on Pentiums )

the lesson is, i realized what i was doing wrong, and from now on, my motto is: SCREW 16-BIT MODE!!!
32 bit mode might be faster on an ''accessing individual values'', but most of the time sending 1 32bit value is no faster than sending 2 16-bit values at once as part of a 32 bit pair. So if you think it''ll run faster than 16 bit mode, think again. You''ll be sending twice the data along the pipeline and that tends to take almost twice as long. And that''s not counting cache thrashing caused by your data being twice the size.
Advertisement
Chippydip:

Great idea about shifting the bits instead of using modulus for 16-bit color. This is my first attempt at 16-bit for a program... all of my testing demos have been 24-bit. I've been working on the back-end AI for quite some time, so I haven't delved into the graphics portion yet, but I'll be sure to keep this in mind when converting my images.

As for verifying the original number is between 0 and 255, I recommend the bitwise AND (& -- as in "red & 255") -- I'm sure it's quicker than using multiple if statements, and a lot cleaner (though maybe a little harder to understand if reading the code later)... or maybe it's just the networking geek in me.

Basically, all of your verification and shifting could be done in one line:

RGB16 = (((red & 255) >> 3) << 11) + (((green & 255) >> 2) << 5) + (((blue & 255) >> 3))

-Chris

---<<>>---
Chris Rouillard
Software Engineer
crouilla@hotmail.com

Edited by - crouilla on 3/20/00 4:20:14 AM
---<<>>--- Chris Rouillard Software Engineercrouilla@hotmail.com
Yes, the verification works that way, but I was just thinking that it shouldn''t really be needed. In all the cases I can think of the color components would be in the 0-255 range anyway... I was just suggesting the checking (asserts or some other *debug* method) to make sure you don''t screw up when coding... If you know a certain value will have extra "grarbage" bits, then it might be easier to & on a case by case basis. It really depends on what your game system is like and what you are using the color conversions for. There might even be a case where the color components are more than 8 bits!?! so you would be losing actual information by using the & on the value instead of some additional shifting... Either way, though... as long as you are aware of what you are doing and using the right operators for the right purpose you should be fine.

This topic is closed to new replies.

Advertisement