Cocos2d-x

Cocos2d는 Objective-C로 구현된 2D 게임엔진인데, iOS용으로 개발되었기 때문에 아이폰/아이패드에서만 사용할 수 있었습니다. Objective-C는 C/C++보다는 덜 대중적이고 생소한 언어인 것이 현실입니다.

이 때문에 C++로 구현된 Cocos2d-x가 나오게 되었습니다. Cocos2d-x는 게임 코드와 플랫폼 코드가 분리되어 있어서, 게임 로직만 구현하면 어떤 모바일 플랫폼이든 쉽게 게임을 출시할 수 있게 되어 큰 인기를 끌게 되었습니다.

Cocos2d-x는 윈도우에서 Visual Studio로 컴파일과 실행이 가능한데, 이 때문에 개발이 정말 편해졌습니다. Visual Studio에서 개발한 뒤 NDK나 XCode로 컴파일 해서 해당 플랫폼에 실행했을 때 큰 문제없이 실행이 되기 때문입니다.

Tizen

Tizen은 삼성전자와 인텔에서 개발하고 있는 리눅스 기반 모바일OS 입니다. 예전에 삼성에서 바다라는 모바일OS를 개발했었는데, 그다지 성공하지는 못했었습니다. 이번에 나온 Tizen에 기대를 걸고 있는 것이 Tizen이 리눅스 기반이라는 점 때문입니다. 그래서 기존 리눅스에서 사용하던 모든 오픈소스 소프트웨어를 그대로 활용할 수 있습니다.

바다는 Nucleus라는 커널을 사용하고 있었기 때문에 범용성 및 확장성이 떨어졌습니다. Necleus 커널은 기존 피쳐폰(Feature Phone)에서나 쓰던 물건이죠.

Cocos2d-x를 Tizen용으로 포팅하면서

저는 2013년 4월 26일 부터 회사일을 마친 이후 시간과 주말 동안 작업을 하였습니다. 작업을 하는 동안 여러가지 난관에 부딫혔는데요. 이 부분들을 공유해보고자 합니다.

Tizen IDE와의 씨름

Tizen은 Andriod와 마찬가지로 Eclipse 기반 IDE를 가지고 있습니다. 올해 2월에 출시된 Tizen 2.0 IDE를 기반으로 작업을 하게 되었는데, 여러가지 문제점이 있었습니다.

프로젝트 생성 방식 문제

Cocos2d-x Android 프로젝트 같은 경우 Makefile 기반으로 되어 있습니다. 하지만 Tizen은 Eclipse 자체 프로젝트 형식을 따르고 있었고 이 프로젝트에서 Tizen 자체 빌드 도구인 sbi(Smart build interface)를 이용해서 Makefile을 임시 생성하는 방식입니다.

이것이 문제가 되는 것이 개별 프로젝트를 관리하기는 편리하지만 Cocos2d-x처럼 라이브러리 단위로 분리되어 있을 경우, 프로젝트를 구성하기가 상당히 힘들다는 점입니다. Cocos2d-x Android의 경우 libcocos2d.a Makefile을 include 하는 방식으로 게임 실행 파일을 컴파일 하도록 되어 있어, 프로젝트가 매우 간단하게 구성이 되어 있습니다.

Tizen의 sbi를 직접 이용하는 방법을 찾게 된다면 프로젝트를 Android 처럼 구성해야 될 것입니다.

프로젝트 디렉터리 구성 문제

Tizen의 C++ 프로젝트인 Tizen Native 프로젝트는 기본 디렉터리 구조가 강제적입니다. inc, lib, res, shared, src 등의 기본 디렉터리 구성인데, 소스 파일은 항상 src에 넣어야 됩니다. Eclipse에서 제공하는 파일 링크 기능을 이용했다 하더라도 src 디렉터리가 없으면 아무것도 되지 않습니다.

리소스 디렉터리 문제

이 문제도 위 2번에서 파생되는 문제입니다. Cocos2d-x sample의 경우 Resources 디렉터리에 리소스 파일이 들어 있고 각 플랫폼별 프로젝트에서 이 리소스를 끌어와서 사용하는 방식입니다. 그런데 Tizen의 경우 Eclipse에서 제공해주는 링크 기능을 이용해서 res 디렉터리에 연결시켜주더라도, 실제 빌드를 해보면 리소스 파일이 복사되지 않는 문제가 있습니다. 결국 Resources 디렉터리의 내용을 Tizen 프로젝트의 res 디렉터리로 일일이 복사해줘야 합니다.

결국 깔끔하게 해결하지 못하고 README.mdown 파일에 Resources 디렉터리의 파일을 res 디렉터리로 복사하라고 명시해둔 상황입니다.

기본 라이브러리와 헤더 파일 문제

Cocos2d-x에서 꼭 필요한 라이브러리 파일이 있습니다. libjpeg, libpng, libtiff, libz, libfreetype, libfontconfig 등이 있는데 이 라이브러리 파일들이 Tizen IDE에 기본적으로 포함이 되어 있지 않았습니다. 물론 헤더 파일도 포함이 되어 있지 않아 정말 난감했습니다.

결국 필요한 라이브러리 파일의 소스(libjpeg, libpng, zlib 등)를 받아와서 Tizen IDE에서 빌드한 후 사용을 해보았지만 정상적으로 동작하지 않았습니다. 하지만 뒤에서 설명할 GBS를 사용하여 어느정도 해결은 하였습니다.

이제 첫 단계인 Cocos2d-x 컴파일이 성공적으로 끝났습니다.

GBS(Git Build System) 활용

Tizen은 모든 라이브러리를 Git으로 관리하고 있었습니다. http://tizen.org에 회원 가입을 하면, http://review.tizen.org/gerrit에 접근할 수 있습니다. gerrit을 잘 세팅해놓아서 조금 놀랬습니다.

더군다나 Git을 이용한 빌드 시스템인 GBS까지 만들어놓았으니 말이죠.

GBS에 관련된 내용들은 서주영님의 블로그에서 많은 도움을 받았습니다.

GBS는 기본적으로 리눅스에서 실행됩니다. 아직 윈도우에서는 실행이 안됩니다. GBS를 이용하여 Tizen Emulator나 Tizen Device용 라이브러리(so, a) 파일을 만들어낼 수 있습니다. GBS로 빌드를 하게 되면 rpm 파일이 생성되는데 이 파일을 Emulator나 Device에 옮긴 후 설치를 하면 됩니다.

저는 Cocos2d-x에 필요한 라이브러리 소스를 http://review.tizen.org/gerrit에서 clone해 왔습니다. 그리고 GBS를 이용해서 rpm을 만들어 냈습니다. 이 rpm 파일을 압축을 풀어서 나온 헤더 파일과 라이브러리 파일을 Cocos2d-x 포팅에 사용할 수 있었습니다.

이 헤더 파일과 라이브러리 파일은 Cocos2d-x/cocos2dx/platform/third_party/tizen/rootstraps/tizen-emulator-2.0.cpp/ 아래 usr/include, usr/lib, lib에 배치하였습니다.

문제는 WebP라는 Google에서 만든 이미지 포맷이 있는데 이 것은 Tizen Gerrit에 없었습니다. 어쩔 수 없이 WebP 소스를 받아서 GBS 형식으로 패키지를 만들어 사용했습니다. WebP는 Emulator및 Device에 포함되어 있지 않으므로 static 라이브러리인 .a 파일로 Cocos2d-x에 포함하였습니다.

OpenGL 2.0 구현

Tizen에는 OSP(Open Services Platform)이라는 프레임워크가 존재합니다. 이 프레임워크는 리눅스 및 디바이스에서 지원하는 자원을 쉽게 사용할 수 있도록 구성해놓은 라이브러리입니다. 처음에는 이 OSP를 사용하지 않고 화면을 출력하려고 했으나, OpenGL에서 화면을 보여주려면 Window Surface가 필요한데 이 Window Surface를 만들려면 Osp에서 제공하는 Form이 있어야 해서, OSP를 활용하는 방향으로 다시 만들게 되었습니다. 물론 OpenGL도 OSP로 래핑이 되어 있었습니다.

이 OpenGL부를 구현하기 위해서 Cocos2d-x의 다른 플랫폼 구현을 많이 참고하였는데, 오히려 Android 구현은 큰 도움이 되지 않았고, BlackBerry와 리눅스, 윈도우 구현이 많은 도움이 되었습니다. Android 구현은 Android의 Java 레이어를 이용하여 간접적으로 구현이 되어 있어서 도움이 되지 않았습니다. OpenGL도 Java를 사용하여 제어하도록 되어 있기 때문이었습니다.

이 OpenGL의 프레임을 처리하는 Advance (혹은 mainloop)도 플랫폼마다 구현이 달랐는데, 리눅스, 윈도우, BlackBerry는 무한루프 방식이었고 Android는 Java onDrawFrame 함수에서 jni를 통하여 Cocos2d-x의 mainloop를 호출하는 방식이었습니다.

Tizen은 OSP 구조상 무한루프 방식은 사용하기가 힘들었고, OSP 기본 OpenGL 예제를 보면 Advance를 Timer로 처리하고 있었기 때문에 이 방식을 그대로 따르기로 하였습니다.

Advance 처리와 SwapBuffer 처리도 정상적으로 해주면서 대망의 HelloCpp 예제 화면을 보는데 성공하였습니다.

화면 방향 설정 구현

Android는 manifest 파일에서 화면 방향이 portrait인지 landscape인지 설정할 수 있지만 Tizen은 OSP에서 설정을 해줘야 했습니다. 따라서 화면방향을 설정하는 인터페이스도 구현을 하였습니니다.

파일 처리 구현

Cocos2d-x에는 플랫폼 별로 File Utils라는 파일 처리 함수들을 제공해주고 있는데, 처음에 이부분을 Cocos2d-x 리눅스 구현에서 가져와서 사용을 하였습니다. 그런데 디버거를 붙여서 실행을 하면 실행이 잘 되었지만, 디버거 없이 그냥 실행을 하면 크래쉬가 발생하면서 실행이 되지 않았습니다.

이 크래쉬의 원인을 찾는데 한참 걸렸는데, 처음에는 File Utils 문제인지 몰랐습니다. 소스 코드를 하나하나 지워가면서 디버깅을 하여 원인을 찾아냈습니다. 현재 실행파일의 경로를 구하려고 리눅스 방식대로 /proc/self/exe에 접근하였는데 여기서 문제가 발생했던 것입니다. 결국 OSP 레이어를 이용해서 해결했습니다. 고맙게도 현재 실행파일의 리소스 경로를 구해주는 GetAppResourcePath등의 편리한 함수를 제공해주고 있었습니다.

폰트 구현

폰트 구현도 OSP를 이용하여 구현하려고 하였으나 시간이 많이 걸릴 것 같아, 리눅스 구현을 그대로 가져와서 사용했습니다. 다행스럽게도 동작이 잘 되었고 libfreetype, libfontconfig 라이브러리가 추가적으로 필요하게 되었습니다.

사운드 구현

Cocos2d-x에는 CocosDenshion이라는 사운드 라이이브러리가 포함되어 있습니다. 각 플랫폼 별로 구현이 되어 있는데, 저는 Tizen의 OSP를 활용하여 구현하였습니다. 기본 뼈대는 CocosDenshion 윈도우 구현을 가져왔고 Player 부분은 OSP를 사용하여 직접 구현하였습니다.

물리엔진

Cocos2d-x에는 2개의 물리엔진을 지원합니다. Chipmunk와 Box2D를 지원하는데, Tizen IDE에서 chipmunk와 Box2D를 static 라이브러리로 컴파일해서 사용하였습니다. 동작에는 큰 문제가 없었습니다.

Extensions 구현

Cocos2d-x에는 GUI, network 등을 제공해주는 Extensions라는 라이브러리를 제공해줍니다. 여기서 network 부분 때문에 libcurl이 필요한데 libcurl이 libcares, libcrypto, libidn, libssl을 사용하고 있어서, 이 파일들은 Emulator에 포함된 .so 파일들을 가져와서 해결하였습니다.

이렇게 구현을 다 하고 나니 Cocos2d-x의 레퍼런스 예제인 TestCpp의 모든 부분이 정상적으로 동작이 되었습니다.

아직 구현되지 않는 부분

  1. Accelerometer : 가속도 센서 부분이 아직 구현되지 않았습니다. Tizen 레퍼런스폰을 구하려고 이리저리 노력을 해보았습니다만 아직 구하지 못하였습니다. 이 부분은 그냥 OSP를 이용하여 구현하면 되지만 Emulator로는 테스트가 불가능하기 때문에, 레퍼런스 폰을 구한 뒤에 작업을 하려고 합니다.

  2. Extensions GUI EditBox : EditBox 부분도 테스트를 제대로 못해봤습니다. Android 구현을 가져와서 집어넣긴 했는데 좀더 살펴봐야 하는 부분입니다.

  3. IME 처리 부분 : 입력기 처리 부분도 아직 구현되지 않았습니다.

마치며

앞서 설명한 부분 중에서 Tizen IDE의 문제점 부분의 해결책이 있다면, 공유해주시면 감사하겠습니다. 또한 더 필요한 작업이나 버그도 알려주시면 감사하겠습니다.

이 글을 쓰는 시점(2013년 5월 17일)에 Tizen 2.1 SDK가 발표되었습니다. Cocos2d-x Tizen 포팅을 Tizen 2.1 SDK에서 컴파일 및 실행을 해보고 대응할 예정입니다.

추가

Accelerometer, Extensions GUI EditBox, IME 처리 부분 모두 구현이 완료되었습니다.

Tizen 테스트 장치를 제공해주신 삼성전자 한덕수님께 감사의 말씀을 드립니다.


저작권 안내

이 웹사이트에 게시된 모든 글의 무단 복제 및 도용을 금지합니다.
  • 블로그, 게시판 등에 퍼가는 것을 금지합니다.
  • 비공개 포스트에 퍼가는 것을 금지합니다.
  • 글 내용, 그림을 발췌 및 요약하는 것을 금지합니다.
  • 링크 및 SNS 공유는 허용합니다.

Published

19 May 2013