scaleform.minarto.com

이미지(아이템) 로드에 관한 고찰... 그리고 최적화 본문

Scaleform

이미지(아이템) 로드에 관한 고찰... 그리고 최적화

미나토 2011. 9. 28. 14:25


MMORPG 가 아니더라도 게임을 만들면 대개의 게임의 경우 수많은 아이템이 필요하게 됩니다. 아니, 아이템이 아니더라도 수많은 이미지를 불러와 사용해야 합니다.

클라이언트의 메모리 상에 늘 그 이미지들을 가지고 있으려면, 수기가의 메모리가 그 이미지 라이브러리만으로 모두 채워질 것이기 때문입니다.


그렇기에 런타임 상에서의 이미지의 로드 관리는 중요한 요소입니다.

코드상으로 로드는 사실 어려울 것이 없습니다. 오히려 어려운 것은 그 로드된 이미지를 잘 활용하고 잘 없애는 것이 중요합니다.
그 잘 활용하는 방법과 잘 없애는 방법에 대해 써보겠습니다.


프로그램상으로 이미지를 잘 활용한다는 것은 cpu / ram 의 역할을 최소화 시키면서 디자이너가 의도한 대로의 퀄리티를 최대한 높여주는 작업일 겁니다.


as2에서 지원하는 이미지 포맷은 jpg, png 두가지입니다. 대부분 png를 사용합니다.
jpg 는 손실압축포맷이기에 이미지 퀄리티가 떨어져 디자이너가 의도한 모습을 보여주기 힘들기 때문입니다. 그리고 일반적인 툴에서 알파를 표현하지 못합니다.
scaleform 에서의 jpg의 더 큰 문제는 압축이 풀려버리면서 메모리를 원래 크기의 4배 가까이 차지하게 된다는 점입니다.



그리고 추가적으로 scaleform 에서는 dds 포맷을 지원합니다.
다음의 링크를 보면 gfx export 시 dds 포맷으로의 설정에 따른 메모리 사용 차이를 알 수 있습니다.
http://blog.naver.com/khagaa/30112116771
추측컨데 dds 포맷은 압축 해제의 과정을 거치지 않으니 속도 또한 빨라질 것으로 생각합니다. 다만 그에 따른 화질의 열화는 생각해야 합니다.

단, dds 포맷은 플래시 개발시에 활용되는 것이 아니고 gfxexport 시에 적용되는 것입니다. 이는 클라이언트와 따로 테스트를 해봐야 한다는 것이죠... 작업은 똑같이 png로 한다는 뜻입니다.


자 어쨌든 포맷은 이렇게 png를 써야 하는데 그럼 그냥 로드하면 되느냐입니다.
그렇지가 않아서 쓰는 글이지요... as2에서는 불러온 이미지의 smoothing 체크를 해주지 못합니다. 이는 이미지 확대/축소시에 깨지는 현상을 만들게 됩니다.
(레퍼에는 MovieClip.forceSmoothing 이라는 속성으로 체크를 해줄 수 있다고 나와있으나 scaleform 에서 지원하지를 않습니다)


하나의 이미지를 불러와 다양한 크기로 재활용을 해야하기 때문에, smoothing 은 필수입니다. 결국 엄청난 노가다를 해야하는데 바로 모든 로드해야할 이미지를 플래시파일로 만들어버리는 겁니다. 플래시 라이브러리 상에서는 smoothing 처리를 할 수 있기 때문이죠...

좋은 해결책이라고는 할 수 없으나 ( Bitmap class 를 지원하는 as3에서는 해결방법이 있습니다) as2에서는 어쨌든 이렇게 해결해야합니다.

그런데 이걸 반대로 생각해보면, 크기를 변화시키지 않아도 되는 이미지는 플래시로 감싸지 말고 그냥 불러들이는게 더 최적화될 수 있다입니다... smoothing 라는 것도 cpu가 해야할 일이란 걸 생각해야합니다. (스케일폼에서는 gpu가 해줄지도...)



자 런타임 상에서의 로드와 활용을 해냈다면 그 다음에는 삭제입니다.

c처럼 메모리 포인터를 직접 찾아 지울 수 있지 않으니 as와 같은 참조형 언어에서는 모든 참조를 없애야 gc(가비지 콜렉션)의 대상이 되어 메모리에서 삭제가 됩니다.
class/함수, 라이브러리는 메모리에 올라간 채로 삭제되지 않습니다.

삭제해야할 건 라이브러리와 class를 통해 생성된 객체들입니다. 그 객체가 무언가를 참조하는 순간 gc의 대상에서 벗어납니다..

as에서 참조는 다음과 같습니다.

1. 리스너가 걸려있을 시... 핸들러가 참조
2. stage에 디스플레이 객체가 얹혀져 있을시 (디스플레이 객체가 stage 를 참조 - as2에서는 그 속성이 없으나 as3에서는 stage란 속성이 있어서 참조를 쉽게 판단할 수 있습니다)
3. = 로 다른 객체와 연결되어 있을 시... 같은 메모리를 참조하고 있으므로 역시 참조

1번의 경우는 리스너를 제거해주는 올바른(어찌보면 당연한) 코드 작성을 해야합니다.
2번의 경우는 stage 상에서 오브젝트를 삭제해주면 참조가 해제됩니다
3. a=b b=c 뭐 이렇게 복잡하게 얽혀있을 때가 문제입니다. 뭐 이런건 잘 해야죠... 지금 참조에 대한 설명이 아니니...

문제는 1, 2, 3이 섞여있을 때인데... 각각을 차근차근 해제하는 게 가장 진리입니다


그리고 unLoadMovie 해주면 끝~

저렇게 했는데도 메모리에서 삭제가 안된다... 그러면 다른 수 없습니다... 다시 1번부터 체크해야죠...



빠른 반응을 위해 현재 저희 UI는 모두 불러놓고, visible 만으로(랜더링 유무)만으로 사용자에게 나타나게 합니다... 이는 유저의 반응성과 cpu의 최적화가 될 뿐, 메모리적인 측면에서는 최적화와 반대되는 길을 걷고 있는 셈입니다. 메모리 상에 사용하지도 않는 UI가 늘 존재해야하기 때문이죠...



어찌 보면 리포팅 툴등을 만들어 사용자의 행동양식을 분석해야 합니다.

마을에서는 스토리지 창을 쓰니 마을에 들어가면 로드, 경매장에 가면 경매장 로드...
길드는 몇렙 이상 부터니 몇렙 이상 유저만 UI 로드...

유저의 위치나, 레벨, 그 이외의 여러 정보들에 따라 이런식으로 좀 더 최적화할 여지가 있다는 얘기입니다...