Day2 이벤트 입력과 렌더링
운영체제에서는 유저가 애플리케이션 윈도우상에서 수행할 수 있는 여러 액션을 제공한다. 액션들을 표현하는 일반적인 방법은 이벤트를 사용하는 것이다. SDL은 운영체제로부터 받는 이벤트를 내부에 존재하는 큐(Queue)로 관리한다. 프레임마다 게임은 큐에 이벤트가 존재하는지 폴링(Polling)한다. 그리고 큐에서 얻어온 이벤트를 무시하거나 처리할지를 선택한다.
이벤트는 입력 타입이므로 ProcessingInput에서 이벤트 처리를 구현한다. SDL_PollEvent함수는 큐에서 이벤트를 발견하면 true를 반환한다.
SDL_Event 구조체를 선언하고 while문과 SDL_PollEvent함수를 통해 이벤트를 처리한다. SDL_PollEvent함수는 SDL_Event의 포인터를 인자로 받는데 SDL_Event의 포인터는 큐에서 막 제거된 이벤트의 관한 정보를 저장한다. SDL_Event의 type 멤버 변수는 이벤트 타입 정보를 포함한다. 그래서 switch문을 이용해 해당 타입 값에 대한 이벤트를 처리한다. 위 ProcessInput 함수에서 event.type으로 이벤트의 타입을 받아서 처리하는데 SDL_QUIT이라는 이벤트는 윈도우 창의 X표시를 누르거나 단축키를 사용해서 윈도우 창을 닫으려고 하는 이벤트이다. 그래서 SDL_QUIT 이벤트가 발생하면 mIsRunning을 false로 바꿔 루프를 종료시킨다.
또 ProcessInput 함수에서 다룰 수 있는 것은 유저의 키보드 입력이다. 키보드의 이벤트를 확인해도 되지만 현재 키보드의 상태를 포함하는 배열의 포인터를 SDL_GetKeyboardState 함수를 호출해서 얻어내는 것이다. 위 소스코드에서 const Uint8* state = SDL_GetKeyboardState(NULL)을 이용해 배열의 포인터를 저장하고 SDL_SCANCODE 인덱스를 사용해 특정 키의 상태를 조회할 수 있다. 따라서 ESC를 눌렀을 때 루프를 멈추게 하고 싶다면 state[SDL_SCANCODE_ESCAPE]를 통해 유저가 ESC를 눌렀는지를 확인할 수 있다. SDL_GetKeyboardState는 Uint형식의 값을 반환한다.
대부분의 디스플레이는 래스터 그래픽스를 사용한다.래스터 그래픽스는 픽셀을 갖고 있음을 의미한다. 이 픽셀은 생상과 빛을 나타낼 수 있는데 이 픽셀들의 생상과 세기의 결합을 통해 사람은 픽셀들을 연속적인 이미지로 인식한다. 색상은 색깔을 셍성하는 RGB값과 투명도를 지원하는 알파값을 사용하는데 RGB값의 혼합으로 색상의 범위를 결정한다. 컴퓨터 그래픽스에서 색상 버퍼(color buffer)는 전체 화면의 생상 정보를 포함하고 있는 메모리상의 위치를 뜻한다. 디스플레이는 콘텐츠를 화면에 그리기 위해 색상 버퍼를 사용한다. 매 프레임마다 게임은 그래픽 출력을 색상 버퍼에 쓴다. 현재 기술로는 전체 화면을 한순간에 갱신할 수 없기 때문에 순차적으로 생신한다. 따라서 약간의 시간이 걸리게 된다. 게임이 색상 버퍼에 데이터를 쓰고 디스플레이가 같은 색상 버퍼를 읽는다고 할 때 디스플레이가 데이터를 읽을 때 게임이 색상 버퍼의 데이터를 쓰는 상황이 발생할 수 있다. 그래서 스크린 테어링 현상이 나타날 수 있다. 그래서 더블 버퍼링(double buffering)기술을 통해 전면 버퍼, 후면 버퍼라는 두 개의 버퍼를 나눠서 하나에 버퍼에 데이터를 쓰고 다른 하나의 버퍼의 데이터를 읽는다. 이것만으로는 테어링을 완전히 제거하지 못하는데 수직동기화(vertical synchronization, vsync)라는 기술이 있다. 디스플레이가 하나의 버퍼에서 데이터를 읽어서 완전히 그릴 때까지 게임이 기다리는 것이다. 그러나 게임이 기다리는 것이기 때문에 버벅거림이 발생할 수 있다.
SDL 그래픽 코드를 사용하려면 SDL_CreateRenderer 함수를 통해서 SDL_Renderer 객체를 생성해야한다. Game의 멤버 변수에 mRenderer를 추가한다(SDL_Renderer* mRenderer).
SDL_CreateRenderer 함수는 생상한 윈도우, 그래픽 카드, 초기화 플래그를 파라미터로 갖는다. SDL_REDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC 는 각각 가속화된 렌더러의 사용 여부와 수직동기화 사용 여부이다.
그리고 ShutDown 함수에서 SDL_DestoryRenderer 호출을 통해 렌더러를 해제한다.
게임용 그래픽 라이브러리로 그래픽을 그리려고 한다면 다음 단계가 요구된다.
1. 후면 버퍼를 단색으로 클리어한다(게임의 현재 버퍼).
2. 전체 게임 장면을 그린다.
3. 전면 버퍼와 후면 버퍼를 교환한다.
GenerateOutput 함수에다가 후면 버퍼를 지우기 위해 SDL_RenderDrawColor를 통해 하나의 색을 지정해야한다. 이 함수는 렌더러 포인터와 RGBA 요소를 인자로 받는다. 그리고 현재 색상으로 후면 버퍼를 지우기 위해 SDL_RenderClear를 호출하고 SDL_RenderPresent를 호출해서 전면 버퍼와 후면 버퍼를 교환한다.