Dark Bit Factory & Gravity
PROGRAMMING => C / C++ /C# => Topic started by: mike_g on July 18, 2008
-
Hi, I have a fadeout effect, but its too slow o my eeepc. I get 15fps :/ I have a fast version ,commented out, but it fades out too quickly. The bottleneck seems to be the floating point maths and the type casting. Heres the code:
void blit_and_fade(float mod)
{
int i, size = GRAPHICS_W*GRAPHICS_H;
Uint32 *pix = (Uint32*)screen->pixels;
Uint32 *buf = buffer;
Uint32 r_b, g;
for(i=0; i<size; i++, pix++, buf++)
{
*pix = *buf;
r_b = (Uint32)((*buf & 0x00FF00FF) * mod) & 0x00FF00FF;
g = (Uint32)((*buf & 0x0000FF00) * mod) & 0x0000FF00;
*buf = r_b | g;
//*buf = (*buf >> 1) & 8355711; // <- FAST FADE LOOKS CRAP
}
}Any suggestion how I coud do this w/o the floating point? Cheers.
-
Straight forward:
void fade(uin32 *dst, uint32 *src, int size, float mod)
{
int f= mod * 256.0f;
for(int i=0; i<size; i++)
{
uint32 col= src[i];
int r= (col>>16&255)*f>>8;
int g= (col>>8&255)*f>>8;
int b= (col&255)*f>>8;
dst[i]= (r<<16)|(g<<8)|b;
}
}
More generally you just replace the float by a fraction of integers a/b and make "b" a power of two to remove the division.
-
Oh yeah, *256 was the wy to do it. Cheers dude I got > 100fps now :)
-
another one (using mmx):
void fade(uint32 *dst, uint32 *src, int intense, int isize)
{
_asm {
mov edi,dst // dst-pointer
mov esi,src // src-pointer
mov ecx,isize // loop counter
shl ecx,2 // *4
add edi,ecx // count backwards
add esi,ecx
neg ecx
mov eax,intense // fade
imul eax,0x01010101 // to 8:8:8:8
pxor mm3,mm3 // 0
movd mm1,eax
punpcklbw mm1,mm3 // 8:8:8:8 to 16:16:16:16 (each upper byte 0)
floop: movq mm0,[esi+ecx] // read two source pixels
movq mm4,mm0 // copy
punpcklbw mm0,mm3 // pixel1: upper dword 8:8:8:8 to 16:16:16:16
psrlq mm4,32 // lower dword to upper dword
pmullw mm0,mm1 // pixel1 * intense
psrlw mm0,8 // pixel1 >>= 8
punpcklbw mm4,mm3 // pixel2: 8:8:8:8 to 16:16:16:16
packuswb mm0,mm3 // pixel1: 16:16:16:16 to 8:8:8:8
pmullw mm4,mm1 // pixel2 * intense
psrlw mm4,8 // pixel2 >>= 8
packuswb mm4,mm3 // pixel2: 16:16:16:16 to 8:8:8:8
psllq mm4,32 // pixel1 to upper dword
paddw mm4,mm0 // pixel2 to lower dword
movq [edi+ecx],mm4 // store two pixels
add ecx,8 // next pixel
jnz floop // loop
emms
};
}
(not quite optimal, the source is 10 years old)
-
Cool. I have wanted to learn how to use the MMX registers sometime. Its just something I havent got around to doing. I'll come back to this later on ;)
-
To take it further you could do something like this:
col=src[i];
dst[i]=((((col&0xff00ff)*f)&0xff00ff00)|(((col&0xff00)*f)&0xff0000))>>8;
EDIT:oops, forgot a little bit of it but I think that's it now.
-
How about the programmer fade? Again from Amiga days...
p = *pix
r =0xff&( p>>16)
g=0xff&(p>>8)
b=0xff&p;
r--
g--
b--
if r<0 r=0
if g<0 g=0
if b<0 b=0
*pix = (r<<16)|(g<<8)|b
Jim
<edit> I should pay attention - this is more for fading screens to black