something's wrong with my 16bit -> 15bit function.

Started by
7 comments, last by VisualLR 23 years, 11 months ago
I know, I know, Im getting sick of posting these kinds of questions myself, but once I get this done I'll be able to move on to more interesting parts of my project... Ive been working on making my game work on both 16bit and 15bit cards, but my ConvertTo15Bit function isn't working, instead of converting it correctly, it converts everything in a blueish tone... this is my function: void ConvertTo15Bit(unsigned char *image, int w, int h) {     unsigned char temp;     for (int i=0; i < w*h; i++)     {         temp = image & 31;         temp += (image & 65504) >> 1;         image = temp;     } } <hr> but like I said before, that converts everything into a blueish color… ok, for some reason this thing is taking some of the code as HTML, so in the for i is less than w*h and on the first line in the for temp = image & 31; everything else is ok… any suggestions? Luis Sempe<BR>visual@guate.net<BR><a href="http://www.spheregames.com">http://www.spheregames.com</a><P><BR> Edited by - VisualLR on 5/7/00 4:07:12 PM Edited by - VisualLR on 5/7/00 4:08:31 PM </i> Edited by - VisualLR on 5/7/00 4:09:36 PM Edited by - VisualLR on 5/7/00 4:10:11 PM Edited by - VisualLR on 5/7/00 4:12:12 PM
Advertisement
You are letting the extra green bit flow into the blue component.

What you want to do is actually a bit more complex/slow.

To convert from 16 bit 565 to 16 bit 555 do this:

// Some handy macros;
#DEFINE CONVERTRED( c ) (((c) & 0xF800) >> 1)
#DEFINE CONVERTGREEN( c ) ((((c) & 0x7E0) >> 6) << 5)
#DEFINE CONVERTBLUE( c ) (((c) & 0x1F))

WORD sourceColor; // Is in 565 format;
WORD destColor; // Is going to be in 555 format;

destColor = CONVERTRED( sourceColor ) +
CONVERTGREEN( sourceColor ) +
CONVERTBLUE( sourceColor );

Note: actually an OR operator would be more correct and nice over here but this will work too. THe messageboard f*cks with my OR operators.

this can probably be optimized and it could contain errors. But this should be the idea. Finally note that the MSB (most significant bit) contains random data after the conversion (the msb of the red component). You might wanna set that to some ok value. (could contain alpha info).

I also suggest constructing your loop as follows:

void ConvertTo15Bit(WORD *image, int w, int h)
{
int targetPixelSize = w*h;
for (int i=0; i < w*h; i++)
{
*image = CONVERT( *image );
image++;
}
}

Notice that I'm indexing 16 bit numbers here. Also notice that I precalculate the w*h. Cause in your loop it gets done every iteration (although a cool compiler prolly will optimize this away). Secondly also notice that I'm not indexing the pointer with the square brackets cause that is slow. I just advance to the next pixel every iteration. Finally I should point out that this routine does not conside the difference between pitch and width of a surface. But neither did your routine . You probably won't need it then .

ANyway, succes.

Jaap Suter

____________________________
Mmmm, I'll have to think of one.

Edited by - s9801758 on 5/7/00 4:27:32 PM
____________________________Mmmm, I''ll have to think of one.
The bluish tone i casued by the use of char instead of word.
Try replacing the unsigned char* to unsigned short*.
What you are doing right now is to truncate the color into
a byte, wich just hold the blue attribute.
16bpp color : rrrrrggggggbbbbb
you char(8 bit) will just half that color -> gggbbbbb.


void ConvertTo15Bit(unsigned short *image, int w, int h)
{
unsigned short temp; // 16bits

for (int i=0; i < w*h; i++)
{
temp = image & 31;
temp += (image & 65504) >> 1;
image = temp;<br> }<br>}<br><br>/ Tooon<br> </i> <br><br>
Tooon, you''re right. THat was his only problem.
I was thinking too complex again. I feel stupid.

But ehm, on another question
why are you ANDing with 31? That doesn''t change much of the value does it?

Jaap Suter

____________________________
Mmmm, I''ll have to think of one.
____________________________Mmmm, I''ll have to think of one.
VisualLR: Sorry for giving you the wrong function last time, I was ANDing with an extra bit.
Jaap: He's ANDing with 31 because when he doesn't the blue value gets shifted too.

So the function becomes like this:
unsigned short p565to555(unsigned short oldcol){   return(oldcol&31+(oldcol&65472)>>1);}; 


Hope it works

Edited by - bosjoh on May 9, 2000 2:22:54 PM
don''t worry about it bosjoh... I think Tooon is also right, because at the moment, my whole graphics engine uses unsigned char *, instead of unsigned short *, so Im going to fix that as well.

Thanks! I''ll let you know how it goes.

later!



Luis Sempe
visual@guate.net
http://www.spheregames.com


I got one more question, where''d you guys learn this stuff? cause Ive just learned how to do it, without fully understanding the theory behind it...

gonna go fix that now.

bye!



Luis Sempe
visual@guate.net
http://www.spheregames.com


ME == STUPID.

I feel so dumb, trying to give a helpfull answer that only contains mistakes. I''m sorry and thanks for correcting me.

Jaap Suter
____________________________Mmmm, I''ll have to think of one.
Here we go...

First let me explain the pixel layout: rrrrrggggggbbbbb.
There are 5 red bits, 6 green bits and 5 blue bits. The other pixel layout is this: 0rrrrrgggggbbbbb.
What we want to do is to shift the bits so the r''s and g''s fall in place with the new pixel layout. Blue shouldn''t be changed (that''s why you take this seperately), but red and green should. But it costs a green bit (6 bits to 5 bits green value).
So first we are taking blue out using the AND operator:
rrrrrggggggbbbbb0000000000011111 (31)----------------00000000000bbbbb

You can also use %32 in stead of AND 31, but AND is faster.
Then we''re taking the red and green value out of the pixel value (I ignore the last green bit):
rrrrrggggggbbbbb1111111111000000 (65472)----------------rrrrrggggg000000

The last thing to do is to shift the bits (blue is ignored):
rrrrrggggg000000----------------0rrrrrggggg00000 (new value)0rrrrrggggg00000 (555 value)

And adding blue let it match the new 555 pixel layout.

This topic is closed to new replies.

Advertisement