• Advertisement

Archived

This topic is now archived and is closed to further replies.

Fast Sprite Rotation

This topic is 6573 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


Link to post
Share on other sites
Advertisement
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.

Share this post


Link to post
Share on other sites
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;
}

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

  • Advertisement