게임 엔진 개발
[게임 엔진 개발] - 더블버퍼링 기법 (화면 그리기)
LKBaekjoon
2024. 7. 1. 13:08
반응형
앞서 공부하고 정리한 내용은 무료 배포된 유튜브 "얌얌코딩"님의 강의를 시청한 후임을 밝힙니다.
얌얌코딩 (게임 개발)
어려운 게임 개발을 쉽게 배우는 방법!
www.youtube.com
사진 출처 : Double Buffering - 더블 버퍼링 기법 :: Move Fast (tistory.com)
Double Buffering - 더블 버퍼링 기법
더블 버퍼링(Double Buffering)은 이중 버퍼링이라 불리기도 하며, 그래픽 객체에 이미지를 그릴 때 사용되는 기법이다. Q) 왜 사용하는가 ? A) API를 시작하다보면 비트맵 이미지를 사용하게 된다. 그
movefast.tistory.com
- 실제로 우리가 캐릭터를 움직이거나 어떤 객체의 움직임을 화면에서 표현하고자 할 때, 그 화면 자체를 지우고 새로 그리는 작업이 필요하다.
- 헌데 그걸 하나의 Bitmap 내에서 수행하게 될 경우, Flicking 현상이 발생할 수 있다.
- 위의 적용 전 화면 전환을 보면, 그림이 그려지기 전에 동일 Bitmap를 사용한 화면이 여전히 유저에게 보여져야 하므로 순간적으로 화면이 깜빡거리게 되는데, 유저로써는 매우 불편한 경험을 하게 할 수 있다.
- 위 문제를 해결하기 위해, 아래의 경우처럼 새로운 Bitmap를 하나 더 만들어서, 거기서 그린다음 화면 전환 자체를 다른 Bitmap로 딸깍 바꿔주는 것이다.
구현 Trade - Off [메모리 vs 연산]
- 허나 생각하기에 다음의 Trade - off가 있을 수 있다고 생각했다.
- 우선 비트맵 (그림을 그리는 도화지) 자체가 두 개이고, 계속 Change해주면서 왔다갔다 하는 것은 연산은 줄어들 수 있으나 메모리 자체를 좀 잡아먹을 수 있다.
- 이를 해결하기 위해 필자의 본 코드에서는 DC 자체를 왔다갔다 하면서 비트맵을 지우고 그려주는 방식으로 구현하여 연산양은 좀 많을 수 있으나 메모리 사용량을 줄였다.
void Application::Initialize(HWND hwnd, UINT width, UINT height)
{
mHwnd = hwnd;
mHdc = GetDC(hwnd);
RECT rect = { 0, 0, width, height };
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, false);
mWidth = rect.right - rect.left;
mHeight = rect.bottom - rect.top;
SetWindowPos(hwnd, nullptr, 0, 0, mWidth, mHeight, 0);
ShowWindow(hwnd, true);
// 윈도우 해상도에 맞는 백버퍼 생성
mBackBuffer = CreateCompatibleBitmap(mHdc, width, height);
//백버퍼를 가리킬 DC 생성
mBackHdc = CreateCompatibleDC(mHdc);
HBITMAP oldBitmap = (HBITMAP)SelectObject(mBackHdc, mBackBuffer);
DeleteObject(oldBitmap);
mPlayer.setPosition(0, 0);
Input::Initialize();
Time::Initialize();
}
- 매 Tick마다 호출되는 Render 함수 자체에서는 BackBuffer에 그려진 것을 원본 버퍼로 복사해주는 Bitㅠlt 함수를 호출한다.
///백버퍼에 있는걸 원본 버퍼에 복사(그려준다)
BitBlt(mHdc, 0, 0, mWidth, mHeight, mBackHdc, 0, 0, SRCCOPY);
반응형