게임엔진/윈도우API

윈도우API)1. 기본템플릿 분석

PJNull 2022. 12. 10.
728x90
반응형

윈도우 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를 호출하여 처리하는 경우 메시지가 갱신되지 않을 경우 루프가 멈추게 된다는 점이다. 게임은 입력->로직->랜더링이 일어나는데 플레이어가 멈추면 게임도 멈춘다는 의미로도 해석할수 있다. 그렇기에 플레이어가 멈추더라도 계속해서 게임이 진행되는 자체적인 프레임워크를 가지는 게임엔진이 필요하다.

728x90
반응형

'게임엔진 > 윈도우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

댓글