Posted on 2008-07-14 14:27
RichardHe 閱讀(783)
評論(0) 編輯 收藏 引用 所屬分類:
OGRE
0.前言:
本人非計算機專業,憑著愛好和一腔熱血混入游戲開發大軍候補小隊,平面尚未鉆透。為趕時髦,企圖叛變到3D陣營,慌亂之中撿起“OGRE”。學到如
今,亦可讓正方體飛機等不明物體在三次元空間胡亂打轉。但覺得本引擎不支持中文顯示而感到不爽,便四處尋求高人指教,但大部分高人指點說:“自己寫引擎算
了。”衡量了一下自己份量,覺得“自己寫”這件事十年內恐尚難做到。再后來找到3DCastle論壇,經過“bug王”以及“浪客☆龍貓”
兩位前輩的指點,也通過高手“renwind”遺留下來的教程,誤打誤撞竟然自己改出了中文支持,興奮之余便想寫點東西留點紀念。
1.準備工作
“bug王”已經通過WINAPI實現了OGRE在Direct7.0下的中文支持,也有高手說這樣效率不高,更因為本人基本上是不怎么熟悉
WINAPI的,所以就放棄了這種方法。企圖直接通過貼圖來實現中文顯示,畢竟OGRE本身文字輸出也是用的這種辦法,更好的是OGRE引擎除了普通的
“ttf”字體外還支持位圖字體(其實“ttf”在引擎中也被Ogre::Font::createTextureFromFont()轉換成位圖了),
基本上就是做一個很大很大的圖片,然后上面畫滿漢字,直接讀進去就可以了,問題也就變成了——如何找這個大圖片。
幸好GBA游戲的開發者們已經找到了很好的文字來源和取得方法,通過金山的16*16點陣字庫得到接近9000個字模,然后通過程序讀出并寫到2048*2048的單色位圖上,轉換成“png”格式圖片才221k。
2.基本知識
修改引擎之前,我們先要知道OGRE是如何顯示字體的。OGRE本身面向對象的設計和自帶文檔都做得非常規范漂亮,很容易就能找到關于顯示文字的類以及相關函數。在這里主要看一下關于位圖字體是如何顯示在畫面上。
(1)字體的讀取。
和這項功能相關的有兩個類,一個是Ogre::FontManager類,負責分析字體信息(*.fontdef)文件。然后用builder模式構
建一個Ogre::Font類。在Font類中最重要的數據莫過于mTexCoords_u1、mTexCoords_u2、
mTexCoords_v1、mTexCoords_v2這四個數組,他們分別用來儲存不同文字對應在圖片上的紋理坐標。
不過數組大小明顯不夠儲存9000個漢字的,一會兒要改的。
(2)字體的顯示。
好像字體顯示中用得較多的是Ogre::TextAreaGuiElement類,不過好像還有其他的,我們在這里只看這個吧,估計其他的也大同小異。看了看好像唯一和顯示字體有關的函數就是void
TextAreaGuiElement::updateGeometry()了,基本上就是根據要寫到屏幕上的字串,在Ogre::Font類中得到相應的貼圖坐標和貼圖,然后畫上去,道理也不是很難。
3.動手術
目標鎖定到Ogre::Font,Ogre::FontManager,Ogre::TextAreaGuiElement三個類中,把所有文件備份一遍手術開始!
(1) Ogre::Font類。
首先是儲存文字貼圖坐標的數組的大小不夠,原來定義的是——寬字符集 (1024 - 32)、ASCII(256 -
32)。這點點大小怎么夠我近9000字大軍進入,索性都改成(9030 -
32)。還有就是set和get文字貼圖的id都是char類型數據,256個id也不夠分配給漢字,看來要都改成unsigned
long形(其實大部分機器上int也是32位,不過long是固定32位的類型,感覺統用點)。
(2) Ogre::FontManager類。
里面從腳本文件中解析貼圖坐標的方法是根據單字符的方式,為支持漢字,改成同時可以分析int的。一個漢字對應數字是他的區位碼+161(前160個留給了半角字)。
(3) Ogre::TextAreaGuiElement類。
這個是相對比較麻煩的,他要從字串中分辨出到半角字和中文。在這里增加一個std::vector<unsigned long>
caption,用來儲存分辨的結果。增加以下幾行:
std::vector<unsigned long> caption;
unsigned char nTemp;
String::iterator it=mCaption.begin();
for(;it!=mCaption.end();++it)
{
if(unsigned char(*it)<=160)//如果是半角
{
caption.push_back((unsigned char)*it);
}
else//處理全角字符
{
nTemp=(unsigned char)(*it);
++it;
if(it==mCaption.end())
break;
//下面是得到區位碼+161的公式。
caption.push_back((94*(nTemp-0xa0-1)+((unsigned
char)(*it)-0xa0-1))+161);
}
}
然后后面所有關于mCaption的地方都用caption代替就ok了。
4.結果。
在OpenGL和DX9.0中成功的支持了中文,但是DX7.0中竟然出現了運行錯誤,具體問題還不清楚,還望各位高手指教。
因為字體本身原因,文字很扁平的不好看,索性又改了改Ogre::Font,Ogre::FontManager兩個類,實現腳本中支持修改文字縱橫比例的系數的proportion,當這個值設置為0.8的時候比較好看了。
相關文件
chinese.fontdef//字體信息文件 放在資源文件加中
font.png//字體圖片 放在資源文件加中
OgreFont.cpp
OgreFont.h
OgreFontManager.cpp
OgreTextAreaGuiElement.cpp
//上面文件覆蓋同名文件 就可以 先備份
這個是在ogre-win32-v0-13-1基礎上改的,請到ogre-win32-v0-13-1.zip下載
中文字體名字就叫 Chinese,以后能做中文游戲了!
免費打工仔QQ:1850070