opengl本身並沒有繪製文字的功能,他只是乙個三維繪圖的api集和,很多東西都要
自己動手才可以實現。opengl繪製文字,網路上已經有很多成熟的方式方法,我這裡給
大家介紹的是我使用的方式,從繪製的效率上來說,速度上從已經達到我個人水平的最大值。
首先介紹下網路上的一些繪製方式。
一、將要繪製的文字按照每乙個字生成乙個小紋理的方式,然後再用將紋理貼到網格
的表面,繪製出來,例如:「-你好」,則會生成6個小紋理,然後生成網格,將紋理
貼到網格的表面。優點:每乙個字的大小顏色都可選擇。缺點:文字多了以後,頻繁的切換
紋理造成效率低下。osg中使用了這種方式,效率極差,尤其是在文字更新的情況下。
二、直接將隨繪製的文字字串生成乙個紋理資料(而不是乙個文字乙個紋理),這樣
做效率上比第一種要好很多,缺點就是更新的時候要重新構建乙個新的紋理。速度上有很大
損失。兩種方式的原理圖如下:
三、將所繪製的文字都放到乙個較大的紋理上去,然後再紋理上做索引,當繪製的時候,
去查表。在將紋理貼到網格上繪製出來,這種方式,速度很快,很多遊戲引擎都在使用這種
方式,存在的問題繪製的文字多了以後速度會變慢,占用大量的cpu時間,當然對於小的應
用已經足夠了,今天我提出的方式也是基於這樣方式的,只是我在索引上最了一些改進,改
進之後的演算法,將不再進行查表操作,而是直接索引,一定程度上降低了cpu消耗,提搞了
存的資料上也很重要,結合opengl,採用gl_alpha的上儲存,這樣可以大大
降低所占用的視訊記憶體空間,從而提高效率。
下面定義乙個文字所儲存的資訊,如下所示:
class為了快速索引,減少查詢的過程,我麼要結合字型本上來做一些處理,我們知道乙個漢字要占用2個位元組character
/*** 儲存當前字元在紋理上的座標位置
*/unsigned
short
x0; unsigned
short
y0; unsigned
short
x1; unsigned
short
y1;};
兩個位元組所能表示的範圍是0-65535,就是6萬多個漢字,那麼我們就宣告乙個這麼大的陣列來儲存字元的
資訊:**如下:
character g_charmap[1當我們要繪製乙個文字的時候,可以直接通過下標就可以直接定位到該字對應的資訊了,例如我們繪製'中'<<16];
character getcharacter(wchar_t ch)然後這樣也存在乙個問題,即一張多大的紋理才可以容納這麼多的字元呢?如果是一般的應用,我們可以忽略
這個問題,中國常用的漢字只有3000多個,假設是乙個漢字佔16*16的空間,那麼乙個1024*1024的紋理
所能容納的字元有 1024/16 * 1024/16 = 4096個,足夠滿足正常的需要,如果你是想做乙個通用的,沒有
瑕疵的應用,我們就要修改我們的設計方式,我能一切從速度優先的方式考慮,我們在上面的character類中
增加乙個字段描述字元所在的紋理控制代碼,如下:
class這樣,就可以拜託之前的限制,實現大規模的繪製文字了。character
unsigned
short
x0; unsigned
short
y0; unsigned
short
x1; unsigned
short
y1;
//! 索引紋理,即當前字元所在的紋理
unsigned texid;
};
說完了方案,我們還有說下實現方式,說道文字繪製,不得不提的就是freetype字型庫了
幾乎所有的三維繪製文字的方式,都採用這個庫。下面以**的方式來介紹他,我們這裡
第一步:初始化字型庫
ft_init_freetype( &_library );第二步:載入字型
ft_new_face(_library,_fontface,0,&_face);第三步:設定字型大小
ft_set_char_size( _face, fontsize << 6, fontsize << 6, 72, 72);第四步:獲取字型的資訊
ft_load_glyph( face, ft_get_char_index( face, code ), ft_load_default );第五步:將bmp資料寫到紋理上ft_glyph glyph;
ft_get_glyph( face->glyph, &glyph );
//convert the glyph to a bitmap.
ft_glyph_to_bitmap( &glyph, ft_render_mode_normal, 0, 1
); ft_bitmapglyph bitmap_glyph =(ft_bitmapglyph)glyph;
//this reference will make accessing the bitmap easier
ft_bitmap& bitmap = bitmap_glyph->bitmap;
gltexsubimage2d(gl_texture_2d,0,x,y,width,height,gl_alpha,gl_unsigned_byte,data);第六步:生成網格,貼上紋理繪製文字
result igraphydeviceimpl::draw2dtext(const wchar_t* text,float x,float y,const rgba4byte& color,rectf*pout)上面簡單的介紹了如何使用freetype與opengl繪製文字,筆者能力所致,說解不到之處,有誤之處,敬請諒glcolor4ub(color._r,color._g,color._b,color._a);
/*** 對字型使用到的紋理和定點座標進行排序
*/bindtexture2d(_fontdefault._textures._texture);
cell::graphy::vertexdeclaration fontdesc =;
drawprimitivedirect(fontdesc,
2,pt_********list,vert,0,index);
opengl 使用gltext繪製漢字
對於freetype如何解析字元,gltext如何包裝freetype並結合opengl進行字元和漢字繪製的具體技術細節,此處就不進行解釋,網上有很多相關的示例。此處只對編譯和使用過程中遇到的坑進行說明。1 在官網上下的freetype2100,個人編譯出來的庫有問題,具體是啥問題,不清楚。迫於無奈...
OPENGL繪製文字
opengl沒有提供直接繪製文字的功能,需要借助於作業系統。用opengl繪製文字比較常見的方法是利用顯示列表。建立一系列顯示列表,每個字元對應乙個列表編號。例如,a 對應列表編號1000 a b 對應列表編號1000 b 以此類推。繪製乙個字串時,依次呼叫字串中每個字元所對應的列表編號。在wind...
OpenGL繪製地形
1.建立頂點緩衝區物件 vertexbuffer 2.建立索引緩衝區物件 indexbuffer 3.載入高度圖 heightmap 3.1把位影象素轉換為高度圖資料 頂點資料 高度圖在每個方向上都是1個單位寬,且其以x z平面上的位置 0,0 為中心,點陣圖的最上角將被對映到 0.5,0.5 右下...