WinAPI

더블버퍼링

Nin 2021. 1. 20. 01:01

Api 코드에 그림,사각형 무엇을 그리던 영역이 겹쳐지면

그리고 지워지고 다시 그리고를 반복하기때문에 겹쳐지는 영역이

깜빡이는것처럼 보이는 현상이 일어난다.

이를 해결하기 위해서 더블버퍼링이라는 기법을 사용하는데

이는 내가 만든 윈도우창과 똑같은 크기의 창을 하나 더 만들어서

거기에다가 그림을 그린후 완성된 그림을 복사해서 화면에 보이는

윈도우창에 보여 주는 기법이다.

위의 그림과 같은 개념으로 BackBuffer에서 그림을 그리고 완성된 화면을 MainWindow에 복사해서

보여주는 방식인데 그림과 같이 TitleBar의 크기를 제외한 순수한 클라이언트창의

크기를 구해서 똑같은 창을 하나 만들어 줘야 한다.

#include <Windows.h>

int ClientSizeX = 900;
int ClientSizeY = 800;
RECT ClientSize = { 0,0,ClientSizeX,ClientSizeY };
	AdjustWindowRect(&ClientSize, WS_OVERLAPPEDWINDOW, false);

HWND MyHWND = CreateWindowW(L"MyWINDOW", L"ClientWindow", WS_OVERLAPPEDWINDOW,
		100, 100, ClientSize.right - ClientSize.left, ClientSize.bottom - ClientSize.top, 
               nullptr, nullptr, nullptr, nullptr);

위의 코드에서 AdjustWindowRect 함수를 이용해서 만들면 타이틀바와 외곽선을 제외한 정확한

클라이언트 사이즈를 900,800으로 만들어준다.

그런다음 우선적으로 일단 그림을 그릴 BackBuffer를 하나 더 만들어줘야 한다.

#include <Windows.h>
HDC      //윈도우에서 제공하는 이미지의 핸들
HBITMAP  // 윈도우에서 이미지에 대해서 간섭할 수 있는 권한
BITMAP   //이미지에 대한 정보
    
HDC DC = CreateCompatibleDC(nullptr);
BITMAP BackBufferBitMap = CreateCompatibleBitmap();

CreateCompatibleDC 함수는 DC(그림을 그릴수 있는 권한)를 만들어 주는 함수다.

DC의 개념은 색깔의 2차원 배열집합이라고 생각할 수 있다.

함수를 이용해서 DC를 만들면 내부에 1,1 크기 Bitmap을 들고있는 상태로 만들어진다.

CreateCompatibleBitmap() 이 함수는 첫번째 인자로 MainWindow의 HDC를 넣어주고 

BackBuffer의 x와 y를 넣어주면 일종의 Bitmap(색깔의 배열)을 만들어낸다.

여기서 MainWindow의 크기만큼 만들어낸다.

그림으로 보면 이런 상황이다. DC를 만들었고 그 DC는 1,1크기의 BitMap과 연결되있고

MainWindow와 같은사이즈의 BackBufferBitMap도 하나 만들어진 상태이다.

그러면 DC를 1,1크기의 BitMap에서 BackBufferBitMap으로 연결해줘야 한다.

SelectObject(DC,BackBufferBitMap);

이렇게 해주면 

이렇게 된다. 그러면 그림에서 보듯이 1,1크기의 BitMap이 남아있게된다.

BITMAP OldBitMap = (HBITMAP)SelectObject(DC,BackBufferBitMap)

저기서 리턴되는값이 원래 가지고 있던 1,1크기의 BitMap이기 때문에 저 값을

보관해둔다.그런다음

BITMAP Info;
GetObject(BackBufferBitMap,sizeof(BITMAP),&Info);

GetObject 함수는 윈도우에서 지원하는 핸들의 정보를 얻어올수 있는 함수로

인자에 백버퍼비트맵을 넣어주고 BITMAP 변수의 주소값을 넣어주면

정보를 채워준다.이제 BackBufferBitMap에 그림을 그리고 

완성된 화면을 MainWindow에 복사해주면 된다.

BitBlt()이란 함수를 사용하면 되고 이 함수는 DC간의 고속복사이다.

BitBlit(
	HDC hdcDest, //이미지를 출력할 위치의 핸들
    int nXDest,  //이미지를 출력할 위치인 x 좌표
    int nYDest,  //이미지를 출력할 위치인 y 좌표
    int nWidth,  //원본 이미지의 너비
    int nHeight, //원본 이미지의 높이 
                 //(이 너비,높이만큼 원본 이미지에서 잘라와서 복사)
    HDC hdcSrc,  //이미지의 핸들
    int nXSrc,   //가져올 이미지의 시작지점인 x 좌표
    int nYSrc,   //가져올 이미지의 시작지점인 y 좌표
    DWORD dwRop) //이미지의 출력 방법 
                 //(SRCCOPY를 넣어주면 원본 이미지를 복사해서 출력)

 

'WinAPI' 카테고리의 다른 글

enum , enum class  (0) 2021.01.22
LoadImage 함수 (이미지 로드)  (0) 2021.01.21
assert 추가 설명  (0) 2021.01.20
InLine 문법  (0) 2021.01.20
Virtual Destructor(가상 소멸자)  (0) 2021.01.18