상세 컨텐츠

본문 제목

Direct3D에 FreeType로 폰트 출력하기

프로그래밍/3D

by ∫2tdt=t²+c 2013. 4. 6. 22:47

본문



별로 대단한 건 아니고

Direct3D로 작성한 게임에 FreeType 라이브러리를 이용해 폰트를 출력하려고 이틀 자료를 모았어여.


http://www.soenlab.com/lecture/library/freetype/freetype.htm

소앤랩(구 WinAPI 사이트)에 라이브러리 사용법은 충분히 나와있는듯합니다.


FreeType은 폰트타입 파일을 열어서, 각종 정보를 읽어와주는 저수준 라이브러리인데, Direct3D에서 제공하는 ID3DXFont 따위의 인터페이스가 마음에 들지 않을때, 폰트를 깔쌈하게 출력하기 위해서 많이 쓰인다고 합니다.


FreeType은 개략적으로 다음과 같이 동작합니다.

1. 라이브러리 초기화

2. 폰트페이스를 읽어온다.

3. 크기, 트랜스폼 등을 설정한다.

4. Glyph(글리프)를 읽어서 렌더링한다.

5. BYTE 단위로 렌더된 폰트 비트맵을 잘 가공해서 출력한다.


문제가 되는건 5번 단계입니다. 그냥 GDI나 쓰면 SetPixel 등의 함수로 점을 찍어서 대충할 수 있을테지만, Direct3D에서는 그런짓을 할수가 없으므로.


그래서 D3D에서 폰트를 출력하려면 렌더된 폰트 비트맵을 텍스쳐에 옮겨 담은 뒤에 이 텍스쳐를 이용해 폰트를 출력해야합니다. 여기서 발생하는 문제


* 폰트 비트맵을 텍스쳐로 옮겨 담으려면 Lock/Unlock이 필수인데, 요놈은 성능을 떨어뜨리는 원인이 된다.

* 그렇다고 사전에 모든 글리프를 텍스쳐에 그려두자니 너무 많다.

* 실시간으로 사용되는 글리프들을 텍스쳐에 그려서 출력하자니 너무 부하가 많이 걸린다.


검색을 해보았더니, 다음과 같은 방법으로 이 문제들을 해결하더군요.


1. 화면 크기 이상의 텍스쳐 한 장을 준비합니다.

2. 필요한 글리프 비트맵(폰트 페이스, 폰트 크기, 문자를 고려하여)이 텍스쳐에 있을 경우에는 그것을 그대로 사용하면 됩니다. 없을 경우에는 텍스쳐 내의 빈 공간을 찾아 락을 걸고 글리프 비트맵을 새겨놓습니다.

3. 텍스쳐가 꽉 차면, 오래된 (혹은 자주 사용되지 않는) 글리프 비트맵을 캐쉬에서 제거하여 빈 공간을 만듭니다.


폰트 페이스 안에는 정말 많은 글리프들이 들어있지만, 실제로 화면에 출력할 때 사용되는 글리프들은 많지 않고, 화면 전체 크기를 넘치는 경우가 거의 없다는 사실을 이용한 캐싱 정책인것이죠.



테스트를 해보았습니다. 생각보다 속도가 괜찮게 나와요. 위의 겹쳐있는 세줄은 텍스트를 출력한것이고,

아래 있는 조그만 텍스트들은 글리프를 캐싱하는 텍스쳐입니다. (빈 공간을 찾아 차곡차곡 글리프를 넣다보니 순서가 엉망진창이 됐지만 그래도 좋습니다ㅎ)

관련글 더보기

댓글 영역

  • 프로필 사진
    2013.05.24 17:17
    예제 소스가 있었다면 더 좋았을텐데요 ㅠ
    폰트 캐싱에 대해 공부중인데..
    텍스쳐에 글씨를 찍고, 해당 글씨를 찾는건 어떻게 될거 같은데
    이걸 어떻게 조합해야될지가.........
    (한글이 아니라 영어라고 해도, 단어나 문장 단위를 조합하는 문제가..)
    난감하네요 ㅜ.ㅜ
    • 프로필 사진
      2013.05.25 04:17 신고
      엇 조만간 예제 소스 정리해서 올릴게요ㅎㅎ. 자간이나 행간 계산해서 폰트 찍는게 궁금하신건가요?
  • 프로필 사진
    2013.12.09 15:39
    제발좀 올려줘요 나 못해서 뒤질것같아요