티스토리 툴바

블로그 이미지

Passion of ComputerScience

Team Blog For Soft Engineering Team Project Manager : Park, Choi, Jeon Project Name : Linkube (Link + cube) "Passion is survival, not death." by cocy


[스크랩] Win32 API 비트맵 회전 함수 전체 소스 코드


  1. #include <windows.h>   
  2. #include <math.h>   
  3.   
  4. #define PI          3.141592654   
  5.   
  6. // 인수목록   
  7. // HDC      hdc         :   
  8. // HBITMAP  hBitmap     :   
  9. // int      source_x    : 회전 이미지 비트맵에서의, 출력할 사각영역의 좌상단x좌표.   
  10. // int      source_y    : 회전 이미지 비트맵에서의, 출력할 사각영역의 좌상단y좌표.   
  11. // int      dest_width  : 회전할 비트맵 이미지의 폭   크기 == 회전할 비트맵 이미지가 출력될 폭 크기   
  12. // int      dest_heigjt : 회전할 비트맵 이미지의 높이 크기 == 회전할 비트맵 이미지가 출력될 높이 크기   
  13. // float    angle       : 회전할 각도.   
  14. // COLORREF bkColor     : 회전후 생긴 공백영역을 칠할 색상. 이미지 사각형을 회전하면, 공백영역이 생깁니다. (예)다이아몬드 형태로 회전된 사각형에서의 뒤부분 영역   
  15. //                        그 공백영역을 미리 채울 색상을 지정합니다.   
  16.   
  17. HBITMAP GetRotatedBitmap( HDC hdc, HBITMAP hBitmap, int source_x, int source_y,   
  18.                           int dest_width, int dest_height, float angle, COLORREF bkColor )   
  19. {     
  20.     HDC sourceDC        = CreateCompatibleDC(hdc);                                      // 회전할 비트맵 원본을 선택할 DC   
  21.     HDC destDC          = CreateCompatibleDC(hdc);                                      // 회전할 비트맵을 출력받을 DC   
  22.     HBITMAP hbmResult   = CreateCompatibleBitmap( hdc, dest_width, dest_height );       // 회전할 비트맵을 출력받을 메모리비트맵 핸들   
  23.   
  24.     HBITMAP hbmOldSource= (HBITMAP)SelectObject( sourceDC, hBitmap );                   // 회전할 비트맵 원본을 DC에 선택   
  25.     HBITMAP hbmOldDest  = (HBITMAP)SelectObject( destDC, hbmResult );                   // 회전할 비트맵을 출력받을 DC에, 회전할 비트맵을 출력받을 메모리비트맵 선택   
  26.   
  27.     HBRUSH hbrBack      = CreateSolidBrush( bkColor );                                  // 회전으로 인한, 공백영역을 칠할 브러시핸들 생성   
  28.     HBRUSH hbrOld       = (HBRUSH)SelectObject( destDC, hbrBack );                      // 브러시핸들 선택   
  29.     PatBlt( destDC, 0, 0, dest_width, dest_height, PATCOPY );                           // 선택된 브러시로, 회전할 비트맵을 출력받을 DC에, 미리 색상을 채워 지움   
  30.     DeleteObject( SelectObject( destDC, hbrOld ) );                                     // 브러시 해제   
  31.   
  32.     angle           = (float)( angle * PI / 180 );                                      // 회전할 각도(360분법)를, 라디안단위의 각도로 변경   
  33.     float cosine    = (float)cos( angle );                                              // 회전이동변환 행렬에 들어갈 cos세타 값을 구함          
  34.     float sine      = (float)sin( angle );                                              // 회전이동변환 행렬에 들어갈 sin세타 값을 구함   
  35.   
  36.     SetGraphicsMode(destDC, GM_ADVANCED);                                               // 윈도우 좌표계의 회전을 위하여, 그래픽모드를 확장모드로 변경합니다.(요구사항:윈98,NT이상)   
  37.   
  38.     // 회전이동변환 행렬을 정의.   
  39.     // (윈도우즈 API정복 개정판 2권 Page(1279) 참조.)   
  40.     // (게임 프로그래머를 위한 기초수학과 물리 Page(196) 참조.)   
  41.   
  42.     XFORM xform;                                                                        // 방정식을 표현하는 3행3열의 행렬 선언   
  43.     xform.eM11 = cosine;                                                                // 1행 1열 성분 설정 (회전성분)   
  44.     xform.eM12 = sine;                                                                  // 1행 2열 성분 설정 (회전성분)   
  45.     xform.eM21 = -sine;                                                                 // 2행 1열 성분 설정 (회전성분)   
  46.     xform.eM22 = cosine;                                                                // 2행 2열 성분 설정 (회전성분)   
  47.     xform.eDx = (FLOAT)dest_width / 2.0f;                                               // 3행 1열 성분 설정 (X축 이동 성분)   
  48.     xform.eDy = (FLOAT)dest_height / 2.0f;                                              // 3행 2열 성분 설정 (Y축 이동 성분)   
  49.   
  50.     // 설정한 행렬로, 인수DC의 윈도우즈 좌표계를 변환.   
  51.     // 인수DC는 출력대상으로 메모리비트맵을 가지므로,   
  52.     // 선택하고 있는 메모리비트맵의 좌표체계가 회전된다.   
  53.   
  54.     SetWorldTransform( destDC, &xform );   
  55.   
  56.     // 회전된 메모리DC에, 회전할 이미지를 출력   
  57.   
  58.     BitBlt(destDC, -(dest_width/2),-(dest_height/2), dest_width, dest_height, sourceDC, source_x, source_y, SRCCOPY );    
  59.   
  60.     // 사용된 자원 해제   
  61.   
  62.     SelectObject( sourceDC, hbmOldSource );    
  63.     SelectObject( destDC, hbmOldDest );    
  64.     DeleteObject(sourceDC);   
  65.     DeleteObject(destDC);   
  66.   
  67.     // 회전된 비트맵 핸들 리턴   
  68.   
  69.     return hbmResult;    
  70. }   
  71.   
  72. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////   
  73. // 인수 목록   
  74. // HDC      hdc         : 화면DC의 핸들. GetRotatedBitmap()함수의 인자로 전달하게 됩니다.   
  75. // HDC      hOffScreen  : 회전 이미지를 출력할, 오프스크린DC의 핸들.   
  76. // int      dest_x      : 오프스크린 상에서, 회전 이미지가 출력될 x좌표.   
  77. // int      dest_y      : 오프스크린 상에서, 회전 이미지가 출력될 y좌표.   
  78. // int      dest_width  : 회전할 비트맵 이미지의 폭   크기 == 회전할 비트맵 이미지가 출력될 폭 크기   
  79. // int      dest_heigjt : 회전할 비트맵 이미지의 높이 크기 == 회전할 비트맵 이미지가 출력될 높이 크기   
  80. // HBITMAP  hBit        : 회전 이미지 비트맵핸들   
  81. // int      source_x    : 회전 이미지 비트맵에서의, 출력할 사각영역의 좌상단x좌표.   
  82. // int      source_y    : 회전 이미지 비트맵에서의, 출력할 사각영역의 좌상단y좌표.   
  83. // DWORD    dFlag       : ROP모드를 나타내는 플래그 매크로   
  84. // float    angle       : 회전할 각도.   
  85. // COLORREF bkColor     : 회전후 생긴 공백영역을 칠할 색상. 이미지 사각형을 회전하면, 공백영역이 생깁니다. (예)다이아몬드 형태로 회전된 사각형에서의 뒤부분 영역   
  86. //   
  87. void RotateBlt( HDC hdc, HDC hOffScreen, int dest_x, int dest_y, int dest_width, int dest_height,   
  88.                 HBITMAP hBit, int source_x, int source_y, DWORD dFlag, float angle, COLORREF bkColor )   
  89. {   
  90.     static HDC hTempMemDC;              // 회전한 비트맵을 선택할 메모리DC   
  91.     HBITMAP hTempBitmap, hOldBitmap;    // 회전한 비트맵을 저장할, 비트맵 핸들   
  92.   
  93.     // 최초 한번만 비트맵DC를 생성합니다.   
  94.   
  95.     if( !hTempMemDC ) hTempMemDC = CreateCompatibleDC( hdc );   
  96.   
  97.     // 비트맵을 회전하는 함수를 호출하여, 리턴되는 회전된 비트맵 핸들을 저장   
  98.   
  99.     hTempBitmap = GetRotatedBitmap( hdc, hBit, source_x, source_y, dest_width, dest_height, angle, bkColor );   
  100.   
  101.     // 회전된 비트맵 핸들을 선택하고,   
  102.   
  103.     hOldBitmap = (HBITMAP)SelectObject( hTempMemDC, hTempBitmap );   
  104.   
  105.     // 오프스크린DC에, 회전된 비트맵 핸들을 선택한, 메모리DC의 이미지를 출력합니다.   
  106.     // 안의 주석을 해제하면, 출력좌표를 중심으로 하는 회전이미지가 됩니다.   
  107.   
  108.     BitBlt( hOffScreen, dest_x/* - dest_width/2*/, dest_y/* - dest_height/2*/, dest_width, dest_height,   
  109.             hTempMemDC, 0, 0, dFlag );   
  110.   
  111.     SelectObject( hTempMemDC, hOldBitmap );   
  112.     DeleteObject( hTempBitmap );   
  113. }   
  114.   
  115. HWND    hWndMain;                   // 윈도우 핸들   
  116. HDC     hdc;                        // 화면         DC 핸들   
  117. HDC     hOffScreenDC;               // 오프스크린 DC 핸들   
  118. HBITMAP hOffScreenBitmap;           // 오프스크린 DC 가 선택하는, 메모리 비트맵 핸들   
  119. HBITMAP hMemBitmap;                 // 이미지를 담을, 메모리 비트맵 핸들   
  120.   
  121. void OnTimer();                     // WM_TIMER메세지의, 핸들러 함수   
  122.   
  123. LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )   
  124. {   
  125.     switch( message )   
  126.     {   
  127.         case WM_CREATE:   
  128.             hWndMain = hWnd;   
  129.             // 화면DC, 오프스크린DC, 오프스크린의 메모리비트맵을 미리 생성합니다.   
  130.   
  131.             hdc = GetDC( hWnd );   
  132.             hOffScreenDC = CreateCompatibleDC( hdc );   
  133.             hOffScreenBitmap = CreateCompatibleBitmap( hdc, 800, 600 );   
  134.             SelectObject( hOffScreenDC, hOffScreenBitmap );   
  135.             PatBlt( hOffScreenDC, 0, 0, 800, 600, WHITENESS );   
  136.   
  137.             // 이미지를 비트맵에 로드합니다.   
  138.   
  139.             hMemBitmap = (HBITMAP)LoadImage( GetModuleHandle(NULL),   
  140.                                              TEXT("player_walk.bmp"),   
  141.                                              IMAGE_BITMAP,   
  142.                                              0,   
  143.                                              0,   
  144.                                              LR_DEFAULTSIZE | LR_LOADFROMFILE );   
  145.   
  146.             // 타이머 생성   
  147.   
  148.             SetTimer( hWnd, 1, 20, NULL );   
  149.             break;   
  150.   
  151.         case WM_TIMER:   
  152.             OnTimer();   
  153.             break;   
  154.   
  155.         case WM_DESTROY:   
  156.             // 사용된 메모리 비트맵과, 오프스크린 DC, 타이머를 해제합니다.   
  157.             DeleteObject( hMemBitmap );   
  158.             DeleteObject( hOffScreenBitmap );   
  159.             DeleteDC( hOffScreenDC );   
  160.             KillTimer( hWnd, 1 );   
  161.             PostQuitMessage(0);   
  162.             break;   
  163.     }   
  164.   
  165.     return DefWindowProc( hWnd, message, wParam, lParam );   
  166. }   
  167.   
  168. void OnTimer()   
  169. {   
  170.     // 비트맵을 회전시킬 각도(360분법) 갱신   
  171.   
  172.     static FLOAT angle  = 0.0f;   
  173.     static BOOL bRotate = FALSE;   
  174.   
  175.     if( GetKeyState( VK_LBUTTON ) & 0x8000 ) { bRotate = TRUE; }   
  176.   
  177.     if( bRotate )   
  178.     {   
  179.         angle += 5.0f;   
  180.         if( angle >= 360.0f )   
  181.         {   
  182.             bRotate = FALSE;   
  183.             angle = 0.0f;   
  184.         }   
  185.     }   
  186.   
  187.     // 오프스크린DC의 이미지를, 하얀색으로 채워, 이전 프레임에서의 이미지를 삭제합니다.   
  188.   
  189.     PatBlt( hOffScreenDC, 0, 0, 800, 600, WHITENESS );   
  190.   
  191.     // 오프스크린DC에, 이미지의 마스크를 출력합니다.   
  192.   
  193.     RECT Rt;   
  194.     GetClientRect( hWndMain, &Rt );   
  195.     RotateBlt( hdc, hOffScreenDC, Rt.right / 2, Rt.bottom / 2, 59, 59,   
  196.                hMemBitmap, 0, 0, SRCAND, angle, RGB( 255, 255, 255 ) );   
  197.   
  198.     // 오프스크린DC에, 이미지를 출력합니다.   
  199.   
  200.     RotateBlt( hdc, hOffScreenDC, Rt.right / 2, Rt.bottom / 2, 59, 59,   
  201.                hMemBitmap, 60, 0, SRCPAINT, angle, RGB( 0, 0, 0 ) );   
  202.   
  203.     // 화면DC에, 오프스크린의 이미지를 출력합니다.   
  204.   
  205.     BitBlt( hdc, 0, 0, 800, 600, hOffScreenDC, 0, 0, SRCCOPY );   
  206. }  

    출처 : http://mumbi.net/216
Comment 0 Trackback 0

Trackback : http://sepoc.tistory.com/trackback/47 관련글 쓰기

Top

prev 1 ... 2 3 4 5 6 7 8 9 10 ... 41 next