2010년 11월 2일 화요일

존 카맥이 iPhone용 RAGE를 말하다

지난 8월 12일 존 카맥은 QuakeCon 2010의 기조 연설에서 iOS용 RAGE를 발표하여 많은 사람들을 놀라게 했습니다. 그리고 발매일을 약 한 달 앞둔 시점에서 카맥은 베데스다 블로그를 통해서 iOS용 RAGE의 개발 비화와 기술적인 사항을 정리한 포스팅을 남겼습니다. RAGE에 대한 언급은 물론, 그래픽스와 사운드, 리소스 관리 등 게임의 전반적인 기술적 사항에 대해서 언급하고 있으므로 RAGE 게임에 관심이 있는 분은 물론 모바일 게임 개발에 관심 있는 분들도 한번 쯤 보시는 게 좋겠습니다. 회사에서 눈치 보면서 대충대충 의역한거라 내용이 부정확할 수 있습니다. 만약 시간 남으시는 분들은 원문과 대조해서 오역 발견하시면 알려 주시면 감사하겠습니다. 원문은 여기에서 볼 수 있습니다. 그리고 몇 가지 부분에서 번역에 조언해 주신 lifthrasiir님께 감사드립니다.

iPhone 용 RAGE

작년에 id에서의 모바일 게임 개발 작업에는 우여곡절이 있었습니다. 계획은 언제나 다음에 RAGE 같은 것을 iPhone/iPad/iPod 터치용으로 만드는 것이었지만 id에서 진행중인 큰 프로젝트의 뒤에 가려져서 모바일 게임 개발은 그다지 우선순위가 높지 않았습니다. 물밑에서 진행중인 작업이 있긴 했지만, 7월 말이 되어서야 프로젝트를 본격적으로 이끌어 나갈 코어 엔진 코드에 손을 댈 수 있었습니다.

저는 일이 잘 풀리자 흥분했습니다. 그리고 그 때는 QuakeCon이 막 시작할 무렵이었죠. 그래서 저는 전통을 깨고 제 기조 연설에서 기술 데모를 시연했습니다. 나중에 생각해 보면 저는 그 때 소개를 나쁘게 했던 것 같습니다. 아마 제가 이렇게 말했던 것 같군요. "이건 RAGE구요, iPhone 용이구요, 60 fps로 돌아가요." 그래서 몇몇 사람들은 PC/콘솔판 RAGE 게임 전체를 iPhone에서 플레이할 수 있다는 의미로 해석한 것 같습니다. 하지만 그런 건 절대로 아닙니다.

제가 시연했던 것은 처음부터 새로 작성된 기술 데모였습니다. 하지만 RAGE의 컨텐츠 제작 파이프라인과 데이터를 활용해서 만들어졌죠. 우리는 iOS에 RAGE 본편 전체를 옮기지 않았습니다, 아니 엄두조차 내지 않고 있습니다. 만약 (놀랍게도!) PC/콘솔 버젼의 RAGE 게임을 약간의 노력만으로도 iPhone 4에다가 컴파일할 수 있게 된다고 하더라도 그것은 절망적으로 나쁜 아이디어일 것입니다. 가장 최근에 나온 최고의 모바일 장비조차도 Xbox 360과 PS3 성능의 극히 일부밖에 되지 않습니다. 그러므로 이 플랫폼에 성능의 트레이드오프를 만드는 것 자체부터 적절하지가 않습니다. 조작의 차이야 말할 것도 없고요.

우리가 만들고 있는 것은 iOS 플랫폼에서 이전에 본 적이 없는 것입니다. 눈부시게 아름다우며 무척 재미있습니다. 지난 QuakeCon 이후로 개발 작업은 격렬히 진행 중이고 11월이 끝나기 전까지는 앱을 출시할 수 있기를 바랍니다.

이 게임의 제작에 메가텍스쳐 컨텐츠 제작 파이프라인을 사용하게 된 것은 이 게임의 범위 때문입니다. 이 게임에 들어가는 데이터는 큽니다. 그것도 아주 크죠. 하지만 700메가가 넘는 iPhone 용 Myst1를 보면서 사람들이 아무리 커다란 앱이라도 다운받을 것이라는 자신감을 가지게 되었습니다. 그리고 그 용량이 RAGE의 SD 버젼의 용량이 되었고 iPad / iPhone 4용 HD 버젼은 그 용량의 2배 가까이 될 것입니다. 이건 앱이라기보단 차라리 영화를 내려받는 것과 비슷할 겁니다. 그러니 오랜 다운로드에 대비해 두세요. 다른 관점에서 보면 RAGE 게임 본편은 JPEG-XR로 압축된 20 기가의 데이터로 채워져 있으니 무압축 0.7 기가의 데이터는 분명 거기서 아주 작은 일부일 뿐이겠지요.

그렇게 광활한 레벨을 게임에 넣지 않을 계획이었기 때문에 게임이 얼마나 좋게 보이든간에 가격을 높이 책정하면 많은 사람들이 실망할 것이라는 것을 알고 있었습니다. iPhone 타이틀의 가격대를 너무 낮은 가격은 피하되 다양하게 책정하면서 실험해 보았습니다. 그리고 우리는 RAGE의 SD 버전은 $0.99, HD 버전은 $1.99로 책정하는 것이 적당하다는 결론을 내렸습니다. 우리는 이 프로젝트를 최대한 우리의 통제하에 놓을 수 있도록 집중해야 했습니다. 하지만 사람들은 이 가격에 만족할 거라고 생각합니다.

우리는 RAGE 게임의 일부분 중에서 "Mutant Bash TV"를 가지고 iPhone 게임을 만들기로 결정하였습니다. Mutant Bash TV는 RAGE의 황무지 세계관에 있는 포스트-아포칼립틱 전투 게임 TV 쇼인데, 이것은 적을 조준하고, 쏘고, 재장전을 하고, 적의 공격을 피하고, 지난 번보다 더 나은 점수를 얻으면서 레벨의 끝까지 가는 등 진정한 일인칭 슈팅 게임으로서는 최적의 설정이지요. 기본적인 서바이벌 외에도 주울 수 있는 아이템이나 헤드 샷, 힛 스트릭 배수2 등 게임성에 깊이를 더하는 부분도 있으며 그냥 쏘기만 하면 끝나는 것부터 거의 불가능에 가까운 것까지 광범위한 스킬 레벨도 있습니다.

이 프로젝트의 최대 목표는 여러번 다시 플레이할 수 있는 게임을 만드는 것입니다. 이런 게임플레이의 핵심은 스토리 진행이나 캐릭터의 발전이나 기타 등등이 아닌 보상의 측면에 있습니다. 예를 들어서 둠 레저렉션에서 게임의 많은 요소가 처음 플레이할 때는 좋았지만 나중에는 리플레이 가치를 떨어트렸죠. RAGE iOS판은 언제나 액션 뿐입니다. 저는 수십 번 이 게임을 플레이해 보았고, 테스트하는 작업은 여전히 일이라기보다는 즐거움입니다.

기술적 상세

id Tech 5 엔진은 기본적으로 게임상의 모든 것에 균일하게 페이징된(uniform paged) 가상 텍스쳐 시스템을 사용합니다. 알고리즘 자체는 3GS나 그 이후 장치들에서 구현할 수 있지만 프래그먼트당 처리 코스트가 상당한 데다가 PVRTC3 형식의 텍스쳐에다가 개별 페이지를 업데이트하는 것은 불가능합니다. 그래서 모바일용 RAGE에서 사용한 방법은 월드 전반에 가변적인 사이즈를 가지는 인접한 "텍스쳐 섬"들을 만들어서 텍스쳐 스트리밍을 적용하는 것이었습니다. 이 방법은 훨씬 빠르지만 큰 표면이 있으면 강제로 분할(geometric subdivision)해야 하며 피드백에 의한 반응이 아닌 철저히 예측적인 방식으로 스트리밍을 해야 합니다. 캐릭터, 아이템, UI는 전통적인 방식으로 텍스쳐링됩니다.

우리는 PC에서 레벨을 만들어서 RAGE에서 돌려보았습니다. 그리고 프로파일링 / 추출 도구를 사용하여 iOS용 맵 데이터를 생성했습니다. 이 도구는 지도 상의 경로를 찾아 다니면서 어느 텍스쳐 섬이 언제, 무슨 해상도와 무슨 방향으로 보일 지를 결정합니다. 텍스쳐 섬의 픽셀 정보는 원래 RAGE의 큰 페이지 파일에서 추출되어 필요한 만큼 여러 해상도로 이방성 필터링4이 적용된 후 장치에 맞는 여러 개의 1024x1024 PVRTC 포맷으로 압축되어 들어가게 됩니다.

텍스쳐 형태로 압축하는 것은 텍스쳐 데이터를 전부 구겨 넣어서 앱 용량을 최소함과 동시에 한 뷰를 수백 개의 텍스쳐 섬으로 쪼개고 싶지는 않다는 서로 상충하는 목표가 있습니다. 다른 NP-완전5한 문제들과 마찬가지로 그리디6한 측정 방식의 최적화 배치 전략을 사용했습니다.

1 기가바이트가 넘는 미디어를 관리하는 데에 플래시 메모리 IO와 프로세스 메모리 관리는 매우 중요하며, 이것들을 연구하기 위해서 상당히 많은 성능 측정 작업을 거쳤습니다.

결정적으로 모든 데이터는 정적이며 쉽게 버릴 수 있습니다. iOS는 스왑 파일7이 없기 때문에 만약 당신이 너무 많은 동적 메모리를 사용하면 OS는 한두번 경고하다가 이내 프로세스를 죽여 버립니다. iOS 개발자들의 골칫거리가 그 "너무 많은" 메모리가 정확히 얼마인지 정의되어 있지 않다는 건데, 사실 이것은 다른 앱들이 (사파리, 메일, iPod 등등) 메모리에 얼마나 상주해 있느냐에 따라서 달라지는 문제입니다. 만약 당신이 모든 게임 데이터를 메모리에 상주시킨다면 OS는 아무 것도 할 수 없습니다. 그리고 당신은 위험에 빠지게 되는 것이죠. 하지만 만약 당신의 데이터가 읽기 전용의 메모리 맵 파일에 들어있다면 OS는 필요할 시 그것들을 해제할 수 있습니다. 이렇게 하면 만약 다음 (메모리 영역)이 필요할 시 게임이 뚝뚝 끊기는 문제가 있겠지만 최소한 갑자기 프로그램이 종료되는 문제는 없습니다. 다만 메모리 부족 경고는 여전히 프레임레이트를 몇 초 동안 지옥에 보내버리는데, 심지어 그 시점에서 게임 자체에서 하는 일이 별로 없다고 하더라도 백그라운드의 다른 모든 앱에서 메모리를 버리기 때문입니다.

흥미있게도 32비트 운영체제임에도 불구하고 단지 700 메가바이트의 가상 메모리 공간에 매핑을 할 수 있습니다. 3 기가 정도는 안 되더라도 저는 최소한 그 두 배는 기대했거든요.

페이지 폴트8 시 메모리 맵 파일에서 32kb의 데이터를 가져오는데 iPhone 4에서는 1.8 ms, iPod touch 2세대에서는 2.2 ms가 소요됩니다. 만약 파일의 맨 처음에서 폴트가 일어나면 32kb가 아닌 128kb를 가져 오는데, 파일의 처음에는 헤더가 있다고 가정한 일종의 최적화로 보입니다.

Apple의 운영체제에서 기존 UNIX 플래그가 제대로 동작하는지 항상 불안했기 때문에 iOS서 fcntl(fd, F_NOCACHE) 함수가 기대했던 대로 정확히 동작한 것이 다행이라고 말씀드리고 싶습니다. 이걸 사용하면 파일 캐싱을 건너뛰면서 페이지로 정렬된 타겟 메모리의 페이지 폴트 대역폭이 30mb/s (구형 아이팟 터치는 22mb/s)로 매우 빠른 성능을 보여 줍니다. 그리고 일반적인 읽기와는 달리 메모리의 복사가 전혀 일어나지 않기 때문에 부분적으로 더 빨라질 수 있습니다. 하지만 가장 중요한 점은 캐싱을 끔으로서 더 중요한 국소성9을 지니는 다른 버퍼 데이터를 침범하지 않는다는 점입니다. 월드 상의 모든 메가텍스쳐 데이터는 제가 언제 먼저 미리 읽어 놓을지를 알고 있기 때문에 캐싱되지 않은 방식으로 읽혀집니다. 그리고 데이터를 버려야 할 시점도 명확합니다. 만약 주어진 영역을 지나가면 그 영역의 텍스쳐 데이터는 앞으로 다시는 필요하지 않을 것입니다. 반면 적들의 애니메이션과 사운드 데이터 같은 데이터는 나중에 다시 나타날 수도 있습니다.

저는 텍스쳐 읽는 작업이 끝난 뒤에 캐싱되지 않은 읽기 스레드에서 관계된 월드의 지오메트리 정보를 미리 읽도록 해 보았습니다. 하지만 생각해 보면 지오메트리 정보를 텍스쳐에 같이 끼워넣고 캐싱되지 않은 읽기를 했어야 했습니다.

OpenAL10은 1024개까지 사운드 버퍼를 만들 수 있는 제약이 있는 것 같습니다. 우리는 큰 문제를 일으키지 않고 정적 버퍼 매핑을 동적으로 생성하고 삭제하고 싶었습니다. 그래도 1024개는 항상 그 아래로 유지할 수 있는 합리적인 갯수입니다.

OpenAL에서 (디스어셈블을 통해) 발견하고 놀란 동작 중 하나는 Play() 명령을 실행하면 버퍼의 4킬로바이트를 항상 건드린다는 것입니다. 말이 되는 동작인데, 사운드 믹싱을 깨트리지 않으려면 일단 버퍼를 램에다가 강제로 페이징해서 올려야 하기 때문입니다. 하지만 호출시 스레드가 예측할 수 없이 잠깐씩 멈추더군요. 그게 적당한 크기의 믹스 어헤드 버퍼를 가진 믹싱 스레드에서 발생한 페이지 폴트로 말미암은 것이었으면 하고 바랐습니다만, 아마도 실제로는 GPU가 이미 모든 버퍼 대역폭을 차지해 버려서 십여 개의 사운드 버퍼가 폴트를 내 버리는 극단적인 상황이라 생각합니다. 그래서 모든 OpenAL 명령을 별개의 스레드에서 처리하도록 만들까 생각중입니다. 그렇게 하면 만약 채워야 할 페이지가 있을 경우 프레임레이트가 불안정해지는 대신에 사운드에 약간의 지연이 생기겠지요.

플래시 메모리 읽기 대기열에 우선순위를 부여할 수 있었다면 좋겠다는 생각을 했습니다. 게임 스레드에서 CPU 폴트에 가장 높은 우선순위를, 사운드 샘플 읽기는 중간, 텍스쳐 읽기는 가장 낮게. 큰 텍스쳐를 여러 개의 덩어리로 나누는 것이 CPU가 멈추는 최악의 케이스를 방지할 수 있다는 것을 발견했습니다.

이 프로젝트에서 고심을 거듭하여 결정한 두 가지 기술적인 점이 있습니다.

기본적인 렌더링 기술은 모두 고정 파이프라인 기능만을 가지고 표현할 수 있는 것을 알고 있었기에 게임을 OpenGL ES 1.1을 사용하여 만들었습니다. 덕분에 낡은 MBX11 GPU 플랫폼에서도 구동이 가능합니다. 구형 플랫폼을 지원하는 것이 좋긴 하나 그것들은 이제 시장에서 무시해도 좋을 정도라는 증거는 충분합니다. 그리고 저는 이 결정을 위해 몇 가지 기능 구현과 최적화를 할 기회를 포기해야 했습니다.

구닥다리 고정 기능을 가지고 삽질하는 것은 재미있었습니다. 예를 들어 싱글 패스로 DOT3 법선 매핑(normal mapping) 위에 단색 동적 광원(dynamic lighting) 효과를 얻기 위해서 조명 수치를 텍스쳐의 환경 색(environment color)의 알파 채널에 붙이는 방법을 사용했습니다. 이렇게 하면 색이 GL_SRC_ALPHA, GL_ZERO 블렌딩 모드를 거쳐서 혼합되어 불투명한 캐릭터에 영향을 주게 됩니다. 이런 식의 고정 파이프라인 트릭을 쓰다 보면 여전히 흐뭇한 기분이 들지만 사실 이런 건 요즘같은 픽셀 쉐이더의 시대에 필요한 스킬은 아니지요.

다른 큰 문제는 코드베이스의 혈통입니다.

제가 개인적으로 작성한 iPhone의 코드에는 울펜슈타인 RPG의 렌더러, 울펜슈타인 클래식과 둠 클래식의 모든 iPhone용 코드, 그리고 몇 가지 테스트 어플리케이션의 코드가 포함되어 있습니다. 그 시점에서 저는 플랫폼에서 '해야 할 옳은 것들'이 뭔지는 잘 알고 있었지만 어떻게 하면 하나의 온전한 게임에 적용시킬 수 있을 지에 대한 원숙한 표현법은 잘 몰랐습니다. 둠 클래식에는 괜찮은 코드가 있었지만 모두 C 언어로 작성된 것들이었고 저는 새로운 게임은 (절제된) C++ 언어로 개발하는 것을 선호할 것입니다.

우리가 선택할 수 있었던 것은 Escalation Studios에서 개발한 (저에게 그닥 접점은 없었던) 둠 레저렉션이었습니다. 게임의 플레이 스타일도 어느 정도 비슷했기 때문에 (RAGE에서 돌아볼 거리가 많긴 하지만요) 이걸 사용하는 것은 합리적인 선택인 것 같았습니다. 이것은 "코드를 절대로 버리지 말라"는 신조와도 일치하는 것이기도 합니다. 저는 제가 성공을 거듭하는 동안 코드를 싸그리 뭉쳐서 갖다 버린 적이 많은지라 저 글의 여러 가지 부분에서 동의하지 않습니다만 저 글에는 여전히 지혜가 녹아들어 있습니다.

만약 처음부터 새로(from scratch) 만든다고 했을때 코드베이스가 어떻게 될 것인가에 대해서는 긍정적이었습니다. 100k 미만의 가변적인 CPU 데이터를 가질 것이며 게임의 리소스와 관련된 어떤 문자열 데이터도 보이지 않을 것이며12 새로운 플랫폼에서는 60 fps, 구형 플랫폼에서는 30 fps로 돌아갈 것이라고 생각했습니다. 그리고 저는 이걸 대략 4개월 내에 할 수 있다고 확신했습니다. (하지만 그건 아마 오산이었겠죠) 하지만 불행히도 아이폰 프로젝트에 4개월을 할애할 수 없는 상황이어서 2개월으로 밀어붙이게 되었습니다. (지금은 거의 완성된 상태이며 다시 돌아갈 연구 주제를 찾고 있습니다.)

그래서 우리는 개발 편의와 코드 효율성을 타협하는 조건으로 레저렉션의 코드베이스 위에서 만들기 시작했습니다. 이것은 저에게는 흥미로운 경험이었는데, 원래 제가 다루는 모든 코드는 저의 "코딩 DNA"가 있는 것이어야 했기 때문입니다. 왜냐 하면 id 소프트웨어의 코딩 표준은 기본적으로 "존 카맥이 하는 식으로 코딩하라"이기 때문이거든요. 반면 Escalation의 프로그래머들은 완전히 다른 배경을 가지고 있었기에 원래의 코드베이스는 "여기에는 STL13이 있고 저기에는 boost14가 있고 프로퍼티 리스트15를 채우고 이벤트를 디스패치하고 저걸 위임(delegate)하라" 같은 식이었죠.

저는 다른 큰 게임들의 코드베이스가 그에 고통받고 있음에도 불구하고 우리의 거대한 코드베이스에서 다양한 "현대적" C++ 디자인 패턴을 활용함으로서 이득을 볼 수 있을 거라는 생각을 하고 있었습니다. 하지만 저는 이 생각을 철회했습니다.

저는 여기에 대해서 (주로 트위터에) 자주 불평하고 있으며 가끔 다른 모바일 개발자들에게 다양한 실례들을 지적하고는 합니다. 지금까지 이 방법은 통하고 있으며 아마 결국 이것은 옳은 결정이었을 겁니다.

존 카맥

10-26-2010

잡담

  • 설마 했는데 정말 OpenGL ES 1.1만으로 게임을 만들었군요. 요즘 스마트폰이나 모바일 장치는 기본이 OpenGL ES 2.0이라 그런지 구형 스펙을 가지고 이 정도 퀄리티의 게임을 만들어 냈다는 것이 믿기지가 않습니다. 생각해보면 텍스쳐 스트리밍 자체가 고정 파이프라인만 가지고도 구현할 수 있는 것이긴 하지만 모바일에서도 프로그래머블 파이프라인으로 쉐이더 써서 게임 만드는 시대에 고정 파이프라인으로 이 정도 게임을 만들었다는 것이 놀랍습니다.
  • 최근에 존 카맥이 트위터로 공개한 사실이지만 안드로이드용 RAGE도 준비중이라고 합니다. 포스팅의 내용에 따르면 iOS용은 PVRTC를 사용했다는 거 같은데 이것은 아이폰의 하드웨어가 PowerVR GPU 위에서만 돌아가고 있기 때문에 가능한 것인 반면 하드웨어에 중립적인 안드로이드 장치에서 PowerVR 전용 확장을 쓰긴 어렵겠죠. Qualcomm의 Adreno, ARM의 Mali, NVIDIA의 Tegra 등 다른 GPU를 쓰는 안드로이드 장치도 많을 텐데 안드로이드 포트에서는 이 문제를 어떻게 해결할 지 사뭇 궁금해집니다. iOS용은 PVRTC 텍스쳐 스트림을 그대로 데이터에 때려박았다는 듯한 뉘앙스인데, 안드로이드 포트는 아예 렌더링 패스를 다르게 구현하려나?
  • 저 바닥에서 짬밥 좀 많이 먹은 프로그래머라면 대체적으로 그렇지만 이 양반도 디자인 패턴이나 개발 방법론에 대해서는 보수적인 면이 있는 것 같습니다. 하긴 뭐 예전부터 그랬으니 별로 새로울 건 없군요. GPL로 공개한 소스를 까 보면 구조 자체는 별다른 언어적 기교 없이 무척 심플하게 되어 있었죠. 여담이지만 롤러코스터 타이쿤 시리즈의 제작자 크리스 소여는 Z80 시절부터 어셈블리로 프로그래밍을 한 영향인지 롤러코스터 타이쿤 2까지 코드 대부분을 x86 어셈블리로 짰다는 전설은 유명하죠.

각주

  1. Myst: 1993년 Mac OS로 나온 그래픽 어드벤쳐 게임입니다. 나중에 iPhone으로 포팅이 되었는데 용량이 720MB에 달했습니다. 다른 평균적인 iPhone 어플리케이션에 비해서 굉장히 큰 편이죠.
  2. FPS 게임에서 죽지 않고 적을 연속으로 계속 죽이면 보너스가 주어지는 게임플레이 요소.
  3. PVRTC: iPod/iPod touch/iPad에서 사용하는 PowerVR 그래픽스 프로세서에서 사용되는 블럭 단위의 텍스쳐 압축 알고리즘입니다. S3TC나 DXTC와는 다르게 저주파 이미지 두개를 Bilinear Interpolation으로 업스케일해서 변조하는 식으로 구현합니다. 알고리즘 상세는 여기서 확인하실 수 있습니다: http://web.onetel.net.uk/~simonnihal/assorted3d/fenney03texcomp.pdf
  4. 이방성 필터링(Anisotropic filtering): 텍스쳐를 여러 장 다운샘플링하여 보이는 각도에 따라 다른 해상도의 텍스쳐를 부분적으로 적용하는 테크닉입니다. 밉 맵(MIP Map)과 비슷하지만 밉 맵은 렌더링 속도를 향상시키기 위한 테크닉이고, 이방성 필터링은 비스듬한 물체의 표면에서 렌더링 퀄리티를 향상시키기 위한 목적입니다. 밉 맵은 등방성(isotropic)인 반면 이방성 필터링은 가로 세로 다른 비율로 이미지를 다운샘플링합니다.
  5. NP-완전: http://en.wikipedia.org/wiki/NP-complete
  6. 탐욕(그리디) 알고리즘: 순간순간마다 최적이라고 생각되는 것을 골라 나가는 알고리즘입니다.
  7. 스왑 파일: 페이징 개념에서 말하는 가상 메모리 파일.
  8. 페이지 폴트: 가상 메모리에 저장되어 있지만 물리적인 기억 장치에 올라오지 않은 메모리 영역이 있을 경우 이를 물리적 메모리에 올리기 위해서 소프트웨어에서 발생시키는 트랩(trap).
  9. 일시적 참조의 국소성(Temporal locality of reference): 메모리 영역에서 순간적으로 접근이 많이 이루어지는 부분을 말합니다. 이를테면 캐싱으로 인해서 빈번하게 접근되는 메모리 영역이 엉킬 수가 있겠죠.
  10. OpenAL: Creative Technology에서 개발한 다채널 오디오 API입니다. 이름에서 알 수 있듯이 OpenGL의 construct를 상당 부분 모방하고 있으며, iPhone 개발 환경에서 오디오 API의 일환으로 제공하고 있습니다.
  11. PowerVR MBX: 구형 iPhone(1세대, 3G)와 iPod touch(1세대, 2세대)의 AP에 탑재되어 있는 GPU입니다. OpenGL ES 1.1 스펙에 대응하고 있습니다.
  12. 아마 리소스 문자열을 코드베이스 내에 하드코딩하는 것을 의미하는 것 같습니다.
  13. STL: C++의 표준 템플릿 라이브러리입니다. container, iterator, functor, algorithm 등 다양한 템플릿 기반의 편의 기능을 제공합니다.
  14. Boost: C++의 연장선상에 있는 라이브러리의 집합입니다. 이 라이브러리의 몇 가지 기능들은 차기 C++0x 표준의 일부로 편입되기도 했습니다.
  15. 프로퍼티 리스트(plist): NeXTSTEP과 여기서 파생된 애플의 API에서 제공하는 직렬화(serializable) 가능한 데이터를 저장하기 위한 파일과 이에 접근하기 위한 API를 말합니다.

2 개의 댓글:

  1. 좋은 글을 읽을 수 있도록 해 주셔서 감사합니다.

    답글삭제
  2. 잘 읽었습니다. 감사합니다.

    답글삭제