• Create Account

## Fast Sprite Rotation

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

5 replies to this topic

### #1CoolMike  Members

122
Like
Likes
Like

Posted 21 January 2000 - 12:18 PM

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?

### #2Ro  Members

122
Like
Likes
Like

Posted 21 January 2000 - 02:30 PM

Try using D3D to do the rotation.

### #3SiCrane  Moderators

11527
Like
Likes
Like

Posted 21 January 2000 - 03:05 PM

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.

### #4CoolMike  Members

122
Like
Likes
Like

Posted 23 January 2000 - 01:07 PM

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;
}

### #5CoolMike  Members

122
Like
Likes
Like

Posted 23 January 2000 - 01:10 PM

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.

### #6SiCrane  Moderators

11527
Like
Likes
Like

Posted 23 January 2000 - 01:40 PM

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.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.