이전에도 계속 포스팅했다시피 난 이 게임(데모)를 Windows Store를 통해 공개할 생각이다. 따라서 엔진을 개발할때부터 UWP버전을 같이 작업해왔다.
그리고 가능하면 XBOX ONE과 Windows 10 Phone에서도 동일한 게임을 플레이하게 하려고 나름 노력하고 있다.
몇 개월전 MS는 하나의 Store를 강조하며 XBOX ONE에서 UWP App을 돌릴 수 있게 하겠다고 발표했다. 얼마 지나지 않아서 프리뷰지만 XBOX ONE에서 UWP App을 돌릴 수 있게 되었다. 개인적으로 굉장히 흥미롭게 생각했고 한국 MS 직원분의 도움으로 XBOX ONE을 잠시 대여할 수 있었다.
이후로 계속 XBOX ONE에서도 테스트를 해왔다. 주로 win32버전으로 작업을 하고 2주에 한번 정도 UWP버전에 변경사항을 업데이트, Windows Phone과 XBOX에서 테스트하는 식으로 진행해왔다.
최근엔 UWP버전을 거의 업데이트 하지 못했는데 , 빌려온 XBOX ONE을 반납할때가 되어서 요 몇일간 UWP버전의 작업에 집중했다.
win32버전의 변경사항을 모두 반영하고 특히 XBOX에선 키보드 마우스를 사용할 수 없다고 전제하여(실제로는 키보드 마우스를 꽂으면 인식하고 PC에서처럼 사용할 수 있다.) 게임패드만 가지고 적어도 로그인은 무사히 통과할 수 있도록 하는 작업을 했다.
아울러 Windows Phone에선 키보드도,마우스도,게임 패드도 없으니 제스쳐로 게임 패드를 대신하도록 했다.
복셀 편집은 마우스가 필요한데 이 부분은 XBOX와 Windows Phone에서 어떻게 처리할지 아직 결정을 못했다.
근래 UWP버전 작업에서 겪었던 이슈들을 몇 가지 적어보면…
[로그인 정보 암호화 문제]
이전 포스팅에선 언급하지 않은 부분이 있다. 사실 UWP버전과 win32버전의 네트워크 플레이를 구현할때 꽤 걸림돌이 되었던게 암호화 API부분이었다.
PC버전에선 win32에서 제공되는 Crypto API를 사용했다. 문제는 이 API를 UWP에선 사용할 수 없다는 것이다.
최초 로그인할때 서버에서 공개키를 받아서 그걸로 암호화해서 보내야하는데 이걸 win32와 UWP버전을 똑같은 방법으로 맞출수 없으니 암호화를 하지 말던가 해야하는데 그러기는 찝찝하고..그래서 계속 미뤄왔었다.
요전에 UWP와 win32간 네트워크 플레이가 가능해졌다는 포스팅을 할 무렵에 작업했던게 공통 암호화 라이브러리의 구축이었다.
약간은…흥미롭게도 이 부분에서 UWP API를 사용했다. 아니 정확히는 WinRT API를 사용했다. 지금 UWP API에 들어있지만 Windows 8 출시 시점에서 Windows 8의 WinRT API에 들어있던 Windows::Security::Cryptography API를 사용했다.
이것을 데스크탑 어플리케이션에서 사용할 수 있다. 사실 생각보다 많은 UWP API들을 데스크탑 어플리케이션에서도 사용할 수 있는데 이 암호화 API가 그중 하나이다.
물론 Windows 7에선 작동하지 않는다. 난 Windows 7을 지원할 생각이 전혀 없다.
하여간 Windows::Security::Cryptography API를 사용해서 win32, UWP각각의 DLL을 만들었다.
win32 버전의 DLL은 서버와 PC용 클라이언트에서, UWP용 DLL은 UWP on PC, UWP on XBOX , Windows Phone에서 사용한다.
그렇게 해서 로그인 계정/패스워드 암호화 문제는 해결.
[DirectX Feature Level문제]
현세대의 PC용 그래픽 카드라면 , 아니 심지어 intel의 내장GPU도 DirectX Feature Level 11을 지원한다. 또한 Feature Level 11을 사용할 수 있다면 DirectX 12 API를 사용할 수 있다.
win32버전의 엔진은 DirectX 11과 DirectX 12렌더러를 모두 지원한다.
UWP API도 물론 기능적으론 DirectX 11/12를 모두 지원한다. 단 UWP API를 돌리는 환경이 모바일이라면, 그러니까 Windows Phone이라면 대부분의 디바이스는 DirectX Feature Level 11을 지원하지 못한다. 스냅드래곤 808이상, 혹은 같은 세대의 보급형 칩에서 지원이 되는데 Windows Phone에서 이런 AP가 장착된 폰이 몇 개 없다.
초기엔 arm버전(Windows Phone)은 DirectX 11 on Feature Level 9를 사용했다. 그런데 Feature Level 9를 사용하고 API는 DirectX 11을 쓰는게 쉬운 일이 아니다. 말이 DX11이지 PC의 DX11렌더러와 코드가 거의 호환되는게 없다.
그래서 루미아 950XL을 구입한 후로 DX11 on Feature Level 9 렌더러는 버렸다.
내 폰에서만 일단 돌릴 수 있으면 그걸로 OK. 앞으론 거의 모든 모바일 GPU가 Feature Level 11을 지원할테니까.
그래서 UWP용 렌더러도 win32 렌더러(DX11)의 코드를 98% 사용해서 거의 같게 만들었다.
물론 폰에서도 잘 돈다.좀 느리지만..
UWP on XBOX에선 약간 다른 문제가 있다. XBOX ONE에 장착된 GPU는 하드웨어 스펙상으론Feature Level 11을 지원한다. 그런데 UWP API상에선 Feature Level 10까지만 지원한다.
따라서 Compute Shader와 테셀레이션 등을 사용할 수 없다. Shader Model도 5.0이 아닌 4.0으로 제한된다. 내 엔진에선 H/W Occlusion Culling에서 Compute Shader를 사용하고 있으므로 XBOX ONE에서 돌리는 경우는 문제가 된다.
결국 UWP용 렌더러의 코드를 수정해서 Feature Level 10에서 작동할때는 이런 기능들을 실행하지 않도록 했다.
[Network API]
이쪽은 Windows 8.1시절까진 꽤 큰 문제였다.아니 Windows 10에서도 th2빌드에선 여전히 문제다.
win32에선 winsock을 사용했다. Windows 8.1까지, 즉 WinRT에선 winsock을 사용할 수 없었다.
WinRT에 들어있는 StreamSocket API를 사용해야 했다. 이 녀석은 내부적으로 winsock을 사용한다. 그럼에도 불구하고 어플리케이션 프로그래머는 winsock을 사용할 방법이 없었다.
그러던것이 Windows 10의 UWP에선 winsock을 사용할 수 있게 되었다.
그런데 그 당시 또 문제가 있는것이…온라인 게임 업계에서 매우 인기있던 스레드풀 API-IOCP를 사용할 수 없다. 많은 PC기반 네트워크 코드들은 winsock-IOCP조합으로 작성되어있다. 내가 만든 네트워크 라이브러리도 마찬가지.
그래서 UWP버전을 위해 StreamSocekt + C++/CX으로 네트워크 라이브러리를 따로 작성했다.
그런데 8월 업데이트 예정엔 Windows 10 Anniversary 빌드(코드명 Redstone)에서부터 IOCP도 사용할 수 있다. 지금 이 문서를 작성하고 있는 시점에 내 PC에 설치된 Redstone의 Insider Preview버전에서 IOCP는 작동한다.
그래서 이쪽도 PC버전의 네트워크 라이브러리를 최대한 거의 그대로 포팅해서 쓸 생각이다. 일단은 StreamSocket버전도 작동을 하기 때문에 차일피일 미루고 있지만 조만간 PC버전의 네트워크 코드를 UWP버전으로 가져올 것이다.
[입력장치 문제]
XBOX ONE에서도 키보드 마우스는 사용 가능하다. 첫번째 데모는 XBOX ONE에 키보드와 마우스를 꽂아서 테스트했다. 아무래도 너무 번거로워서 적어도 로그인과 기본 플레이(전투,이동)만큼은 게임패드로만 할 수 있어야겠다는 생각이 들었다.
그래서 자주 사용하는 계정 목록을 그냥 저장해놨다가 로그인 화면에서 게임패드의 좌우 버튼으로 자동 입력이 되도록 했다.(나중에는 MS 계정이나 구글계정을 세이브해둬야겠다.)
그리고 얼마전 UI 라이브러리를 왕창 뜯어고치면서 게임패드 입력을 받을 수 있도록 했다.
A버튼을 누르면 기본적으로 OK버튼을 누른 것으로 처리한다.
일단 로그인을 패스하고 나면 게임패드만으로 이동,전투는 가능하다. 이것은 PC버전과 완전히 동일하다.
Windows Phone에선 게임패드도 없다. 레드스톤 정식 출시 이후,블루투스 게임패드를 연결하면 가능할것 같은데 테스트해보진 않았다. 어쨌건 아직은 게임패드 연결이 불가능하다고 가정한다.
그래서 Gesture기능을 이용했다.
Windows::UI::Input::GestureRecognizer API를 이용하면 화면 터치를 특정 제스쳐로 판별할 수 있다. 이것으로 상하 좌우 스와이프를 게임패드의 좌우상하 버튼으로 맵핑했다.
여기까지 하면 XBOX ONE과 동일한 상황인것으로 이제 로그인 화면은 OK.
<정리하면…현재 기술스펙은 다음과 같다.>
[win32버전]
– 타겟 디바이스 : x86/x64(PC)
– API : win32 , DirectX 11/12 , winsock
– Language : C/C++
[UWP버전]
– 타겟 디바이스 : arm(Windows Phone) , x64/x86(XBOX ONE, PC)
– API : UWP , win32(부분적으로) , DirectX 11
– Language : C/C++/CX
작업환경. 왼쪽이 XBOX ONE에 app을 deploy하고 디버깅할 pc-서피스북. 그 위에보이는 것이 XBOX ONE. 우측 화면이 XBOX ONE의 화면.dev mode로 진입한 상태이다.
7월 14일 현재 XBOX ONE의 Dev Mode는 Windows 10 14388빌드로 작동한다. 이것은 PC의 Insider Preview의 최신 빌드와 같은 버전이다.
XBOX ONE에서 Voxel Horizon UWP버전을 실행. 로그인 화면이다.로그인 다이얼로그 옆의 커서는 최근에 생긴것으로 보인다.게임패드로 이 커서를 움직일 수 있고 UWP앱에서의 터치를 대신한다.
PC와 XBOX ONE에서 일본의 Azure VM에 띄워놓은 서버에 접속했다.
단편적으로 UWP on XBOX개발에 관련된 포스팅을 3개 했는데 조만간 싹 정리해서 ppt로 업로드할 예정이다.