윈도우 API를 공부하는 이유
윈도우API는 운영체제에 일련의 함수들을 호출하여 필요한 기능을 수행하는 것을 의미한다. 이러한 윈도우API를 이용하여 간단한 게임을 만드는것으로써 게임엔진의 전체적인 구조를 만들고 게임엔진에 대한 이해도를 높이는것이 본 포스팅의 이유이다.
윈도우 애플리케이션 기본템플릿
기본템플릿은 꽤나 긴 코드로 이루어져 있지만 핵심적인 내용은 wWinmain 안의 3가지로 축약할수 있다.
1) 윈도우 창 정보 등록
MyRegisterClass(hInstance);
윈도우 창 정보 등록에는 위와 같은 함수를 사용한다. 위의 함수는 WindowAPI에서 제공하는 함수가 아닌 프로그램상에서 만든 함수이다. 그중에서 주요한 부분은 다음과같다.
ATOM MyRegisterClass(HINSTANCE hInstance)
{
wcex.lpfnWndProc = WndProc;//함수포인터이며,WndProc를 이용해서 처리를 부탁함
return RegisterClassExW(&wcex);//윈도우 창에 정보를 등록
}
2)윈도우 창 생성
윈도우 창 생성에는 아래와 같은 함수를 쓴다.
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
InitInstance함수는 등록한 앞서 등록한 정보들을 바탕으로 윈도우 창을 만들어주는 역할을 한다.
CreateWindow를 통해 윈도우창을 생성한다.
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // 인스턴스 핸들을 전역 변수에 저장합니다.
HWND hWnd = CreateWindowW(L"WindowAPI", L"Client", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, 800/*넓이*/,600/*높이*/, nullptr, nullptr, hInstance, nullptr);
//등록한 키값을 이용하여 윈도우 창을 생성
}
3)메인루프
메인루프는 기본적으로 GetMessage를 호출하여 메인루프를 처리하는 방식이다.
메시지를 받으면 콜백에 등록되어 있는 함수(Wndproc)에게 전달한다.
while (GetMessage(&msg, nullptr, 0, 0))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
이런식으로 메시지를 받으면 위에서 설정한대로 wndProc에서 처리하게 된다.
이중에서 가장 중요하다고 생각되는 부분은 화면상으로 그리는 것을 처리하는 부분인 WM_PAINT와 마우스가 이동하는 좌표를 받아주는 WM_MOUSEMOVE가 있다.
페인트 부분
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
TextOut(hdc,100,100,L"TEST",4);//문자
Rectangle(hdc,200,200,400,400);//사각형
Ellipse(hdc,200,200,400,400);//원
MoveToEx(hdc,300,300,nullptr);//시작점
LineTo(hdc,400,400);//선
LineTo(hdc,500,300);//선
EndPaint(hWnd, &ps);
}
break;
}
}
다만 이코드는 메시지에 변경이 일어날때만 콜백함수가 작용하여 다시 그려주기 때문에 매 프레임마다 랜더링이 되어야 하는 게임이랑은 맞지 않다.
마우스 부분
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
int x=LOWORD(lParam);
int y=HIWORD(wParam);
break;
}
}
위 코드에서 행하는 일은 wParam과 lParam을 받고 그것을 x와y좌표로 변환해주는 것이다. LOWORD와 HIWORD가 행하는 것은 아래와 같은 방식으로 x와y좌표를 추출할수 있게 해준다.
HWND와 HDC
위 코드에서 종종 보이는 HWND와 HDC는 무엇일까?
HWND(Handle Windows)
HWND는 윈도우의 핸들을 말한다. 파일에 접근하려면 파일 핸들을 이용하듯이 윈도우도 역시 HWND라는 핸들을 사용하여 접근해야 하는데 HWND의 값은 숫자로 이루어져 있다. 이 윈도우의 번호가 몇 번이다 라는 걸 알고 있어야 운영체제에서 관리를 할 수 있다. 관리를 위한 id를 식별하기 위하여 HWND가 필요하다.
윈도우는 공통적으로 메세지 큐를 가진다. 윈도우즈 프로그래밍은 기본적으로 메세지 처리 방식이기 때문이다. 즉 메세지 큐를 가지는 것은 전부 윈도우라 볼 수 있다. 메세지 큐라는 것은 윈도우즈에서 발생하거나 넘겨준 메세지를 저장하고 있는 곳인데 이 메세지큐에 저장된 메세지 들이 해당 윈도우로 흘러 들어가서 처리하는 것이 윈도우즈 프로그래밍의 기본 원리이다.
HDC(Handle Device Context )
Device Context 란, 출력에 필요한 정보를 가지는 데이터 구조체 , 좌표 ,색 ,굵기등 출력에 필요한 모든 정보를 담고있다.HDC 란 DC의 정보를 저장하는 데이터 구조체의 위치를 알기위해 존재하는 것이며 포인터는 아니다.실제 객체의 메모리 주소를 가르킬 뿐이다. 즉, 물리적으로 메모리 주소가 바뀌어도 , DC의 실제위치를 찾아간다는 뜻이다.
문제점
위 코드가 게임과 어울리지 않는 이유는 GetMessage를 호출하여 처리하는 경우 메시지가 갱신되지 않을 경우 루프가 멈추게 된다는 점이다. 게임은 입력->로직->랜더링이 일어나는데 플레이어가 멈추면 게임도 멈춘다는 의미로도 해석할수 있다. 그렇기에 플레이어가 멈추더라도 계속해서 게임이 진행되는 자체적인 프레임워크를 가지는 게임엔진이 필요하다.
'게임엔진 > 윈도우API' 카테고리의 다른 글
윈도우API)8. 벡터 (0) | 2022.12.18 |
---|---|
윈도우API)7. 삼각함수 (0) | 2022.12.18 |
윈도우API)5. 오브젝트 설계 (0) | 2022.12.17 |
윈도우API)3. Scene과 SceneManager (0) | 2022.12.16 |
윈도우API)2. 프레임워크 제작 (0) | 2022.12.15 |
댓글