개발하는 리프터 꽃게맨입니다.

[WinAPI] 더블 버퍼링 본문

Window API

[WinAPI] 더블 버퍼링

파워꽃게맨 2024. 2. 1. 23:07

 

최근에 만들 윈도우 API 프로그램입니다.

방향키를 누르면 사각형이 이동합니다.

 

그런데

 

 

이동을 하면 잔상이 남는 모습을 볼 수 있습니다.

그림을 그리는 것은 모니터의 픽셀 버퍼에 원하는 값을 저장하는 형식으로 진행됩니다.

우리가 이전 버퍼를 지워주지 않았으니 이렇게 잔상이 남는 것이죠.

 

 

이런 식으로 매우 큰 흰색 사각형을 그려줘서 지워주는 건 어떨까요?

아마 매우 빠르게 깜빡 깜빡 거릴겁니다.

 

이게 왜 그렇냐면 

그리기 버퍼를 단 1개만 사용해서 그렇습니다.

 

컴퓨터가 아무리 빨라도

화면에 픽셀을 하나하나 그려서

모두 그리는데 시간이 걸리겠죠?

 

저 코드를 넣어주면, 

컴퓨터가 원하는 그림을 먼저 싹 그린 다음에

흰 색 큰 사각형을 싹 그려주고.. 를 반복합니다.

그러면 깜빡깜빡 거린다는 거죠.

 

깜빡이는 이유는

그리는 과정이 보이기 때문입니다.

 

예를들어서 우리가 화가에게 그림을 사고자 합니다.

그런데 우리는 화가의 그림에 관심이 있지 그리는 과정은 관심이 없잖아요?

마찬가지로 우리는 다 그려진 결과만 관심이 있지 그려지는 과정은 보고싶지 않습니다.

 

그래서 우리는 그리기 버퍼를 2개 사용해서

1개는 보여주기용 1개는 그리기용으로 둬서

 

A버퍼를 보여주고 B버퍼에 그리고

B버퍼를 보여주고 A버퍼를 그리고

를 반복해줄겁니다.

 

이를 버퍼를 2개 사용한다하여 더블 버퍼링이라고 부릅니다.

 

결국 더블 버퍼링이라는 작업은

그리는 과정은 숨기고 그린 결과만 보여준다. 라는 것이죠.

 

 

이게 제가 사용하는 프레임워크의 Render함수인데요.

이 함수를 조작해서 더블 버퍼링을 구현해보겠습니다.

(temp 부분은 오브젝트를 쭉 순회하면서 렌더링해주는 함수입니다.)

 

일단 2가지 변수가 필요한데요.

이 2가지 입니다.

 

 

이런 식으로 우리가 hdc를 이용해서 윈도우 커널로 그림을 그려주고

윈도우에는 비트맵 형태로 그림이 저장됩니다.

 

그래서 hdc와 비트맵은 같이 다니는 짝꿍이라고 생각해주시면 됩니다.

 

 

먼저 이렇게 변수를 초기화 해주는데 

 

_hdc와 호환되는 backhdc를 정의하고

_hdc와 호환되는 비트맵도 정의해준다음

 

_backHdc와 _bitMap을 연결시키주는 과정입니다.

원래 HDC는 태어날 때부터 1픽셀짜리 비트맵을 가지고 있는데요

selectobject하면 그 비트맵이 튀어나옵니다.

그걸 받아서 삭제까지 해주면 됩니다.

 

 

이제 기존에 hdc에 그려줬던 렌더링관련 인자들을

 

 

이런식으로 backHdc에 그려주도록 유도한 다음에

 

 

BitBlt 이란 함수로 _backHdc에 있던 비트맵을 _hdc에 싹다 복붙하고

백hdc를 patblt으로 완전 하얗게 칠해줍니다.

 

 

그러면 더블버퍼링 구현 완료입니다.