Jump to content
  • Advertisement

Archived

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

CGameProgrammer

Faster Bitmap Rotation

This topic is 6532 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 wrote a bitmap rotation routine that works; however, it works a little too slowly. It takes about three seconds to rotate a 90x90 bitmap 72 times. This isn't done in real-time, it's done while the world is loading, with the generated images stored in memory and blitted to the screen at real-time. But for a game to have many fully rotated enemies, the long load time will be annoying. The code is a bit long but not complicated so I won't bother posting the exact code here. It uses fixed-point math and look-up tables; however, here is a simplified floating-point representation of the algorithm:

// Rad = radians = Pi * Degrees / 180.0
 
float XNewLine = (cos(Rad) * (-Width/2)) - (sin(Rad) * (-Height/2));
float YNewLine = (sin(Rad) * (-Width/2)) + (cos(Rad) * (-Height/2));
 
float XStart = XNewLine - cos(Rad) + sin(Rad);
float YStart = YNewLine - cos(Rad) - sin(Rad);
//
for( int X = 0; X < Width; X ++ )
{
    float XPos = XStart;
    float YPos = YStart;
    XStart += cos(Rad);
    YStart += sin(Rad);
 
    for( int Y = 0; Y < Height; Y ++ )
    {
        XPos -= sin(Rad);
        YPos += cos(Rad);
 
        int XDest = (int)XPos + (Width/2);
        int YDest = (int)YPos + (Height/2);
 
        if( XDest >= 0 &&
            YDest >= 0 &&
            XDest < Width &&
            YDest < Height )
            PlotPixel( XDest, YDest, GetPixel(X, Y) );
    }
}
 
This may seem confusing, but keep in mind it works perfectly, just a bit slowly. Also the real algorithm does NOT use type conversion (it's ALL fixed-point) and it uses look-up tables instead of sin and cos, and it does not use function calls within the loops. It DOES use that if statement every time it's about to plot a pixel, but I can't think of any other way of doing it. Also, it does use for loops, but I doubt while loops will really give a big speed boost. Edited by - CGameProgrammer on 8/27/00 6:06:07 PM

Share this post


Link to post
Share on other sites
Advertisement
Hm... maybe I should post the real code. It uses these four variables:

ScanXAxisX // Delta-X of ScanX ray
ScanXAxisY // Delta-Y of ScanX ray
 
ScanYAxisX // Delta-X of ScanY ray
ScanYAxisY // Delta-Y of ScanY ray

These are the rays those variables refer to:



And here is the code for 24-bit color depth:

float XNewLine;
float YNewLine;
float FHalfWidth = float(Width) / 2;
float FHalfHeight = float(Height) / 2;
long XStart;
long YStart;
long XRay;
long YRay;
long ScanXAxisX;
long ScanXAxisY;
long ScanYAxisX;
long ScanYAxisY;
int HalfWidth = Width >> 1;
int HalfHeight = Height >> 1;
int XGet;
int YGet;
int XPut;
int YPut;
int SrcPoint; // Source pixel location
int DstPoint; // Destination pixel location
 
// int Deg = degrees of rotation
 
/* Member variables:
 
BYTE* m_RotImage[360];
BYTE* m_Image;
int m_Pitch;
*/
 
XNewLine = (Cos[Deg] * -FHalfWidth) - (Sin[Deg] * -FHalfHeight);
YNewLine = (Sin[Deg] * -FHalfWidth) + (Cos[Deg] * -FHalfHeight);
 
ScanXAxisX = long(Cos[Deg] * 65536);
ScanXAxisY = long(Sin[Deg] * 65536);
ScanYAxisX = -ScanXAxisY;
ScanYAxisY = ScanXAxisX;
 
XStart = long(XNewLine * 65536) - ScanXAxisX - ScanYAxisX + (HalfWidth << 16);
YStart = long(YNewLine * 65536) - ScanXAxisY - ScanYAxisY + (HalfHeight << 16);
 
for( XGet = 0; XGet < Width; XGet ++ )
{
XRay = XStart;
YRay = YStart;
XStart += ScanXAxisX;
YStart += ScanXAxisY;
 
for( YGet = 0; YGet < Height; YGet ++ )
{
XRay += ScanYAxisX;
YRay += ScanYAxisY;
 
XPut = XRay >> 16;
YPut = YRay >> 16;
 
if( XPut >= 0 &&
YPut >= 0 &&
XPut < Width &&
YPut < Height )
{
SrcPoint = YGet * m_Pitch + ((XGet << 1) + XGet);
DstPoint = YPut * m_Pitch + ((XPut << 1) + XPut);
 
m_RotImage[Deg][DstPoint][0] = m_Image[SrcPoint][0];
m_RotImage[Deg][DstPoint][1] = m_Image[SrcPoint][1];
m_RotImage[Deg][DstPoint][2] = m_Image[SrcPoint][2];
}
}
}

So, can anyone help?

Edited by - CGameProgrammer on August 27, 2000 7:57:56 PM

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!