Advertisement

Color confusion

Started by March 18, 2000 08:52 PM
11 comments, last by braves 24 years, 9 months ago
Hello, I am just learning DirectX programming by readin the book Tricks Of The Windows Game Programming Gurus. I am not really understanding the stuff on color. Example 8-bit DDSURFACEDESC2 ddsd; ... ... UCHAR *video_buffer = ddsd.lpSurface; int mempitch = ddsd.lPitch; video_buffer[x+y*mempitch] = color; 16-bit #define RGB16BIT565(r,g,b) ((b%32) + ((g%64) << 5) + ((r%32) << 11)) DDSURFACEDESC2 ddsd; ... ... UCHAR *video_buffer = ddsd.lpSurface; int mempitch = ddsd.lPitch; USHORT color_16 = RGB16BIT565(r,g,b); video_buffer[x+y*(mempitch >> 1)] = color_16; I understand the 8-bit version but how is this 16 bit working? Why would you divide mempitch by 2 and how does dividing it by 2 convert mempitch to 16 bit? The other question on #define RGB16BIT565(r,g,b) ((b%32) + ((g%64) << 5) + ((r%32) << 11)). Say ou do RGB16BIT565(0,0,255). How does it convert this to 16 bit Blue just by doing that shifting when with 8-bit, 255 is blue. One other thing. What''s the difference between a RGB(6,5,5), RGB(1,5,5,5) and a RGB(5,6,5). If I understand, the RGB(6,5,5) makes it a brighter Red, RGB(5,6,5) makes it a brighter Green but what the heck is a alpha and how does it change the color? I hope someone can help me. Thank you for your help in advance. Braves
Just a little note, shouldn''t the 16 bit video_buffer variable be a USHORT?
Advertisement
mempitch is specified in bytes, but the video memory is being referenced by short ints (2 bytes long). Therefore in order to refernce the pointer properly you need to divide the pitch by the size of the short int.

In eight-bit 255 is blue iff you have the palette entry at 255 indexed to blue. For a 565 16-bit surface, blue has a maximum value of 31.
On a 565 surface the first 5 bits are red, the next 6 bits are green and the last 5 bits are blue.
RRRRRGGG GGGBBBBB
The macro maps the color values to the right bits.
So if you wanted the most brilliant red you''d get:
11111000 00000000
The most brilliant blue would be:
00000000 00011111

There are other color formats. They just shift around which bits represent red green blue or alpha.

Hopefully that made some sense.
To Cloxs:
The book I am using has it UCHAR *video_buffer = ddsd.lpSurface and not USHORT *video_buffer = ddsd.lpSurface.

To SiCrane
I pretty much understand everything you said except two points. You said : mempitch is specified in bytes, but the video memory is being referenced by short ints (2 bytes long). Therefore in order to refernce the pointer properly you need to divide the pitch by the size of the short int.
why don''t you have to divide by 2 on 8-bit? Would you have to do video_buffer[x+y*(mempitch >> 2)] = color_24 if it''s a 24-bit color? The other point on : In eight-bit 255 is blue iff you have the palette entry at 255 indexed to blue. For a 565 16-bit surface, blue has a maximum value of 31.
Why is the maximum value 31 and not 255?
Thanks again




You know, I''ve never actually programmed 24 bit, so I''m not sure how the bytes are aligned.

The maximum value for blue is 31 because there''s only 5 bits for blue. Max value in five bits 11111 base two or 31 base ten. On a 565 surface, green can go up to 63 though.
braves, i have that same book. 8-bit is a mini-version of 24-bit, however it only allows 256 colors on screen simultaniuously. thats why there are three 8-bit color registers for 8-bit mode. 8-bit uses a Color Look-Up table, so it only simulates an 8-bit mode, when it actuality, it is 24-bit. it only simulates 8-bit because there weren't be enough variation of colors it it was a true 8-bit mode. hmm...three 8-bit color registers, sounds a lot like 24-bit, huh? 16-bit is (1.)5.5.5 or 5.6.6 (im using (A.)R.G.B format), 24-bit is arranged 8.8.8 (similar to 8-bit), so you can think of it as an expanded 8-bit mode, and 32-bit is 8.8.8.8, for the ultimate in colors. now, to help you figure out your RGB16BIT565 macro, think of 16-bit 5.6.5 mode as 00000.000000.00000
the first 5 bits is for red, the seonds 6 bits for green, and the last 5 bits for blue (if there were an alpha bit, green would also have just 5 bits). for red and blue, there is a possible 32 different setting avaible (however, since green has 6 bits, it can have a possibiltiy of 64 different settings). lets say you want to set red to 11011 (or 27 for you decimal lovers). ok. as explained in you RGB16BIT565 macro, red is left shifted 11 times. heres a graphical representation.
00000.000000.11011 = no shifts
00000.000001.10110 = 1 shift
00000.000011.01100 = 2 shift
00000.000110.11000 = 3 shifts.....
this continues until you make 11 shifts in which it will look like:
11011.000000.00000 = 11 shifts.
remember, the first 5 bits are for red, and isnt it right that we wanted to set the red register to 11011? so 11 shifts is correct. the same is applicable for green, when you make five shifts. try it out. and since blue is, by default, in the correct possition, no shifts are neccesary. does this help explain how color = (red<<11) + (green<<5) + blue ?
any more questions? im sure you do have some, since binary is so different than decimal. but can you figure out more than two states for switches?

Edited by - Zipster on 3/19/00 12:53:08 AM
Advertisement
Zipster,
Thank you. You have helped me understand much more than I did before. I do have a few more questions. First one, I understand why the 16-bit 5.5.5 RGB are all max of 32, because in binary 11111 = 32 and in 5.6.5 the max green can be 64 because 111111 = 64. Now the book says you can only have 6.5.5 1.5.5.5 or 5.6.5. Why can''t you have 5.5.6
and why even have an alpha if it''s transparent? I would think you would want to give some color the max. The other question I have, in the book the autor does this :// primary surface, they will be instantly visible
for (int index=0; index < 1000; index++)
{
int red = rand()%256;
int green = rand()%256;
int blue = rand()%256;
int x = rand()%640;
int y = rand()%480;
Plot_Pixel_Faster(x,y,red,green,blue.....);
}
and inside of PLOT_Pixel_Faster he calls the macro
USHORT pixel = _RGB16BIT565(red,green,blue);
Now the max color red, green or blue can be is 255(11111111)
and in 5.6.5 the max the color can be is either 32(11111) or 64(111111). Why put a 255 color into a 32 or 64 bit color? The other question I had was with 8-bit the author does this:
video_buffer[x+y*mempitch] = color;
and for 16-bit he does this
video_buffer[x+y(mempitch >> 1)] = 16_bit_color; example on
why divide by 2 and not multiply by 2?
Thank you once again in advance for you help.
braves



thats a lot of questions. ill try to divide them up:
1) technically you could have 5.5.6 or 6.5.5, of 4.10.2 for that matter, but the video card manufacturers tried to make it as even as possible, and since the human eye is most sensitive to green, it gets the extra bit.
2) the alpha bit is kinda useless, however it does easily make a certain color transparent it you dont want to alter the RGB value. ie it makes transparency easier, but cuts in half the amount of different colors you can have.
3) if you recall the _RGB16BIT565 macro it is:
((b%32) + ((g%64) << 6) + ((r%32) << 11))
you notice the %, which means modulus? this means it automatically takes the remainder of the number. so, if a number is indeed greater than 32 for red and blue, and greater than 64 for green, it takes the remainder, which is always between 0 and 31, or 0 and 63, depending on what colors register it is.
4) as for divinding mempitch by 2, recall that 16-bit pixels require twice as much memory as 8-bit pixels, but we still have to fit the same number of pixels in each row (assume 800x600). so each row must be 800 pixels regardless of color depth. the mempitch for 8-bit is 800. however, sonce 16-bit is twice as big, we need to cut mempitch in half to acompinsate. example: plot pixel at (10,30) in 8-bit, pixel size is 1 (this is for example purposes, remember. pixel size isn''t really one):
Video_Buffer[(10*(30*800)) * 1 ] = color;
the bolded one is the pixel size^
plot the same pixel in 16-bit:
Video_Buffer[(10*(30*400)) * 2 ] = color;
the bolded two is the pixel size^
both results are the same!!
does this help?
Dedicated:
Yes, you answered all my questions. Thank you very much. Just want to see if I better understand this. I could have wrote this same macro like this
((b%32) + ((g%64) << 6) + ((r%32) << 11))
((b&31) + ((g&63) << 6) + ((r&31) << 11))
The second one would be alot faster too? Right?
Thank you again for you help
braves

actually, the second macro could be totally different in some cases. for example take 62 as a blue values. in the second macro, 62 % 31 = 0
while in the first macro 62 % 32 = 30
big difference. stick with the first one.

This topic is closed to new replies.

Advertisement