2012-03-17 8 views
1

私はある角度で回転しなければならないビットマップ(ちょっとスプライト)を持っています。私はこのコードを見つけました。私はアプリケーションのためにそれを適応しようとしましたが、うまくいかないようです。スプライトはまったく回転しませんが、少し動きます。winapiのビットマップローテーション

ここでは、機能コードです:

void Sprite::Rotate(float radians, const char* szImageFile) 
{ 
    // Create a memory DC compatible with the display 
HDC sourceDC, destDC; 
sourceDC = CreateCompatibleDC(mpBackBuffer->getDC()); 
destDC = CreateCompatibleDC(mpBackBuffer->getDC()); 

// Get logical coordinates 
HBITMAP hBitmap = (HBITMAP)LoadImage(g_hInst, szImageFile, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE); 
BITMAP bm; 
::GetObject(hBitmap, sizeof(bm), &bm); 

float cosine = (float)cos(radians); 
float sine = (float)sin(radians); 

// Compute dimensions of the resulting bitmap 
// First get the coordinates of the 3 corners other than origin 
int x1 = (int)(bm.bmHeight * sine); 
int y1 = (int)(bm.bmHeight * cosine); 
int x2 = (int)(bm.bmWidth * cosine + bm.bmHeight * sine); 
int y2 = (int)(bm.bmHeight * cosine - bm.bmWidth * sine); 
int x3 = (int)(bm.bmWidth * cosine); 
int y3 = (int)(-bm.bmWidth * sine); 

int minx = min(0,min(x1, min(x2,x3))); 
int miny = min(0,min(y1, min(y2,y3))); 
int maxx = max(0,max(x1, max(x2,x3))); 
int maxy = max(0,max(y1, max(y2,y3))); 

int w = maxx - minx; 
int h = maxy - miny; 

// Create a bitmap to hold the result 
HBITMAP hbmResult = ::CreateCompatibleBitmap(mpBackBuffer->getDC(), w, h); 

HBITMAP hbmOldSource = (HBITMAP)::SelectObject(sourceDC, hBitmap); 
HBITMAP hbmOldDest = (HBITMAP)::SelectObject(destDC, hbmResult); 

// Draw the background color before we change mapping mode 
HBRUSH hbrBack = CreateSolidBrush(mcTransparentColor); 
HBRUSH hbrOld = (HBRUSH)::SelectObject(destDC, hbrBack); 
PatBlt(destDC, 0, 0, w, h, PATCOPY); 
::DeleteObject(::SelectObject(destDC, hbrOld)); 




// We will use world transform to rotate the bitmap 
SetGraphicsMode(destDC, GM_ADVANCED); 
XFORM xform; 
xform.eM11 = cosine; 
xform.eM12 = -sine; 
xform.eM21 = sine; 
xform.eM22 = cosine; 
xform.eDx = (float)-minx; 
xform.eDy = (float)-miny; 

SetWorldTransform(destDC, &xform); 

// Now do the actual rotating - a pixel at a time 
BitBlt(destDC, 0, 0, w, h, sourceDC, 0, 0, SRCCOPY); 
// Restore DCs 
::SelectObject(sourceDC, hbmOldSource); 
::SelectObject(destDC, hbmOldDest); 

BITMAP btm; 
::GetObject(hbmResult, sizeof(mImageBM), &mImageBM); 

} 

は、画像を回転させない理由を私は理解することはできませんが、代わりにそれを移動します。また、これを行う別の方法を知っていれば、私は提案をしていますが、私はwinapiのみを使うことができることを覚えておいてください。追加のライブラリはなく、私はWindowsプログラミングの初心者です。

編集:ここにコードがあります:http://www.codeguru.com/cpp/g-m/bitmap/specialeffects/article.php/c1743/です。私はそれをちょっと変えなければならなかったが、それが原因だとは思わない。私はCDCをHDCに変更しただけだ。私が間違っていた重要なことの1つは、(0、0)のcoordです。そのコードの画像はコーナーで扱われますが、私のアプリケーションではスプライトの中心にあります。それが問題だとしても、ビットマップの新しい次元を計算するのは問題だと思いますが、回転との関連は見えません。

+0

SetWorldTransformが成功したか失敗したか確認してください。つまり、TRUEまたはFALSEを返します。 – Robinson

+0

TRUEを返します。 – Andrei

答えて

2

ビットマップが動いている場合は、ワールドトランスフォームとブリットの両方が機能しているように思えます。
トランスフォームのeDx/eDyパラメータのために移動する量ですか?
「回転」の例の値をハードコーディングするだけで違いがありますか?hereは違いがありますか?正弦波は反対の符号をつけて渡されます。したがって、変換の回転部分を無視し、変換のみを行った可能性があります。

+0

私は例の値を入れても、違いはありません。 XFORM構造体のどの値でも、同じ方向および同じ距離で移動します。私は角度(関数に渡すラジアンの数)を変更すると方向が変わります。 – Andrei

+0

DCまたはbitblt自体の問題である必要があります。 Drawrectのためにbitblitをスワップしてみてください。 –

+0

まだ何もありません。私は変更しようとしました 'sourceDC = CreateCompatibleDC(mpBackBuffer-> getDC()); sourceDC = CreateCompatibleDC(NULL); destDC = CreateCompatibleDC(NULL); ' と同じことをします。 – Andrei