color blending in 5551 mode???
color blending in 5551 mode???
Could someone please help me out with color blending?
Basically, I need a fast function which would take 2 unsigned shorts representing PSP's 5551 colors and will return the third, representing the resulted blended color:
u16 blend(u16 color1, u16 color2);
for example, if I blend green and white, the func() should return light green...
I am really bad with bit operations, so any help / advise will be greatly appreciated...
Basically, I need a fast function which would take 2 unsigned shorts representing PSP's 5551 colors and will return the third, representing the resulted blended color:
u16 blend(u16 color1, u16 color2);
for example, if I blend green and white, the func() should return light green...
I am really bad with bit operations, so any help / advise will be greatly appreciated...
for one value:
Code: Select all
C3_r = (C1_r + C2_r) >> 1; // eg R value
- ChaosKnight
- Posts: 142
- Joined: Thu Apr 14, 2005 2:08 am
- Location: Florida, USA
And if you want even more examples (not PSP specific but good) you can check out the late Seumas McNally's work on software pixel blending here: http://www.ldagames.com/seumas/progblend.html
w00t
Based on your advise I came up with following func() but it does not work
correctly for all colors.
for example when I blend magenta and white I end up with dome dark blue shade; light blue colors also become darker...
what am I doing wrong here?
PS: Thank you for all your help, guys...
unsigned short blend(unsigned short c1, unsigned short c2){
return (unsigned short)(((c1 & 0xF7BC)>>1) + ((c2 & 0xF7BC)>>1));
}
correctly for all colors.
for example when I blend magenta and white I end up with dome dark blue shade; light blue colors also become darker...
what am I doing wrong here?
PS: Thank you for all your help, guys...
unsigned short blend(unsigned short c1, unsigned short c2){
return (unsigned short)(((c1 & 0xF7BC)>>1) + ((c2 & 0xF7BC)>>1));
}
It should work, Mine PSP is not working right now soo I can not test.
But I did a test with Notepad and the Calculator.
White
=
31 31 31
=
11111 11111 11111 0
and
11110 11110 11110 0
=
11110 11110 11110 0
>> 1
=
01111 01111 01111 0
Magenta
=
31 0 31
11111 00000 11111 0
and
11110 11110 11110 0
=
11110 00000 11110 0
>> 1
=
01111 00000 01111 0
01111 01111 01111 0
+
01111 00000 01111 0
=
11110 01111 11110 0
=
30 15 30
=
Lighter Magenta
But I did a test with Notepad and the Calculator.
White
=
31 31 31
=
11111 11111 11111 0
and
11110 11110 11110 0
=
11110 11110 11110 0
>> 1
=
01111 01111 01111 0
Magenta
=
31 0 31
11111 00000 11111 0
and
11110 11110 11110 0
=
11110 00000 11110 0
>> 1
=
01111 00000 01111 0
01111 01111 01111 0
+
01111 00000 01111 0
=
11110 01111 11110 0
=
30 15 30
=
Lighter Magenta
This one should work too and you don't lost the one precious bit of precicion either:
[/code]
Code: Select all
const unsigned short maskRB = 0x7c1f;
const unsigned short maskG = 0x03e0;
unsigned short res = ((((a & maskRB) + (b & maskRB) + 0x401) >> 1) & maskRB) |
((((a & maskG) + (b & maskG) + 0x20) >> 1) & maskG);
My texture class says:
And it works and looks ok, so I assume that I made right assumption :)
I did not check what kind of assembly the code generates, but as the alpha bit is last (and not used in this case), it should work in 16bit. On 565 you'll need to do it in 32bit.
Code: Select all
inline u16 pack5551( u8 r, u8 g, u8 b, u8 a )
{
return (r >> 3) | ((g & 0xf8) << 2) | ((b & 0xf8) << 7) | ((a & 0x80) << 8);
}
I did not check what kind of assembly the code generates, but as the alpha bit is last (and not used in this case), it should work in 16bit. On 565 you'll need to do it in 32bit.