posted by REDFORCE 2017. 6. 12. 13:22

이번에는 경량 패턴에 대해서 두 번째 내용을 보도록 하겠습니다.


경량패턴은 앞선 글에서 봤듯이 어떤 객체의 개수가 너무 많아서 좀 더 가볍게 만들고 싶을때 사용합니다.


인스턴스 렌더링에서는 메모리 크기보다는 렌더링할 나무 데이터를 하나씩 GPU버스로 보내는 데 걸리는 시간이 중요하지만, 기본 개념은 경량패턴과 같습니다.


이런 문제를 해결하기 위해 경량 패턴은 객체 데이터를 두 종류로 나눈다는 것이 특징입니다.


먼저 모든객체의 데이터 값이 갚아서 공유할 수 있는 데이터를 모읍니다. 이런 데이터를 GoF에서는 고유상태(intrinsic state) 라고 부르고, 필자가 참고하고 있는 game programming pattern 교재에서는 자유문맥(context-free) 상태 라고 부릅니다. 이전 글에서 다루었던 나무 형태가(geometry)나 텍스쳐가 이에 해당합니다.


그리고 나머지 데이터는 인스턴스별로 값이 다른 외부 상태(extrinsic state)에 해당합니다.

예제로 살펴봤던 Tree Class에서 나무의 위치, 크기, 색 등이 이에 해당합니다. 

이전 글의 예제코드에서 확인한 것과 같이. 경량 패턴은 한 개의 고유 상태를 다른 객체에서 공유하게 만들어 메모리 사용량을 줄 이는 방식입니다.


여기까지만 확인한 걸로는 기초적인 자원 공유 기법이지 패턴이라 부를만한 내용은 충족하지 않는 것 처럼 보입니다. TreeModel 클래스로 깔끔하게 분리가 될 수 있었기에 그렇게 보이는 측면도 있지만, 실제로 공유 객체가 명확하지 않은 경우 경량 패턴은 잘 드러나 보이지 않습니다.


해서 이번엔 위 예제에 이어서 지형 정보(타일같은...)를 이용해서 경량 패턴을 쓰임을 확인해보도록 하겠습니다.


나무를 심을 땅도 게임에서 표현을 해야하는데, 보통 이런 땅들은 흙, 언덕, 호수, 강 같은 다양한 지형을 이어 붙여서 만들게 됩니다. 여기에서 이 땅들을 보통 타일 기반으로 만들게 될텐데요.

이 타일들은 게임플레이에 영향을 주는 여러 속성들이 들어있을 수 있습니다.

  • 플레이어가 얼마나 빠르게 이동할 수 있는지를 결정하는 이동 비용 값
  • 강이나 바다처럼 보트로 건널 수 있는 곳인지 여부
  • 렌더링할 때 사용할 텍스쳐


이런 속성을 지형 타일마다 따로 저장하는 일은 있을 수 없습니다. 이런 지형 종류에 대해서는 아래와 같이 열거형을 사용하는게 일반적이죠.



그리고 이런 지형을 거대한 격자형태인 2차원 배열로 관리합니다.


다음 타일 관련 데이터는 다음과 같이 얻을 수 있습니다.




그러나 위 코드들은 동작은 가능하지만 모든 경우의 수에 대해서 하드코딩을 해야하며

각 지형종류에 대한 데이터가 여러메서드로 나뉘어져 있습니다.


이런 경우에는 하나로 합쳐서 캡슐화를 시키는 게 좋습니다.


해서 아래와 같이 지형 클래스를 따로 만드는 방법을 추천합니다.



하지만 타일마다 매번 Terrain 인스턴스를 생성하는 것은 결과적으로 똑같이 많은 비용을 발생시키게 됩니다. 따라서, Terrain 클래스에는 타일위치와 관련된 내용은 전혀 없는 것을 볼 수 있습니다. 즉. 경량패턴식으로 이야기하자면 모든 지형 상태는 '고유'하다(context) 자유 문맥에 해당한다는 것을 알 수 있습니다.


나머지 내용은 3번째 글에서 이어적도록 하겠습니다...