본문 바로가기

Coding Note

[winAPI] 더블버퍼링 - 깜빡임 없애기


winapi 에서 비트맵 파일을 화면에 뿌려줄 때,
계속 그리고 지우고 그리고 지우고 를 반복하느라 그 사이에 공백이 비츼게 되어 깜빡이는 현상이 나타난다.

이런 현상을 근본적으로 해결하려면 더블버퍼링 이라는 방법을 사용해야 한다더라.


(출처 : http://cafe.naver.com/buildgame.cafe)

더블버퍼링의 기본적인 개념이다.
그림만 봐도 이해가 될 정도로 간단한 개념이다 ㅎ..

그래서 더블 버퍼링을 사용하여보기로 했다.

먼저 사용되는 변수는 어떤것들이 있는지부터 보자.

HDC hdc    
//실제 화면dc

HDC backMemDC    
//화면에 보내기 직전의 완성된 메모리DC.  모든 이미지들을 이 dc위에 작업한다.

HDC MemDC1, MemDC2....    
//그리려고 하는 이미지들을 담기위한 메모리들.
//사실 임시dc하나만 만들어서 오브젝트 선택->backMemDC로 복사, 다른 오브젝트 선택->
//복사.. 하는식으로 사용해도 되지만, 알아보기 편하게 사용할 이미지 수에 맞게 DC를 만들었다.

HBITMAP backBitmap
//backMemDC의 크기설정.
//이게 중요한데, backMemDC는 초기 1픽셀의 공간을 가지고 있다. 그런데 다른 메모리디씨의 이미지를
//백디씨에 옮기려 하면 공간이 없으니 당연히 복사될 리가 없다.
//그래서 먼저 backMemDC에 도화지를 펼쳐준다고 생각하면 된다.

HBITMAP hMyBitmap, hOldBitmap
//그릴 비트맵들의 핸들

..등등이 있다.


그럼 더블버퍼링을 사용해보쟈.
여기선 그림 하나만 넣었다.

HDC hdc, backMemDC, MemDC;
static HBITMAP backBitmap=NULL;
HBITMAP  hMyBitmap, hOldBitmap;
PAINTSTRUCT ps;
static RECT window_rt;

hdc=BeginPaint(hWnd,&ps);

backMemDC=CreateCompatibleDC(hdc);
MemDC=CreateCompatibleDC(hdc);

backBitmap=CreateCompatibleBitmap(hdc, rt.right, rt.bottom); //도화지 준비!
hOldBitmap=(HBITMAP)SelectObject(backMemDC,backBitmap); //도화지 세팅
FillRect(backMemDC, &rt, (HBRUSH)GetStockObject(WHITE_BRUSH)); //도화지 색 변경

hMyBitmap=LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BITMAP1) ); //g_hInstance는 전역 핸들
SelectObject(MemDC,hMyBitmap);

BitBlt(backMemDC, x, y, x+MybitmapSize+X, y+MyBitmapSize_Y, MemDC,0,0,SRCCOPY);
//MemDC의 이미지를 backMemDC의 원하는 위치로 고속복사시킨다.

BitBlt(hdc,0,0, rt.right, rt.bottom, backMemDC, 0,0, SRCCOPY);
//backMemDC의 완성된 그림을 화면으로 고속복사시킨다.

DeleteObject( SelectObject(backMemDC,hOldBitmap) ); //끝으로 메모리와 오브젝트을 해지해준다.
DeleteObject(hMyBitmap);
DeleteDC(backMemDC);
DeleteDC(MemDC);

EndPaint(hWnd,&ps);


많이 어렵지 않다.
이런식의 더블버퍼링은 개념을 익힐정도의 쉬운방식이다.
더블버퍼링은 지금 위 방법 말고도 여러가지 방법으로 할 수 있지만,
아직은 잘 모른다 ㅎ


이제, 전에만든 얌얌.exe를 더블버퍼링을 써서 깔끔하게 만들어야지 ㅋ..