冒险解谜游戏中文网 ChinaAVG

标题: 【汉化资料】开源的图形渲染引擎OGRE(3) --让OGRE支持中文TTF字体 [打印本页]

作者: shane007    时间: 2008-10-22 16:15
标题: 【汉化资料】开源的图形渲染引擎OGRE(3) --让OGRE支持中文TTF字体
开源的图形渲染引擎OGRE(3) --让OGRE支持中文TTF字体
, G! K0 D! l; A3 h% q1 L0 G2 ?* ~& G2 G: R: @3 y
0.还是前言 8 V' U0 i) P& T0 G+ `
% _8 V. Y( b* ~" g! R% b
        如果你希望能看懂这篇文章,请先确定你已经看到了《让OGRE支持中文》(http://www.gameres.com/Articles/Program/Visual/3D/OgreSupChn.htm),因为本文是在上一篇文章的基础上写的,并且假设文件都已经按照上一篇文章进行了手术。但是如果你只想简单的使用TTF字体,只要下载本文附带的文件,重新编译就可以了。
2 u: ]. O$ N  o: E) ?  j% s- {
) f' e& p9 D- e2 f0 N! l1 \. |/ G1.检讨
5 w! i1 p8 q7 T( o8 _5 Q! e3 o: q" z
9 H3 F* d  v* ~) |/ b        正如上回说的,我们已经实现了一个位图的字体。但是当冷静下来思考时,就能发现这种方法的诸多缺陷。读入一个2048*2048的位图,等于在显存中保存一个2048*2048的贴图,不说是否所有显卡都支持这么大的贴图,单是每个Font字体类吃显存的胃口,就足以令人心惊肉跳。如果定义足够多的字体类,我想你的游戏的配置要求,在某些方面足以超过《DOOM3》了。
0 R  m4 H: u) l. t
, \% B( `3 ~9 b        而且这并不是唯一的缺陷,文字大小相对于位图大小比例相差太大,导致浮点数的文字位置误差很大,你可以在一个文字旁边看到其他文字的影子。(虽然可以通过增加文字间距来解决。)还有点阵字体本身的缺陷,就是字形单一,不适合放大缩小,一些文字边缘的马赛克,足以熄灭任何玩家的投入感。 0 `! q9 z1 c, W6 A
1 c# E6 Q! U" D% ^; v' D
        似乎TTF是唯一的解决之道。 , E; P3 O, k* f2 }3 B( w* h3 Q
+ W/ ?$ k4 b. t  B8 V1 ~' ?
2.基本知识 ! L+ P) `- \3 q8 p- @8 C2 {# R
( b: `% T  ^) f( `
(1)TTF字体。 2 I1 M$ A, o! Z2 q7 [
7 }9 o' Q7 `% K, |
        TTF是一种矢量字库。我们经常可以听到矢量这个词,像是FLASH中的矢量图形,在100*100分辨率下制作的flash,就算它放大为全屏,显示出的画面也不会出现马赛克。所谓矢量,其实说白了就是用点和线来描述图形,这样,在图形需要放大的时候,只要把所有这个图形的点和线放大相应的倍数就可以了。而且,在网站上有很多的TTF字库可以下载,或者你可以去买一些专门的字库光盘。然后在你发行你精心制作的游戏时,可以顺便捎上这些后缀为.ttf的文件就行了。包括Quake这样的惊世之作,也都是用的TTF字库。
4 B( t9 n+ B5 }( Q- I8 U; ^* e" K# V3 B1 l' F
(2)FreeType2库
& H' L1 m4 e  q
) S! J/ z; ~; y        在http://www.freetype.org,有一个FreeType的免费库,而且是OpenSource的。它目前有2个版本:1.0和2.0。其区别在于,1.0只能读取TTF格式的,而2.0支持更多的文件格式,在使用它之前请详细阅读所要遵循的Licence,以下是摘自FreeType2.0对字库的支持列表:
4 N" U0 F: B  i, W6 Q1 [4 n
/ r+ ^+ E3 X; |( V  b        TrueType fonts (and collections) ! p5 s, }4 {, i8 b% t1 x
. a  |6 ]5 e; J) }  F% f( h
        Type 1 fonts + f4 ~( q% E( W4 i! F  s
$ h; J1 s: i2 v& E% D& n+ X
        CID-keyed Type 1 fonts
" a) @  I) a: n/ G8 W
1 A! E9 |+ s! N& p, h6 W/ B1 b1 E        CFF fonts
1 E6 z! k3 Z+ I, c: X3 q" |
7 ^4 H4 m# m& \3 P9 @        OpenType fonts (both TrueType and CFF variants) : c+ M2 O# {/ I& E7 A2 w/ B
4 I  f7 A3 {& E: R8 b
        SFNT-based bitmap fonts . |5 e( I) A) d4 |, \" P

0 j& K  c* o8 G2 m" _3 f        X11 PCF fonts
# R0 G" ^& E6 W" M/ k: U( e5 i
& ]: ^9 p: U# N& ]        Windows FNT fonts / |3 _8 y8 Y8 M1 u  o6 B( B( ]

+ b' _7 E: }4 c( G7 g(3)“主体思想” 5 m2 ]0 C: |) n9 \: g- ]' F
" b! ]( N+ d5 }- F; I0 g- T/ F
        请参照炎龙工作室的《游戏中汉字显示的实现与技巧》这篇文章,可惜使用的是Windows API,作者千里马肝,上网上搜一下吧。
! m2 _2 {7 x) a0 w, O- c$ B# D( D, Y
        附带说一句,上面两条都是直接从这文章中剪切下来的,>_<  不要骂我啊,不知道算不算侵权呢。
. p* A! {% ?6 y! B5 F# E! E. Z- p! g) F( K! @  e
3.动手术---比你想象的要麻烦
: Y3 j8 K+ L- M( }: P8 y1 Q( |6 M. X( v(1) 1 a6 G% Q+ ^5 q  d- W& {: R3 @7 Y5 {
        首先要告诉字体类,我们下一次渲染需要哪些字。以便字体类可以在需要的时候释放不使用的字体。 * g! O5 k" Y- \! s6 h% @
9 v; F% p: O: \# D+ `1 u( U
        在Font类中~
3 j  p7 M' h7 ^( A% `
7 ~! s& u$ Y3 `1 h4 D, Y  O5 w( v        a.增加数据 bool mUsing[OGRE_NUM_GLYPHS]; 用来标记文字是否使用。 8 r) f, X7 H0 o8 X0 X
7 I# M: ?0 V+ U
        b.增加函数
0 I4 r6 r/ d7 `( |$ o) o
: `+ D  r  V  J2 _/ l" ?                inline void setUsing(std::vector<unsigned long>& caption)2 m4 [) E6 S7 ]" O0 M. r0 E

4 y" D3 l$ v, e6 C7 C! T" b. [                {
4 S6 V' T- |, u' m. _! ]% ]" V3 o9 h9 s
( h2 x+ X6 T1 k9 {5 B0 B$ k$ W                        memset(this->mUsing,0,sizeof(this->mUsing));
, \: o3 {7 B( R" C# r6 W" e3 o) e, s2 m2 J  m9 X- f
                        std::vector<unsigned long>::iterator it;, e9 x9 p" A$ a/ I8 F$ O
$ D4 ^* Z$ @( z8 ?' y, @: D. |" z( K% f
                        for(it=caption.begin();it!=caption.end();++it)
4 c% U$ {) @0 d$ V6 q
! Q+ q9 J3 \# |+ s8 Y                        {6 W# N0 F+ o0 z8 p2 R

( w$ r9 r7 I8 S                                if(OGRE_GLYPH_INDEX(*it)<OGRE_NUM_GLYPHS)
! L- e4 p( j1 ^: u* c& K/ n  b7 ?" g+ h9 w! Q4 h! E: d0 W
                                this->mUsing[OGRE_GLYPH_INDEX(*it)]=1;//标记文字为使用
' R* V6 {* X. X$ n3 D) t* c  v0 c. F+ {
                        }
- `% S! e# a' S! q7 h, i! i. Z5 p4 ?3 K, c! n7 {5 \9 p
                }* o6 ^, H. n* Z

. d0 l' y- o( ~        并在 void TextAreaGuiElement::updateGeometry() 中调用这个函数。
* O$ C, v6 o, m2 Y6 X(2)
) k5 @* N5 P9 f' h+ S5 F8 c; h) q7 g6 V$ t4 N, R" n. q3 X
        然后是修改void Font::createTextureFromFont(void);
6 B7 x+ s, n) G* E
6 N0 s% a4 p  C( E6 o+ y' }8 Z        Font类是通过void Font::createTextureFromFont(void)来把通过FreeType2分析好的英文字画在一个2^n*2^n的贴图上,然后再保存英文字的位置。 4 x) ^- u* I/ _& }/ X1 m

1 O* N) r8 y4 [' ~, m        我们需要修改的是:
4 I. B/ b: d# y6 A
3 S. Q3 g9 t6 {' h        a.从函数中分离并保存画字的FreeType2和辅助变量。我们通过一个类来保存和处理这些变量。
7 o- D1 \% i8 s
$ F! w" V+ d! e9 G9 m7 b        class TTFMsg5 Z6 x9 K7 [7 v3 g  l2 O6 {1 ~
6 o' B% a8 b  V0 u* F- P
                {
0 d5 V8 D  I+ f. D6 Z) `! r" L* w+ {9 n
                        class Max//类中类,用来保存几个"最大",
7 g; i4 T& I2 g. j! R9 \# u- W9 p+ k7 l' @5 n5 S9 A" n
                        {1 w, ?, J/ G3 n4 y4 R
" z' Y. D7 ?4 M7 \& P3 j2 }
                                int nothing;//这个是用来占位的,没意义,反正没他就运行出错,可能和数据对齐有关吧。 0 {2 z+ G1 c" `5 t( N0 |

" a6 ?( B9 K+ z+ r  |                        public:
- w0 q. P: f4 T6 V6 c0 l  B) F& Y                                int height;//文字最大高度 : K+ J6 K, n/ B/ \2 q; @
                                int width;//最大宽度 * x+ a7 w) g; N1 ?7 B/ k
                                int bear;//最大空隙? 1 V0 e/ c% A' N$ t( x3 x( e
                        };
! C) R0 D- ^: U, H( D                public:
  L; R% t3 A1 R                        FT_Library ftLibrary;//FreeType2用
) g1 u4 D, m$ i' Z                        FT_Face face;//FreeType2接口?
! ?1 |  l. A7 Q! f1 }                        uint char_spacer;//文字空隙 + y5 m2 V9 ~: _1 Y5 `6 H" n
                        SDDataChunk ttfchunk;//数据块,用来保存ttf信息
( K+ B) e; K6 I& T8 E                        FT_F26Dot6 ftSize;//FreeType2字体大小
& n$ \, }- }7 y) J5 i( I                        std::pair<uint,uint> point;//在位图上画字的点 # }9 w6 k+ l% B' |; a% Y; l$ O
                        SDDataChunk imgchunk;//数据块,用来保存位图信息 1 E; w: Q; t- u, N' e. A+ X
                        bool dirty;//标记,看是否需要更新贴图 8 A. n1 ]$ U) Z
                        Max max;//几个最大 / x4 a) Y* k  F; x
) P; x2 _# V. W8 R( K
                        inline bool init(Font*  font) //这个是初始化函数在void Font::createTextureFromFont(void);中调用.
* o/ D6 W7 }" p4 c+ ~+ I- S0 E' v4 A& Q: O/ K
                        {       & Q: H9 B/ r- u, U& e' K, m
2 C# F& E" \6 c$ n
                                //以下都是初始化,大部分都是从void Font::createTextureFromFont(void);移植过来的
& K: r7 `# r7 r  v6 `) P3 \
; D5 k1 v. F3 ^1 R" n                                dirty=false;
3 O: _7 Z* P  k( y6 S
8 o  d& r) }6 v2 J                                if( FT_Init_FreeType( &ftLibrary ) )- y2 @- |& {0 ]# p2 x

( r, }! M2 i$ B  j3 q                                  Except( Exception::ERR_INTERNAL_ERROR, "Could not init FreeType library!"," @6 K5 w; M. Q( b
$ @- _3 f* s" b- j
                                "Font::Font");
# b- j) r% ~: Q* q# i' _5 _2 Z
* n1 U0 ]6 x5 q2 v+ i: m                6 g1 x! b* \# G  e6 f4 A
) \" J* T7 F! I1 F8 m1 ]6 [
                                char_spacer= 5;8 ^" f. |8 D, q0 W/ u$ y6 F

* Z5 C, ?, p$ Z( [                                FontManager::getSingleton()._findResourceData(font->mSource,ttfchunk);
4 f$ g* h! k" O7 ]/ I- Y9 c* |
- N! \+ I( }! x  v0 d                                if( FT_New_Memory_Face( ftLibrary, ttfchunk.getPtr(), (FT_Long)ttfchunk.getSize() , 0, &face ) )+ l$ d% N: Y) h$ {$ D

& T3 ]' u+ [: E' v& M9 J$ t& t                                         Except( Exception::ERR_INTERNAL_ERROR,
3 o% i9 x! Y7 r9 Q1 P. ?
; Y- U3 s/ W% ?/ s% G8 V6 h                                        "Could not open font face!", "Font::createTextureFromFont" );5 Q) X: G- T# Z
- B( w% x# N1 g
                                ftSize = (FT_F26Dot6)(font->mTtfSize * (1 << 6));* M7 u5 Z1 v/ `+ M
7 f% }2 l2 F( S* b
                                if( FT_Set_Char_Size( face, ftSize, 0, font->mTtfResolution, 0 ) )* E$ p1 }* ]) N7 x! _
( \5 B% A9 P) G: s6 ^
                                        Except( Exception::ERR_INTERNAL_ERROR,
5 U6 u. V0 N0 d; A) q
, B$ v% I/ S- O8 }5 `) l3 W                                        "Could not set char size!", "Font::createTextureFromFont" );
8 h: j& j) |- }6 |  l2 v7 o+ ]) I$ c* S9 _* W7 o& I" H: y, B9 @
  
' \6 K. a- Q9 j5 C1 t* X: k
, r: l5 F) s6 x, ~% {! _                                return true;
) Z. q% c3 K3 C! w2 [
: R# K$ e1 Z- ^* B7 @# S                        }
8 n: {/ R4 a! L' Q2 ~) @
; B8 J' Y; C! o                        inline bool done()% j1 W$ Y8 ?# m, m1 A4 |

0 `- a; [% m/ i7 J. k: w                        {# c  U* H. `/ H/ R' z: w
+ B: V, o1 N- _" l) L( {9 e
                                //在Font的解构函数中调用的,本来应该调用下面两个函数,但是不知道为什么一调用就出错,不用倒没事。 : L' j+ ?5 {0 h$ J

, B5 X" d% x* o6 K* _9 O5 p% X0 N                                //FT_Done_Face(face);' @( c  a  S! h0 u7 f

& n# q2 E7 A; b. R- H0 H. ~3 D! [0 a                                //FT_Done_FreeType(ftLibrary);
& i$ _" N1 C/ \, g. W0 m& b: K3 J" P. U3 r/ b5 H% m. y" J# D
                                return true;- x# _' Z6 T7 H
# e- }  h/ u: V/ q0 w1 b7 r* Z0 N  Q
                        }) r' e% @9 `. R( S% N% i' s! A

0 |" |" J9 h# Q. E& W                        inline bool getRect(Image::Rect & rect)//这个函数以后用的,是用来找到可以画字的贴图的空的位置 # e* \9 W' N+ t# b3 F

" s" @* g4 J# ~4 V                        {* C( [' b0 K8 N( S4 l! d

: h- j3 Z8 k0 `7 K% g) z  H                                if(511<point.second+max.height+char_spacer); C! M" f. c0 R9 C; t- U

( f, c$ v, V% _' [                                {
: R  q' r% M1 t+ b
" I2 g# p) H# @" r3 x                                        rect.right=rect.top=rect.left=rect.bottom=-1;. i; ~3 S+ b) R+ t% m  Z8 r5 A+ Z; B
& P3 m3 I: g' N* Q
                                        return false;+ [5 e: @2 M0 ]1 k2 Z4 X! ^6 C

! B! W7 ]+ G! O# ~" P, w% A                                }
  o/ u( n7 W3 }) w1 A" m4 A
: ^" V1 ^3 A, s* l& J                                if(511<point.first+max.width+char_spacer)" X+ w# Q4 _$ m: F7 p

6 u1 u! a' N) Z( }                                {
: o; s$ U( J: X/ J5 S1 e7 R
% l. C! a. Q9 j3 ?9 O                                       
, S- ~6 ~) f" M3 ~# o( F: B" `0 t  F& |  h5 F( K
                                        point.second+=max.width+char_spacer;
, e. q; `. q* r- R4 `: |6 Y9 N  M* L
                                        point.first=0;+ y# ~* a- d0 s6 b7 _: a* I
# _( ^2 y3 t4 q, C
                                        if(511<point.second+max.height+char_spacer)& z# \) K8 @% k6 G! [/ Q( u9 A
5 o; v) M' g4 U
                                        {
( Y. X* \: T6 [- b) x" f% t  m: [% g8 h+ F' N
                                        ( b0 ]* @, ~  i! m5 `. r

+ Y. y6 P7 o4 J3 e1 t4 {                                                rect.right=rect.top=rect.left=rect.bottom=-1;& ?, H  o2 O4 ]. g
7 W3 j. q# J& T+ j; Y
                                                return false;
6 r+ R: q- a7 N3 D( d/ X
& _8 ?$ n  ^6 E# h! ^+ \' V6 n                                        }3 B0 M* I$ B( y4 c! [9 i+ u$ z

2 i$ w$ h9 L  j. m                                }
8 N! D8 f* b# |3 g# y3 o( |9 N
/ T6 A  o- ~5 n0 Y# x0 g                                rect.left=point.first;. T: k3 C, {0 \; _1 r
# L! Y& A- m( q0 w. j- Q$ u
                                rect.top=point.second;
+ @8 b4 t' \7 f$ Q) v0 g% y: D  O) D4 O4 ~& m' m' p  T
                                rect.bottom=max.height;
2 j( F! e! b4 W( f2 V( y# Y; H" H* y& ~! [/ i- t' \
                                rect.right=max.width;
# E* E+ x2 m; r: z4 ]2 [! [, t+ [. o* v+ |. [9 e2 a
                                point.first+=max.width+char_spacer;
  g2 k( Y1 ]! A" f5 S' C' h
( y" c- ^9 E# r% C                                return true;, F& l* q: ^) `9 q) j$ o

# F& L; f/ G' g/ `2 E9 ]                        }
* ?8 G2 F7 ]3 m5 P; ^" F" R  i- F- m4 M# u# c: ~2 q  _2 ?
                };
8 Z  a) N6 s; b: s) H
. H/ {) _  T& m' ]$ g3 R        上面的类定义在Font类中,在Font中增加 TTFMsg * mTTFMsg 数据,并在构造函数中 mTTFMsg=new TTFMsg;
/ n" Z# K' u; H
0 n, X# {/ {7 `% x! a        5 L/ h" I3 O5 Z

; C  A% Q6 ^) N2 `# q* f5 H8 |8 s        正是修改void Font::createTextureFromFont(void);函数,主要几点,首先是分离出很多变量和构造到TTFMsg类中了,然后是贴图从2^n*2^n变成固定的512*512,为什么要这个数字呢,因为256太小(废话了)。能保证512*512大小的文本区不会出现不够画字的情况(所有英文+符号+没有重复的汉字),这个安全区域基本上是够用的。(什么,你要画满屏幕的汉字?哪你自己看着改吧。)还有一个重要功能是,要找100个汉字,找出最高和最宽和最大空隙作参考。修改完成这个样子了~1 S- Q) [- c9 r. k$ l
. U- h" c5 ^7 s4 G5 [5 C$ Q! ]3 [  Z4 Y
    void Font::createTextureFromFont(void)
% g2 n& E3 k& \. q. \6 Y3 V$ ?
- m! Y& K& P4 Y    {, i$ W5 }( l  u9 P1 d2 [
+ o1 y  L  ]9 r6 \2 R
        mTTFMsg->init(this);//初始化FreeType2
6 T& _: H) M- d/ b/ m
" m3 q( p9 P! _7 X! Q3 C2 T        uint i, l, m, n;
# z* N& w$ v0 n7 V, f; v2 G, d- m5 W( N; @7 V( g- f! i- [) m0 p
        int j, k;
3 p% c( n- |7 `% B/ x% y* [: t5 B4 w' I! y* W1 }
  
$ e: x9 Q8 T' {$ P  n7 E' e/ `8 s
      
  d5 v  b, W2 D' {6 s; i% P, m: M, i* O; v- v3 y
        FILE *fo_def = stdout;//啥意思?我看不明白
. T. h$ a0 ?5 K- l$ c, N1 g, r% ^5 T$ ]! o
  
4 l, o4 W' Q# g" B) _2 i; F) r0 B. h4 j
        int max_height = 0, max_width = 0, max_bear = 0;7 }. E# {7 S0 e. M

$ }+ _  ~4 D8 f0 q& W/ M0 U+ c& {  
; v. U* r" l7 _1 B5 Q; S* h! ~5 e, s6 Z$ s% B
        uint startGlyph = 33;
, ?# q- B3 p4 b2 J6 D! A, c& ?' B. ?1 p2 l
        uint endGlyph = 167;: V1 e5 `0 w& t

+ n- |7 r, A% E0 U  ) T! e, `4 Q. ?

8 @& S9 k  n( Q; K9 X2 @) g        // 找英文的找出最高和最宽和最大空隙
8 b) l( G2 p2 y" \& l2 u- x8 K4 x) w) c* x8 M' d) k1 g0 v
        // Calculate maximum width, height and bearing
% c0 n% i5 J9 y, O# }+ V. I' `: h5 J
        for( i = startGlyph, l = 0, m = 0, n = 0; i < endGlyph; i++ )
- S, o  x& s9 D' p& ]& P* ~3 ~/ X- ~; o3 E. V
        {
/ C2 W3 k3 l' f6 X" W# l( x7 o; i' i+ X( l  U4 c
            FT_Load_Char( mTTFMsg->face, i, FT_LOAD_RENDER );# ^9 r8 [! I$ ]" b( j2 R1 [5 D

2 k7 V- n6 p- v            //以后的 <<6和>>6都是FreeType2中的数据和我们使用的数据的转换 0 j( `! d$ e% e. ?, L3 v, t

- N6 M0 \2 M" n0 Q8 l3 }            if( ( 2 * ( mTTFMsg->face->glyph->bitmap.rows << 6 ) - mTTFMsg->face->glyph->metrics.horiBearingY ) > max_height )
1 w- q4 I" p/ Z1 e. s1 U' \
8 f# S$ q9 x) n. a* ]                max_height = ( 2 * ( mTTFMsg->face->glyph->bitmap.rows << 6 ) - mTTFMsg->face->glyph->metrics.horiBearingY );/ b6 h& J/ A$ ]5 c, j+ S  I6 S

0 g( e, @2 M7 v            if( mTTFMsg->face->glyph->metrics.horiBearingY > max_bear )
, ]& O+ g, |: b- s: V, f" `2 j* [% {" @$ K, w) P' \$ k
                max_bear = mTTFMsg->face->glyph->metrics.horiBearingY;! A* B1 c- u0 q5 U

" H- f/ M4 R+ m& H) {  : J9 W5 x5 I. Z

. x1 K) R+ P4 ~( R# N4 X1 t            if( (mTTFMsg->face->glyph->advance.x >> 6 ) + ( mTTFMsg->face->glyph->metrics.horiBearingX >> 6 ) > max_width)7 e( e) \" e0 e0 f: T. e( X$ B

/ K: G# c& U5 m, m5 L+ K' x7 X                max_width = (mTTFMsg->face->glyph->advance.x >> 6 ) + ( mTTFMsg->face->glyph->metrics.horiBearingX >> 6 );
2 j: X2 l$ h$ N; W4 D: I7 p, k* q" p* Z+ q! H- n$ u
        }
* f6 {  r" F- K0 x: x; D  B
8 M/ {' R# z) D% G8 `0 D  1 |* l3 }7 M9 v( j* {
- t6 {- m4 H% a9 D& Y. |
  " v& X% \) j# W4 Z5 Y" p

( `1 r$ S! g/ u# Y& R2 s, e        //下面的for是找100个汉字,找出最高和最宽和最大空隙作参考。姑且认为最的汉字就在这一百个里了。 % c: ?- c+ i" v' v2 x
/ v. O9 v; G& E# r: _
        for( i = 20643, l = 0, m = 0, n = 0; i < 20743; i++ )8 \2 C2 P8 }0 z- w
& G4 f; Q, v- G' ]8 J
        {% n# Z; q3 h% e- i( R
' m0 d3 B* N/ S* H' d, \# f
            FT_Load_Char( mTTFMsg->face, i, FT_LOAD_RENDER );6 n9 q8 q3 I1 E$ t( N, ~$ i6 R4 A; {

% S6 v0 X, t* {1 C0 s( v2 x  
% ?: B# Y* n. k3 n( D5 s& T! i
+ N% ]1 o8 s$ }( l% U            if( ( 2 * ( mTTFMsg->face->glyph->bitmap.rows << 6 ) - mTTFMsg->face->glyph->metrics.horiBearingY ) > max_height )
; c0 E  Q7 Q% W3 c1 e  |) Q
, P. Y4 |$ j6 S" L9 r. ^                max_height = ( 2 * ( mTTFMsg->face->glyph->bitmap.rows << 6 ) - mTTFMsg->face->glyph->metrics.horiBearingY );
# T& @. s* b6 \% ~0 w" t' Q  g* N6 {# B; p2 ~8 Q$ p% R
            if( mTTFMsg->face->glyph->metrics.horiBearingY > max_bear )
2 Q6 f/ h: c9 H. H$ Q& i# g& D9 I# X1 n) s' U
                max_bear = mTTFMsg->face->glyph->metrics.horiBearingY;
/ r6 a1 ]8 c. Z: L
2 s1 G- O6 E2 X' M! V  ) U. `1 D" O; b, o
3 s" X3 U! C0 T: M0 c0 q1 q
            if( (mTTFMsg->face->glyph->advance.x >> 6 ) + ( mTTFMsg->face->glyph->metrics.horiBearingX >> 6 ) > max_width)* h8 C" v/ j# n* Q' Q( H% j

' R- X. j" c9 m% e3 N- I                max_width = (mTTFMsg->face->glyph->advance.x >> 6 ) + ( mTTFMsg->face->glyph->metrics.horiBearingX >> 6 );$ q6 m6 M) j, ~! C8 t; C- z- `
+ Q3 g! \5 z% m6 X4 ^' T
  7 y4 l" k0 a3 r. e. u) Q

6 T- r! s# C8 W# Z/ B0 _! A$ T5 j                        
/ D; t/ R% M3 V, Y- o) d- O
/ i8 j& S' f& v8 m  k            if( (mTTFMsg->face->glyph->advance.x ) + ( mTTFMsg->face->glyph->metrics.horiBearingX ) > mTTFMsg->max.width)
" p7 V. R/ V* P( x7 I! b" H# L% f, ~1 ?6 r1 s" p# `/ N" w
                mTTFMsg->max.width = (mTTFMsg->face->glyph->advance.x  ) + ( mTTFMsg->face->glyph->metrics.horiBearingX );
+ T+ M4 c3 p% R$ f/ Q3 l) z8 A2 B7 Z1 Z4 `0 @1 r: K+ h9 S" Y  n
        }0 }6 M. v) ?9 J8 R" d

8 C* R$ a8 b" Z3 G) J9 P6 @  
! R# V! d: q& ?
. A; w- k( h8 n                //下面几行行不需要了 我们要512*512
% k8 q4 w* t3 ?5 |' X0 i% q# [  Q4 S- ]; W
                size_t tex_side=512;//就是这个了 5123 x, a/ X( P1 ~8 k
, [+ g8 r0 T/ P0 z0 x
        //定义数据宽度 因为是32位的位图 四个char为一个像素,为什么要位这么大呢,难道不能用8位的么,我尝试着改来着,不过改了之后就不透明了。望高手看看能不能改。
0 K6 v# ~2 d& K4 G2 z2 z8 z' i% O9 J
) k/ g+ l- H: V+ I# j( q- i/ {                size_t data_width = tex_side * 4;9 n* A: R5 @* Y9 G9 F6 F
/ ]( T2 K6 ]8 i( c' G. q
  
2 @: E; M' j: c" C8 `" x$ X, D. l' T7 b9 H! y
                LogManager::getSingleton().logMessage("Font " + mName + "using texture size " +* C& c0 c* |$ J) ^& Z1 v: c+ I3 _
- _  E' f2 T. ]1 g4 C0 `
                        StringConverter::toString(tex_side) + "x" + StringConverter::toString(tex_side)); 0 u; `1 h4 Q! V: ~7 P+ m8 z

% R+ S8 L3 e1 t3 w( R3 I2 W  
9 q: S* |% F0 `. ^- i( v, F: q5 e% l7 Q; y. r
        uchar* imageData = new uchar[tex_side * tex_side * 4];//设置一个空间用来保存位图 2 c: Y: V3 F2 Y! i5 w# g1 ~; q6 {( c
3 @' _! u& k5 M" m8 r) A, }. @  v! T
                // Reset content
5 B$ z( R9 D3 l. X' X4 _+ s: c# \; |$ p4 r8 E6 \" r
                memset(imageData, 0, tex_side * tex_side * 4);//清零 9 {7 }" D6 Q4 F' z

% X2 d) T# H5 E! X) x  ; ]* n# f% n! [2 L

8 b( l  g7 [1 n7 [9 o  I; h4 R9 W        for( i = startGlyph, l = 0, m = 0, n = 0; i < endGlyph; i++ )//遍历每个字, 2 z2 j. v9 b- E- L+ k3 J
( y6 U* w% M: b+ w& J
        {
$ o) @& q- l1 L/ x5 Q) {( E% p( W7 i1 F) b, q: d  b
                        
+ _" K% k! r' M& u. E7 Y
+ W/ F4 l  S; y5 J            FT_Error ftResult;
2 S6 q+ G1 H; i* p; p- o, r" {
$ B! W) g3 H+ ?4 g  3 O# y7 v; E- L: W6 ~% n+ e* _7 B
- z6 I. \) b5 c
            // Load & render glyph
' ]2 ?- b6 f% j; ]+ X" }6 Z' v
/ r, }  ~' p6 i7 F% `            ftResult = FT_Load_Char( mTTFMsg->face, i, FT_LOAD_RENDER );//读取字体
) Q+ w3 p% t- E8 Q, ?7 M/ K. X2 ^8 ?( Z7 Y: M$ D: {  `6 ?
            if (ftResult). P3 Y! c7 j3 C' t' S+ b$ v: f

$ z1 ~2 r6 Z* l$ R# d4 M5 r  p            {
. K5 f* b% S8 {: Z
) G5 F9 }- p, O- h2 f3 B                // problem loading this glyph, continue - h% g8 u) E$ H/ Q. v
) `/ h( Z  Q) ^% c
                LogManager::getSingleton().logMessage("Info: cannot load character " +5 \. d- L/ x( _2 V) `' T) ~

8 `4 T3 i" s2 t. B* S( a                    StringConverter::toString(i) + " in font " + mName);
8 M8 I! T8 }: r( M+ V5 [' h0 P. C7 a( l7 y4 Z
                continue;//如果错误跳过 % S' o; O% d. G, o  W/ U. t

- q; A! d3 p1 A            }
# O2 p& f+ ]( J( J) C- H# A8 J3 @: ~1 Z! s& _3 D4 G4 e. T: E3 a# V/ _
  , Q8 a6 Y- P2 v; \+ c

5 ]$ {" f9 F& {- M/ ?4 j                        // 应该是字宽 ; ?, @; }3 Q# W

" h+ H* o1 O# i: {8 I                        FT_Int advance = (mTTFMsg->face->glyph->advance.x >> 6 ) + ( mTTFMsg->face->glyph->metrics.horiBearingX >> 6 );
( x9 D+ V9 m3 o6 M# P- V+ q2 @: z# g
                        
0 H4 n: j; c" g2 `1 I  `
9 E8 ], T, w! F' H$ Z* [* P                        // 得到FreeType2的位图 $ b3 {+ U- ]9 W: G9 O/ F
' }, r0 E1 {) A" q: ~- \2 C
            unsigned char* buffer = mTTFMsg->face->glyph->bitmap.buffer;+ {( N6 _/ w9 |2 q" s' Q
/ |/ [1 M, @9 Q% V9 K- Q% I
  
( s: n$ t3 _  J3 w- k3 H+ u
& h  p& J9 B2 {$ y, F3 z            if (!buffer)
" b. P! K# q- `5 y! S- n% X# m
+ z' E+ R* b3 K+ s; c            {
& w$ x0 d9 M2 o" j) d* J8 B9 O1 y: v* G0 s; w5 I! a) s
                // Yuck, FT didn't detect this but generated a null pointer! / w1 o- _: G6 \6 v
- C  q- z# ?7 X* V0 a$ r/ n8 ]* O
                LogManager::getSingleton().logMessage("Info: Freetype returned null for character " +
" r3 L6 Y5 O# Q* g1 j" w- v* Y7 F; I9 X6 a6 [; s' n
                    StringConverter::toString(i) + " in font " + mName);
  K" X1 @3 U+ Y' Z- J
" W! Z  n! x. t/ S& t- z                continue;//如果得不到跳过
1 c0 o& e3 _2 |. R
3 z0 k+ Q3 Z5 Q7 B; g            }
9 a' Z# Y, e# B  p& ?( \& z
, e' [! g/ A) |) Z; z  . t) P0 r# @; j/ h# P
6 P* [( g0 M% l3 Z9 n: K
                        // 得到y的空隙 (最大空-空-本字空)就是说空出这些字底部就平了 2 J7 ^8 ]2 g, x" D* M8 o
+ z( K0 o! K6 S2 D& [0 E
            int y_bearnig = ( max_bear >> 6 ) - ( mTTFMsg->face->glyph->metrics.horiBearingY >> 6 );
3 |( s; `8 b% Y# V. o) r$ l& i& q* `) v6 t" Z
                        
0 i# h5 w: ]8 u2 d" N6 D2 |0 ^  I+ O+ x8 k- x" q
            for( j = 0; j < mTTFMsg->face->glyph->bitmap.rows; j++ )
# q9 d& V' [* k$ `0 O& e% ?" L) `3 J3 B  u4 c3 ^9 W
            {
+ g( ^9 h& _3 X$ u
% F! I6 I# ~: x$ s  k; M& o                                int row = j + m + y_bearnig;//相对行+本字在位图的总行+空隙 2 m# h5 @! Y; y4 ^' j

. E* D; ?( g9 @1 k                int col = l;//列 0 W4 ^' Y' a  t& O; @8 F$ F/ u; r

) v/ U/ ]+ v4 f- g+ X9 X                uchar* pDest = &imageData[(row * data_width) + l * 4];//找起点   
: S6 n( u+ Z8 A; l" ^* m+ l- ?2 i4 D
: `' c. O8 [! c7 V2 v5 t& o6 j+ i                for( k = 0; k < mTTFMsg->face->glyph->bitmap.width; k++ )//画图 - V' X" X; x( H* I+ _
7 m  n, F/ w9 l9 d7 E; X
                {+ M* F- f" y% D
/ I; }/ ]$ z' V: P8 M2 _$ e' |+ H8 ?
                    if (mAntialiasColour)//看不大懂,难道是灰色字体? $ |) [  W* f  t/ t% d

: [% m- J) T! L8 j                    {6 J+ \5 y, S; `7 O1 [6 m- l) j
3 A! m) L7 H9 |" i
                        // Use the same greyscale pixel for all components RGBA 0 u4 }5 G- F9 Q5 o: K4 D, H

0 x* A7 q" ?' D7 Q) Y# A! r1 h                        *pDest++= *buffer;, ^) F% j$ W) c7 O4 P) R9 `
" s* M+ @1 M/ m! R; J6 z
                            *pDest++= *buffer;
6 L( k" Q9 m5 h. H, R' C6 [8 J, v  x9 r) F9 V
                            *pDest++= *buffer;
8 Q. [/ q) E; J& }2 Z! o+ E$ f, F
( k1 W, u4 v: |+ e/ g% Y) U                    }5 N" g* y. B0 K# n4 a
, I$ |# e9 q5 d1 v, w
                    else 0 \+ j! _6 g  R+ X! q- w) H5 R3 x
, m$ s$ y6 l4 E) t
                    {# j+ C, w; Q/ |6 W
+ F* T% E. P2 g7 r" ^3 q
                        // Clamp colour to full white or off
- u$ _; Q% ^! h. B7 d3 L! T7 D/ n0 w. x/ Q1 C2 k* W1 z& J
                        if (*buffer > 0)
) K" @, I7 X4 u& x3 `% {; @5 |  N) ]% e! F# X
                        {
/ @6 r+ J5 r8 h4 u
1 }6 M. r3 Q7 l" O7 i                            *pDest++= 0xFF;) P4 P+ g5 _' N& _1 [, e
" R& x9 m5 A  T: c, @
                            *pDest++= 0xFF;
- u( [' ~% M5 K8 K& b9 D8 c1 ~4 z# N" G; K
                            *pDest++= 0xFF;' D- o' F' o( Y6 R8 \+ {- h! \6 Y/ I7 ^
% y1 n) ?* H& l! E
                        }
! E9 h) o- H; h: M( E
; [/ K6 |$ X& P- y' @: Q0 r! U2 m. F, g                        else
0 H  m& Y( @* K- \  J6 g! g4 I4 P! d- r; o) ^5 F* K3 t3 J) P
                        {
8 E$ B9 v3 n6 A
4 Q. d. z( h2 \9 Q                            *pDest++= 0;+ {% R  j8 ?$ G4 u

/ m& E% w6 l! G2 W; @2 s                            *pDest++= 0;* z/ n/ G! W5 B. S2 K" q
3 g6 r! e, X9 X2 d$ X
                            *pDest++= 0;
8 c( D+ m9 q' a0 ~# t8 `$ G+ O9 `$ d6 d5 K8 J5 P7 w3 ]
                        }
/ b  ^- K1 K' y4 u' B, ]; A% r/ r
' n' r5 ?. T6 ?3 O' U                    }9 c' x( Q% _. ?0 `( P  D2 i0 A* e
% @/ ]" K- C; F+ W8 w
                    // Always use the greyscale value for alpha 5 b! r6 E% S  a0 _& l0 e
2 \, t$ m& e. y1 D# a% c, O+ d
                                       
& l# p5 s* I4 z5 r* u& n9 H+ T
5 ^" m/ y) b3 s! m. x  U                    *pDest++= *buffer++;//alpha! 我是一点不了解了为什么是这个?
( N, W) r# N4 ]- H& _  n! ^
% @, T2 V/ z. R8 T% q, x                }
/ R- |% p1 c8 S+ O* Y; L) a' a. ]) P0 X- B8 E9 T' m3 F. C6 \
            }6 O! k8 \5 Q* @0 y6 Y

. F, w  }& h( @- w    h  w7 k+ G" e' t8 l
1 y: z$ b$ J$ s$ r' G+ j
            this->setGlyphTexCoords( i, ' y3 g- @8 I8 E$ _" G: H1 _

+ H  B) ?: z2 U6 Y                (Real)l / (Real)tex_side,  // u15 P6 Q. J  n9 `2 {8 w7 E+ u

6 r  B1 I4 R; l9 p+ Z                (Real)m / (Real)tex_side,  // v1$ L9 }3 I. ?, z" {2 _0 v
3 A* z  W% f5 o( B
                (Real)( l + ( mTTFMsg->face->glyph->advance.x >> 6 ) ) / (Real)tex_side, // u22 v8 j0 \, i2 ?. x' G8 v$ N
6 a7 |& b- ?" V- {1 W" `
                (Real)( m + ( max_height >> 6 ) ) / (Real)tex_side // v2/ }/ F, t6 E" b. \6 y8 ]8 V7 f- g" Y
  w% A0 Y% f( `
                );//设置坐标
, P- u5 Q0 r' @  n' M
" g- f% V2 B# A) p6 s$ H  
4 Z: B5 Z/ y' M$ h% V0 w$ F
5 Q7 U$ m2 L7 V9 ~) q% U            // Advance a column
7 O' o" {% b( {6 B
3 E  W- `; s; F, P7 P" ~4 B            l += (advance + mTTFMsg->char_spacer);4 R* k, {. R; l

( a0 ]( \7 Y. S3 R+ X9 l                        //l+= 本字宽+字空 ) g4 A4 m5 [9 @$ P! h- U+ W" F

1 D$ h0 \4 J& b  
+ M, j; I# h, J( a- f
0 B5 O; i" G! R' F            // If at end of row
7 ?1 ?! Y+ _7 s  e) U" S/ }1 |; ~. l; ~0 O: m* u! t
                        //如果到头容不下一个字
! S; ?% N- `6 D' l
6 B2 p: v( p( m( _( l, K            if( tex_side - 1 < l + ( advance ) )8 |8 H8 G9 z! d

5 ]! {! U' v3 D* t            {6 X2 C( J  A: O; k

$ c) x' Q% f# s  u                m += ( max_height >> 6 ) + mTTFMsg->char_spacer;' s3 H: n( R# a( Z  F( P2 h
+ ]: O- U! y: G! Z1 O0 v
                l = n = 0;
; x* p; O% |5 q5 K8 M  t
  T/ H: Q: \% R1 G( ^3 o            }4 `8 R1 b  P; E3 a. ]4 i

1 u/ T8 m6 _! X* L  
4 d8 P1 U6 Z4 o( W# \4 G. q: y
, `& _& Q& ~: k7 O, L        }
, x5 V' s6 I; k* K! A
: l) P5 m% g# _. M. J: C# v                // 把信息存到我们的mTTFMsg中 >_<
7 c! m# G) D  R5 ?0 O/ y1 W8 W/ `; J( s- t( k
                if(l)3 f' c4 _! i5 k/ f- g3 |

6 h' A) N9 G/ r4 Q  G( V1 u                        mTTFMsg->point.second = m + ( max_height >> 6 ) + mTTFMsg->char_spacer;
( ^/ z5 E( j* \+ ]3 `6 u- U9 k8 V1 f% w8 M" P1 g
                else " o( O0 i) S1 Y6 V" d: _. P

3 u" ~( Y+ y+ e  Z2 Z( ^* m& i3 m2 R                        mTTFMsg->point.second = m;, C7 i2 l& r4 |
7 G" }, N1 J' O8 F# e
  
/ {9 L4 l- l4 Y6 v5 Y
  J1 P9 U' E/ M/ C$ m                mTTFMsg->point.first = 0;//另起一行 ) X9 G7 r/ _* F, V" f# k
4 C6 S' y- e5 L* o+ _
  
5 o9 \" a6 {& n+ o# b8 G+ i
3 G2 L" t* K# {; ^                //下面是保存几个最大。 8 r+ m* L0 q4 e$ Y9 [$ S9 F
1 v& u2 d4 P2 N& j8 l
                mTTFMsg->max.height = max_height >> 6;6 |: w& K, o9 N% S9 s9 t, U2 r
6 q8 d7 k2 Z9 B* X) ~$ f
                mTTFMsg->max.bear=max_bear >> 6;
  t, U! U# m- X6 I9 D. P8 z( M- F- Z) L8 o5 g% ~: E2 }9 ^
                mTTFMsg->max.width=max_width;
& q7 e7 w) Q. M% \4 `% E, M$ b0 z, |" _: U3 g# `) T
  / I! ]8 F  z* }5 q7 ]4 p! K; k$ t
; l% l: {" Q) r3 g1 B
                mTTFMsg->imgchunk.allocate( tex_side * tex_side * 4,imageData);
/ X8 v0 Q. l6 ~6 e+ ^  e4 M% N" g3 g' `, T0 |6 [
                0 [" a7 I: j, g: D; w
6 ^: \3 y: v' J% A0 \2 r, ^
                //不知道为什么要设置img这个中间变量,似乎可以直接从chunk创建贴图
8 q; a7 L: c, e* u6 ~9 X0 l1 e2 E3 X5 H0 `& n4 \
        //--Image img;
( B# O' |6 X: P4 l8 g1 q! [. a8 Y0 z# Y: {8 R+ ~
                //img.loadRawData( imgchunk, tex_side, tex_side, PF_A8R8G8B8 );4 m- p$ j# N* C4 n

% s  ^; ?  z% w  & x% U; {' w% `! J% X& G

1 }2 x0 Y4 Y5 w" D- s& A* E0 Q                //贴图名 * b  j# m2 e3 }3 p7 `, ~2 J
: l3 e) t- F* R. y0 B$ |
        String texName = mName + "Texture";
0 K3 y& H1 v0 J0 v+ H/ @% w0 @; N
, l1 a0 C# |5 K4 |+ O                // Load texture with no mipmaps
* y7 P. E3 o) E6 y9 U) Q$ ^6 x( e7 V/ N, \( d
        // 把从img创建位图改成直接从chunk创建贴图
) f* Z0 u/ l. }. P5 Z: D, [3 {
0 Q6 R. q, R$ W* Z! C: e$ _6 h' ^                //TextureManager::getSingleton().loadImage( texName , img, TEX_TYPE_2D, 0  );0 b7 o( M* P; n: K6 l+ J

* h9 M2 H7 u# G' X+ ?# [5 A: d                TextureManager::getSingleton().loadRawData ( texName , mTTFMsg->imgchunk,tex_side, tex_side,PF_A8R8G8B8, TEX_TYPE_2D, 0  );2 b: V- O6 E+ p$ d7 S* h2 P& K7 d

6 p/ p  q) p: F8 T$ I* m        TextureUnitState* t = mpMaterial->getTechnique(0)->getPass(0)->createTextureUnitState( texName );
6 U1 t+ s, Y9 I6 y  ~6 M8 u
2 A5 F) Q) W- q                // Allow min/mag filter, but no mip
& |8 B! {7 k; N* I# L
7 g. R& t9 P$ v$ `' y0 g) D                t->setTextureFiltering(FO_LINEAR, FO_LINEAR, FO_NONE);) e0 ^7 X8 ]5 Q6 t. Z1 L8 u

. W  i2 [1 m) S* v1 E: {        // SDDatachunk will delete imageData
8 n) y# a8 N0 C+ `: N
! d3 F1 \" y. x! f3 U% k3 {, q( t        2 ^4 \9 `6 H4 {3 u7 V) W8 |5 F$ q

. G. A: R" D. ^+ g+ [% Z; V    }' N2 G, }- t/ ]& @

8 i/ S- f# h3 @' T        你应该对照一下以前的函数,改了很多的。 - S% ^: w- M) H) b
9 q* S. `7 z$ ^
  ) A+ d5 @- x$ A% A, A/ I  e
7 W3 ~# h8 _: R. w$ J2 H2 D
  
4 {3 j$ d( k; l  ?5 J! c, R
, N4 j5 E, f# }2 I8 u# W) u(3) & w( ^: g, W: N

. S& H% l: K" [2 h% l        然后最重要的是动态的申请和画字。 1 |& }, m2 V' A5 U- f9 G
% J# T6 }. y& L$ ^4 F, K
        首先最重要的是我们要一个方法得到汉字的unicode码,我们用到了unicodeMap数组,提供了区位码到unicode码的转换工作,等一下提供这个表给你,好不容易从网上找到的阿,可惜这个表没有中文标点的对应,如果希望支持中文标点,就要努力找到unicode码并加进这个表了。这个表是这样的 char c[3]="邸";unicodeMap[94*(c[0]-0xa0-1)+c[1]-0xa0-1];就得到邸的unicode码,不知道为什么没有5165~5169的unicode码,是轮空么?
4 T5 d* M% u8 c# N+ [9 v0 i+ y! \: l! X
        
+ o; l8 [$ K3 R. B1 j5 {4 @6 h, M' G  A4 @3 S7 Z0 s
        申请渲染(字)
: U* r, ]" @: Q, o. n" q! S5 K) `9 h* h9 v! ^, H
        {6 S1 f* V# u* V, d% \/ h

$ w* T$ o* [3 U( E; ?* m& r# _                if(有这个字)( p5 x) p1 {; s

: h: Q" k. a$ K8 {+ A" h                        返回位置
$ T0 x8 K. V; A5 b3 E
) I3 A  Z9 C& o0 x7 _                else
( V5 M5 g( R& o) ?- N
8 i, w6 b7 S+ S5 b$ {5 d                {
+ A( C5 |1 T+ \! z5 H2 Y
% a  U5 q( f# t: P" v  m" ]                        if(有空间)
0 G1 b, y. H' E4 J6 q
$ N% `8 s, i+ b7 C" ^2 K$ V4 j                                画字 7 _* C& P8 ~! Q) {! q* s/ a7 B- W$ i
. `* T# I1 ]/ b7 t; i# k
                        else, j# W. l6 [6 ^5 l

0 [0 R$ M* s' u5 @5 R9 R- U4 e: c+ S) V                            找不用的字//找不到就出错,没地方画了 2 W! H1 a6 p1 l; ~- y0 g  e
+ W1 G& [, x1 Z+ V; Q
                                删除 在这个位置上画字 7 h( P% l6 M9 \9 t9 R' I9 W& O

0 [% D  W7 Z" v. `$ g                返回位置 $ P8 q2 G3 m- k$ G# Y8 u" ]

/ |0 ?+ r. G  \+ B                }
7 C" o3 K$ a' d7 v$ N
3 X* v6 V" @9 b. I+ t! M, Y        }1 u4 o/ g8 D8 J8 W, |

7 x: W/ T) D/ A0 D/ x6 b) l        上面很直观把,大体就这个意思了,申请渲染的函数是inline void getGlyphTexCoords(unsigned long id, Real& u1, Real& v1, Real& u2, Real& v2 )  const。去掉const改一改。得到 , v8 X! o% Q/ a' i
" F& }: k1 S$ ^% H7 C6 r
        a.申请渲染 , E1 y" |4 K$ V& m- ?' G
8 N# Z( ~% D# S+ e: s
        inline void getGlyphTexCoords(unsigned long id, Real& u1, Real& v1, Real& u2, Real& v2 )         
+ P+ }( H5 S8 }: G9 g0 V, J6 v! T& D3 `4 y! k3 c  S- P4 ^
        {* u1 q  _1 `5 A2 b, b& L* `
4 _! {" t$ [4 y
                unsigned long idx = OGRE_GLYPH_INDEX(id);* h) V1 M4 K* B
+ h/ r3 |4 G: E3 V7 e
                if(this->mType==FT_TRUETYPE)//ttf?8 N5 E8 Y  Z' e% x5 g# D# C' y* `

9 M5 b; P# Y) {7 J4 ^6 K3 p3 Z                if(id>=161&&idx<OGRE_NUM_GLYPHS)//汉字?/ _' K% d* V, z, e" l

* ~8 ~2 z9 N* {! |3 I5 Y/ s- P1 ]' a6 [                        if(!mTexCoords_v2[ idx ])//没有?4 o  w, J( V2 L! p& k! u: H

8 N5 ]9 g  {; ^6 Q                                setChar(id);//画字去 6 j0 R" ]9 f! A/ m3 Y% a
; ~; Z# v3 ~' u1 P' ]' Z
             ) H2 X+ r7 u3 T5 e
+ V* z! x% u" q% p, z) ]
            u1 = mTexCoords_u1[ idx ];- a, ^1 p$ E6 y1 A2 \% A
! V5 h) P8 O0 V% G6 E( i! e" d; H
            v1 = mTexCoords_v1[ idx ];, y  C' {; x" Y/ I/ J4 n
. I# p/ V6 A9 j/ O0 {
            u2 = mTexCoords_u2[ idx ];* ~, a6 w. p: N9 k- J+ s/ M2 i

0 T; c5 ]8 @* g1 `8 z/ V            v2 = mTexCoords_v2[ idx ];
# v; ?7 l: u) N0 @. X% ^& h/ ^% x& c/ `  f  H$ |
        }
3 G& K' N# w, s. |5 g* k* C) F3 A9 Z1 R1 F; ?* u  i
        b.画字等 , o: N2 i9 q" {/ w

! c, {+ m8 \7 o; C) @- Y  i        bool Font::setChar(unsigned long dwChar)+ z: e5 M6 ]) ~1 Y4 {

  C1 C4 a- `8 z5 y8 w        {& _$ z3 A7 V; V6 N! Y

% H; u" Q# {8 [                int j,k;0 k% `9 _6 f8 ?2 A" v4 I
8 z/ @& q! @2 C2 e$ E* k
                uchar* pDest;//操作数据的指针 , B, L$ _, i) c% m, Z; i

- P% R+ u/ I$ Y9 G; t1 G! f                mProportion=0.8;//不知为什么,总觉得中文都太扁平了,所以设置这个参数,在《让OGRE支持中文》中创造的参数
* g: O$ ~& u# _6 i' |$ ~2 ?% P# c9 `, B$ F3 N
                Image::Rect  rect;//画字的位置 ( B4 H" b) P2 h4 d  t+ N$ z

& ?/ e- l3 N* d& x* ^7 R( x                if(!mTTFMsg->getRect(rect)/*回头看看这个函数吧*/)//如果得不到空位置
% W7 P6 V% {, R& y9 m8 V) r. y& y* m' W+ V% \, d
                {: A+ ~) m& f0 ?  t. e2 M# T6 u

( r5 i9 T" e- I' R% X                        for(int i=161;i<OGRE_NUM_GLYPHS;++i)//寻找不用的字 . ]0 N1 k  X1 \1 L  [8 R/ }9 E* g

& e, O! {" k' t! z' q' f                        {$ W( W# k! p/ A
% o7 S! O  }& j8 E% [) q
                                if(!mUsing&&mTexCoords_v2)7 P3 x& d, ~8 _; c" p9 R8 p1 J
  R/ Q7 S) r7 r5 @# [: ^
                                {/ T" ]0 G% i- e) @- K

) _4 E& M* E' I                                        // 得到坐标
- v* D5 l7 r- c& ?- u  \* w/ Y" ?! n
                                        rect.left=mTexCoords_u1*512;
7 b1 Q; w/ G1 Q; G8 {+ C# f, ]9 j. b" `6 {
                                        rect.top=mTexCoords_v1*512;: ~0 l9 l! ?( m( n. B! o- h

5 k0 ~- b: o) k4 V- W; h5 g# \5 ]* p                                        rect.bottom=mTTFMsg->max.height;
6 h9 G, Y# Y8 S4 D4 [- X) a% V0 W3 {* \; L
                                        rect.right=mTTFMsg->max.width;
  J) t: U* X0 r" P& v- H" L$ N
  ' @0 `0 J2 [2 `' K' `7 c  T
* d! e, X) i& C. h3 |
                                       
+ W  v" l: `5 w- k) C
; ]; r. i" R* u/ r( ?4 ]0 x% K                                        , a! a' P) o0 ^' `8 b" q4 g, o

$ I5 e6 n7 P4 e% k: b9 B% O/ I                                
) v( R  \! Y3 }1 j- r5 t# M2 k/ u2 G# X) v
                                        //擦除(这段代码没有试验过,等做完输入的类在检查吧) 2 @+ v5 _/ e% G# \2 n  U- ^- \
, Y0 W% F) t' z' d
                                        for( j = 0; j < mTTFMsg->max.height; j++ )
6 Y4 E- T/ ^- m8 C
! z% Q0 B1 o- y+ U" z6 _, V0 p                                        {6 y3 b' `% U3 O+ i* |! y
4 \  |7 h& Q! g* C
                                                pDest=mTTFMsg->imgchunk.getPtr();$ E: b: W5 E; I% z/ {  Y" N0 ]
8 m8 ?) A0 N- F
                                                pDest+=((j + rect.top)* (512*4)) + rect.left * 4;# D& w) h  A) ?6 S) ]1 Z( m

- @7 U+ D  s. R, O; u. C8 I                                                memset(pDest,0,mTTFMsg->max.width*4);2 N0 R7 f1 T5 D! k

& L# R! G$ g: I) n. X/ ~                                        }
" y% \' x- s9 @% @* H' r  g2 X+ [9 p/ {6 N
                                        mTexCoords_u1=mTexCoords_v1=mTexCoords_u2=mTexCoords_v2=0;
! Q: \/ h2 V' R7 x+ j, I3 q- ?
7 D: E# t2 H: E# o6 E# k  
+ ~; v9 d' P! Q" R1 W: c0 l# M+ ?6 V! j3 x2 G+ ^
                                        break;
$ X  P7 U3 A. S' ~3 l* i* y. B3 t- {( y% @0 s" V
                                }
8 Q! i# c% Y& }) D& b3 `6 o# e( ?, @4 Y. O
                        }
. ~: B5 }7 M4 s9 s! r# A; M3 Z/ S4 u( o9 r- Q
                        " A) O+ J1 d; Q- J* [# w
' f  l( O+ N5 z$ Z6 U7 |  M
                        if(rect.top==-1)//啊啊啊啊啊啊啊啊啊,贴图竟然都用完了,没办法了,出错了
8 N( g. d% O; |, X+ u, z* P/ D7 ^4 k5 j1 B' e
                        {
$ l8 \) I6 g1 Y# O8 q6 c* t6 s7 [! k9 v) V+ _
                                LogManager::getSingleton().logMessage("你太贪婪了,用的汉字太多了,这是对你的惩罚.");
, m* P  D1 P' u- `7 i7 q
$ I' O2 P5 M! Y  U1 \                                return false;
# h9 x: J; D( b5 V6 x% F# H0 @7 R1 I. y
                        }  U& n" {4 W$ f% L/ ]
, z7 p& F5 x6 O5 _
        ) q/ |1 |) k9 B: [0 V/ [) u- ]
$ K6 X* J9 b: K& d# X- Y
                }; r2 r3 T. l! a+ {$ X+ ~# P
  H# B# p" V* K: f
                        - h0 H7 ]" O' e5 I9 U

9 N/ q/ O1 ]$ ]1 n                ! q( b9 [' D" u, w3 R1 @- j* o% ?
8 z3 z; Z5 P6 ]3 E
                  //以下画字的都是招葫芦画瓢的, % I0 o: s+ V2 b; s5 F4 h1 X

- Y/ V5 U2 D6 O" O% {) e5 _. Q9 e                  FILE *fo_def = stdout;
! A" n1 ^6 A, I; `3 |
5 B2 [1 L! |* a* r/ `3 n6 b5 e$ V8 P                 FT_Error ftResult;
) {8 x& m" g0 e( b& M# G7 L' @$ J( \5 i2 b
  . A3 B* V* t6 e4 A

0 |) N9 ~; J- {- T: \: J5 B            // Load & render glyph
9 Z+ P0 B8 P/ T1 Y
( k: |$ [+ {+ }. ?                    _1 K! O) E8 `& l7 b& ^

, r9 ]6 Z0 _5 Z( ?9 T            ftResult = FT_Load_Char( mTTFMsg->face, unicodeMap[dwChar-161], FT_LOAD_RENDER );//读取字体
( q( m# L: j0 F' t" m
* @7 z# I  M0 q6 [8 r( }            if (ftResult)
3 A- h# T6 R$ q' ]
% j9 q" Y" V+ V9 W            {* l3 A( v* n; H% O8 i+ m
4 E  D0 {! s% }4 n
                // problem loading this glyph, continue 0 O" u& `* z6 U2 e! j

% p1 W5 |4 p: I' z( V' z                LogManager::getSingleton().logMessage("Info: cannot load character " +, @, u% f6 P- B5 S# |, s) H1 V* o  D& ~2 b
' W4 d5 j$ e, e) {: ]
                    StringConverter::toString(unicodeMap[dwChar-161]) + " in font " + mName);
) }% n0 M$ F/ J- Q8 M6 b4 l$ h6 c" S. [. w  q$ b
                return false;//如果错误跳过
" M* ~1 A; j/ |) R: ^+ E: ]6 w- \% Z' {* m/ }/ T/ c, p# V
            }& p9 \( V$ J" q9 D4 H* i
  ?  f; f* `5 ?2 G$ I1 g
  
! [" D3 b7 r% h$ l0 v% I* d, J
  S( U/ a4 g" l3 i+ e' d) {; Y          unsigned char* buffer = mTTFMsg->face->glyph->bitmap.buffer;
( S3 K/ k' I+ A
6 l2 @" |# ~. {7 G  J                  // 位图指针
. `* q2 ?9 b8 L8 t' W
0 F# D  a4 E! j' ^2 ?4 o1 e            if (!buffer)# i6 N& M/ m9 D6 Y
* m( B% [/ P: Z0 _! J2 v) t7 K* T% `
            {
+ y& R- e7 k' p- K4 ^3 ~# d# Z. V  n
                // Yuck, FT didn't detect this but generated a null pointer!
9 }$ z# `( o: k7 V9 t' A/ S
+ a- D+ d8 R( Z3 n8 i3 |" `                LogManager::getSingleton().logMessage("Info: 1111Freetype returned null for character " +( f1 s% g% w* `" v" ~) U" O
2 D" j* g% o! ~8 T. z
                    StringConverter::toString(unicodeMap[dwChar-161]) + " in font " + mName);
2 c8 L) Z7 r* E% @& d5 C5 R: |6 _4 g6 M1 L/ j
                return false;//如果得不到跳过 & y8 v+ {  M, g6 K

- U2 @& G8 V  W3 V( @0 r            }
1 o) T3 q; O/ l0 t
6 l' N# ~# _; R- N- r4 m  g  4 f, u* |- w( M. x& f2 j

1 z. t1 q' i% {" i  l: c& G                         int y_bearnig = ( mTTFMsg->max.bear) - ( mTTFMsg->face->glyph->metrics.horiBearingY >> 6 );
. U8 G' t2 \9 D0 y5 Y- E! U
7 ^* G! R/ ^0 r: k- S, w1 z' G: i, ^      
, ~6 E! ?+ s( V/ A% \3 |
: {% ?: X; M& w                        ' {7 V8 @( J2 f# L

% \. X! G% z" p5 A4 a            for( j = 0; j < mTTFMsg->face->glyph->bitmap.rows; j++ )
' d! j. K+ M6 j- Z9 f$ z8 m- B6 U6 S( J9 c
            {
) S! v/ s4 N/ X. h+ L8 L8 V" M( ~2 q+ S8 X& o
                int row = j + rect.top+y_bearnig;
1 N- o* n: s3 G; ]0 ]9 Q# W' s% \5 y# H# n, A
                int col = rect.left;//列
0 x, X4 T1 V' |% d' \3 L* l$ [
: Z5 p5 r' o3 x4 f$ ?% l                                pDest=mTTFMsg->imgchunk.getPtr();! q( X. U1 _* `; b" V

. b/ N0 y5 _8 `  7 x% X4 n/ g' x8 F- s- n/ a
0 C# _. \7 y/ ]% n6 G6 H
                        
/ p" v2 @9 l1 T7 T6 z
9 D) ?; `& G( l: U" ~( ~* N                                pDest+=(row * (512*4)) + col * 4;6 ?& y% v: X( C- R. a! F3 y( ^9 u

2 @, S0 J7 C8 x# `4 a; O' X               for( k = 0; k < mTTFMsg->face->glyph->bitmap.width; k++ )//每行的点
) c! x' C9 \  q' u. ?2 i
$ Y% U) d+ w& _8 x$ F* p                {
  B/ G6 @- k) ]9 M0 l  @4 x
5 f, ]' m% X; M; S. @5 z: O' _                    if (mAntialiasColour)
# ]: i8 y6 F- K5 U7 F/ H/ y/ _, g' X) |- W7 J
                    {
7 V' L$ K* o8 {# ~! [  j& h' A. s
                        // Use the same greyscale pixel for all components RGBA
# e! H$ C- c! f% ^8 A# }) `+ x& C' i! b  N) }4 r0 x8 p8 V+ ?- U( N  }: ?
                                                        *pDest++= *buffer;2 K% K6 G/ @% j1 W2 U2 P
, r, K+ D6 O2 {1 B( N
                            *pDest++= *buffer;( B2 O: ^  d+ O
* p& c! T1 p7 u7 S( H
                            *pDest++= *buffer;- ^4 m% Z4 M; `( X- ^0 v
, J" z  ]) H% u; s
                    }
0 b$ G1 Z$ s+ R( |3 e( H% h$ ?4 b! K/ \# x8 R* Z5 b- E7 v- O
                    else
" Q% G) ~$ i. b4 G
8 ]* l5 E' ^- ?7 X6 k9 a; u+ \                    {
; ~4 s8 U. U% U3 Z6 b2 v! m1 g  C( x$ S8 ~  {8 t
                        // Clamp colour to full white or off
2 g7 j) ?* Z4 I+ b' v, Q: e5 M( G. |) I8 B( W
                        if (*buffer > 0)$ o* P3 e1 I! ^3 q4 T

4 K: h' B: ~5 h# w3 J                        {
1 v* c  i) y+ k7 _* }+ S
3 }# O! D" }" _% L7 b                            *pDest++= 0xFF;
5 K; |8 y, N  F: V# c* c! L( h; o4 F2 l" U
                            *pDest++= 0xFF;6 v9 M9 F$ C- \$ a8 Q

* t* F5 g% k- v# ]                            *pDest++= 0xFF;1 c. F" v! Z, Y' q1 }

$ z& Q2 A0 T4 r% n: F( V0 i                        }, h1 s1 O# s/ ]) t* p

8 u0 u& q6 }$ U  s                        else
: b3 W" u# N# R' [: E6 I1 y* g
! M, E$ d9 o, B; y9 W+ e  L; b                        {: E. c7 U6 ^* a+ Z

+ ]7 Q' i. _" A; o$ K+ i1 H+ e2 e                            *pDest++= 0;
9 q& E  Z4 u2 I( L- M1 c& x" [- [7 Y
                            *pDest++= 0;
4 F& d" j3 @1 ?8 `- U6 e8 B/ F- a: v9 ^: h4 |, @
                            *pDest++= 0;: j7 Q9 o8 c( U* x1 k+ c

2 b9 y: t( u# n                        }. ]* \3 @* {7 T
- V$ d9 P4 ?2 z( b. F8 l7 R
                    }
6 R3 E2 v, E2 s# y5 I4 E' O
, s% D# ?: C' d" {) |, n                    // Always use the greyscale value for alpha
5 i$ b( [4 V* t( {2 ^9 d3 y( e$ c6 `: K  B
                                        0 ~: q5 X& d4 P

6 U( p; ?, p( X6 H8 O" X- @, o                                //      LogManager::getSingleton().logMessage(StringConverter::toString(*buffer)+"is cool");
; A) x9 v' h! k) {5 I( |8 g, q! u; [: K8 p
                    *pDest++= *buffer++;
& _# j2 ?* ]* ~* Q
1 \4 N7 d  f' c5 q                }
6 T' ^3 s7 a8 R: a* P- c& z# m2 t3 q5 {
                                
2 J& j+ I' u) j7 g$ h- o' _: z: h: u% O
                        }
) I4 d( _% j9 D- E+ F
0 K0 K" L: m5 s* H                        // 设置位置 1 T" U4 D/ g  l3 d$ y* g
$ k" X/ Y# X: W, y% B
                        this->setGlyphTexCoords( dwChar,
7 M- j8 k9 H# R' n' C
) _1 D2 M- h9 S' j9 u                                 (Real)rect.left / 512.0f,  // u16 T3 a4 H- U! S( x2 {/ c
# o+ {' E4 N, n- D
                                (Real)rect.top / 512.0f,  // v10 o4 Q% ]' x  |* J5 e
: t" e; F" G3 x# {
                                (Real)( rect.left + (mTTFMsg->face->glyph->advance.x >> 6) ) / 512.0f, // u2! Z; T( `" D& a

) A! g6 T: i" q: N; p7 O# T3 v6 ^) {: j                                (Real)( rect.top + rect.bottom ) / 512.0f // v2+ _8 K/ S* i$ c; W* @# [
! a! O3 g2 p, g2 D- w' }; Q& a
                                        );0 d) [6 H! N* N. T3 p, W
$ v+ L1 l/ K/ N: Y9 M# o
                mTTFMsg->dirty=true;//贴图需要更新 + l8 k9 u1 L8 c- Y1 Q0 \5 ~0 f' \

) e5 w$ h$ u( L: U                return true;
2 @5 j% j( A  H' [5 @" Q
/ k  V4 V; l8 s5 |9 M4 E$ d        }
# y9 X( ~& G: h) s0 l, H0 n* ?% K( d( q7 p  A
  . R5 ?+ m3 J3 O5 D9 x, z6 F

, L: {# M) E. b(4) % F2 Y* ]5 i3 p# Y" R. f
5 Z3 R( X6 |* O4 U* J5 {
        松口气吧,繁重的工作都做完了,就是更新贴图了。
  |& W# f5 t3 }% c% \* J7 {; f/ J1 d+ {6 {2 b3 R  _
        Font类中~
' W* E: l3 h% ~2 z8 g+ @
0 ?; y, O3 k  `/ O& v. I        inline void write(); [% @1 L4 ~8 F

, C/ v( F. g9 K0 e# e; u. c5 `                {6 j7 A3 V% c2 ~5 Q
1 ~, j- M4 c6 W. i- E5 K% `
                        if(mTTFMsg->dirty), F8 }% ?3 r1 T. }; d

7 d* Q7 z& V  q2 ^7 u1 R                        {       ! S+ ?, D* \* x) \/ @5 D

; `  Z0 O2 x1 o9 T( M) F% z- |4 i) i                                // 重新载入贴图,顺便说一句,类似功能的函数还有
$ J" s! a" I) b4 V2 l9 M; ~/ |& X. E. O6 m  B; F; S( C
                                //virtual void  blitToTexture (const Image &src, unsigned uStartX, unsigned uStartY)=0 * J0 }+ Q' [2 b/ a; u! f
; c' `; D* X8 b9 j
                                //和virtual void  blitImage (const Image &src, const Image::Rect imgRect, const Image::Rect texRect)
  I6 `, q$ B, V$ G/ e% e8 g; h
) f7 d. _1 `+ D5 m7 h                                //不过blitToTexture()在ogre-win32-v0-14-0之前没有实现,没有尝试使用。 blitImage()就算到现在也没有实现。 0 R: s  s# Y2 H1 s! v9 D" a4 Q
, k* P! I; {3 H3 o- e8 C7 S8 }
  
8 k% n/ F+ l+ y5 C
% h, p) b/ v5 M: u                                TextureManager::getSingleton().unload ( mName + "Texture");6 Y: ^) n, |- A5 c' w& n
5 f! ~" `. [  ^; ?! }: u7 [9 p0 F
                                TextureManager::getSingleton().loadRawData ( mName + "Texture" , mTTFMsg->imgchunk,512, 512,PF_A8R8G8B8, TEX_TYPE_2D, 0  );+ s7 _3 ?4 h& Y2 V3 ~

, z! j% \* ]3 N% z) @& ^                                mTTFMsg->dirty=false;
3 O/ a( R+ q# K5 c7 ?0 a' [- {5 ^1 }; R+ j- \# d
                        }" K3 ^3 t) ]+ ?! h' l. g" f

* n. D3 }4 x( R/ l  ^) O% W6 p                } 4 j, X/ \$ _. \# l
4 P  P9 {9 M: k  N* X- i
  
& f; X; S: @9 [1 e$ t/ h# P0 c
# y  N* `& N# {4 ]: I         在 void TextAreaGuiElement::updateGeometry() 中调用这个函数。 & h' s  ~, I( x/ \5 z2 m/ h

. H2 e0 Z2 N+ B4 z, i% G+ Z( ?  
1 X" D1 d, V+ e2 {0 ^! N* u( p9 ]' q# ]
  
+ Z+ _+ y% R( s3 b" ]$ K4 L2 b2 f. v: Q, t2 ?
4.结果。
* G: @8 m& ]' P- G9 ^! K. w# E
# J: n! q/ y6 m8 _        好长阿,写了好长。虽然多是代码,但写注释也很累啊。重温了这些天的工作结果。就像上一篇一样“在OpenGL和DX9.0中成功的支持了中文,但是DX7.0中竟然出现了运行错误,具体问题还不清楚,还望各位高手指教。”。不过本来OGRE就不怎么支持DX7的,不管了吧。OpenGL中渲染的比DX9.0清晰,是我的显卡的原因么?以上的winXp+vs2003.net+艾尔沙980se通过~。。 ) |- V' a* B! T$ D

& D' a; r, Y# |. {7 n        顺便说两句,上次发表了拙作,没想到好多朋友和高人们找到了我。甚至联系到了一个南方的公司,说要做一个引擎支持中文的方面。但是卖完400多的火车票之后竟然因为住房问题作废了,5555,退票少了80元啊。还是自己差阿,如果再多学点可能就能要我了把~。努力吧,争取写《让OGRE支持中文》三部曲。 4 K) ?, `! d! L  z
: U, r4 v- F0 X* w' X" _+ |* N
        下一篇应该是《可以输入中文了》。 ( [7 A0 C! G$ {& L/ @' w
8 c$ S0 y7 W/ W7 n3 h0 V
        也可能写不出来的~~~~~~~~~~~~~~~~~~~~    / E3 N- Y) q# Q+ Q( O

4 F2 P7 l4 p4 R& C7 Y    相关文件 ( v+ ~: y- l/ R. v, y
) O2 f0 @: }4 N# Q6 d
    chinese.fontdef//字体信息文件 放在资源文件加中
2 v* A/ P! d1 _& }: w
$ Z2 g# B, C6 ~- S    font.png//字体图片 放在资源文件加中 ( J, n/ N8 J. u* N
  c& V8 B/ |' L3 a! J8 B
  
7 H+ S4 ?% D6 d% Y# L
' n* ]' G$ k" E& |9 m    OgreFont.cpp) _% z7 p5 A+ h5 x0 e  m" O

* _; e" S9 ^% D: G4 I! _    OgreFont.h4 O+ E" f+ p( A3 g8 y  A
8 H% u4 T1 z  w3 o1 B" i9 L& h
    OgreFontManager.cpp3 Z7 b* s; G2 o: ~* ?  r; v6 P8 }
4 c% j4 `9 ~0 N. @
    OgreTextAreaGuiElement.cpp
( X! Y% ], d5 `
4 t' s7 q( n: V# f; b2 y* Q    //上面文件覆盖同名文件 就可以 先备份 ) ]: V) V6 r0 ^  R+ M' w/ g) e: a
" N" _% D" V+ P# ~
   
( ^: ~/ j% ^& b, Y4 x* J! ?( h3 Q/ O. z6 C; n/ B  o
   solo5.ttf//这个是一个中文ttf 我直接替换了原来的ttf
7 R" r4 P6 s/ S1 ]% ?3 B* o% L
0 f( f1 b/ [3 `6 i& A   unicodemap.h//这个重要,是换算unicode码的数组(文中提到)
1 O7 @) `0 H, z& S* F0 n, Z* Z. Q) I: |
  # O& U" U; R8 `& v' |

( y5 b; y' B% k4 @5 H这个是在ogre-win32-v0-14-0基础上改的(上次是ogre-win32-v0-13-1), 3 p& P& R$ V& u5 w( o
1 ?) m6 Z% {6 \& [2 P) I
请到http://sourceforge.net/projects/ogre/下载 ! X2 i) {* P# j( t

% X/ L  Z: O  [2 V2 p, i配套档案下载:http://www.gameres.com/Articles/ ... /ttf.files/file.rar ( z( x# J9 ~/ b1 v% B! l
/ [* \  m( j& X0 m9 Z
免费打工仔QQ:1850070
4 L3 B% I2 I  V9 p6 G; `# {- Q
7 L$ y6 c; Q8 [' p/ }% \/ d, nFrom: GameRes " N3 B' b4 Q% s# M2 i! Q  o9 O
" q) S& k' @# s
http://www.gameres.com( D7 _/ [3 ~1 z  d0 V

, v/ w$ k# O2 S* t! ~7 k上面图中“免费打工仔TTF:213.786”是TTF 其他是位图的,中文的位图字体也小修改了一下,支持半角字体了~




欢迎光临 冒险解谜游戏中文网 ChinaAVG (https://chinaavg.com/) Powered by Discuz! X3.2