본문 바로가기

프로그래밍/디자인패턴

[디자인패턴] 경량 패턴(Flyweight Patterns)-타일 맵

경량 패턴(Flyweight Patterns)란

공유를 통해 많은 수의 소립 객체들을 효과적으로 지원합니다 (GoF의 디자인 패턴)

 

화려한 3D 그래픽의 판타지 게임이 있다고 해보자 필드에는 수천 개의 나무가 있을 때 이 많은 나무들을 어떻게 최적화할 수 있을까? GPU로 보내는 데이터 양을 최소화하기 위해서는 공유 데이터인 3D 모델링을 딱 한 번만 보낼 수 있어 야한다. 그런 후에 나무마다 값이 다른 위치, 색, 크기를 전달한다. 요즘 나오는 그래픽카드나 그래픽 API에서는 이런 기능을 제공한다. DirectX와 OpenGL에서 제공하는 인스텐스 렌더링이 바로 그 기능이다.

 

프로젝트 정보(Project Informaion)

사진 및 프로젝트 설명

처음 프로젝트를 실행하면 나오는 화면이다. 기본적인 움직임 외에는 아무것도 작동하지 않는 간단한 클라이언트 환경이다.

방향키를 이용하면 월드를 움직일 수 있고 화면 밖과 중앙에 있는 물 부분에서는 이동을 할 수 가없다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
class Terrain{
private:
    int                       movementCost_;
    bool                    isWater_;
    Texture*               texture_;
public:
    Terrain(int movementCost, bool isWater, Texture& texture) :
        movementCost_(movementCost), isWater_(isWater), texture_(&texture) {}
 
    int                        GetMovementCost()const;
    bool                     IsWater()const;
    const Texture&        GetTexture()const;
};
 
 
 

프로젝트에 있는 지형정보를 가지고 있는 클래스이다. 이렇게 지형에 관련된 데이터는 하나로 합치는 캡슐화를 진행하는 것이 좋다. 여기서는 지형의 위치 관련 변수나 함수가 보이지 않는데 Terrain 인스턴스(객체)를 하나씩 만드는 작업을 피하기 위해서이며 경량 패턴식으로 얘기하면 모든 지형 상태는 고유하다라고 말할 수 있다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class World{
private:
    Terrain*             tiles_[WIDTH][HEIGHT];
    Terrain                groundTerrain_;
    Terrain                waterTerrain_;
    Terrain                ironTerrain_;
public:
    World() :
        groundTerrain_(1false, g_groundTexture), waterTerrain_(1true, g_waterTexture),
        ironTerrain_(1false, g_ironTexture) {}
 
    void                 GenerateTerrain();
    const Terrain&       GetTile(int x,int y)const;
 
};
 
 

지형 정보를 가지고 있는 World 클래스이다. 각 지형 메모리를 가지는 변수를 선언하여 tiles_가 해당 지형정보 데이터를 사용할 수 있게 한다.

지형 정보는 tiles_라는 2차원 포인터 배열을 통해 관리를 하게 되며 이때 텍스처 정보를 인스턴스(객체) 하나하나가 따로 가지는 게 아닌 같은 메모리를 사용함으로 써 데이터를 줄이는 게 경량 패턴의 핵심이다. 여기서는 2차원 단순의 텍스처라서 성능의 큰 차이는 보기 힘들겠지만 3D 모델링 데이터에 숲을 채운다고 할 때에는 많은 성능 차이가 나올 것이다. 

 

 

후기

디자인 패턴 프로젝트로는 3번째이며 패턴으로는 2번째인 경량 패턴을 진행하였다. 이 패턴의 핵심은 위에 말한 거와 같이 같은 지형정보를 공유함으로 써 GPU로 넘어가는 정보를 최소화하자는 게 핵심이다. 이 책에서도 말하지만 성능에

깐깐한 사람들은 포인터가 열거형보다 느리다고 말하는 등  여러 트집 요소가 있기도 해서 완전히 좋다고는 말하지 않는다.

하지만 경량 패턴은 객체 지향 방식의 장점을 취할 수 있기 때문에 한 번쯤은 고려를 해봐야 한다고 한다.

이다음에는 프로토타입 패턴을 진행할 예정이다.

 

 

 

출처 및 소스코드 링크

git: https://github.com/SnowFleur/2020-Design-Patterns/tree/master/경량%20패턴/타일%20맵%20생성

Book: goF의 디자인 패턴(프로젝트미디어), 게임 프로그래밍 패턴(한빛미디어)