[게임 개발 : 히어로 체스] 1. 이중 버퍼 패턴 적용

WIGWAG·2023년 1월 16일
0

히어로 체스

목록 보기
2/5

프로젝트를 진행하려는 데 WinAPI를 사용한 지가 너무 오래되어 게임 제작에 필요한 기초적인 지식들에 대한 공부가 필요했다.
여러 명령 처리와 비트맵과 애니메이션을 다루는 방법을 공부한 후에 프로젝트를 진행하게 되었다.

게임프로그래밍 패턴 책에서는 이중 버퍼 패턴은 나중에 나오지만 WinAPI에서 디바이스 컨텍스트만 바꿔주면 이중 버퍼 패턴을 쉽게 적용할 수 있기 때문에 먼저 진행하게 되었다.


이중 버퍼 패턴이란?

렌더링과정에서 화면을 그리는 중간과정을 생략하고 부드럽고 빠르게 화면을 보여줘야한다. 이 문제를 해결하기 위해서 이중 버퍼 패턴이 필요한데 이 패턴은 현재 버퍼와 다음 버퍼 이 두 가지 버퍼가 준비되어 있어야 한다. 정보를 읽을 때는 현재 버퍼에 접근하고 정보를 쓸 때는 다음 버퍼에서 점차적으로 수정한다. 변경이 끝난 후 현재 버퍼와 다음 버퍼를 교체하여 다음 버퍼가 보여진다. 현재 버퍼는 새로운 다음 버퍼가 되어 정보를 쓰게 된다.
이중 버퍼 패턴으로 그래픽이 중간에 끊기는 테어링 현상을 해결할 수 있다.

<마법사 클래스의 Render함수>

void C_Magician::Render(HDC memdc)
{
    //애니메이션 카운트 업데이트 하기
    count = ++count % 16;
    //이미지DC 생성
    HDC image_dc = CreateCompatibleDC(memdc);
    //해당 애니메이션 프레임 이미지DC에 넣기
    HBITMAP oldBit = (HBITMAP)SelectObject(image_dc, MagicianBit[count]);

    //이미지DC의 사진을 임시DC의 적절한 곳에 넣기
    //정확한 이미지 크기가 들어가야 제대로 나온다.
    TransparentBlt(memdc, x, y, MAGICIAN_W, MAGICIAN_H, image_dc, 0, 0, MAGICIAN_W, MAGICIAN_H, WHITE);

    //이미지 지우기
    SelectObject(image_dc, oldBit);
    //이미지DC 삭제
    DeleteDC(image_dc);
}

<더블버퍼링 적용>

case WM_PAINT:
{
        //메인 도화지 생성
        hdc = BeginPaint(hWnd, &ps);

        //임시 도화지 생성
        memdc = CreateCompatibleDC(hdc);
        if (!hBit)
            hBit = CreateCompatibleBitmap(hdc, WIN_W, WIN_H);
        HBITMAP oldBit = (HBITMAP)SelectObject(memdc, hBit);

        //임시 도화지에 오브젝트 들 그리기
        background.Render(memdc);
        board.Render(memdc);
        magician.Render(memdc);

        //임시 도화지의 그림내용 메인 도화지로 옮기기
        BitBlt(hdc, 0, 0, WIN_W, WIN_H, memdc, 0, 0, SRCCOPY);

        //비트맵 지우기
        SelectObject(memdc, oldBit);

        //임시 도화지 삭제
        DeleteDC(memdc);

        //메인 도화지 삭제
        EndPaint(hWnd, &ps);
}
        break;

모든 디바이스 컨텍스트(DC)가 메시지 처리 함수를 호출할 때마다 초기화 되므로 메인DC와 서브DC를 지정해주는 편이 좋다. 서브DC에 이미지를 렌더링한 후 작업이 끝났을 때 BitBlt를 통해 서브DC에 그린 내용을 메인DC에 옮겨준다.

profile
윅왁의 프로그래밍 개발노트

0개의 댓글