1:綜述
在引擎中常用的漢字文字顯示分二維或者三維文字顯示,不論二維或者三維文字基本思路都是先找到漢字字型庫,然後把字形提取出來進一步處理,方法基本分兩大類,一種是直接剖分成網格顯示,這種方法生成和顯示速度慢一些。另一種是把字形做成紋理,這種相對於網格方法會快一點。
2:osg中顯示文字方法
先用字型庫生成相關的字形,然後把字形貼到四邊形網格上形成紋理,然後繪製。主要**利用的osgtext庫,這個庫網上有相關的使用方法,具體了解這個庫查閱相關資料和源**,這個不多說。
這個庫提供了邊框,補白,陰影等顯示效果,在顯示文字比較少的情況下是夠用了。但是如果顯示文字多的話,每一次都要生成字形,每一渲染都要上傳紋理,生成速度,速度都比較慢。
3:大規模文字生成和顯示
目前市面上的引擎或者專門顯示字型的庫,一般都著重於顯示效果,顯示大資料量的文字就很慢了,基本都會卡死。本人針對大數量文字的顯示提出了乙個基本思路,基本方法就是用空間換時間,具體方法如下:
做乙個工具把所有的常用的漢字字形提取出來,然後把這些字形按照行列排成正方形成乙個png檔案,然後儲存。等使用的時候把這個png檔案讀入記憶體,再一次性上傳到gpu,顯示具體文字的時候再去查詢文字在png中的位置,然後把文字紋理從png中摳出來,再貼到四邊形上顯示出來。
相關的實現類有qfontimplementation, 這個類主要用於生成字形。osgbigtextimag, 這個類主要實現生成png的工具,顯示文字。sharetexture2d,這個類主要實現所有的共享紋理。
這種方法有兩個優點,第乙個就是把所有的字形事先生成乙個大png檔案,所以生成文字速度塊,第二個就是共享紋理大,省去了每次上傳字形紋理的過程,所以顯示速度快。
這個是程式生成的常用漢字的字形組成的大紋理
下面是部分**注釋:
這個靜態函式就是生成工具,呼叫後直接生成所有文字的排列的png檔案,下面分別
簡單注釋一下相關函式,更詳細的注釋可以直接看源**。
void osgbigtextimag::createtextimagetool()
ifs.close();
}//把所有的文字排列成正方形,形成image
void osgbigtextimag::gridimage()
//算出文字排列的正方形的邊長
m_gridrc = gettotalgrid();
//寫出文字在紋理圖中的行列,用txt檔案儲存
std::map::iterator it = m_images.begin();
int index = 0;
for(; it != m_images.end(); it++)
qimage *markerimage = new qimage(m_gridrc * m_images[0]->width(), m_gridrc * m_images[0]->height(), m_images[0]- >format());
qpainter *painter = new qpainter(markerimage);
qimage* temp = null;
for(size_t i = 0; i < m_gridrc ; i++)
else
//32 48
painter->drawimage(32 * j, 48 * i, *temp);}}
std::ofstream ofs(text_path"bigtexttexture.dat", std::ofstream::binary);
ofs.write(((char*)markerimage->bits()), markerimage->bytecount());
ofs.close();
std::ofstream infos(text_path"info.dat");
infos
infos
infos
infos<:create3dtextfast qstring text float width height osg::vec4 color>
//先查詢是否已經生成
std::map::iterator it = m_text_pos.find(text.tostdstring());
float num = 0.0;
if(it != m_text_pos.end())
//計算文字在中所佔的位置
osg::ref_ptrpos = new osg::vec3array();
pos->push_back(osg::vec3f(-width, 0, 0)) ;
pos->push_back(osg::vec3f(width, 0, 0)) ;
pos->push_back(osg::vec3f(width, 0.0, height)) ;
pos->push_back(osg::vec3f(-width, 0.0, height));
osg::ref_ptrtex = new osg::vec2array();
tex->push_back(osg::vec2(0, 0));
tex->push_back(osg::vec2(1, 0));
tex->push_back(osg::vec2(1, 1));
tex->push_back(osg::vec2(0, 1));
color = osg::vec4(num, 1.0, 0.0, 1.0);
//生成四邊形,把文字貼上去。
osg::ref_ptrgeode = creategeode(pos, osg::primitiveset::quads, color);
( (osg::geometry*)geode->getdrawable(0) )->settexcoordarray(0, tex, osg::array::bind_per_vertex);
//所有文字共享的stateset
( (osg::geometry*)geode->getdrawable(0) )->setstateset( m_global_stateset );
transform->addchild(geode);
return transform;
}
5:效能分析目前的這種加速的優化方法,只用事先生成的乙個大紋理,紋理只上傳一次且用shader程式設計實現,生成和顯示檔案的速度非常快。
這種方法每個文字只繪製乙個四邊形,越是繪製文字數量多,越能顯示出優勢, 預計顯示幾十萬個文字甚至上百萬的文字沒有問題,已經達到了文字顯示的最大速度。
利用文字標籤控制項進行文字顯示和生成超連結
using system using system.collections.generic using system.componentmodel using system.data using system.drawing using system.linq using system.text u...
快速生成26個英文本母
在學習中經常會拿26個英文本母序列做為字串的例子來說明。但是自己又不想每次都自己手動輸入。所以就想寫個方法能快速的生成這個字串。generate 26 english characters return void public static void generate26chars system.o...
QtQuick實現文字編輯和顯示文字行號 改進版
可以檢視這個簡單的專案 qtquickeditor 先上張效果圖 現在簡單的說說 的 主要講講textview的 下面的 是乙個自定義button的控制項 work for desktop and harmattan by qyvlik qyvlik qq.com 2014 10 25 11 33 ...