상세 컨텐츠

본문 제목

FreeType으로 Direct3D에 글자 출력하기

프로그래밍/3D

by ∫2tdt=t²+c 2013. 6. 1. 04:13

본문




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 크기의 텍스쳐를 이용하는 것도 방법일듯합니다.

관련글 더보기

댓글 영역