设为首页收藏本站官方微博

【汉化资料】开源的图形渲染引擎OGRE(3) --让OGRE支持中文TTF字体

[复制链接]
查看: 2407|回复: 0
打印 上一主题 下一主题

【汉化资料】开源的图形渲染引擎OGRE(3) --让OGRE支持中文TTF字体

跳转到指定楼层
楼主
发表于 2008-10-22 16:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

【汉化资料】开源的图形渲染引擎OGRE(3) --让OGRE支持中文TTF字体

开源的图形渲染引擎OGRE(3) --让OGRE支持中文TTF字体
  N) R7 ^+ }; K4 Y5 x8 C/ s$ A- T" ^* w/ F
0.还是前言
# T, \9 u1 ?" P( k7 _. l& o& m' b( F( B
        如果你希望能看懂这篇文章,请先确定你已经看到了《让OGRE支持中文》(http://www.gameres.com/Articles/Program/Visual/3D/OgreSupChn.htm),因为本文是在上一篇文章的基础上写的,并且假设文件都已经按照上一篇文章进行了手术。但是如果你只想简单的使用TTF字体,只要下载本文附带的文件,重新编译就可以了。
. G9 C) @5 N$ Y6 I
7 i" T  i2 P5 p/ I% Q1.检讨 7 y- ~( N/ k! {& u
1 P% K( c% c& p
        正如上回说的,我们已经实现了一个位图的字体。但是当冷静下来思考时,就能发现这种方法的诸多缺陷。读入一个2048*2048的位图,等于在显存中保存一个2048*2048的贴图,不说是否所有显卡都支持这么大的贴图,单是每个Font字体类吃显存的胃口,就足以令人心惊肉跳。如果定义足够多的字体类,我想你的游戏的配置要求,在某些方面足以超过《DOOM3》了。
$ X7 X6 T8 Q! g$ `5 `9 x( ]5 Q7 f# ^) ?
        而且这并不是唯一的缺陷,文字大小相对于位图大小比例相差太大,导致浮点数的文字位置误差很大,你可以在一个文字旁边看到其他文字的影子。(虽然可以通过增加文字间距来解决。)还有点阵字体本身的缺陷,就是字形单一,不适合放大缩小,一些文字边缘的马赛克,足以熄灭任何玩家的投入感。
, L; A) {% ~. n5 O* U" r) \% `5 X+ h1 ^2 w
        似乎TTF是唯一的解决之道。
0 a- U2 c/ F% u0 U0 l; U, j; f/ C0 s$ ]$ {) L' C2 D, l
2.基本知识 4 \# @: P( [6 o7 C* k( f# T, P
/ K, P# X( n" P: g% k
(1)TTF字体。 % b1 G' o5 R8 d8 k5 F' Q
2 H, T/ [3 d9 l8 I/ z
        TTF是一种矢量字库。我们经常可以听到矢量这个词,像是FLASH中的矢量图形,在100*100分辨率下制作的flash,就算它放大为全屏,显示出的画面也不会出现马赛克。所谓矢量,其实说白了就是用点和线来描述图形,这样,在图形需要放大的时候,只要把所有这个图形的点和线放大相应的倍数就可以了。而且,在网站上有很多的TTF字库可以下载,或者你可以去买一些专门的字库光盘。然后在你发行你精心制作的游戏时,可以顺便捎上这些后缀为.ttf的文件就行了。包括Quake这样的惊世之作,也都是用的TTF字库。   O- {" h2 V) f9 |& M+ a9 Y# l

+ ?3 {# \! {. D$ }$ j2 o. {$ m(2)FreeType2库
9 m3 x; n6 H! ~) H8 x& X
2 S, D) v* C. \        在http://www.freetype.org,有一个FreeType的免费库,而且是OpenSource的。它目前有2个版本:1.0和2.0。其区别在于,1.0只能读取TTF格式的,而2.0支持更多的文件格式,在使用它之前请详细阅读所要遵循的Licence,以下是摘自FreeType2.0对字库的支持列表: 3 @+ w2 U% f7 v

4 U2 j: l5 g* x/ p4 A8 a0 X        TrueType fonts (and collections)
  S) V8 c# I, _! n1 S* ~* Z# E- C0 m" S* Z
        Type 1 fonts
4 j2 J) n$ r+ F: a1 S
, `$ }6 K6 n9 m. \" {+ o& b        CID-keyed Type 1 fonts
) p: o) U) U& s- Y! h: Z: a4 k7 `2 c# |% {3 q
        CFF fonts
* ~# f; C! e% {2 ]1 p- F8 H4 U& t
( I6 v2 m: `' _9 l        OpenType fonts (both TrueType and CFF variants)
* ~# @( O) T4 ]% Y
1 m6 D( }# w/ ^0 c7 c: f9 _        SFNT-based bitmap fonts % N; ~9 G) }. b: ?+ e) C  U
: C+ p' A2 s2 ?# I8 e( h/ q
        X11 PCF fonts 9 ?4 \; p+ K2 i4 i' b
* G$ W' H* {4 ?4 g' O0 T
        Windows FNT fonts
6 |! |3 e* d2 a4 G2 h2 H0 t
5 E9 I6 [, A5 {( t3 u(3)“主体思想” ; i7 \# s0 E4 ^
& ?" U7 C. M! j# p9 P% c
        请参照炎龙工作室的《游戏中汉字显示的实现与技巧》这篇文章,可惜使用的是Windows API,作者千里马肝,上网上搜一下吧。 : R- y: a$ U* e5 f6 L% ~/ b! w' ?4 ]

  L# [; L. o- Q8 e: m  G        附带说一句,上面两条都是直接从这文章中剪切下来的,>_<  不要骂我啊,不知道算不算侵权呢。
: i1 U; T$ I1 l! \0 U5 n& X1 s, b; @
6 V( ^# v+ F$ P1 m; u3.动手术---比你想象的要麻烦
- H/ n7 v  S7 R/ D3 ?* {' ](1)
7 x2 x4 _; Y: [, m; o* E" ^        首先要告诉字体类,我们下一次渲染需要哪些字。以便字体类可以在需要的时候释放不使用的字体。
/ m1 t+ S5 f# P" h- g# o# \4 S* d0 f! ]
0 |5 p, ?7 a$ X) G* l, D& n+ f        在Font类中~ 0 t7 D  s; T" H6 u" Z$ p6 N

/ ]' ?4 m/ q& O1 z- ]/ M' L        a.增加数据 bool mUsing[OGRE_NUM_GLYPHS]; 用来标记文字是否使用。
0 p7 X8 k- O- t( P: N% o7 g6 D* B( F9 V7 D# T1 M) P8 t
        b.增加函数
0 r$ @3 i8 x. B% a3 a
/ ^$ g9 S3 m4 j+ n9 D, ?                inline void setUsing(std::vector<unsigned long>& caption)9 P# U6 N0 C- J) @! V: q, f8 E( v# n
8 [8 m0 }9 f3 w% n) a( t
                {3 `7 }( |( u5 R* U
7 W5 \% {5 x, g- x6 i: v
                        memset(this->mUsing,0,sizeof(this->mUsing));
0 E% n0 K0 R9 \, F" e4 z; @' ?+ ^$ }" E
                        std::vector<unsigned long>::iterator it;
+ f8 N9 ?; g5 C( \
/ I# U( j6 V" s3 F                        for(it=caption.begin();it!=caption.end();++it)  l& V& B. v8 g6 x; [- Y

- n# |, _' Z- }% I4 u2 o" T; L* V; @* G                        {& ?$ r7 W0 u  P* }% }- t
2 @/ u& g# Q6 `7 R2 M& S
                                if(OGRE_GLYPH_INDEX(*it)<OGRE_NUM_GLYPHS)+ _7 p1 i3 Q0 O2 k& G

9 Y, L! ?- s+ W/ @$ y                                this->mUsing[OGRE_GLYPH_INDEX(*it)]=1;//标记文字为使用 6 Z) A. j- b& G! a$ p+ F5 S7 F
9 b; @4 p9 l: {0 O/ p
                        }
7 ]/ ]4 J( I  F/ V* N' C3 {7 G! q9 r" [
" n  H  q- M6 h. q: v                }4 F& ]4 H+ g  s4 M9 P  K  _) @; v
  y  i# H- ~4 I- d# v/ S2 J4 l
        并在 void TextAreaGuiElement::updateGeometry() 中调用这个函数。
+ H  N/ b$ e1 p1 N  r9 Z(2) 8 l; g6 ^9 H* J# Z& n3 a6 B

9 s! b! q" O1 K1 y' V        然后是修改void Font::createTextureFromFont(void);
: S3 U- x3 ?. h/ K
# N9 L: h/ \; [& h" S        Font类是通过void Font::createTextureFromFont(void)来把通过FreeType2分析好的英文字画在一个2^n*2^n的贴图上,然后再保存英文字的位置。 6 s- P: m: \5 ~# m2 M  W

) y3 C# k3 F+ w; Z" f        我们需要修改的是: / k5 |: C" `) o  A8 e

5 s: {' w, u- v0 J+ w) ?: y8 ^9 Q, R        a.从函数中分离并保存画字的FreeType2和辅助变量。我们通过一个类来保存和处理这些变量。 - Q) j: Y. \: v4 j% v- j

$ K( \* V- `, @8 c( x6 V        class TTFMsg& Q. z7 r0 J5 q( ?! R1 C

& n0 B6 q0 |% p  \/ D                {
) I. @0 E/ p& Y% Z) F6 G9 s. I; \8 l7 e  J3 W4 i
                        class Max//类中类,用来保存几个"最大",
; Q5 j# i. h$ K2 u! C* A" T( R0 |8 }1 {$ y4 A3 Z
                        {
: y9 U8 E! ~, ?* i& F3 F/ j0 a( ~: e1 \/ C5 v: Y  z7 @/ z
                                int nothing;//这个是用来占位的,没意义,反正没他就运行出错,可能和数据对齐有关吧。 3 }: ^' T/ M$ M4 r' A
; H4 ?0 Y! e" y2 L: [
                        public:- Y% n5 s9 k' _; n8 d, C, @* h
                                int height;//文字最大高度
' w) w7 v+ S- j$ H2 {                                int width;//最大宽度
$ ~& {: V1 s4 ~2 d0 D                                int bear;//最大空隙?
; {$ Z! M6 ^$ d7 |: E$ j                        };
! g6 i4 }' C5 M- x$ k; ?* g$ a                public:+ m3 \+ }8 e; X$ c
                        FT_Library ftLibrary;//FreeType2用 7 l/ \# d/ i$ B, T% j6 b" R
                        FT_Face face;//FreeType2接口? ) c9 R+ m% Z7 y4 U6 C& f
                        uint char_spacer;//文字空隙
7 f5 w9 Q5 \/ C, ]  |' j                        SDDataChunk ttfchunk;//数据块,用来保存ttf信息 + Z& R; P; d; R; S
                        FT_F26Dot6 ftSize;//FreeType2字体大小
0 }, Z+ {( b# ~; h  k0 r& {2 O                        std::pair<uint,uint> point;//在位图上画字的点 / e! Q/ B8 H0 {. {4 m
                        SDDataChunk imgchunk;//数据块,用来保存位图信息
3 I5 {: ]3 g8 p" B6 Z  l& N                        bool dirty;//标记,看是否需要更新贴图
/ _" t( ?+ i( f- y- n( Q                        Max max;//几个最大
) o0 g: x  f5 w% v" v4 u+ o
7 S9 a2 \) ~/ |/ O: I) M# }# y- s0 \                        inline bool init(Font*  font) //这个是初始化函数在void Font::createTextureFromFont(void);中调用.
  ~+ y# v  C# \- R3 a/ y$ Q- Y. x( q5 p' ?
                        {      
/ D, ^" {' e% s8 _8 g9 X2 [; i! F" c9 o" i
                                //以下都是初始化,大部分都是从void Font::createTextureFromFont(void);移植过来的
$ }7 V* i! [( z. V; V' J) t# X4 j" v* `+ d6 k0 `
                                dirty=false;
  P7 n' j2 ^1 b8 ]' A2 c; b
8 C6 e" k; M, s! {* u) j2 h; v                                if( FT_Init_FreeType( &ftLibrary ) )
/ |2 n* O3 F! i) h+ \
9 v/ A9 C4 B# v; w9 ^+ c* L                                  Except( Exception::ERR_INTERNAL_ERROR, "Could not init FreeType library!",0 l# X2 L: S) P1 Q1 R1 E, A
# W2 s+ n; ~5 ~* Y6 l# r" M
                                "Font::Font");3 K( L7 ~9 a5 |7 Q( \5 p8 j
* S* `" A8 y6 o% {% [6 D
                " K; `1 S0 t/ l+ ^; Y
! U3 U7 l* H, b. @8 j2 h
                                char_spacer= 5;% x! ?) j8 M, ~! f$ w

8 N! W6 H/ Q8 S, O% e! [1 D                                FontManager::getSingleton()._findResourceData(font->mSource,ttfchunk);( f& C( i! {. D

) [7 ^% @9 a$ v$ Z                                if( FT_New_Memory_Face( ftLibrary, ttfchunk.getPtr(), (FT_Long)ttfchunk.getSize() , 0, &face ) )$ |) Z& b0 S) O( Z* x* u7 y* s/ q
( G8 s+ a2 r+ H  i' I/ j
                                         Except( Exception::ERR_INTERNAL_ERROR,
6 m/ U3 w# S/ `- n
2 c. a3 E9 {7 X: @                                        "Could not open font face!", "Font::createTextureFromFont" );* t  z' A) s: U4 o
$ e& k- _" v, j
                                ftSize = (FT_F26Dot6)(font->mTtfSize * (1 << 6));
' G& g0 e2 r. I% r7 Z: ~
" J% {, L& u" S3 ^                                if( FT_Set_Char_Size( face, ftSize, 0, font->mTtfResolution, 0 ) )
6 [: `" T6 r) i1 z6 k# p
. {. g; T: n, }. i1 o6 [) f  B                                        Except( Exception::ERR_INTERNAL_ERROR,
5 `& L) q4 Z) I+ ~+ D+ w' ^4 O- G) n4 b
                                        "Could not set char size!", "Font::createTextureFromFont" );+ S* `, @. n' i/ p9 d. S; N7 h  y
0 Z1 H3 V5 |1 G: f7 l" ^1 f
  
: ~' d6 R$ N8 e* |$ f
" C8 ^9 \9 k9 H8 N) H4 q' d                                return true;: {, S0 F# Z, ~/ p8 i' s+ e" O

$ ~/ k5 J# Q' H5 t- L! _# x4 t1 m                        }# l0 K0 O; J2 U7 |# ~5 j: I
: U! V! y9 b2 P4 f
                        inline bool done()9 L3 i+ f4 L& F6 M! K

0 ?; ?5 _6 g7 x# R5 L3 M9 A7 |8 v                        {
& j4 g& Q/ Y, T7 N& ]- _6 U/ p, Q- Y! v  I; L
                                //在Font的解构函数中调用的,本来应该调用下面两个函数,但是不知道为什么一调用就出错,不用倒没事。 + F' \, Z* ?  j6 h
$ n/ c- t# a. z
                                //FT_Done_Face(face);
( {5 q& z- t$ X! I: I, c+ v3 T
& O( N9 K: F2 ^. _# Y                                //FT_Done_FreeType(ftLibrary);; \( v* ?4 y. g8 x% Q

! M2 h# }6 O% \) ?                                return true;
5 ~, E6 m8 g  R* ~) x6 }6 x$ n! u9 p8 h2 c
                        }+ P8 S( u* q/ X( w) e, y% ~
0 l& O+ G2 ^' i
                        inline bool getRect(Image::Rect & rect)//这个函数以后用的,是用来找到可以画字的贴图的空的位置
/ x, T+ `( H& ~- `2 \' X1 R4 M/ }0 w. k7 }
                        {+ a1 w$ t6 R# w  t
/ ~9 V! A. O$ }0 X# A
                                if(511<point.second+max.height+char_spacer)
; t) g5 y  z0 N' u: b( O1 V/ g3 Z) C; {- f
                                {
$ d0 O, a+ T3 i7 e5 @4 Y- b5 a+ i- x8 l
                                        rect.right=rect.top=rect.left=rect.bottom=-1;
8 |$ k- b# y! x6 l% F3 U% k/ b$ Z6 b( g7 H3 K( |: y5 C" P
                                        return false;% }. F3 i( F. ]  G3 `( _( i! l8 ?( \

' s0 |( U5 r+ W# p* M                                }$ b6 Z2 Y, c/ p' D) X- w( Z

% _5 o& m$ L0 V                                if(511<point.first+max.width+char_spacer)7 S2 o2 s7 W4 ~( y

9 A/ S; L  F" s6 f                                {5 t: `4 d* R8 g' T2 Q( q

% T8 B8 h# b  u8 \1 D                                       
7 B9 N+ f. t- C/ ~( T$ y8 R4 Z
( P) x- z, U% `! ?# J                                        point.second+=max.width+char_spacer;+ t& F' [# K2 u) T
; p+ x8 T) r6 N8 d
                                        point.first=0;3 ~2 z6 J7 H5 a" K8 H# }5 N

# ~4 Y' M: H. [  R% Z                                        if(511<point.second+max.height+char_spacer)- M) F" I# i2 S; L8 ]
( M: U) y0 g5 e: s* x, [
                                        {
" k6 r, I# K: W9 ^3 j& N, _( f+ M) p  K4 q5 P, \2 l
                                       
+ E. O. V; j- [+ F) B# Y4 Y5 p9 ?. K# Y4 }0 E1 b9 b1 j2 T
                                                rect.right=rect.top=rect.left=rect.bottom=-1;
+ p- B3 o1 [$ |. U; h1 a6 U$ j, H: z! G8 X/ h8 p+ T" q4 h
                                                return false;
1 u9 \: `, c6 a; {8 x
' ?+ i' e! I  z9 _                                        }
0 Z7 H" Q4 `- U# f, i  `5 E( P( r4 P7 i  ~
                                }
; ^8 ?4 K& @3 Y" V# ~4 p3 [' ~5 R2 R! V& m! V8 O& v, B( Z
                                rect.left=point.first;: T: Z0 C0 y/ f1 v% K" S: x( U4 [
7 ~* R! {1 U# a. b
                                rect.top=point.second;
) W8 U) Z3 C- N8 _8 b8 U, ~3 N4 l$ r7 b, i
                                rect.bottom=max.height;. r, d* E0 _3 N# y
" p( K' o$ c# @. t" j
                                rect.right=max.width;
* g/ Y. x1 }7 A, F. v
- i- V1 h: C% \5 D0 c/ A' k* g                                point.first+=max.width+char_spacer;( V  w( }9 {, Q: w. ]. G' |
* ?' _# {" e2 W( P5 M8 I
                                return true;
7 @+ i( P7 R6 O1 G1 M. d! l/ u( p3 _" ]7 S6 D1 C
                        }
/ e2 N, y" Q, L) i, R5 ]1 N
" ^: h( ^8 i) W                };( N$ I' }, b2 J7 d
1 `, K, L' V# ]$ Y
        上面的类定义在Font类中,在Font中增加 TTFMsg * mTTFMsg 数据,并在构造函数中 mTTFMsg=new TTFMsg;. j. C" ?# s/ d' {0 [& D0 G

+ l2 o3 Z% y7 ?( M4 ^' _        
+ I: g( t" b/ `' F$ ~5 r9 a7 J5 \7 R8 r- g3 ^8 i
        正是修改void Font::createTextureFromFont(void);函数,主要几点,首先是分离出很多变量和构造到TTFMsg类中了,然后是贴图从2^n*2^n变成固定的512*512,为什么要这个数字呢,因为256太小(废话了)。能保证512*512大小的文本区不会出现不够画字的情况(所有英文+符号+没有重复的汉字),这个安全区域基本上是够用的。(什么,你要画满屏幕的汉字?哪你自己看着改吧。)还有一个重要功能是,要找100个汉字,找出最高和最宽和最大空隙作参考。修改完成这个样子了~
* A" u9 \9 g- f0 F
# M8 i4 t1 X5 \: U# B+ _) a    void Font::createTextureFromFont(void)
3 d1 ]2 L: }( J5 h, V# m0 P1 I) l6 w! q1 `, H% }9 n4 Y4 x
    {4 |9 {8 K+ c$ l0 H8 l  w

8 ]1 V7 P$ z* j- y1 {( u% s9 v        mTTFMsg->init(this);//初始化FreeType2
2 r! Z$ s0 c: u  z( F  ?6 t/ ?6 Z
        uint i, l, m, n;
: [6 ]* \& \* t" }! U6 @# P
- d$ Q4 [& F* \1 |3 {/ I        int j, k;: h% t; H5 ^: x% R

( E/ j/ |3 M( K& w2 o3 o  ( j0 E: L; h% Z) n+ G

. T2 r1 f2 q. c! p3 Y      
7 Y1 U. B) f' Y
0 U. i: U1 w/ R+ ~1 t; K7 a        FILE *fo_def = stdout;//啥意思?我看不明白
" y; Y0 v$ g6 s" i
+ x7 I- _3 d2 e* H: r2 u  4 Y# m) \8 r3 S- x) T

9 }% x* w- i' r; _, S% E/ O9 o        int max_height = 0, max_width = 0, max_bear = 0;6 ~+ F/ _; c" c: G$ Y

  S1 h( U" Z& |5 }: C! c  H8 r  
% r4 f' E/ Z0 g2 T2 S
( e% z1 X4 W+ y! J        uint startGlyph = 33;9 |$ Q+ G) u( k

( m. T# \; I/ e# X        uint endGlyph = 167;' o5 I( H( j* i/ T. b
1 K* k$ x' F0 t" @, G- W
  $ g# w8 V4 ?; C5 H" M9 \

) ]7 p: V* P" I- r        // 找英文的找出最高和最宽和最大空隙
) Y/ S; [& x6 U* y- f
6 l  T8 q8 p  H  x2 A        // Calculate maximum width, height and bearing
  x8 ~; z0 P9 H& A* v  u7 W
3 c/ J! P+ {( U- J7 U. n- S! V        for( i = startGlyph, l = 0, m = 0, n = 0; i < endGlyph; i++ ), ?0 n. g3 D; I

- @, b& ]0 X1 A! b        {
5 k3 a1 G" d; b- Y% }1 |9 J' }0 n: \2 l, v
            FT_Load_Char( mTTFMsg->face, i, FT_LOAD_RENDER );
- m  J# N2 Z  f- K
8 ^+ U" D9 B7 v0 i2 Y9 F            //以后的 <<6和>>6都是FreeType2中的数据和我们使用的数据的转换 , s+ s: @& }) i9 c+ D' u
( E6 ~0 S* p$ w( G. ]: X# i
            if( ( 2 * ( mTTFMsg->face->glyph->bitmap.rows << 6 ) - mTTFMsg->face->glyph->metrics.horiBearingY ) > max_height )
5 `, s7 l/ |9 {4 u9 A
- H+ |; h2 K4 x6 M; b0 S                max_height = ( 2 * ( mTTFMsg->face->glyph->bitmap.rows << 6 ) - mTTFMsg->face->glyph->metrics.horiBearingY );
9 G) z/ ~9 ?$ z, p5 C8 h
- |3 V; b; p; Y# d2 o4 r            if( mTTFMsg->face->glyph->metrics.horiBearingY > max_bear )# K( g9 }  f3 \2 ?$ v1 A4 o6 m

) b% z4 [9 b5 X% a                max_bear = mTTFMsg->face->glyph->metrics.horiBearingY;
) i" o) K& g8 {3 t5 E% @6 u2 G' P. w% i  V; G4 ]
  $ Q4 ~% o+ V% z7 }- ?) W) v

$ p1 a; c. q( e, ?            if( (mTTFMsg->face->glyph->advance.x >> 6 ) + ( mTTFMsg->face->glyph->metrics.horiBearingX >> 6 ) > max_width)
* p- o" C! X# Z$ _) e8 k) @5 l& A% x( P9 C! ?
                max_width = (mTTFMsg->face->glyph->advance.x >> 6 ) + ( mTTFMsg->face->glyph->metrics.horiBearingX >> 6 );/ v$ |  w) G1 u4 W

1 y$ A8 j( d& o3 w' G  C        }
" ^0 H! }" }/ W; m4 ]6 G9 L6 G% V
  $ q: R, t$ a& Z
- Z0 @& [$ G. P9 x" O- f3 f
  
+ j4 ?" |! B0 u( o* s6 I
% n* t. Z6 K, G  n4 h5 |        //下面的for是找100个汉字,找出最高和最宽和最大空隙作参考。姑且认为最的汉字就在这一百个里了。 . k# h5 w! r! ^& _$ d1 [

5 E1 L3 Q( v* @9 X8 g" n        for( i = 20643, l = 0, m = 0, n = 0; i < 20743; i++ ); M1 E/ p% z0 x6 G. a7 H

' b5 Q: s; n" d% h5 }        {
  t- l( I' X6 u8 W& j6 z* B
, }: U, D% {3 x* O- ]            FT_Load_Char( mTTFMsg->face, i, FT_LOAD_RENDER );
: ]; M8 I! x4 r- c& l" ^
' p( e& L4 M9 v5 H$ C. v; B  1 Y+ W3 W( c6 ~. |" l$ a+ E

( t$ w1 _* @0 h" N, e            if( ( 2 * ( mTTFMsg->face->glyph->bitmap.rows << 6 ) - mTTFMsg->face->glyph->metrics.horiBearingY ) > max_height )
, n1 _- ^, f0 A  Y- s! `9 M3 z) w
                max_height = ( 2 * ( mTTFMsg->face->glyph->bitmap.rows << 6 ) - mTTFMsg->face->glyph->metrics.horiBearingY );# k+ G' t# t0 a: O  A. X. B
0 l, ]" g% M  r
            if( mTTFMsg->face->glyph->metrics.horiBearingY > max_bear )% i; w  L# L. ?8 G$ W1 t+ z

1 h1 M4 f7 t, a6 _                max_bear = mTTFMsg->face->glyph->metrics.horiBearingY;
3 @4 J8 `  `% r* C+ `& a  M/ Y7 R, B% p* |. }1 ~7 A
  
5 M) ]) C* o9 U" C% Y
# N- o9 h& j' j* _4 H- V8 B            if( (mTTFMsg->face->glyph->advance.x >> 6 ) + ( mTTFMsg->face->glyph->metrics.horiBearingX >> 6 ) > max_width)7 x* f' r3 j0 f+ U; a
: v+ I- j0 J+ F1 P! _
                max_width = (mTTFMsg->face->glyph->advance.x >> 6 ) + ( mTTFMsg->face->glyph->metrics.horiBearingX >> 6 );/ y3 m+ F* _; v: V5 K
* Y, d: \) ~! w! @7 k
  + L9 e) e* q9 [- N- h
7 Z6 s: a/ Q8 W
                        
) Z' r/ k3 e1 E: j+ W, q) Q8 u2 g
6 I9 V/ V7 M4 r2 j% z  P3 ^. q6 s+ |            if( (mTTFMsg->face->glyph->advance.x ) + ( mTTFMsg->face->glyph->metrics.horiBearingX ) > mTTFMsg->max.width)' I* h- s1 Y2 `! ]% |7 B6 O
/ i6 K( s4 {2 E- Q% @
                mTTFMsg->max.width = (mTTFMsg->face->glyph->advance.x  ) + ( mTTFMsg->face->glyph->metrics.horiBearingX );; `) c8 f$ v; K4 V
1 n2 e7 t1 j7 r( v
        }
* L6 Q' U* _) m; A5 k: M) I# w# k, ?- h8 d1 x- P& F" h& a2 l
  
4 m+ x& }/ }) q! y2 `  w; {2 h
8 z& Z; K& n7 T                //下面几行行不需要了 我们要512*512
2 ]  ?& Y" A" `8 x  N9 P! a) E$ L0 A8 h% R- W; J" F" {1 R  f' N& u
                size_t tex_side=512;//就是这个了 512
  G* t0 Z; f' `) g4 w2 w4 ^. f: c3 c# B6 a. a  r5 P! {! a% _7 T3 o& _
        //定义数据宽度 因为是32位的位图 四个char为一个像素,为什么要位这么大呢,难道不能用8位的么,我尝试着改来着,不过改了之后就不透明了。望高手看看能不能改。
& |# f! H# b* ~" T4 A
5 [+ ^/ g# Y- \* O) h# _$ s: i                size_t data_width = tex_side * 4;' X; A( ~9 g- s2 N; F1 r
9 h& ]6 i" s5 Z. H
  
( H9 E  s! _" X9 M. l* u3 j9 b+ s+ T: E2 k  c9 d9 ]
                LogManager::getSingleton().logMessage("Font " + mName + "using texture size " +  C" q! b0 R) r% x7 c& c$ `
# q) m$ K$ J+ l! D2 k
                        StringConverter::toString(tex_side) + "x" + StringConverter::toString(tex_side)); ! ?2 u; q; P* E$ o) V+ L
  d% n; \7 v/ Q/ f# m8 `0 U1 x- f( V
  
. e! Y2 G" K# E' e+ \4 R" W) d
0 E8 E" G; Y! U' A        uchar* imageData = new uchar[tex_side * tex_side * 4];//设置一个空间用来保存位图 % l& ^* p2 Y2 y' W' L# d, P9 B' a

2 d6 T8 \9 W( g; h# H3 \4 w3 V" m                // Reset content* Z2 I5 v" D- A5 D
1 _- \- E- e' o. e! A& r2 Q. \6 H
                memset(imageData, 0, tex_side * tex_side * 4);//清零
& o4 h; M3 }8 J* A7 v7 j
9 O& u. Y  w' ?9 t, H$ }  
6 Y% \) _. T; ]+ h# E$ U
+ E+ S" c8 P( }        for( i = startGlyph, l = 0, m = 0, n = 0; i < endGlyph; i++ )//遍历每个字,
4 {' h3 R8 c1 k) O  t
4 L3 W$ e( V: O9 p( j& m0 ]  g$ c        {' M2 Z: y' ?9 ~4 z9 v8 L" e
' T) M# \! N1 O) L4 }
                        2 ]8 D' A1 S) z" |  Q" n
* w$ ~9 S2 ?, q+ M7 _3 O6 J% n
            FT_Error ftResult;1 t% T! }* R- J
( R" f9 W& G! L' F! L+ f5 p
  2 w, v/ w- |5 `

2 J* U) K3 P* {4 j2 c; ~9 |            // Load & render glyph   I" h3 A: ?1 s* q
- s$ u" r) m* n" M0 N. x$ I
            ftResult = FT_Load_Char( mTTFMsg->face, i, FT_LOAD_RENDER );//读取字体
4 \( Z  z/ u' R% Q0 l) v0 d
% d- I# A1 f" q! C            if (ftResult)$ m3 D5 B. U3 p# d. i6 j6 y/ j9 w
. Z3 S3 y" @$ P. s% |
            {, f& s$ t0 A7 ~7 a3 h
: z" Z  t0 f4 w# r
                // problem loading this glyph, continue
# j) }- z. Y' X" ~! J8 z9 z. }: ^& N5 G0 h! w2 Y  T% o9 T
                LogManager::getSingleton().logMessage("Info: cannot load character " +
, T7 [0 |# J& ?  M7 }% v8 ^4 V6 q1 ^4 K  Q5 n* N
                    StringConverter::toString(i) + " in font " + mName);
4 |/ q; R" j; {  @
3 Z5 I9 V+ L( T6 y                continue;//如果错误跳过 . Y0 ~6 A  o0 t- W* k' l* q- K
7 a9 h1 f, T) c
            }
; @# F  Z7 E7 [3 S- n
" r* k" Q+ q+ S# o1 X: V  8 Q) @8 ^3 M: m: n  E- ]6 Y
: X- a$ N5 _  R& H' ^
                        // 应该是字宽 8 {2 ^7 k( O; B7 i& W, M
- ^) z9 ^9 z9 i
                        FT_Int advance = (mTTFMsg->face->glyph->advance.x >> 6 ) + ( mTTFMsg->face->glyph->metrics.horiBearingX >> 6 );+ R8 t0 C  v& h- w* H8 \  p
) J, ~3 [. L& Q: y! t
                        1 z4 N+ D# i. @8 A$ [  t$ d

. c$ C' Y( B+ s' y& v& z! P                        // 得到FreeType2的位图
4 q! G- {( [0 E, m0 `, C
+ K8 L( m9 I8 L6 B            unsigned char* buffer = mTTFMsg->face->glyph->bitmap.buffer;
( N8 D9 f( ~3 {& h8 c# \+ b
2 ~. b- ]& ]0 i' ^5 l& `8 B( P  x  
" G1 S7 e  Z0 a- L) r0 Z) v7 W( I8 I$ F$ q
            if (!buffer)
1 F& [6 u) H7 j' l" `( S7 R* d/ i8 L  ]/ s4 A5 O
            {
0 n. i! ?0 h  F$ i+ p
3 n1 C  Q$ X% B) W. \                // Yuck, FT didn't detect this but generated a null pointer!
0 ]  Q2 T. |' l$ S" E( m0 C% M; a7 P& B0 U
                LogManager::getSingleton().logMessage("Info: Freetype returned null for character " +
9 ?0 P3 r- }% f) j% [; {- Q: y8 E8 L8 b
                    StringConverter::toString(i) + " in font " + mName);7 c4 C4 T6 P. ~& u5 `3 M2 A9 o

9 j9 `; i- D: k1 D: Z( D" X3 v; p                continue;//如果得不到跳过 0 m+ |# M2 z9 a; n% m/ W+ N

2 U9 H" c: w; }1 ^# T, n6 r            }6 h; E- m/ I' t# ?% \9 o

9 _# {& b. W" T, Z7 F3 F8 P; x5 l  ; U4 b) g8 q" J4 f  P
2 u& D# ?7 e4 N1 p0 p% ]  V2 f6 h# i
                        // 得到y的空隙 (最大空-空-本字空)就是说空出这些字底部就平了 7 Y, I9 O5 o  ]
* f2 r2 c" R% e* u
            int y_bearnig = ( max_bear >> 6 ) - ( mTTFMsg->face->glyph->metrics.horiBearingY >> 6 );
1 r8 E" R# L( o' e: {! D
/ i. F! z+ U1 @8 w* D8 b- ?0 F                        
' t$ B0 t9 J" L) v; L
: H/ T% u6 G, ^& G$ @% N9 ^5 D            for( j = 0; j < mTTFMsg->face->glyph->bitmap.rows; j++ )
& {% L! L9 g: Q6 e5 C1 E6 K& x4 o. P9 m* D
            {
( B" G3 L' I0 ]9 x& H
0 r0 l1 u( d! d2 n+ T* G' d4 z  D8 t# ^                                int row = j + m + y_bearnig;//相对行+本字在位图的总行+空隙
! g  H- t. i: K% S, j8 o# v
$ ?$ ]: Y0 }( L3 ^3 X% g                int col = l;//列 # W# b. S. d/ M! m7 t0 k
& a4 X3 r; x5 u7 \! H) }
                uchar* pDest = &imageData[(row * data_width) + l * 4];//找起点   ) f: q8 ]  T& a! L$ R; t
0 t- d9 M3 |" H* q  W
                for( k = 0; k < mTTFMsg->face->glyph->bitmap.width; k++ )//画图   u8 u3 E) J: u5 C. d0 }

8 M4 g' a9 o' K                {
( K  M) l9 X) g( g- {8 M3 {% P9 G4 u: j3 I, Y
                    if (mAntialiasColour)//看不大懂,难道是灰色字体?
" o4 S7 ], L- J$ R' u* o" h1 C) U. A8 h$ a: U
                    {/ A* U& D, a: ]7 F
1 ]( N4 M+ G" X; G0 K, ]
                        // Use the same greyscale pixel for all components RGBA ( c5 a8 s% t0 J1 v$ g. L

  x2 v  o( C1 K1 u. z- z                        *pDest++= *buffer;
+ ^! c+ P1 ^: `: T) M( a" `" G$ k
                            *pDest++= *buffer;
  v, o9 D( u+ e# ~1 ~2 _& a0 e+ d/ y2 t  [. i% k  w
                            *pDest++= *buffer;/ S- w: ^2 S: j) P& d

* b8 I+ \( O' l# {                    }
) H- c& B' f7 s$ z
0 A! _0 Q: Y4 h/ f6 l                    else   l/ D/ w3 d. j: w) z6 |$ Q" L! [. k

: ]0 Z$ q; r; G: J. T/ S  @                    {
, M/ e, ]5 D% O3 C- G4 Z
4 J# B8 \, n/ ]& Y8 d# m" W                        // Clamp colour to full white or off
- j+ _, Z( z" M  I, X9 J
! r1 n) H* w( y" L) e8 l( y! B! W                        if (*buffer > 0)
& K2 u& I5 G) M. D: O4 y, x3 W' S1 g; A4 S+ J8 R
                        {1 n; ?7 A; O8 X* O( S

. k; K, Y; ^) P/ h- ^+ ~# a                            *pDest++= 0xFF;+ Y' m) V, S0 c& w) r  J( k

' {$ u1 ~; k% n. R, ?                            *pDest++= 0xFF;
/ {2 G' ?  b/ p+ N( Z/ H
/ t) u" S# U4 \                            *pDest++= 0xFF;
: F2 ~8 p& K: s- }  q1 O9 g% b) ^0 `) B. o
                        }# l: h1 F$ R! k1 X
8 c. \8 |0 M0 P% Y, O; L
                        else ' ?' ~+ \$ e% U' j5 q
8 u6 a5 p( {2 b1 ^
                        {! F! Y0 R: S5 a1 H" q& u
9 r" j; K- S* u' h9 W/ ^# s5 J
                            *pDest++= 0;
/ {' i+ X4 d9 ?5 e
" `+ e3 Q$ P4 ~, m0 C  j% J                            *pDest++= 0;, w$ A- X) \- G/ O, t
3 P: \4 L7 R8 k* g. N/ J& O
                            *pDest++= 0;
0 l/ ~/ e/ K9 S  ~" A5 o; V
7 ]/ e/ W1 B# u$ v: M, d. K                        }2 T7 ]/ P5 n8 \2 |
6 I/ k0 c6 |' e2 B  A
                    }3 b! F, u8 z  _6 c  x" M' \6 v
/ x& h& g5 Q7 _! t* U0 e+ w
                    // Always use the greyscale value for alpha 1 P! F) w9 u. L" j3 }! J! ?
9 v6 ?- |7 u, d% o" q" H
                                       
3 L% D: O  e( `3 H. T/ C4 Y; @0 Z% r' m
                    *pDest++= *buffer++;//alpha! 我是一点不了解了为什么是这个? & ~' v; ^3 B- M. f

" c- V* v$ j- a. ^7 j( m- ?- v5 K& P                }
; j: c$ E: B4 I, u2 {" E$ e, S9 Z0 }( a: C% L! b% F
            }$ }: T6 l! U3 E; d+ C

: z! f+ K6 D, p# B5 }. ]- y+ \+ F  
. v" v3 b, ?7 S, i: }
5 g. X3 m; k4 l5 i( x& w  ~            this->setGlyphTexCoords( i, . w& ]0 r3 y: g8 ?) q
# X* z5 g3 C6 u7 X  D6 {
                (Real)l / (Real)tex_side,  // u1
# k6 H5 g( M- g+ B' u$ ^" e( ^* c5 M
                (Real)m / (Real)tex_side,  // v1
+ B& [8 `% A( z1 t) W- f
$ O% A2 K3 g2 k                (Real)( l + ( mTTFMsg->face->glyph->advance.x >> 6 ) ) / (Real)tex_side, // u2- o4 V4 O; L3 m0 `1 g1 b5 O

. y. u* i6 R  l4 B+ E) y" Q                (Real)( m + ( max_height >> 6 ) ) / (Real)tex_side // v2/ g) @! M" r$ \+ x
: O6 h1 X' K9 O' I% s8 D; T
                );//设置坐标
$ `9 u, \, C, L& C  ~" u
& b4 u/ h7 [( M6 I) @3 t& D* p6 l3 R  ( p, s& c* C2 K' a6 B

- E* R% k" |: O+ K4 J7 c            // Advance a column ) T* S6 B& M$ |, L. W, ?3 d$ ^
# i4 f' J" l$ w7 e% v9 d
            l += (advance + mTTFMsg->char_spacer);
& |4 F/ \6 _$ V+ a* w- [+ \3 b& ?/ ?- _1 v0 V* _
                        //l+= 本字宽+字空
, d+ w& u7 E. Z- k. M( q! o1 E& k3 L0 g4 b8 x2 o, a9 L
  # Z  o# V1 \: @5 _( B" F

8 Y+ J0 A' M; L0 t            // If at end of row ; c& [8 W+ t+ K' q
: O/ ^7 D6 n# C8 _) b. h( W
                        //如果到头容不下一个字
% x  |  ^, x3 P( W) x7 Q
/ z0 ]0 e# m0 k" k/ F            if( tex_side - 1 < l + ( advance ) )
( b$ H7 N) l4 o$ i4 S% S
8 w/ h: Q, V( Q& D+ T6 I7 x* T0 S            {
( f3 I/ _/ H4 H2 a2 I4 B" ]- p- H$ t/ a8 B  R  E- s5 y
                m += ( max_height >> 6 ) + mTTFMsg->char_spacer;
0 j/ f% Z2 E5 s( K1 I* _3 u/ b6 J3 N  C! b
                l = n = 0;5 U. d+ x1 t7 I7 U2 z; O# b
% N: s$ ~4 |! d* e- j6 n
            }
" p  W- ~/ F2 k7 B' A5 P9 \3 L$ p3 h2 \  _/ `0 j: o
  " D. W0 E' E1 u, M
& a# v5 G3 l1 p  f$ b! l2 H
        }$ f4 K  j- V0 x9 G8 o" E% k
( x0 [- y% H7 z- V- j- C! d
                // 把信息存到我们的mTTFMsg中 >_<# E; n/ n0 W# \. w% [$ C

" V! e) z4 I) O+ R. I1 v                if(l), |, l& w2 @7 K4 g6 w6 \
( p+ I  j/ f$ V8 c1 Z5 q9 m8 c) x
                        mTTFMsg->point.second = m + ( max_height >> 6 ) + mTTFMsg->char_spacer;/ x1 G) ~3 b/ @8 X* _( Z1 ]

2 a% i8 Z: t* @% x6 W                else
; }) d6 G6 k+ D& y1 X
2 x3 R3 r! f6 n1 I8 L/ W) u                        mTTFMsg->point.second = m;
; k7 Y0 E. w$ f2 V7 `
5 c$ U1 l* c7 G+ P4 i4 C  
, O1 w, o1 |" S  B' r. o: f! i* W2 x, T$ D- `* V
                mTTFMsg->point.first = 0;//另起一行 + F- Q. N8 z: }) {$ B$ h! e$ ^

8 `7 u* u' k6 b9 F7 s  
  ?$ P. p4 F# z& _) M1 i/ j5 w# _8 n6 D6 V
                //下面是保存几个最大。 $ h$ `2 v1 _( Z3 r' Z1 [
- j3 ~" C! @0 K
                mTTFMsg->max.height = max_height >> 6;
/ i1 _( ^7 U* h' a8 b$ ~% _2 q& \, _8 Z0 J$ A
                mTTFMsg->max.bear=max_bear >> 6;
) e  t  s2 I4 R' V- i* d
7 v' w. k8 N, ]. q                mTTFMsg->max.width=max_width;
/ R/ i8 N6 v: \; a2 k. V3 e1 _7 |9 I3 _6 _
  
# G+ ]9 u/ ~  x* Z6 D
0 ~' |2 ]& P) X  o, y1 A$ ?                mTTFMsg->imgchunk.allocate( tex_side * tex_side * 4,imageData);9 G3 N0 Q7 I. s4 ~, |: @
% l. v' W* a* m8 \, d0 \* e
               
; z( A( O  x  }2 q% W
+ t1 a+ d! w8 w                //不知道为什么要设置img这个中间变量,似乎可以直接从chunk创建贴图 % N6 ~& x  f4 K$ C3 I/ t
2 F7 f* Q9 G8 e* E& P" k
        //--Image img;
" j1 E. P- X9 n2 v2 X
* H) V6 q; O% e0 c% g' w                //img.loadRawData( imgchunk, tex_side, tex_side, PF_A8R8G8B8 );
9 c+ m" [5 p# d) |/ o8 E: I7 n* \3 G9 ^
  
" q3 |2 J# K2 a0 \3 w' T
, D3 }$ e* M! T                //贴图名 6 o9 f8 C0 F0 E4 }$ Q: [' p$ H8 A

( y; ^) U1 ]+ U! b4 x  K        String texName = mName + "Texture";
/ u" H$ L2 ~, F. h( w: z' s; J/ U' S0 o5 F# d5 J( r1 V) v0 \6 y
                // Load texture with no mipmaps - d2 b" d  n% F; @* Y
7 i- [+ f9 c& ~; N8 a' Z
        // 把从img创建位图改成直接从chunk创建贴图
& O/ h4 X4 Q+ N5 \1 [7 Q3 [- ]& g$ Q* a0 x1 o  l7 L
                //TextureManager::getSingleton().loadImage( texName , img, TEX_TYPE_2D, 0  );
% B0 A# m( ]# P$ J' H$ j, d# Q% ~) u
                TextureManager::getSingleton().loadRawData ( texName , mTTFMsg->imgchunk,tex_side, tex_side,PF_A8R8G8B8, TEX_TYPE_2D, 0  );
6 k/ _3 M6 e. H9 X8 u& |
$ |: n9 R( C# M, g        TextureUnitState* t = mpMaterial->getTechnique(0)->getPass(0)->createTextureUnitState( texName );) d( g/ L2 H; f, G% b$ f
6 ~; p$ h! u; Y/ j3 t3 Q
                // Allow min/mag filter, but no mip / m* }! C2 P* j6 z% a
" Q7 r+ ]) L) O5 I' ^& Z
                t->setTextureFiltering(FO_LINEAR, FO_LINEAR, FO_NONE);7 Q' L/ H% V. d) b) k- O

4 e/ a5 o  _+ e6 P7 B3 Q        // SDDatachunk will delete imageData
# M2 }0 L1 S/ L, a7 \- T
. I8 [7 X! Q( e  K" X+ @        
- P" V/ J8 R4 S4 Z0 @0 k% D8 a& R0 r0 G% c
    }
  o7 q6 U8 [9 m! }* x* @6 b1 c" X' L
        你应该对照一下以前的函数,改了很多的。
8 u! r3 g$ |0 R- n6 i, t& L# |9 |! n( J
  * }; f2 \; H; Y9 ^

4 L0 J4 r7 o8 b' T$ O4 x( {; d, `8 `  / O0 f2 ~- [3 L! T( V

0 G( g& \0 j$ S6 n(3)
4 V: j9 X, j# y1 W0 o8 k) G* A- R# R# y( r
        然后最重要的是动态的申请和画字。 0 l- P- m9 F* o4 v( J$ z: f

1 S6 D; d. p7 n! }" ?! Y$ q        首先最重要的是我们要一个方法得到汉字的unicode码,我们用到了unicodeMap数组,提供了区位码到unicode码的转换工作,等一下提供这个表给你,好不容易从网上找到的阿,可惜这个表没有中文标点的对应,如果希望支持中文标点,就要努力找到unicode码并加进这个表了。这个表是这样的 char c[3]="邸";unicodeMap[94*(c[0]-0xa0-1)+c[1]-0xa0-1];就得到邸的unicode码,不知道为什么没有5165~5169的unicode码,是轮空么? , X6 J4 ~& e0 v0 |- r  [! B

4 @9 w: c, @4 u$ Q( y        # c/ W# J& p' F% j/ A9 |

0 f6 X: Q2 R# k8 M' O        申请渲染(字)
4 V( x+ H( D; \9 i
  k5 f& A  c5 C8 T7 y& L! Z        {
& j7 l  w$ B7 q% a7 i) U( }* |4 o, G% v: L6 q
                if(有这个字). h9 S( A! d0 Q  z4 z
& j0 C/ e# o+ F5 j  C) r
                        返回位置 " b3 C, a' d3 L; ]- v9 d2 n

5 E* y4 N3 m* W/ ~) X4 p( o                else
; S2 b" j# Z: a! L) h  n: P+ |$ f
                {
. I" Z7 Z. n% ?& m( @: Z: v' y( e# g  {
                        if(有空间)
+ f5 V2 b8 I9 }0 `8 r  V" G" D+ `
                                画字
0 q: {( ~/ w: @: X2 s5 b& Y
! u7 X, p# Y# r: u                        else- {. B7 I, A1 F7 G; w

& y9 e; M2 `1 i1 u) ?0 F                            找不用的字//找不到就出错,没地方画了 " l& z6 y3 [5 Y3 Y7 u( ^# [
5 P% \) g) ?* V9 z- q5 a0 u" p
                                删除 在这个位置上画字 2 d4 W0 P, H- I8 ^8 T% ~
2 {& k+ f% O, A6 e# n% \) @
                返回位置
7 j. h5 _7 r# r" _8 y5 I
/ T: g# u* F8 W$ W% n/ n3 X6 }                }
" p* b3 d9 O1 I0 E, x6 F+ f( ?  j) Y. Z3 T' {
        }
, D* y% l3 Y7 e* C( _) p/ S. C3 Q  f4 s/ {' l) S
        上面很直观把,大体就这个意思了,申请渲染的函数是inline void getGlyphTexCoords(unsigned long id, Real& u1, Real& v1, Real& u2, Real& v2 )  const。去掉const改一改。得到
9 A& _% [' E7 l+ Y2 x. f) L8 D4 s: q* M- }
4 ]# K' w6 w7 Z4 ^& h6 C& Y        a.申请渲染
# |5 X: |. f9 b9 F. \. W. X! W- D+ R3 m3 J/ Y: J  j/ L) l
        inline void getGlyphTexCoords(unsigned long id, Real& u1, Real& v1, Real& u2, Real& v2 )         3 e. u* o! ]/ `- i$ s: S
& S0 O6 ?  I' ~1 v6 p- n. x* v
        {
- H- `2 b) U7 a5 l
. Z+ Y3 C2 b! T                unsigned long idx = OGRE_GLYPH_INDEX(id);% g% y9 o& v/ `3 {, ~1 {% W9 \

  J5 R; R7 M5 w/ z6 ?                if(this->mType==FT_TRUETYPE)//ttf?5 N" F! ]' d. c+ i- l% {5 z9 G

5 \+ W. ]: W2 n/ R8 j6 A                if(id>=161&&idx<OGRE_NUM_GLYPHS)//汉字?6 _4 Z7 g% G7 S, M" ]

2 ?+ P+ y/ i% s7 p# S/ s                        if(!mTexCoords_v2[ idx ])//没有?6 }1 ]: `& e, z% L9 O  R' }
1 W' b. I* p+ o& k9 i  k5 X9 W
                                setChar(id);//画字去 9 ^5 G4 f/ D/ ~, F# Q8 s# m
- s0 u' w3 j6 p( y4 ]6 |; L/ _: X, }
             * O% ]3 A# W& B4 Q1 b
% Q# V1 O7 P3 D* [' D4 O$ I
            u1 = mTexCoords_u1[ idx ];: U; Q; ^: p' \. {

" _2 c7 ?7 t( X8 R( l2 u& z) c# `            v1 = mTexCoords_v1[ idx ];+ z7 f- u$ W; [% R2 e( {/ d1 [
7 W! J" X, U# b! F( E3 Q$ a
            u2 = mTexCoords_u2[ idx ];
$ x. `' e& |2 c, c
: B: l  z; R: p9 T- }) P. U3 A  A* C2 y0 g            v2 = mTexCoords_v2[ idx ];% g* _3 H' z& H. D
9 \1 `5 H$ E0 {9 J7 D
        }
7 R2 p/ k: T' ~& I
' l; {3 Y" p9 z7 _        b.画字等
, h  c# f: }( |: d
" y, }5 `" B+ }) L& d# U        bool Font::setChar(unsigned long dwChar)
9 R/ v$ e4 U. L* V; d5 p- Q$ T" {( J/ ~8 z9 C
        {. O- J* s+ x) ~5 R# e

  q1 m' M# j# l8 p2 S: Q2 @                int j,k;  V. I0 ~- V0 q5 B  U# }
- h/ y' K; n+ D' }5 U
                uchar* pDest;//操作数据的指针 , w2 ]+ G% _  ~0 c9 L5 c$ C7 O5 D
  Y/ v( m; b  E* |
                mProportion=0.8;//不知为什么,总觉得中文都太扁平了,所以设置这个参数,在《让OGRE支持中文》中创造的参数
6 [- A% i! S) \3 D9 q  d/ v' }1 E& I7 e5 U+ @
                Image::Rect  rect;//画字的位置 $ G( w! V( V$ X1 W# W" Y/ s

1 f  @; k7 S1 _% v( B  s  p                if(!mTTFMsg->getRect(rect)/*回头看看这个函数吧*/)//如果得不到空位置   ~, W3 Q2 U0 u# Q
( V: f3 Y1 B8 u- t+ X: _
                {0 A: M0 V# s. T4 I$ z+ v

% I. V7 s# j$ C9 f- @" ^- `                        for(int i=161;i<OGRE_NUM_GLYPHS;++i)//寻找不用的字
- E# H/ Z8 q3 B2 U/ l9 @5 d2 v( m' u8 ?: e
                        {
( Y0 P; Y( T  M  A2 o: L3 h- H8 L" u
                                if(!mUsing&&mTexCoords_v2)8 r+ l: {8 |: F; S- b$ o: a

; _% k) U9 q* f" U/ C                                {
/ b' G. F9 N; T% u
1 h+ ?- R! v0 t! P5 J/ r! K6 |                                        // 得到坐标 ' [/ e& d( q, [! B5 p. J
; s  T/ B3 Y/ \! f+ A0 L: d0 P
                                        rect.left=mTexCoords_u1*512;0 i/ S& H* f9 w3 S; _
9 }+ d' t8 M2 Z; `/ U, ]- H) S
                                        rect.top=mTexCoords_v1*512;  U( S: B. q% l, U# K8 m$ U$ o+ {

3 ]* k( d- s+ h" r0 F                                        rect.bottom=mTTFMsg->max.height;7 n! f/ V8 ^9 P" k8 ^* [6 g
$ J1 j3 T8 e( M! G: u4 O9 |! x- p
                                        rect.right=mTTFMsg->max.width;
: B8 q. L4 M+ F& J& `) A
, _! a" Z0 N! \' P. T  {, g0 b  # N7 ~* R$ D4 \* W) y& [

' p) G/ q2 @1 b% p/ E0 ~$ [8 t                                       
: i" Z% n( z; t! w4 G+ y
6 ]5 p8 e: e* w) C9 ^+ U                                       
- l0 T% ^0 |9 u  d& S( ?9 E  @4 ?7 X7 @/ |, {) u
                                - M& N9 [  K" Q; b. a7 J

- B* _- i9 b: W9 ?* k3 y& w* a                                        //擦除(这段代码没有试验过,等做完输入的类在检查吧) * G# R* F% f) {, s+ u+ z3 ]

0 q) F/ z7 U% z0 b& v                                        for( j = 0; j < mTTFMsg->max.height; j++ )
" X3 D0 s: [0 M& p
: R6 p* F. t5 w$ k4 U                                        {
# t4 e3 U8 g* o3 a5 A9 c& p2 e; D
% ?: z& C0 \: O' d9 |. c                                                pDest=mTTFMsg->imgchunk.getPtr();
# d4 j' ~( s7 \1 q& T, D- J
3 L3 K+ D. r4 g0 p                                                pDest+=((j + rect.top)* (512*4)) + rect.left * 4;
+ R8 q) }) P  P  I1 _& J
) i6 l8 u) f8 H3 ^                                                memset(pDest,0,mTTFMsg->max.width*4);
# ]. N) h1 y8 L
4 F+ I0 d3 D5 N, `2 s: \                                        }3 h; I6 {8 q% g  I
0 z7 D7 p4 L/ L4 L
                                        mTexCoords_u1=mTexCoords_v1=mTexCoords_u2=mTexCoords_v2=0;0 c/ a9 w: `8 N3 S9 r1 K; j

! [" N$ H* Y& a0 G7 c  8 M, R4 L1 |. v& f' J
: R4 B9 m& j1 M1 `" @
                                        break;
+ u& ?* d8 K  M. T' L6 S$ D: X: G& p& u# R% X- N4 b- b- h- h
                                }( i  G8 v# `: P5 f  G

3 a2 k( Q3 L4 I; B2 p                        }3 _% J$ K( H$ ]

* d4 Q3 q9 Q: I9 y( w: w# O                        
+ m5 o3 S: P& c2 y/ c( H
5 B8 e) g9 s6 {' l: s  q                        if(rect.top==-1)//啊啊啊啊啊啊啊啊啊,贴图竟然都用完了,没办法了,出错了
7 q( n! `5 P8 h7 |
5 i9 m& v- G+ m4 Y                        {
5 {+ E& A9 @: S- V0 u$ H7 @% E, Y5 L  Z9 s! M8 ^
                                LogManager::getSingleton().logMessage("你太贪婪了,用的汉字太多了,这是对你的惩罚.");
; g' X7 G$ D8 _8 W0 G8 G; q3 q9 x1 N6 Q. i  r7 G3 Z
                                return false;* z8 W) k6 n8 e+ Q8 l& n

, f2 E* N& |. |" o7 v0 y                        }$ ~7 r# G8 ~/ a9 ]1 t+ C! I

$ \( @( g( {) e5 W        . h; l" T8 y. p- x8 N) e

$ Q+ R- T( x3 G5 L, f                }; c+ ?# @2 |* ]! K# _* v
# U/ F. F6 O3 A$ q3 S  M
                        * ?8 ]2 I( k& v4 `6 ~+ E

! r7 k, S$ a* S" }2 z: H                ( }: Y7 J& @/ q3 R0 L
! P9 U7 e: M. F/ Z" y9 K. b" W
                  //以下画字的都是招葫芦画瓢的, 1 T5 X9 B/ i/ L9 I$ T

8 r# x: |$ Q! d! F; u+ p, i                  FILE *fo_def = stdout;/ [2 [5 |& N' Y5 ?5 Z/ O5 y* f8 N

. a3 x; A4 C3 s* q0 e/ e                 FT_Error ftResult;
; E( H! L9 s9 z5 ], _' a5 x
4 B' _- ]% A3 c( ?+ i8 Q  
" S+ ^7 m% ^: z5 c/ Z/ u$ \6 Z
* a' t3 L" [- j" H, C9 Y# e  ~            // Load & render glyph ' X. m2 x* i6 C* Q

+ c8 W( J( E+ {; g4 ^& ]                  
% Q/ t% \& {7 [: ~* Y# J' f( `- `
' _1 r0 F$ z+ ?            ftResult = FT_Load_Char( mTTFMsg->face, unicodeMap[dwChar-161], FT_LOAD_RENDER );//读取字体 9 t3 c" M" \8 u# d6 f5 T; n

- v# [' s/ _% m- f$ P            if (ftResult)
( |( `. G/ `$ B% L6 W: Q$ r" P* z6 u! k0 M$ _6 r4 T
            {! C! D" b. p; v1 O0 {+ l$ _

9 B+ w( \9 c6 L  J                // problem loading this glyph, continue ( l; {7 @1 l8 `
' s7 z2 @* V) g
                LogManager::getSingleton().logMessage("Info: cannot load character " +8 h8 ~  a; {2 q: Q
- O) _* u* @6 _) _
                    StringConverter::toString(unicodeMap[dwChar-161]) + " in font " + mName);$ A1 E7 i4 O- g6 |+ m" U& A8 B
2 u4 G2 D' q3 g, x! s0 R/ A
                return false;//如果错误跳过
& a8 c- Q- @8 I4 z" y, y6 y: N; u( f) k1 `$ C5 ~; Y) K) Z& ]
            }
. e3 r/ r4 |0 K9 s) Q! A! o8 u: S
3 V1 _4 s( k7 E7 T  8 U4 H4 s1 C+ e4 t5 h

- g% x: m8 n9 l7 K3 N/ Y% O          unsigned char* buffer = mTTFMsg->face->glyph->bitmap.buffer;
0 a7 y+ z3 N5 A  F5 C2 w
7 z, j" d( y* w8 c. i                  // 位图指针 * g; V' F0 O& O

2 ]" h2 h0 |2 N* t( Q8 |+ m5 U9 S            if (!buffer)
1 W$ b9 W1 h: _6 m) J
/ q, G0 C# `- ^, }+ C            {3 Y% S8 ~+ O/ n

( A) z" p6 l; @% x. y                // Yuck, FT didn't detect this but generated a null pointer!
: W( k4 P8 g* j. A
( r5 q0 F+ r, F" b                LogManager::getSingleton().logMessage("Info: 1111Freetype returned null for character " +/ f- f7 u0 [+ A' n8 `

- i( {! f  j! V9 F8 F: l/ i- t) a# ^                    StringConverter::toString(unicodeMap[dwChar-161]) + " in font " + mName);) u( h. E3 v- e, x  }4 B7 ?
9 ^- B+ `, Y/ D4 z4 R& W! A
                return false;//如果得不到跳过 * }; F$ v# ?, H* B5 h  i% `
. h! }) a% u8 h. U) d) ^
            }
0 \% f6 u+ d2 G9 z9 d# y
' m8 }. n8 ^! h. d& N) d& Q* Z  
4 R5 I6 P* u9 g& L5 d. C$ D1 z/ u! I+ t7 g, _0 Y' z+ @- H
                         int y_bearnig = ( mTTFMsg->max.bear) - ( mTTFMsg->face->glyph->metrics.horiBearingY >> 6 );
1 m* ^; [) [# V6 s' {( a: a. H- I* t9 K1 W# y% d4 U4 _8 p. {
       8 R* b  U* r0 B+ m' n" R' N

7 C' ]8 r! E+ c0 o" {: w( ]                        
  R3 m! p1 S, ^3 {* C0 u4 A
+ f/ e) r6 }! \            for( j = 0; j < mTTFMsg->face->glyph->bitmap.rows; j++ )
: ~+ n6 }, N: o6 ^' }( M, i8 ~  {9 ?- I
            {
; _/ d0 ?6 Q3 _5 E) _0 U. W0 S: R& E. N+ L2 y3 Z$ O% f
                int row = j + rect.top+y_bearnig;
$ q1 H9 v' `% ?' M9 J8 W
5 x( F! D' w& V* x) Z8 E* Q                int col = rect.left;//列
# ]  M, ~2 t- C$ u7 N4 n8 i9 [( D3 K) x
                                pDest=mTTFMsg->imgchunk.getPtr();1 i9 p4 @' J: \
. s- S3 y3 b! n# l6 l" F& G
  / ?6 L% F6 j. O( ~! ^: z8 f
% c+ M0 G0 _+ \6 }
                        
$ R" o4 i  [5 G: \; d% V: l. i3 \: E7 N5 |, d
                                pDest+=(row * (512*4)) + col * 4;
* u2 C8 `, Q/ U' t5 |
3 A' ~% z. D6 t% J               for( k = 0; k < mTTFMsg->face->glyph->bitmap.width; k++ )//每行的点 6 s. `6 M$ d. c# b( m, y7 k) n

6 Y3 v; l, q5 y4 S6 L' W( p                {- ~" ^6 @! G9 M4 m
5 L/ W! q! M, ]6 O. U2 q
                    if (mAntialiasColour)" R( E+ O- a) {; ]' x' t/ R

  ^7 M1 Y2 x5 J3 P                    {
  K6 v& [3 {  o& K
( y6 S. m8 J* S& z* x2 r3 D: Q9 W                        // Use the same greyscale pixel for all components RGBA ) x5 |4 S0 l; ^1 ?7 ]

2 Y6 k! B2 T: s0 z% {& L) K; l                                                        *pDest++= *buffer;' V! w7 }$ j4 }$ Q5 a
: G) i" @0 q# z& r/ h  i7 b2 I6 p
                            *pDest++= *buffer;1 N- u# F, S/ l7 T# g; j% \+ V

$ T/ @$ o: f$ p  |5 `9 ^0 g( _: S0 M                            *pDest++= *buffer;
" C- O0 u8 L7 p! d6 e/ Y( a- b8 g4 E! J& Y4 G1 C* T" B
                    }
! E- X' J* ~' P+ s1 r. l4 T& l* y: M; z+ ~
                    else
7 S* g, [- G. P- o% d5 N; ~
* {+ [  C: o' ^- ^# {% n) J3 `                    {- }+ \8 i  N& C0 Y  r: }7 ~$ L: I- \
% V7 J% ?' ?; P5 r6 B  [" n
                        // Clamp colour to full white or off 4 `1 P% {* ]& H# G# K

4 J1 c0 }0 {! |+ ]                        if (*buffer > 0)
6 u4 I& W/ j# p! M% N8 s9 d8 L* r& l( n
                        {
! w# R, [, F7 j
. Z, b$ a$ E8 F4 ^9 a; o$ J                            *pDest++= 0xFF;( z" s" I0 E6 B! {9 y& v# U
, d6 P* |# K3 S. P3 B2 M- x4 E- p$ P
                            *pDest++= 0xFF;9 p& T0 y) \7 H* ^% }; |
. X0 j6 l& h7 W+ }! U, R
                            *pDest++= 0xFF;
# A. J4 e8 g  Q. r3 D) T: f  d9 P- Y, s2 y. P1 ^  t, f: J8 b
                        }
7 c! ?( Q) y; E: |5 i# j6 V; t
7 I! C1 U& G7 u8 C) x                        else # V" q% y$ ?0 f# I- N

6 L9 i& \$ G3 a                        {3 V- V: X% s) R3 v7 J. M4 o

% P. D7 h- p- f; \  i+ t                            *pDest++= 0;
" B2 }0 P) i1 s+ S  c. H2 ]* {6 L4 f( T$ }* ~* ]0 K2 p+ x% g
                            *pDest++= 0;
) D1 R' x2 m' @2 l# A( K# a% `; X/ u" f: S- Z
                            *pDest++= 0;
3 M! N& }) g0 o  u5 T& J9 t. P* P3 L0 p
                        }
6 u; r/ l) ~) o4 p& N2 a" T' k. F, n6 K1 J+ Z
                    }
9 D, J5 _6 y! y  J' r% J7 U  l4 M) \% L
                    // Always use the greyscale value for alpha
6 h8 C1 E. r2 l1 ]! y6 q% l) K1 }7 v8 V
+ O' t8 Y  A. _; n# v, @                                        1 W, F& S" T/ [" ?/ U4 F. `
( N# [( `3 T# G5 Z
                                //      LogManager::getSingleton().logMessage(StringConverter::toString(*buffer)+"is cool");
& T% {( V$ [% ]! @$ O: X3 T8 w9 h& |! R- r' c" }3 M
                    *pDest++= *buffer++;
3 a8 z* p" s; O9 @* B- p6 ]9 y
                }7 S; ]7 N5 F; U' i+ ^8 q& [7 o
( w' g! t7 x7 L6 {0 r  \& k
                                
: o8 t, _' I. S$ n: |9 \# x/ F
% J- `0 W4 d' u& q) W, M" z* }% d                        }
, G& q0 Y+ f/ p( y9 x; a- B( m$ O4 z0 Z0 O2 g0 X
                        // 设置位置
# T& \, `* U1 F: z9 r* r
& s, v& t: M/ W7 H! v                        this->setGlyphTexCoords( dwChar,
3 |! R  G. u3 {. h7 b1 i* f* }0 i# T2 Z4 b% c
                                 (Real)rect.left / 512.0f,  // u1
4 \5 C; `3 E0 @1 d( x6 ]- A  M2 J2 \+ y; ?- b) X% {
                                (Real)rect.top / 512.0f,  // v1
/ R- A2 R- w6 h! q, s9 \6 C1 H. _, A" C+ L1 x( i( }
                                (Real)( rect.left + (mTTFMsg->face->glyph->advance.x >> 6) ) / 512.0f, // u2
3 r; U. |. G5 t9 m  ^: x0 u) k" @8 s* {: l3 B' T: a5 x, ~
                                (Real)( rect.top + rect.bottom ) / 512.0f // v2, s9 X: r. B( q  Y* ]6 [( N

) S! G8 U9 W0 E9 u6 r" W1 [                                        );* M5 @  w8 C5 Y- S9 H6 \  I
: i. U% T; L1 W$ k; B9 t
                mTTFMsg->dirty=true;//贴图需要更新
* J! K( z- ~9 G6 R' S! L  `6 ^5 o4 X9 n
                return true;" H1 i& C, K  C, V

, l. m* ~8 G: {4 U0 a# s- ?$ M! p        }; l; G' f& z8 K- ^0 I, ]) w5 m! y

8 w$ e1 \* l! F+ i! u. h7 z  4 B( `. q8 p( i+ ]; m- l" ^; r

8 @+ `% V6 f: Z  M(4) 2 z1 i3 r' ]8 z/ O7 W
5 g% n7 E+ G/ ~3 D. Z% ?' Z
        松口气吧,繁重的工作都做完了,就是更新贴图了。 3 d3 _( n8 z- g* C4 _3 [" c- D

- ?8 h0 X! d1 Y; A5 _        Font类中~1 j3 C  a2 C  Z$ K0 |' D( [! S
; f$ o% |4 J+ B/ P1 @! L( l! z& w
        inline void write()4 n0 f* T( s& \. H& k. A

: ~6 V- s8 k7 F" p                {6 h  I$ H- \: g

9 f9 ]/ c  `/ F8 c                        if(mTTFMsg->dirty)
5 r/ t3 b3 C7 Y  v3 M( y- G4 h
3 c4 F4 P" F$ y% h$ p7 P$ q& n' \/ l/ T                        {       # H, M6 q9 X' W2 j3 P. T, O1 |/ X+ w% G
( `2 _# e( @8 y% u1 y2 N- @
                                // 重新载入贴图,顺便说一句,类似功能的函数还有
( j( c7 x1 v; w, ~7 j- o
% J0 d2 o  V2 L                                //virtual void  blitToTexture (const Image &src, unsigned uStartX, unsigned uStartY)=0 4 Y7 M2 X4 M7 ~$ g6 G8 l8 ]7 K1 Y

" E/ z( c) m% e- I                                //和virtual void  blitImage (const Image &src, const Image::Rect imgRect, const Image::Rect texRect)
+ J7 K4 f/ A% I  B$ D7 i. `* g7 b( x# g+ F9 X
                                //不过blitToTexture()在ogre-win32-v0-14-0之前没有实现,没有尝试使用。 blitImage()就算到现在也没有实现。
2 J* X$ f9 e1 B3 t/ w7 `1 p4 a4 {2 p6 {# p# I* }. p
  / n( ?8 O# y$ u6 C
4 @$ @! a. M4 V8 R/ C
                                TextureManager::getSingleton().unload ( mName + "Texture");
& w$ O; b& c, ^# Q; `: M) U
! L2 R+ C. B1 ~  {( k0 ~                                TextureManager::getSingleton().loadRawData ( mName + "Texture" , mTTFMsg->imgchunk,512, 512,PF_A8R8G8B8, TEX_TYPE_2D, 0  );
0 h  l: x6 n2 r& v+ }3 {# z2 L5 h2 R
                                mTTFMsg->dirty=false;
) M0 |  e" x, e' W& {, d" T; r5 x; s& p8 \5 j" `3 @1 `& x
                        }
$ P- M1 h  l+ g
5 w8 F$ {' P+ }, d8 o8 d/ h                } / Q/ F0 L3 V7 G9 ~, q

) r+ ]  `. W4 F* U( S  , M) `8 U: S& z3 V* m

3 v& Q. ~, K; S, j         在 void TextAreaGuiElement::updateGeometry() 中调用这个函数。
$ |( Q* A$ N- @, J2 O3 w  H5 c9 W$ |0 R
  
; o9 H/ |; A# c# P! \
! U% ^  U  i4 x7 {% y* F  1 l6 u$ B9 ?  j" {% E% y
, L* s' Y( h2 H4 g1 G
4.结果。 , H8 ?' A' Y) p, ]7 \6 Y& k

1 j' L& X+ {9 q& A        好长阿,写了好长。虽然多是代码,但写注释也很累啊。重温了这些天的工作结果。就像上一篇一样“在OpenGL和DX9.0中成功的支持了中文,但是DX7.0中竟然出现了运行错误,具体问题还不清楚,还望各位高手指教。”。不过本来OGRE就不怎么支持DX7的,不管了吧。OpenGL中渲染的比DX9.0清晰,是我的显卡的原因么?以上的winXp+vs2003.net+艾尔沙980se通过~。。
* v+ j; U3 Z* A3 |8 K% \$ _9 X6 E9 M
        顺便说两句,上次发表了拙作,没想到好多朋友和高人们找到了我。甚至联系到了一个南方的公司,说要做一个引擎支持中文的方面。但是卖完400多的火车票之后竟然因为住房问题作废了,5555,退票少了80元啊。还是自己差阿,如果再多学点可能就能要我了把~。努力吧,争取写《让OGRE支持中文》三部曲。 0 \- v( _, x" V) H" X1 ]

, Q- ?& D5 l) @3 g, B9 D        下一篇应该是《可以输入中文了》。
  v0 z+ Q. ]9 R$ [$ j4 M; c! Y
" r% j& G2 B+ F. B5 D" ?4 B# }+ j        也可能写不出来的~~~~~~~~~~~~~~~~~~~~   
0 U" ~$ x: A! G' j0 x$ x8 s1 \. t5 k5 g; \% P. R
    相关文件 ( q0 ]1 A( ~( \' T

+ k* D* T- z( h. o. e' t; f    chinese.fontdef//字体信息文件 放在资源文件加中 / o/ z. h5 D# r2 ~
9 c$ z9 l& Z2 L% c: v$ n
    font.png//字体图片 放在资源文件加中 5 S& m/ |1 A# g% }5 Y0 F) P$ y
# Z) _* S9 T5 x. I1 M5 |. T2 u- t
  ( ?6 w& ~) l5 t) d% {9 l7 p
) y" i% @; K( Q% E) ]# _7 r
    OgreFont.cpp
" S! i* G- {3 e  y! E
3 B9 f6 B4 z6 `* {: M+ e    OgreFont.h
8 G0 t: C+ c' y$ d' d$ ?! x# ~' ]& f
    OgreFontManager.cpp% v# H* P5 Q  J& e# O1 ^5 O$ E: n

+ L4 _6 `# R9 C9 F    OgreTextAreaGuiElement.cpp
( ^7 \' L4 Z; j0 b* }
) [: }! V( d3 J' Y2 y/ t& ]    //上面文件覆盖同名文件 就可以 先备份 2 x4 [# H4 [! K) I7 A* y5 u: K5 j
% K" E7 U8 |! ^+ S$ k
   % y! N* }& I9 X1 D2 S( Y6 x

( b+ x+ S7 v3 i6 d- E   solo5.ttf//这个是一个中文ttf 我直接替换了原来的ttf
5 k% ~7 [9 j2 s
8 G1 L. u0 G& ]+ u  `) v6 g/ A   unicodemap.h//这个重要,是换算unicode码的数组(文中提到) 3 ?: F2 N6 `6 O5 F; P, {2 W  N

1 j& q& @$ N) W* l0 F  
8 }6 K: C; H* ]' [, S5 B7 t: D0 t9 r% \& o# Y3 _. P) f
这个是在ogre-win32-v0-14-0基础上改的(上次是ogre-win32-v0-13-1), ( H: L& O$ w$ i+ X9 A9 j% o/ H" r$ p
( S4 |, Q: r; D& f: q- X
请到http://sourceforge.net/projects/ogre/下载
0 L' P# i1 S# Q/ ]& o, s+ [  ?& r" l2 I
配套档案下载:http://www.gameres.com/Articles/ ... /ttf.files/file.rar
4 V, a9 L# Y4 u7 M; h& d' d/ z
1 V3 [2 x# y& B 免费打工仔QQ:18500707 f8 N7 z& ^2 k0 ^" `5 i2 L
1 G0 b1 d. f  V" H. G. Y
From: GameRes
" P2 _* u/ A  m6 E
4 e; ^6 g7 I# [* ^) rhttp://www.gameres.com
: `/ K  o! x4 F+ A5 d( D% ~; A* I, k# j5 u9 k0 }
上面图中“免费打工仔TTF:213.786”是TTF 其他是位图的,中文的位图字体也小修改了一下,支持半角字体了~

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 很美好很美好 很差劲很差劲
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

冒险解谜游戏中文网 ChinaAVG

官方微博官方微信号小黑屋 微信玩家群  

(C) ChinaAVG 2004 - 2019 All Right Reserved. Powered by Discuz! X3.2
辽ICP备11008827号 | 桂公网安备 45010702000051号

冒险,与你同在。 冒险解谜游戏中文网ChinaAVG诞生于2004年9月9日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

快速回复 返回顶部 返回列表