관리 메뉴

KoreanFoodie's Study

윈도우 API 프로그래밍 10 : 백버퍼와 픽 메시지 본문

Game Dev/윈도우 API

윈도우 API 프로그래밍 10 : 백버퍼와 픽 메시지

머니덕 2021. 10. 17. 22:40

게임클래스의 하민우 교수님 강좌를 듣고 기억할 만한 내용을 리마인드하는 글입니다

 


윈도우 API 프로그래밍 10 : 백버퍼와 픽 메시지

백 버퍼는 화면에 그려지는 버퍼에 바로 렌더를 살 경우 버퍼가 지워지는 순간 또는 버퍼에 전체가 다 그려지기 전에 화면에 그려지기 전에 화면에 그려질 경우 덜 그려진 부분이 화면에서 잠깐 지워진 상태가 되기 때문에 깜빡이는 것처럼 보이는 현상이 생긴다.

이때, 백 버퍼를 생성하여 백 버퍼에 모든 내용을 그리고 백 버퍼를 화면에 렌더하는 방식으로 위의 문제를 해결할 수 있다.

백퍼퍼와 픽 메시지

기존에는 WM_TIMER를 이용하여 업데이트를 처리했지만 이는 모든 메시지 중에서 우선 순위가 가장 낮고 최대 속도가 0.01초이다. 이를 극복하고 cpu 성능을 제대로 활용하기 위해 픽 메시지를 사용한다!

    HDC hdc = GetDC(g_hWnd);
    g_hDC = CreateCompatibleDC(hdc);    // 화면에 출력되지 않는 비트맵 객체를 연결할 수 있는 DC

    HBITMAP hBitmap = (HBITMAP)CreateCompatibleBitmap(hdc, WINSIZEX, WINSIZEY); // 렌더를 할 비트맵 생성
    SelectObject(g_hDC, hBitmap); // 생성한 비트맵을 백버퍼 DC에 연결

	pMainGame = new MainGame;	// 할당
	pMainGame->Init();

    // 기본 메시지 루프입니다:
    // 데스 타임 : 메시지를 대기하며 일을 하지 않는 시간
    while (true) {
        if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
        {
            if (msg.message == WM_QUIT)
                break;
            
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        // 메시지를 받지 않는 상황에서는 계속 업데이트와 렌더를 진행시킨다 (데스 타임을 없애기)
        else {
            if (pMainGame) {
                pMainGame->Update();
                pMainGame->Render();
            }
        }
    
    }

먼저, GetDC( ) 를 통해 글로벌 변수로 설정된 g_hWnd를 받아들이고, 새로운 DC 객체를 만들어준다.

렌더를 할 비트맵을 만들어 준 다음, g_hDC를 hBitmap과 연결시켜 둔 후 대기시킨다.

PeekMessage( ) 함수를 이용해서, 메시지를 받으면 받은 메시지를 처리하고, 받지 않을 때는 업데이트와 렌더를 꾸준히 해 준다.

 

MainGame::Render()

	PAINTSTRUCT ps;

	HDC hdc = BeginPaint(g_hWnd, &ps);

	PatBlt(g_hDC, 0, 0, WINSIZEX, WINSIZEY, WHITENESS);

	// 클래스 렌더
	if (m_pPlayer) m_pPlayer->Render();
	if (m_pObjects) m_pObjects->Render();

        /*

        여기에 그리고 싶은 것을 그린다!

        */


	BitBlt(hdc, 0, 0, WINSIZEX, WINSIZEY, g_hDC, 0, 0, SRCCOPY);

	EndPaint(g_hWnd, &ps);

여기서 PatBlt( )를 이용해 먼저 화면을 새하얗게 만들어 준 후, BitBlt(hdc, 0, 0, WINSIZEX, WINSIZEY, g_hDC, 0, 0, SRCCOPY); 를 호출해 지금껏 g_hDC에 그린 내용을 다시 hdc에 복사한다!

 

 


더 자세한 내용이 궁금하시다면 직접 들어보시는 걸 추천드립니다!

 
0 Comments
댓글쓰기 폼