1. 더블 버퍼링 (Double Buffering)
프론트 버퍼 하나로 그래픽을 표현하면 잔상, 혹은 이미지가 갱신되지 않는 문제, 입력이 지연되는 문제가 발생한다.
이 문제를 해결하기 위해 백 버퍼(Back buffer)를 추가하여 출력하는 더블 버퍼링이 생기게 되었다.
그래픽 출력 순서는 아래와 같다.
1) 프론트 버퍼에 그림
2) 백 버퍼에 그림을 복사 ; 이 과정에서 그림이 그려지는 과정이 숨겨지게 된다(잔상 방지)
3) 프론트 버퍼와 백 버퍼를 서로 교체
4) 프론트 버퍼의 내용을 화면에 표시
5) 백 버퍼에 그림
6) 프론트 버퍼에 그림을 복사 ...
2. Game.h, Game.cpp
기존의 _hdc가 프론트 버퍼에 해당한다.
private:
RECT _rect;
// 백 버퍼 추가
HDC _hdcBack = {};
HBITMAP _bmpBack = {};
}
1) 비트맵과 DC
- DC(Device Context) ; 그래픽 디바이스 정보와 그림을 그리는 영역이 저장되어 있음.
- 비트맵(Bitmap) ; 메모리에 생성되는 이미지 또는 그림(픽셀 단위로 표현되어 저장).
1-2) 비트맵 표시 절차
(1) 메모리에 비트맵 할당
(2) DC 생성, 비트맵과 DC 연결
(3) 비트맵을 DC 위에 그림
(4) 화면에 표시
void Game::Init(HWND hwnd)
{
_hwnd = hwnd;
_hdc = ::GetDC(hwnd);
::GetClientRect(hwnd, &_rect);
_hdcBack = ::CreateCompatibleDC(_hdc); // _hdc와 호환되는 DC를 생성
_bmpBack = ::CreateCompatibleBitmap(_hdc, _rect.right, _rect.bottom); // _hdc와 호환되는 비트맵 생성
HBITMAP prev = (HBITMAP)::SelectObject(_hdcBack, _bmpBack); // DC와 비트맵 연결
::DeleteObject(prev);
void Game::Render()
{
uint32 fps = GET_SINGLE(TimeManager)->GetFps();
float deltaTime = GET_SINGLE(TimeManager)->GetDeltaTime();
{ // 마우스 위치 출력
POINT mousePos = GET_SINGLE(InputManager)->GetMousePos();
wstring str = std::format(L"Mouse({0}, {1})", mousePos.x, mousePos.y);
::TextOut(_hdcBack, 20, 10, str.c_str(), static_cast<int32>(str.size()));
}
{ // FPS, Delta Time 출력
wstring str = std::format(L"FPS({0}), DT({1} ms)", fps, static_cast<int32>(deltaTime * 1000));
::TextOut(_hdcBack, 650, 10, str.c_str(), static_cast<int32>(str.size()));
}
// 액터 출력
GET_SINGLE(SceneManager)->Render(_hdcBack);
// 더블 버퍼링, 비트 블릿 ; 고속 복사
::BitBlt(_hdc, 0, 0, _rect.right, _rect.bottom, _hdcBack, 0, 0, SRCCOPY);
// 복사 이후 백 버퍼 클리어
::PatBlt(_hdcBack, 0, 0, _rect.right, _rect.bottom, WHITENESS);
}
먼저 _hdcBack으로 명명되어 있는 백버퍼에 렌더링하고 프론트 버퍼인 _hdc로 넘겨줄 것이다.
기존에 마우스 위치와 FPS, Delta Time을 _hdc에 그리고 있었던 것을 _hdcBack으로 수정한다.
이후에 비트블릿 함수를 사용하여 백버퍼를 프론트버퍼에 고속 복사한다.
복사 이후에 백 버퍼를 클리어한다.
'Windows API & 게임 수학' 카테고리의 다른 글
1-7. 오브젝트(Object) 설계 (2) - 디버깅, 몬스터, 피격 판정 (0) | 2023.10.17 |
---|---|
1-6. 오브젝트(Object) 설계 (1) - 플레이어, 투사체, ObjectManager (0) | 2023.10.17 |
1-4. 게임을 위한 프레임워크 제작하기(3) - Scene, SceneManager (1) | 2023.10.16 |
1-3. 게임을 위한 프레임워크 제작하기(2) - TimeManager, InputManager (1) | 2023.10.16 |
1-2. 게임을 위한 프레임워크 제작하기(1) (0) | 2023.10.16 |