inline unsigned int RGBA(unsigned int R, unsigned int G, unsigned int B, unsigned int A)
{
return (unsigned int)((A & 0xFF) << 24 |
(R & 0XFF) << 16 |
(G & 0XFF) << 8 |
(B & 0XFF));
}
unsigned int alphaBlend(unsigned int a, unsigned int b){
float aa = 255.f/(a>>24&0xff);// A colors alpha channel as a float 0 - 1
float ba = 255.f/(b>>24&0xff);// B colors alpha channel as a float 0 - 1
char ar = aa * (a&0xff);//alpha influenced
char ag = aa * (a>>8&0xff);
char ab = aa * (a>>16&0xff);
char br = ba * (b&0xff);//alpha influenced
char bg = ba * (b>>8&0xff);
char bb = ba * (b>>16&0xff);
return RGBA(ar+br,ag+bg,ab+bb,(a+b)*255);
}
unsigned int RGBA(unsigned int R, unsigned int G, unsigned int B, unsigned int A)
{
return (unsigned int)((A & 0xFF) << 24 |
(R & 0XFF) << 16 |
(G & 0XFF) << 8 |
(B & 0XFF));
}
unsigned int alphaBlend(unsigned int a, unsigned int b){
float aa = 255.f/(a>>24&0xff);// A colors alpha channel as a float 0 - 1
float ba = 255.f/(b>>24&0xff);// B colors alpha channel as a float 0 - 1
char ar = aa * (a&0xff);//alpha influenced
char ag = aa * (a>>8&0xff);
char ab = aa * (a>>16&0xff);
char br = ba * (b&0xff);//alpha influenced
char bg = ba * (b>>8&0xff);
char bb = ba * (b>>16&0xff);
return RGBA(ar+br,ag+bg,ab+bb,(a+b)*255);
}
void XgeFillScreenRect(XgeColor Color, int x0, int y0, int width, int height)
{
int skipX = PSP_LINE_SIZE - width;
int x, y;
XgeColor* data = XgeGetVramDrawBuffer() + x0 + y0 * PSP_LINE_SIZE;
for(y = 0; y < height; y++, data += skipX)
{
for(x = 0; x < width; x++, data++)
*data = alphaBlend(Color,data);//We put the mixed color
}
}
#define RGBA(r, g, b, a) ((r)|((g)<<8)|((b)<<16)|((a)<<24)) //Use this instead of the other function
void blitAlphaImageToImage(int sx, int sy, int width, int height, Image* source, int dx, int dy, Image* destination)//With alpha
{
// TODO Blend! - Done! xD
Color* destinationData = &destination->data[destination->textureWidth * dy + dx];
int destinationSkipX = destination->textureWidth - width;
Color* sourceData = &source->data[source->textureWidth * sy + sx];
int sourceSkipX = source->textureWidth - width;
int x, y;
for (y = 0; y < height; y++, destinationData += destinationSkipX, sourceData += sourceSkipX) {
for (x = 0; x < width; x++, destinationData++, sourceData++) {
Color color = *sourceData;
*destinationData = alphaBlend(*destinationData,color);
}
}
}
This is what works for me, I haven't tested the rectangle function, sorry :-S
No idea of how did you got that :-S
It is not possible to do that alpha blending without using two colors, maybe with the GU, but that would do the same thing really.
I don't use images but fillscreenrect only for memory purposes...
I want to find a way to draw an alpha rectangle on the screen,
just like sceGuTexImage, but without loading something like 1MB of image...
Anyway sorry for misunderstanding with the two colors and thanks both.
unsigned int alphaBlend(unsigned int a, unsigned int b){
float aa = 255.f/(a>>24&0xff);// A colors alpha channel as a float 0 - 1
float ba = 1.f-(255.f/(b>>24&0xff));// B colors alpha channel as a float 0 - 1
unsigned char ar = aa * (a&0xff);//alpha influenced
unsigned char ag = aa * (a>>8&0xff);
unsigned char ab = aa * (a>>16&0xff);
unsigned char br = ba * (b&0xff);//alpha influenced
unsigned char bg = ba * (b>>8&0xff);
unsigned char bb = ba * (b>>16&0xff);
return RGBA(ar+br,ag+bg,ab+bb,(a+b)*255);
}
should do the trick.
I do advise switching to the GU as this is terribly slow on the CPU, you need to do this calculation for each pixel :/ where as the GPU has built in hardware blending procedures which are extremely fast.
-=EDIT=-
Oh crap and the psp uses 0xAABBGGRR not 0xAARRGGBB so this is the updated RGBA func
Just for note: It should be 1-aalpha, if anything, for the common alpha blending behaviour.
Still, this software solution is stupid for anything else but learning how alpha blending works.
pspsdk/samples/gu is your first source of information. Afterwards, there are lots of open source graphical engines available, that you can learn from, like OSlib or triEngine to name only two.
Using gu is very simple. It's just a matter of a little time investment to learn the concepts of a state machine and a very basic graphics api. If you have some pre-knowledge on OpenGL it's easy as cake.