2012-03-17 6 views
1

나는 특정 각도로 회전해야하는 BitMap (작은 스프라이트)이 있습니다. 이 코드를 발견하고 응용 프로그램에 적용하려고했지만 작동하지 않는 것 같습니다. 스프라이트는 전혀 회전하지 않고 약간 움직입니다.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로 바꿨다. 내가 간과 한 한 가지 중요한 사실은 (0, 0) coord입니다. 그 코드의 이미지는 구석에있는 것으로 간주되지만, 내 애플리케이션에서는 스프라이트의 중심에 있습니다. 그게 문제가된다고해도, 비트 맵의 ​​새로운 차원을 계산하는 것이 문제라고 생각합니다. 회전과의 연결은 보이지 않습니다.

+0

SetWorldTransform이 성공했는지 실패했는지 확인할 수 있습니다. 즉, TRUE 또는 FALSE를 반환합니다. – Robinson

+0

TRUE를 반환합니다. – Andrei

답변

2

비트 맵이 움직이는 경우 세계 변환과 블릿이 모두 작동하는 것처럼 보입니다.
변환의 eDx/eDy 매개 변수 때문에 이동하는 양은 얼마입니까?
"회전"예제의 값을 하드 코딩하면 here이 달라 집니까? 사인은 반대 기호로 전달됩니다. 그래서 변환의 회전 부분을 무시하고 번역 만했습니다.

+0

예제의 값을 넣더라도 아무런 차이가 없습니다. XFORM 구조의 모든 값에서 동일한 방향과 동일한 거리로 이동합니다. 내가 각도 (함수에 전달하는 라디안 수)를 변경하면 방향이 바뀝니다. – Andrei

+0

DC 또는 bitblt 자체에 문제가 있어야합니다. Drawrect의 비트 블릿을 다시 시도해보십시오. –

+0

아직 아무것도. 나는 변경하려고 시도했다 'sourceDC = CreateCompatibleDC (mpBackBuffer-> getDC());destDC = CreateCompatibleDC (NULL); destDC = CreateCompatibleDC (NULL); ' 그리고 동일한 작업을 수행합니다. – Andrei

관련 문제