Fast Sprite Rotation

Started by
4 comments, last by CoolMike 24 years, 3 months ago
I currently have 2 functions: one that can rotate a sprite any possible angle, and a function that is only meant to rotate it 90, 180 and 270 degrees. Of course the first function should be pretty slow, but does anybody know how to do rapid 90, 180, and 270 degree rotations? My Diamond v770 ULTRA TNT 2 video card doesn''t seem to be able to use the DDBLTFX rotation tools, and my functions are really slow. Can anybody help?
Advertisement
Try using D3D to do the rotation.
What''s you''re current approach to the 90 degree rotations? Of the top of my head all I can think of are some so-so for loop techniques.
Here is the function I use to rotate a sprite 90, 180, or 270 degrees. It works, but very slow. I just do a for...loop for each pixel in the sprite.
As for Direct3D, I am basically a beginner with DirectX. I am just starting to learn DirectSound and DirectInput, and Direct3D looks to advanced for right now.

BOOL fastRotateSprite(RECT srcRect, LPDIRECTDRAWSURFACE lpddsSrc, int rotDir)
{
int sizeX = srcRect.right-srcRect.left, sizeY = srcRect.bottom-srcRect.top;
RECT destRect={ 0,0,srcRect.right-srcRect.left,srcRect.bottom-srcRect.top};
UCHAR *rotBuff=NULL;
UCHAR red,green,blue;
POINT origPoint;

//int x=400,y=300;

//blit sprite to corner of lpddsROT
lpddsROT->Blt(&destRect,lpddsSrc,&srcRect,DDBLT_KEYSRC,NULL);

//extract data from lpddsOrig to origBuff
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);

lpddsROT->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR / DDLOCK_WAIT,NULL);
rotBuff = (UCHAR *)ddsd.lpSurface;

for(int x=400;x<400+sizeX;x++)
{
for(int y=300;y<300+sizeY;y++)
{
switch(rotDir)
{
case rot90:
origPoint.x = y-300;
origPoint.y = 400+sizeX-x;
((USHORT *)rotBuff)[x+y*800]=((USHORT *)rotBuff)[origPoint.x+y*800];
break;
case rot180:
origPoint.x = sizeX-x+400;
origPoint.y = sizeY+300-y;
((USHORT *)rotBuff)[x+y*800]=((USHORT *)rotBuff)[origPoint.x+y*800];
break;
case rot270:
origPoint.x = y - 300;
origPoint.y = x - 400;
((USHORT *)rotBuff)[x+y*800]=((USHORT *)rotBuff)[origPoint.x+y*800];
break;
}
}
}

lpddsROT->Unlock(rotBuff);

return TRUE;
}

One other thing: would replacing the multiplication with shifting speed the function up much? I tried replacing y*800 with something like y<<9+y<<8+y<<9 but it didn''t work.
1: you''ve got a for loop with a switch statement inside. Replace that with three for loops and use a switch statement to choose between them.

2: pre-compute the y*800 instead of doing the multiplication twice. Heck you can replace the y * 800 with a yloop = 0 before your y loop, and yloop += 800 at the top of every y loop.

3: rather than recompute origpoint.x and origpoint.y within the loop everytime, only compute them in the loop that it changes in.

4: often your origpoint.x or origpoint.y change only by 1, use ++ or -- instead of adding and subtracting. The compiler will optimize this to increment or decrement assembly instructions.

Those four should probably increase your speed by at least 20%. Then start doing similar things inside the loop.

This topic is closed to new replies.

Advertisement