[[프로그래밍_NOTE]]/Window Programing

메모리 DC , 더블 버퍼링

갑빠돌격기 2009. 1. 28. 11:16

발췌 : 윈도우즈 API 정복 1 , 김상형(한빛 미디어)

윈도우즈는 비트맵을 곧바로 화면 DC로 출력하는 함수는 제공하지 않는다. ..(중략)
왜냐하면 비트맵은 크기가 큰 데이터 덩어리이며 따라서 출력 속도가 형편없이 느리고 화면으로 곧바로 출력할 경우 여러가지 꼴사나운 현상이 발샐할 수 있기 때문이다. 마치 파일에서 한 바이트 단위로 읽어 들이는 함수가 없는 것과 같은 이유인데 파일을 읽고 싶으면 반드시 열기 , 읽기 , 닫기의 과정을 거쳐야 한다.
( ※ 현대의 하드웨어 환경이 좋아져 비트맵을 직접 출력하는 함수가 있어도 별다른 문제가 없다. CPU의 속도가 빨라진 것도 이유이지만 , 더 주요한 이유는 요즘 출시되는 그래픽카드의 대부분이 비트맵 출력을 하드웨어적으로 처리하는 가속 기능을 제공하기 때문이다. 비트맵 출력 절차중 가장 느린 함수는 LoadBitmap 이므로 이 함수만 주의하면 된다.)

마찬가지로 비트맵도 워낙 대용량이라 직접 출력하는 함수는 제공하지 않으며 약간의 준비를 거친 후 출력해야 한다. 이렇게 준비 동작을 취한 후 출력하면 여러번 출력할 때 이미 준비된 데이터를 전송하기만 하면 되므로 출력 속도가 빠르고 예비 동작을 미리 취해 놓을 수 있다는 점에서도 유리하다.

비트맵은 화면으로 직접 출력할 수 없으며 반드시 메모리 DC에 미리 준비해 놓고 사용해야 한다.

메모리 DC란 화면 DC와 동일한 특성을 가지며 그 내부에 출력 표면을 가진 메모리 영역이다.
메모리에 있기는 하지만 화면 DC에서 사용할 수 있는 모든 출력을 메모리 DC에서도 할 수 있다. 선,면, 원등의 작도 함수는 물론 화면 DC에서는 불가능한 것까지도 가능하다. 그래서 메모리 DC에 먼저 그림을 그린 후 사용자 눈에 그려지는 과정은 보여주지 않고 그 결과만 화면으로 고속 복사하는 방법(더블 버퍼링)을 많이 사용한다.

사용자 눈에 화면이 그려지는 과정을 보여주는 것은 그리 깔끔한 모습이 아니다. 여기서 우리가 하고자 하는 비트맵 출력을 위해서도 반드시 메모리 DC를 사용해야 한다. 비트맵도 일종의 GDI 오브젝트이지만 화면 DC에는 선택할 수 없으며 메모리 DC만이 비트맵을 선택할 수 있다. 그래서 메모리 DC에 먼저 비트맵을 읽은 후 화면 DC로 복사하는 것이다.
메모리 DC를 만들때는 다음 함수가 상용된다.

HDC CreateCompatibleDC( HDC hdc );

인수로 화면 DC의 핸들을 주면 이 화면 DC와 동일한 특성을 가지는 DC를 메모리에 만들어 그 핸들을 리턴한다. (중략)
메모리 DC를 만든 후에는 비트맵을 읽어오고 이 비트맵을 메모리 DC에 선택한다. 선택할 때는 여타의 GDI 오브젝트와 마찬가지로 SelectObject 함수를 사용하며 비트맵을 읽어올 때는 LoadBitmap 함수를 사용한다.

HBITMAP LoadBitmap (HINSTANCE hInstance , LPCTSTR lpBitmapName);

[※※필기자※※  pda (windows mobile6 )같은 플랫폼에서는 SHLoadDIBitmap()함수를 사용한다. Ex.SHLoadDIBitmap(L"\\Program Files\\1.bmp") ]

DC간의 영역끼리 고속 복사 (화면출력) 를 수행하는 함수는 아래와 같다.(2가지)

BOOL BitBlt( HDC hdcDest , int nXDest , int nYDest , 
                int nWidth , int nHeight , HDC hdcSrc , int nXSrc , int nYSrc , DWORD dwRop);

BOOL StretchBit(HDC hdcDest , int xXOriginDest , int nYOriginDest , 
                        int nWidthDest , int nHeightDest ,
                       HDC hdcSrc , int nXOriginSrc , int nYOriginSrc ,
                       int nWidthSrc , int nHeightSrc , DWORD dwRop);