로그라이크 게임 구현 1주차 (3)
이번 글에선 더블 버퍼링에 대해서 작성하겠다.
게임의 기본은 버퍼링이다.
아무리 재밌는 게임이라도, 프레임이 작동을 하지 않는다면, 플레이어는 아무것도 하지 못한다.
Win32에선 프레임을 생각보다 쉽게 구현이 가능하다. 바로 Invalidate()함수를 이용하는 것이다.
그런데 나는 Invalidate()함수만을 이용해서 프레임을 구현하다가, 얼마지나지 않아 문제를 직면했다.
Invalidate()함수는 클라이언트 영역의 전체 또는 일부를 잘못된 것으로 표시한다.
이렇게 적으면 너무 어려워 보이지만, 쉽게 말하면 클라이언트 영역을 초기화하고, 다시 그리게 하는 함수이다.
게임을 진행하면서 장면이 전환 되었다면, 우리는 Invalidate()함수를 호출해서 새로 그려주어야한다.
그런데 이 그려주는 방식이 문제가 있다.
그리려고 하는 비트맵이 세 개라고 가정해보자. 그러면 클라이언트는 첫번째 비트맵을 그리고 화면을 송출하고, 두번째 비트맵을 그리고 화면을 송출하고, 세번째 비트맵을 그리고 화면을 송출할 것이다. 즉 비트맵의 개수만큼 화면 송출도 반복하는데, 이렇게 되면 클라이언트가 굉장히 깜빡거린다. 어느정도 깜빡거리는게 아니라 눈 아플 정도로 말이다.
그렇기 때문에 나는 더블 버퍼링을 구현할 필요가 있었다.
[WIN32 API] 더블 버퍼링(Double Buffering)
더블 버퍼링 win32 API에서 비트맵 파일을 화면에 뿌려줄 때, 계속해서 그리는 작업을 반복하기 때문에 비트맵 이미지가 깜빡이는 현상이 나타나게 됩니다. 이런 현상을 해결하기 위해서 더블버퍼
junk-s.tistory.com
해당 글이 잘 정리 되어있다.
글을 요약하면 클라이언트에 비트맵을 그리면서 업데이트를 하는게 아닌
다른 영역을 선언해서, 그 영역에 모두 그린 다음 그 영역을 송출하는 방법이다.
MemDC = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &bufferRT);
hdc = CreateCompatibleDC(MemDC);
BackBit = CreateCompatibleBitmap(MemDC, bufferRT.right, bufferRT.bottom);
oldBackBit = (HBITMAP)SelectObject(hdc, BackBit);
PatBlt(hdc, 0, 0, bufferRT.right, bufferRT.bottom, WHITENESS);
비트맵 그리는 함수들...
GetClientRect(hwnd, &bufferRT);
BitBlt(MemDC, 0, 0, bufferRT.right, bufferRT.bottom, hdc, 0, 0, SRCCOPY);
SelectObject(hdc, oldBackBit);
DeleteObject(BackBit);
DeleteDC(hdc);
EndPaint(hwnd, &ps);
나는 이런 식으로 구현했다.