FreeType으로 Direct3D에 글자 출력하기

Posted by 적분 ∫2tdt=t²+c
2013.06.01 04:13 프로그래밍/3D




FreeType을 이용해서 Direct3D에 폰트를 출력하는 방법에 대해서 자세한 문의가 자주 들어오더라구요. 

(2013/04/06 - [프로그래밍] - Direct3D에 FreeType로 폰트 출력하기) 그래서 혹시나마 도움이 되고자 그나마 얕은 코드 지식 드러내 가며 글을 씁니다.

요 코드는 이전에 개발하던 리듬게임과 현재 개발하는 포니게임에 사용하고 있는 자체제작 엔진인 Interstella의 일부분을 발췌한 것입니다. c 11코드와 ISI 클래스의 메소드들이 사용되어서 난해할수 있지만, 최대한 주석을 달고 넘어갈테니 알아서 보시길ㅠㅠ (저걸 일일히 D3D용으로 바꿔서 올릴만큼 잉여력이 있지는 않아서)

코드를 보기에 앞서 어떤 방식으로 구현을 했는지 간단하게 설명을 하자면,


1. 1024x1024 혹은 2048x2048 크기의 A8R8G8B8 포맷의 텍스쳐를 생성합니다.

2. 화면에 찍어야하는 글자가 있다면 이 텍스쳐에 Lock을 걸고 글리프를 새깁니다.

3. 이 텍스쳐를 화면에 찍어서 글자를 표시합니다.

4. 다음 번에 그 글자를 또 찍을 때는 이미 텍스쳐에 글리프가 새겨져 있으므로, 다시 Lock을 걸 필요가 없습니다. (캐싱 정책)


이를 위해서는 폰트와는 독립적으로 존재하는 글리프들을 담아두는 텍스쳐를 관리할 필요가 있습니다. 이를 GlyphBank라고 이름붙일게요. 이 클래스가 하는 일은 다음과 같습니다

1. 텍스쳐의 생성 및 해제

2. OnLostDevice, OnResetDevice에 대처하는 일

3. 찍을 문자 글리프가 캐시되어 있는지 확인하는 일

4. 캐시되어 있지 않다면 Lock을 걸고 텍스쳐에 글리프를 새기는 일

5. 새로운 글자를 찍어야 하는데 글리프를 새길 텍스쳐가 모자라다면 텍스쳐를 비우고 다시 글리프를 새기는 일


물론 GlyphBank 클래스만으로 폰트를 출력할 수는 없습니다. 실제 폰트출력을 담당하는 클래스가 필요하죠. FontFT라고 이름붙일게요. 이 클래스가 하는 일은 다음과 같습니다.

1. 폰트 파일을 열어서 폰트 데이터를 읽어온다.

2. GlyphBank에서 얻은 정보를 통해 실제 화면에 폰트를 출력한다.






길었죠... 이렇게 글리프 뱅크를 관리하는 클래스를 만들었구요

이 뱅크를 이용해서 실제로 폰트를 찍어주는 클래스가 필요하겠죠





ISGlyphBank는 당연히 하나만 생성되어야하므로, ISI 엔진에서 시작할때 하나 생성하고, 끝날때 파괴합니다. 이식하실 분들은 전역변수로 생성하시던지 싱글톤을 이용하시면 될듯하네요.


난장판인 코드를 보느라 수고 많으셨습니다. ㅠㅠ


이렇게해서 폰트를 출력하면 짜잔.

중간에 있는 조그만 글씨들이 모여있는게, GlyphBank의 텍스쳐입니다. 저런식으로 캐시가 됩니다. 처음에는 텍스쳐를 새기느라 약간 버벅이지만, 그 뒤로는 거의 끊김이 없죠. 알파벳과 숫자 기호만 사용한다면 캐시가 넘칠일은 없습니다...만 한글 같은 경우는 워낙 문자가 많아서 넘치는 일이 발생하곤 합니다. 1024x1024 텍스쳐를 가로 세로 32 픽셀인 글리프로 가득채운다고 해도 1024개가 들어갑니다. 근데 보통은 더 작은 크기로 폰트를 출력하고, 자주 사용하는 문자만 자주 사용되기 때문에 너무 걱정안하셔도 됩니다. 정 그렇게 걱정되면 2048x2048혹은 2048x1024 크기의 텍스쳐를 이용하는 것도 방법일듯합니다.

Tags
이 댓글을 비밀 댓글로
    • 도움좀..
    • 2013.07.16 03:21
    위에 있는걸들을 어떻게 어떻게 잘 변경해서.. 조~금만 바꾸면 돌아가게 만들 수 있게 된거 같은데..
    ISData의 정체를 모르겠습니다..
    FT_Data에도 Length , pointer 가 있길래 같은걸로 생각하고 m_data를 FT_DATA로 만들었는데..
    처음 생성할때 FT_DATA를 넘겨야 하는거 같은데, FT_DATA 자료형으로 변수를 만들고나서 어떻게 데이터를 채워야할지 갑갑합니다..
    레퍼런스를 찾아봐도 구글링를 해봐도 FT_DATA에 관한건 없는듯 보이고.
    그외 다른 자료형은 Length나 Src , Pointer를 가진게 안보이는듯 싶네요..
    도움 부탁드립니다.
    • 아 ISDatat는 파일입출력을 추상화해주는 놈입니다. 제가 개발 중인 프로그램에서는 폰트가 메모리 상에 압축되어 저장되어 있어서, 저런 클래스를 필요로 한 거구요,
      일반적으로 사용하시려면 FT_New_Memory_Face 말고 FT_New_Face로 직접 폰트 파일을 여시는게 편할거에요.
    • 도움좀..
    • 2013.07.16 22:41
    감사 드립니다.
    바꾸고 나서 몇가지 좀 더 삽질좀 해보니 출력이 잘 됩니다. ㅋㅋ
    한 5~6일간 한글 출력때문에 밤을 샜었는데 이제야 제대로 한글이 출력되는 것을 보니 참 기분이 좋네요..
  1. 아주 좋은정보 감사드립니다 ㅠㅠ 국내엔 FreeType을 다루는(DirectX 에서) 방법을 찾기가 쉽지 않았는데, 정말 감사드립니다.