冒险解谜游戏中文网 ChinaAVG

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

作者: shane007    时间: 2008-10-22 16:02
标题: 【汉化资料】开源的图形渲染引擎OGRE(2) --让OGRE支持中文
如何修改字幕输出函数,也许这篇文章可以参考。% |+ f5 Z1 ^' E' `, W: @
& s0 S0 a8 P- M+ U4 L5 M- M
! I# d7 J# _- F9 A
让OGRE支持中文 (转贴)
8 n& l: |) u" U: R/ ]
) z8 K! t, z4 J/ _4 R0 A
! g8 J6 S, B$ F$ S0 o0.前言:# B* |; W  J( W( p  X: `" t* ^
本人非计算机专业,凭着爱好和一腔热血混入游戏开发大军候补小队,平面尚未钻透。为赶时髦,企图叛变到3D阵营,慌乱之中捡起“OGRE”。学到如今,亦可让正方体飞机等不明物体在三次元空间胡乱打转。但觉得本引擎不支持中文显示而感到不爽,便四处寻求高人指教,但大部分高人指点说:“自己写引擎算了。”衡量了一下自己份量,觉得“自己写”这件事十年内恐尚难做到。再后来找到3DCastle论坛,经过“bug王”以及“浪客☆龙猫” 两位前辈的指点,也通过高手“renwind”遗留下来的教程,误打误撞竟然自己改出了中文支持,兴奋之余便想写点东西留点纪念。! z0 g5 ~* R6 S0 Y
1.准备工作
/ ]: j5 x; T) O3 D$ M“bug王”已经通过WINAPI实现了OGRE在Direct7.0下的中文支持,也有高手说这样效率不高,更因为本人基本上是不怎么熟悉WINAPI的,所以就放弃了这种方法。企图直接通过贴图来实现中文显示,毕竟OGRE本身文字输出也是用的这种办法,更好的是OGRE引擎除了普通的“ttf”字体外还支持位图字体(其实“ttf”在引擎中也被Ogre::Font::createTextureFromFont()转换成位图了),基本上就是做一个很大很大的图片,然后上面画满汉字,直接读进去就可以了,问题也就变成了——如何找这个大图片。: I& [# D- n0 b# {$ @
幸好GBA游戏的开发者们已经找到了很好的文字来源和取得方法,通过金山的16*16点阵字库得到接近9000个字模,然后通过程序读出并写到2048*2048的单色位图上,转换成“png”格式图片才221k。
4 C& R2 T. a. w2 ~* w  g# a2.基本知识; I; Y9 q/ `- t" G/ n. j7 b4 X
修改引擎之前,我们先要知道OGRE是如何显示字体的。OGRE本身面向对象的设计和自带文档都做得非常规范漂亮,很容易就能找到关于显示文字的类以及相关函数。在这里主要看一下关于位图字体是如何显示在画面上。(1)字体的读取。
( {' z) ^8 E; l3 I6 Y和这项功能相关的有两个类,一个是Ogre::FontManager类,负责分析字体信息(*.fontdef)文件。然后用builder模式构建一个Ogre::Font类。在Font类中最重要的数据莫过于mTexCoords_u1、mTexCoords_u2、mTexCoords_v1、mTexCoords_v2这四个数组,他们分别用来储存不同文字对应在图片上的纹理坐标。 不过数组大小明显不够储存9000个汉字的,一会儿要改的。
5 r* F+ o+ F( _; K$ @9 G' U  r" V(2)字体的显示。/ w* N7 J/ ~4 S7 G
好像字体显示中用得较多的是Ogre::TextAreaGuiElement类,不过好像还有其他的,我们在这里只看这个吧,估计其他的也大同小异。看了看好像唯一和显示字体有关的函数就是void TextAreaGuiElement::updateGeometry()了,基本上就是根据要写到屏幕上的字串,在Ogre::Font类中得到相应的贴图坐标和贴图,然后画上去,道理也不是很难。$ L: i! q7 f; n" N! S* [6 z) X
3.动手术% d4 `6 R+ c& @3 ^
目标锁定到Ogre::Font,Ogre::FontManager,Ogre::TextAreaGuiElement三个类中,把所有文件备份一遍手术开始!6 W! V! o% n  x9 v2 |1 D
(1) Ogre::Font类。
  y& \5 G& x, J3 ~1 e首先是储存文字贴图坐标的数组的大小不够,原来定义的是——宽字符集 (1024 - 32)、ASCII(256 - 32)。这点点大小怎么够我近9000字大军进入,索性都改成(9030 - 32)。还有就是set和get文字贴图的id都是char类型数据,256个id也不够分配给汉字,看来要都改成unsigned long形(其实大部分机器上int也是32位,不过long是固定32位的类型,感觉统用点)。
  v0 x" N* @6 {% D& w& n(2) Ogre::FontManager类。
; K9 ?& D9 I7 Z) n( o" k里面从脚本文件中解析贴图坐标的方法是根据单字符的方式,为支持汉字,改成同时可以分析int的。一个汉字对应数字是他的区位码+161(前160个留给了半角字)。3 s, ?3 f* z2 L4 W5 J1 |
(3) Ogre::TextAreaGuiElement类。
* I! B8 {; ^6 W; c这个是相对比较麻烦的,他要从字串中分辨出到半角字和中文。在这里增加一个std::vector<unsigned long> caption,用来储存分辨的结果。增加以下几行。
' f$ [3 J- J$ A# [: dstd::vector<unsigned long> caption;. t0 @1 ^* k2 P8 m
unsigned char nTemp;! O% N2 ^" j/ H# t6 F5 _! y7 ?
String::iterator it=mCaption.begin();: e" f+ R  Y- W
for(;it!=mCaption.end();++it)
- @8 S1 I  b7 \+ W2 [& J# [{& c  |4 Y3 I- z6 X2 B2 X% ~+ o; B
if(unsigned char(*it)<=160)//如果是半角0 |" o: Z/ U. _# [2 y9 J" M$ h
{
, ?. k7 {3 o) S3 V, I, ?7 ^( zcaption.push_back((unsigned char)*it);
, t7 G- P9 k) \}0 z) q  s" k; m+ w0 V
else//处理全角字符7 P; W/ B% S5 W+ X6 x9 A1 @
{ 1 {* B3 P, I2 k; r( d: m- t
nTemp=(unsigned char)(*it);
3 k: I2 ~) q2 C5 ~3 Z6 M0 _++it;- F* \% Y' t' O+ U' A4 S
if(it==mCaption.end())  m; t7 F7 f1 C
break;
: X1 u# [' \% T7 `8 y* J//下面是得到区位码+161的公式。1 ^0 |/ X2 h1 ]1 ]6 ~2 o
caption.push_back((94*(nTemp-0xa0-1)+((unsigned char)(*it)-0xa0-1))+161);* W  Q; Z, R: `
}/ a8 a6 Z" g3 X& M' A
}
8 X6 n$ \5 y0 ]. ^( V0 ~然后后面所有关于mCaption的地方都用caption代替就ok了。
: v' T( c/ E; I7 i6 [1 L. C" H1 V4.结果。
9 r: X6 l3 M! c3 T3 w) k6 u8 k在OpenGL和DX9.0中成功的支持了中文,但是DX7.0中竟然出现了运行错误,具体问题还不清楚,还望各位高手指教。$ X2 l/ e% l* |  X: K9 W2 F5 [& E
因为字体本身原因,文字很扁平的不好看,索性又改了改Ogre::Font,Ogre::FontManager两个类,实现脚本中支持修改文字纵横比例的系数的proportion,当这个值设置为0.8的时候比较好看了。
2 a- W% f# Y  M
: F3 l4 i2 [/ ~4 Y
/ M7 A- N' ^2 c相关文件' v2 ^6 q8 M, r
chinese.fontdef//字体信息文件 放在资源文件加中
+ ~5 J. X* ?" _7 x4 Ffont.png//字体图片 放在资源文件加中: B2 y' A2 {6 n4 R' B) {1 z

" `. O/ x* C& A- F! b1 JOgreFont.cpp) P* @8 ]( H' E+ w1 c2 R, _
OgreFont.h& p6 c8 ?$ n# c1 p( x7 i
OgreFontManager.cpp
1 V3 g% t0 h  c( m: qOgreTextAreaGuiElement.cpp* t! V7 `0 k1 P" k! P% f
//上面文件覆盖同名文件 就可以 先备份( d) f' {- Z# C8 n

; E8 f( E, O  e6 Y; y+ u& [0 t这个是在ogre-win32-v0-13-1基础上改的,请到$ \( `+ \! ^$ {2 g
ogre-win32-v0-13-1.zip下载5 V7 X5 [& n1 e( s8 J0 B

/ H5 v% N2 }1 c中文字体名字就叫 Chinese,以后能做中文游戏了!




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