이전 04 글에서 화면에 사각형을 그리고 움직였다. 만약 화면에 그려야할 오브젝트가 많아진다면? 그리고 내 캐릭터를 움직이는데 키를 지속적으로 누르고 있다면? 화면에 그려지는 정보는 어떤 식으로 보여질까? 게임에서 렌더링과 프레임을 생각해보자.
우선 메시지 기반에서 렌더링을 볼 수 있게 코드를 수정해보자. 마우스 좌클릭시 위치를 받고 좌클릭이 끝나는 지점에서의 위치를 받아 해당 영역만큼 사각형을 그리는게 목표다.
먼저 다음과 같이 전역 변수를 만든다. 이전 오브젝트 위치와 크기를 받는 전역 변수를 구조체 안에 넣었다.
그 후 #include<vector>와 using namespace std;를 통해 vector 컨테이너를 만들고 objInfo를 담는다.
그 후 마우스 좌클릭시, 마우스 좌클릭 뗐을 때, 마우스 이동할 때의 case문을 추가하여 수정해준다.
이 때 마우스 좌클릭시 좌상단 위치를 받아오고 마우스를 이동할 땐 우하단의 위치를 받아온다.
그 후 case WM_PAINT 내부에서 사각형 그리는 코드를 다음과 같이 수정한다. 이를 통해 마우스 클릭 후 이동한 영역에 대해서만 그리고 이 정보를 넣은 배열에 해당하는 값들만 그린다.
이를 실행하여 막 그리다 보면 사각형이 늘어날수록 깜빡거리는게 더 눈에 띄는데 원인은 두가지가 있다.
1) InvalidateRect의 실행으로 화면에 그리는데 이 호출 타이밍이 잘못되어 우리는 완성된 그림이 아닌 그리는 과정을 보고 있기 때문이다.
2) 현재는 Message가 있어야 명령을 수행하기 때문이다. (왜냐면 Message Queue에서 꺼내야하니깐)
그러면 강제로 메시지를 발생시켜 일정시간마다 그려준다. (주석으로 코드를 작성해뒀습니다~)
1) InitInstance함수 내 HWND를 전역 변수로 받아서 WinMain에서 while문 시작전에 SetTimer()를 통해 1초마다 이 HWND를 실행한다.
2) 그 후 WinProc 함수 내 case WM_TIMER:를 추가하여 함수를 실행한다.
이렇게 하면 메시지 기반 함수에서도 게임을 만들 수 있다. 그러나 메시지 기반 방식은 매우매우 느리기에 이는 실시간인 게임에는 비효율적이다! (많은 선배님들이 입증해줬지만 궁금하다면 직접 테스트해보자...)
따라서 이를 메시지 처리 없이 실행할 수 있게 WinMain의 while문에서 GetMessage 함수를 고쳐야한다. 어떻게? 메시지가 있던 없던 처리할 수 있게 바꿔야한다. (GetMessage가 어떤 식으로 처리되는지 헷갈리면 다시 MSDN ㄱㄱ)
PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)를 사용하는데 PeekMessage는 몰래 본다는 의미로 메시지 유무 상관 없이 항상 true를 반환한다. (PM_REMOVE 는 메시지가 있다면 반환하고 지우는걸 의미하므로 이를 넣어야 GetMessage처럼 처리가 잘된다)
문제는 while문이 항상 true면 계속 실행하니 PeekMessage를 GetMessage처럼 사용하기 위해 변환한다.
이는 GetMessage와의 차이가 뭘까? 간단하다! if문이 생겼다면 else문을 통해 메시지가 없는 경우에 대한 처리가 생긴다! 즉 timer를 사용하지 않고도 우선 while문을 실행시켜 메시지가 없는 상황에 대해서 처리가 가능해진 것이다.
따라서 메시지가 들어오지 않는 대부분의 시간은 else문에서 체크해서 처리하면 된다는 것이다!!
'WinAPI 32' 카테고리의 다른 글
07 WinAPI) Window 창 받아 만들기 (0) | 2023.11.15 |
---|---|
06 WinAPI) Singleton (0) | 2023.11.12 |
04 WinAPI) 핸들과 DC(2) (0) | 2023.11.10 |
03 WinAPI) 핸들과 DC(1) (0) | 2023.11.09 |
02 WinAPI) 기본(2) (0) | 2023.11.07 |