Rotating images
Hi,
I have tried rotating bitmaps with Blt()''s rotationAngle
argument. This doesn''t work because of hardware limitations
on my system. Is there any other way to rotate bitmaps
without making all the rotation angle images yourself?
--Darkalla
Yes; use Direct3D to rotate a plane (2 triangles) with the texture of the image on it (Use a D3DXSprite).
This is a lot of work as well, but you''ll gain some other benefits like sub-pixel transformation and alpha blending. It might be worth the trouble.
Greetings, CondorWitte.
This is a lot of work as well, but you''ll gain some other benefits like sub-pixel transformation and alpha blending. It might be worth the trouble.
Greetings, CondorWitte.
Hi,
Thank you for the reply. I was wondering if there is a software based way to rotate a bitmap. I really want to steer away from hardware requirements. Is there any way to do this without using hardware? If so, does anyone have a code snippet of it?
--Darkalla
Thank you for the reply. I was wondering if there is a software based way to rotate a bitmap. I really want to steer away from hardware requirements. Is there any way to do this without using hardware? If so, does anyone have a code snippet of it?
--Darkalla
Software rotation is certainly possible and with some speed too. Just look at all those old Wingcommander games that used bitmap graphics, not 3D.
The key thing was no smoothing and using paletted images...
Paul.
The key thing was no smoothing and using paletted images...
Paul.
Okay, you could use D3D, if you don''t have hardware it will be emulated in software and this will potentially be very slow (depending on processor).
The key to software rotation (and other effects) is to do the minimum required to give the required appearence.
This entirely depends on what you are doing, and the effect you are trying to achieve, but at the end of the day, in a game you are not bothered about accurate rotation. Just giving the appearence that something is rotating is good enough (ala Wingcommander). This can be achieved in many ways and you would probably want to produce a set of fixed rules and limitations which you want to follow for your particular implementation.
The good thing about games is that everthing is usually moving very quickly so the player doesn''t notice defects and irregularities in the graphics too much.
At the end of the day you have to weigh up two things - the system you are targeting at (i.e. CPU power), and the actuall effect you want (and what you can get away with).
The key to software rotation (and other effects) is to do the minimum required to give the required appearence.
This entirely depends on what you are doing, and the effect you are trying to achieve, but at the end of the day, in a game you are not bothered about accurate rotation. Just giving the appearence that something is rotating is good enough (ala Wingcommander). This can be achieved in many ways and you would probably want to produce a set of fixed rules and limitations which you want to follow for your particular implementation.
The good thing about games is that everthing is usually moving very quickly so the player doesn''t notice defects and irregularities in the graphics too much.
At the end of the day you have to weigh up two things - the system you are targeting at (i.e. CPU power), and the actuall effect you want (and what you can get away with).
Found this on Google, of course you''ll need to use DirectX, SDL or (shudder) the GDI to get at the pixels...
http://www.inversereality.org/tutorials/graphics%20programming/bitmaprotation.html
http://www.inversereality.org/tutorials/graphics%20programming/bitmaprotation.html
Of course you can rotate a hi-color image fast enough without using D3D hardware support.What you have to do is to transform the source rect image to another dest rect image pixel by pixel.
The following code which is part of my project can do that work:
void CBitRotate::InitBitRotate(LPDIRECTDRAWSURFACE lpDDSSrc,LPDIRECTDRAWSURFACE lpDDSDst)
{
DDSURFACEDESC srcDDSD,dstDDSD;
if(lpDDSSrc == NULL)
return;
if(lpDDSDst == NULL)
return;
srcDDSD.dwSize = sizeof(srcDDSD);
srcDDSD.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
lpDDSSrc->GetSurfaceDesc(&srcDDSD);
dstDDSD.dwSize = sizeof(dstDDSD);
dstDDSD.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
lpDDSDst->GetSurfaceDesc(&dstDDSD);
ZeroMemory(&srcDDSD, sizeof(srcDDSD));
srcDDSD.dwSize = sizeof(srcDDSD);
lpDDSSrc->Lock(NULL, &srcDDSD, DDLOCK_WAIT, NULL);
ZeroMemory(&dstDDSD, sizeof(dstDDSD));
dstDDSD.dwSize = sizeof(dstDDSD);
lpDDSDst->Lock(NULL, &dstDDSD, DDLOCK_WAIT, NULL);
nSrcLineBytes = (WORD)srcDDSD.lPitch;
nDstLineBytes = (WORD)dstDDSD.lPitch;
// Initialize the pointers to the first pixel in the rectangle
lpSrcData = (BYTE*)srcDDSD.lpSurface;
lpDstData = (BYTE*)dstDDSD.lpSurface;
//Initialize the height and width of surface
nSrcHeight = srcDDSD.dwHeight;
nSrcWidth = srcDDSD.dwWidth;
nDstHeight = dstDDSD.dwHeight;
nDstWidth = dstDDSD.dwWidth;
SRect= CRect(0,0,nSrcWidth,nSrcHeight);
SRect.NormalizeRect();
SRect.DeflateRect(1,1);
nDstCenterWidth = (nDstWidth+1)>>1;
nDstCenterHeight = (nDstHeight+1)>>1;
nSrcCenterWidth = (nSrcWidth+1)>>1;
nSrcCenterHeight = (nSrcHeight+1)>>1;
}
BOOL CBitRotate::Rotate16(LPDIRECTDRAWSURFACE lpDDSSrc,LPDIRECTDRAWSURFACE lpDDSDst,double dfAngle,POINT *lpCenterpoint)
{
int col=0,row=0,Col=0,Row=0;
int DPixelRelativeRowNum=0,DPixelRelativeColNum=0;
double SPixelRowAddr,SPixelColAddr;
int SPixelRowNum,SPixelColNum;
double RowDelta,ColDelta;
double CosRot,SinRot;
InitBitRotate(lpDDSSrc,lpDDSDst);
CosRot=cos(dfAngle);
SinRot=sin(dfAngle);
LPBYTE lpDstLine = lpDstData;
LPBYTE lpSrcLine = lpSrcData;
LPBYTE lpSrcLineNext = lpSrcData;
for(row=0;row {
DPixelRelativeRowNum = row - nDstCenterHeight;
for(col=0;col {
DPixelRelativeColNum = col - nDstCenterWidth;
//Computer the address of pixel
SPixelColAddr = (double)DPixelRelativeColNum*CosRot+(double)DPixelRelativeRowNum*SinRot;
SPixelRowAddr = (double)DPixelRelativeRowNum*CosRot-(double)DPixelRelativeColNum*SinRot;
SPixelColAddr+=(double)lpCenterpoint->x;
SPixelRowAddr+=(double)lpCenterpoint->y;
SPixelColNum = (int)SPixelColAddr;
SPixelRowNum = (int)SPixelRowAddr;
ColDelta = SPixelColAddr-SPixelColNum;
RowDelta = SPixelRowAddr-SPixelRowNum;
Row = SPixelRowNum;
Col = SPixelColNum;
CPoint SPoint=CPoint(Col,Row);
if(SRect.PtInRect(SPoint))
{
lpSrcLine=lpSrcData+Row*nSrcLineBytes;
lpDstLine[col*2] = lpSrcLine[Col*2];
lpDstLine[col*2+1] = lpSrcLine[Col*2+1];
}
}
lpDstLine+=nDstLineBytes;
}
lpDDSSrc->Unlock(NULL);
lpDDSDst->Unlock(NULL);
return TRUE;
}
//=================
written by SoftGrand
softgrand@sina.com
The following code which is part of my project can do that work:
void CBitRotate::InitBitRotate(LPDIRECTDRAWSURFACE lpDDSSrc,LPDIRECTDRAWSURFACE lpDDSDst)
{
DDSURFACEDESC srcDDSD,dstDDSD;
if(lpDDSSrc == NULL)
return;
if(lpDDSDst == NULL)
return;
srcDDSD.dwSize = sizeof(srcDDSD);
srcDDSD.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
lpDDSSrc->GetSurfaceDesc(&srcDDSD);
dstDDSD.dwSize = sizeof(dstDDSD);
dstDDSD.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
lpDDSDst->GetSurfaceDesc(&dstDDSD);
ZeroMemory(&srcDDSD, sizeof(srcDDSD));
srcDDSD.dwSize = sizeof(srcDDSD);
lpDDSSrc->Lock(NULL, &srcDDSD, DDLOCK_WAIT, NULL);
ZeroMemory(&dstDDSD, sizeof(dstDDSD));
dstDDSD.dwSize = sizeof(dstDDSD);
lpDDSDst->Lock(NULL, &dstDDSD, DDLOCK_WAIT, NULL);
nSrcLineBytes = (WORD)srcDDSD.lPitch;
nDstLineBytes = (WORD)dstDDSD.lPitch;
// Initialize the pointers to the first pixel in the rectangle
lpSrcData = (BYTE*)srcDDSD.lpSurface;
lpDstData = (BYTE*)dstDDSD.lpSurface;
//Initialize the height and width of surface
nSrcHeight = srcDDSD.dwHeight;
nSrcWidth = srcDDSD.dwWidth;
nDstHeight = dstDDSD.dwHeight;
nDstWidth = dstDDSD.dwWidth;
SRect= CRect(0,0,nSrcWidth,nSrcHeight);
SRect.NormalizeRect();
SRect.DeflateRect(1,1);
nDstCenterWidth = (nDstWidth+1)>>1;
nDstCenterHeight = (nDstHeight+1)>>1;
nSrcCenterWidth = (nSrcWidth+1)>>1;
nSrcCenterHeight = (nSrcHeight+1)>>1;
}
BOOL CBitRotate::Rotate16(LPDIRECTDRAWSURFACE lpDDSSrc,LPDIRECTDRAWSURFACE lpDDSDst,double dfAngle,POINT *lpCenterpoint)
{
int col=0,row=0,Col=0,Row=0;
int DPixelRelativeRowNum=0,DPixelRelativeColNum=0;
double SPixelRowAddr,SPixelColAddr;
int SPixelRowNum,SPixelColNum;
double RowDelta,ColDelta;
double CosRot,SinRot;
InitBitRotate(lpDDSSrc,lpDDSDst);
CosRot=cos(dfAngle);
SinRot=sin(dfAngle);
LPBYTE lpDstLine = lpDstData;
LPBYTE lpSrcLine = lpSrcData;
LPBYTE lpSrcLineNext = lpSrcData;
for(row=0;row {
DPixelRelativeRowNum = row - nDstCenterHeight;
for(col=0;col {
DPixelRelativeColNum = col - nDstCenterWidth;
//Computer the address of pixel
SPixelColAddr = (double)DPixelRelativeColNum*CosRot+(double)DPixelRelativeRowNum*SinRot;
SPixelRowAddr = (double)DPixelRelativeRowNum*CosRot-(double)DPixelRelativeColNum*SinRot;
SPixelColAddr+=(double)lpCenterpoint->x;
SPixelRowAddr+=(double)lpCenterpoint->y;
SPixelColNum = (int)SPixelColAddr;
SPixelRowNum = (int)SPixelRowAddr;
ColDelta = SPixelColAddr-SPixelColNum;
RowDelta = SPixelRowAddr-SPixelRowNum;
Row = SPixelRowNum;
Col = SPixelColNum;
CPoint SPoint=CPoint(Col,Row);
if(SRect.PtInRect(SPoint))
{
lpSrcLine=lpSrcData+Row*nSrcLineBytes;
lpDstLine[col*2] = lpSrcLine[Col*2];
lpDstLine[col*2+1] = lpSrcLine[Col*2+1];
}
}
lpDstLine+=nDstLineBytes;
}
lpDDSSrc->Unlock(NULL);
lpDDSDst->Unlock(NULL);
return TRUE;
}
//=================
written by SoftGrand
softgrand@sina.com
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement