OpenGL進(jìn)行文字顯示的方法_第1頁
OpenGL進(jìn)行文字顯示的方法_第2頁
OpenGL進(jìn)行文字顯示的方法_第3頁
OpenGL進(jìn)行文字顯示的方法_第4頁
OpenGL進(jìn)行文字顯示的方法_第5頁
已閱讀5頁,還剩7頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、任何一個DEMO、仿真項目、游戲,都少不了文字這種媒體。這不可不說是對圖形視覺媒體的補充我們還有一些無法超越文字來向觀眾表達(dá)的心事,或是補充說明,或是感悟,或是感激。ZwqX一般的文字不屬于圖形渲染部分,而屬于用戶界面部分,這在游戲引擎中看或許一目了然,但是在底層的圖形渲染APIOPENGL或D3D中,文字的顯示“并不是必須”,但它是多么深深地被需要著口牙。所以,把字體設(shè)置、文字顯示作為一種圖形學(xué)技術(shù)而非單純的完全我屬或他屬,我是這么想的。(同樣,拾取也算是這樣吧?亂彈OpenGL選擇-拾取機制)本文來源于ZwqXin( 轉(zhuǎn)載請注明原文地址:怎么表達(dá)文字呢?在OpenGL中,我們沒有什么現(xiàn)成的

2、東西可用,但確實有辦法讓我們“得到這種技術(shù)”。讓我最記憶深刻的是NEHE的兩三篇教程(貌似都是十幾課吧),講述的就是今天的這個主題。可以到NEHE網(wǎng)站或者在DANCINGWIND的中文翻譯(見搜集的優(yōu)良OpenGL教程 )看看。而我所知道的這三種方法,前兩種應(yīng)該就是來自那里吧(記得),當(dāng)時要努力完成課程DEMO,于是胡胡混混地就把相應(yīng)的那兩三課學(xué)了,而且把它的文字顯示方法應(yīng)用到自己的程序中(還經(jīng)歷了一段艱辛的探索史.連我當(dāng)時的MyFont類也記錄了這份小辛酸,現(xiàn)在看來,是因為當(dāng)時的知識水平不夠理解吧)。然后后來又一個課程DEMO,老師后來覺得我應(yīng)該“寫中文”,于是我又去探索中文字體顯示方法了,

3、并在一個開源DEMO中找到,分析代碼段后就拿來主義了,至昨不曾好好考究這就是我所知的第三種方法。三種方法都是三步曲:在初始化的時候“創(chuàng)建字體”Build,在渲染階段“應(yīng)用字體”(顯示文字)Print,在程序結(jié)束或不再需要文字顯示的時候“銷毀字體”kill。其中前兩步比較重要,著重討論討論哈1. 常規(guī)的屏幕字體打?。∟ormalFont)應(yīng)用得比較廣,大名鼎鼎的AZURE以前的DEMO就是用這個的。NEHE教程中作為首次出現(xiàn)的字體顯示方法,介紹應(yīng)該比較全面,大家想仔細(xì)了解的話請務(wù)必從上面網(wǎng)址進(jìn)入學(xué)習(xí)(當(dāng)然還有因為我理解不透不敢亂講的緣由)。1. /一般的英語字體打印2. voidMyFont:B

4、uildGLFont(intfontHeight)3. 4. HDChDC=:GetDC(HWND_DESKTOP);/就是這里搞暈了半晚5. 6. inttFontHeight=-1*fontHeight;7. 8. NormalFontBase=glGenLists(96);/StorageFor96Characters9. HFONTfont=CreateFont(-tFontHeight,/HeightOfFont10. 0,/WidthOfFont11. 0,/AngleOfEscapement12. 0,/OrientationAngle13. FW_BOLD,/FontWeigh

5、t14. TRUE,/Italic15. FALSE,/Underline16. FALSE,/Strikeout17. ANSI_CHARSET,/CharacterSetIdentifier18. OUT_TT_PRECIS,/OutputPrecision19. CLIP_DEFAULT_PRECIS,/ClippingPrecision20. ANTIALIASED_QUALITY,/OutputQuality21. FF_DONTCARE|DEFAULT_PITCH,/FamilyAndPitch22. Georgia);/FontName23. 24. HFONToldfont=(

6、HFONT)SelectObject(hDC,font);/SelectsTheFontWeWant25. 26. wglUseFontBitmaps(hDC,32,96,NormalFontBase);/Builds96CharactersStartingAtCharacter3227. 28. SelectObject(hDC,oldfont);/SelectsTheFontWeWanttoreturnto29. DeleteObject(font);/DeleteTheFont30. 31. SetBkMode(hDC,TRANSPARENT);32. 33. NormalFont=tr

7、ue;34. 其中bUild的時候首先用到的是GDI的CreateFont函數(shù)創(chuàng)建字體這應(yīng)該是比較常用的方法,設(shè)置了關(guān)于字體的一切并選入字體后,有一步重要的操作:wglUseFontBitmaps。1. 2. wglUseFontBitmap3. 為當(dāng)前選中的GDI字體創(chuàng)建一組OpenGL顯示列表位圖字體4. BOOLwglUseFontBitmap(HDChDC,DWORDdwFirst,DWORDdwCount,DWORDdwListBase);5. 6. 參數(shù)7. hDC8. 設(shè)備環(huán)境句柄9. 10. dwFirst11. 用于創(chuàng)建顯示列表字體的第一個字符的ASCII值12. 13. d

8、wCount14. 字符數(shù)15. 16. dwListBase17. 第一個顯示列表的名稱18. 19. 返回值20. 成功返回TRUE,否則返回FALSE21. 輸入為DC,32,96以及創(chuàng)建的96個新顯示列表的base列表。函數(shù)繪制從ASCII碼為32-128的字符進(jìn)入顯示列表,依賴OPENGL顯示列表的高速顯示能力(直接從硬件拿存儲區(qū)),可以方便進(jìn)行字符的切換。在Print過程中,調(diào)用glCallLists就能調(diào)動起這些列表了,但是怎么決定具體要“調(diào)動”哪些字母呢(96個之中)?1. voidMyFont:PrintGLText(GLintx,GLinty,constchar*strin

9、g,.)2. chartext256;3. va_listpArguments;4. 5. if(string=NULL)6. return;7. 8. va_start(pArguments,string);9. vsprintf(text,string,pArguments);10. va_end(pArguments);11. 12. 13. glPushAttrib(GL_LIST_BIT|GL_CURRENT_BIT|GL_ENABLE_BIT|GL_LIGHTING_BIT);14. glDisable(GL_DEPTH_TEST);15. glDisable(GL_LIGHTIN

10、G);16. glDisable(GL_TEXTURE_2D);17. glColor4f(mColor0,mColor1,mColor2,mColor3);18. 19. glWindowPos2i(x,y);20. 21. glListBase(NormalFontBase-32);22. glCallLists(strlen(text),GL_UNSIGNED_BYTE,text);23. glPopAttrib();24. 首先看函數(shù)形式printf形式,若想有個詳細(xì)了解,可到這里看看。簡單來說,就是C時代的可變參數(shù)列。va_start - vsprintf - (va_arg)- v

11、a_end這套機制就是為了把可變參數(shù)列的內(nèi)容,通過va_list(char*指針)一個一個從棧中取出來賦予他者我們的glCallLists所要接受的所有“具體字符”,通過base為基礎(chǔ)的索引快速尋覓而取得對應(yīng)ASCII字符的字體信息(實際是位圖字體),并依照期望使其形成為“具體字符串”印入屏幕。另外著重介紹的是我所添加的兩個優(yōu)化它們貫穿三種文字顯示方法之中。其一是glPushAttrib,它與glPopAttrib配合,保證了其之間的OPENGL狀態(tài)設(shè)置的獨立性,使其不影響該代碼邏輯的前后的具體渲染狀態(tài)。當(dāng)然參數(shù)取GL_ALL_ATTRIB_BITS是保險點,但只要你弄清楚自己的需要,像上面這

12、樣給予特定的狀態(tài)作為參數(shù)效率會更高。恩,顏色,光照,深度測試,混合選擇與當(dāng)前方法最匹配的狀態(tài)而沒有對狀態(tài)機的后顧之憂,如同文字本身一樣作為對象完全獨立于圖形渲染“模塊”。另一是glWindowPos2i(x,y),按OpenGL編程指南第8章所說,它取代我們以前用的glRasterPos2i,不再讓作為描繪對象的物體承受模型-視圖-投影變換之苦亂彈OpenGL中的矩陣變換(上) ,而是直接獨立到OPENGL世界的出口屏幕坐標(biāo)系,如GDI般用窗口坐標(biāo)(根據(jù)屏幕像素數(shù))來描述文字的起點位置。這同樣是賦予文字的獨立性,而且意義重大可知道,當(dāng)時我用glRasterPos2i多么狼狽,好難才讓文字不在場

13、景“里面”亂竄。在具體應(yīng)用中,在初始化調(diào)用BuildGLFont.,在渲染階段調(diào)用PrintGLText。譬如:1. /CMAINFRAME2. MyFontmFont;3. 4. /初始化:5. mFont.BuildGLFont(25);/25是字體字高,控制字體大小6. 7. /渲染階段(RenderGLScene)8. 9. mFont.PrintGLText(530,710,http:/www.Z-My3DGraphics);10. 11. /將在坐標(biāo)X=530,Y=710位置開始繪制文字。對1024*768大小的渲染窗口中,即在右上角注意,OpenGL窗口坐標(biāo)系的原點在窗口的左下角

14、,橫坐標(biāo)為X,豎坐標(biāo)為Y,最大值在右上角。(同見亂彈OpenGL選擇-拾取機制 )瀏覽一下效果,第一行就是了,因為我默認(rèn)用的是Georgia字體(應(yīng)該一般人電腦都有),所以很漂亮接下來會談及其余兩種方法,并比較之。真正的紋理文字是怎樣弄的呢?怎樣讓中文字體乖乖顯示?什么時候用哪種方法?我集成的MyFont類是怎樣個怪樣?聽下回分解:在OpenGL上設(shè)置字體和顯示文字(下)本文來源于ZwqXin( 轉(zhuǎn)載請注明原文地址:Tags:OpenGL代碼工具類C分類:OpenGL技術(shù)| 評論:1 | 引用:0 | 瀏覽:7399 水效果 - 水池在OpenGL上設(shè)置字體和顯示文字(下) 分享到新浪微博QQ

15、空間騰訊微博人人網(wǎng)豆瓣0 點擊這里獲取該日志的TrackBack引用地址 相關(guān)文章: 亂彈OpenGL選擇-拾取機制(下)(2009-6-14 23:3:8)亂彈OpenGL選擇-拾取機制(上)(2009-6-13 16:54:2)子類調(diào)用父類的純虛函數(shù)之問題(2009-6-8 23:18:32)視錐類CFrustum .zwqxin ver(2009-6-2 22:39:52)標(biāo)準(zhǔn)MFC在OpenGL(2009-5-31 17:46:47)QuickSort 快速排序的實現(xiàn)(2009-5-6 1:21:55)全屏反鋸齒 - 多重采樣(2009-5-3 19:50:7)全屏反鋸齒 - 多重采樣

16、(2009-5-2 16:21:56)圖像處理里的空間域濾波(2009-4-27 23:53:18)一年前,首次獻(xiàn)給OpenGL之夜.雷達(dá)追蹤(2009-4-5 22:18:52)在OpenGL上設(shè)置字體和顯示文字(下)2009-8-6 10:22:27 | 發(fā)布:zwqxin本篇緊隨上篇,繼續(xù)說一下鄙人所了解的在OpenGL進(jìn)行文字顯示的方法,也方便不知從哪個次元來到這里的學(xué)習(xí)者提供一點這方面的信息。上一篇見:在OpenGL上設(shè)置字體和顯示文字(上) ZwqX本文來源于ZwqXin( 轉(zhuǎn)載請注明原文地址:2. 紋理字體最近接觸Irrlicht引擎,里面的GUI模塊涉及的字體設(shè)置就是用了這種紋

17、理字體的方法。事實上,上篇的方法最后多少了涉及到了位圖字體,但是這里所說的,是直接從一張“寫著各個英文字符和其他常用字符”的紋理上,按對此紋理上的圖案“結(jié)構(gòu)”的先驗知識而獲取字符對應(yīng)的“紋理部分”,顯示到屏幕上。換句話來說,這就是真正的紋理貼圖了,因此必須結(jié)合一張?zhí)囟ㄔO(shè)計的“字體紋理”。要顯示一個字符,需要你繪制一個一定大小的矩形(這個長度值相當(dāng)于之前的字體高度它控制最后出來的文字的大小),然后找到你所需字符在該紋理上的紋理坐標(biāo),作為索引檢索出紋理上的對應(yīng)字符部分的小紋理,貼到該矩形上。1. 2. /從字體集紋理中取出的字符3. voidMyFont:BuildTextureFont(GLui

18、ntfonttex,intfontHeight,intscreenWidth,intscreenHeight)4. 5. TextureFontFont=fonttex;6. 7. floatcx;/HoldsOurXCharacterCoord8. floatcy;/HoldsOurYCharacterCoord9. 10. glEnable(GL_TEXTURE_2D);11. 12. TextureFontBase=glGenLists(256);/Creating256DisplayLists13. 14. glBindTexture(GL_TEXTURE_2D,TextureFont

19、Font);/SelectOurFontTexture15. 16. for(intloop=0;loop1)TextureSet=1;5. if(TextureSetbmiHeader.biSize=sizeof(binf-bmiHeader);33. binf-bmiHeader.biWidth=bm.bmWidth;34. binf-bmiHeader.biHeight=bm.bmHeight;35. binf-bmiHeader.biPlanes=1;36. binf-bmiHeader.biBitCount=1;37. binf-bmiHeader.biCompression=BI_

20、RGB;38. binf-bmiHeader.biSizeImage=bufsize;39. 40. UCHAR*Bits=newUCHARbufsize;41. :GetDIBits(MDC,bitmap,0,bm.bmHeight,Bits,binf,DIB_RGB_COLORS);42. 43. glPixelStorei(GL_UNPACK_ALIGNMENT,1);44. 45. /glRasterPos2i(x,y);46. glWindowPos2i(x,y);47. glBitmap(size.cx,size.cy,0,0,0,0,Bits);48. 49. deleteBit

21、s;50. SelectObject(MDC,oldBmp);51. :DeleteDC(MDC);52. 53. 54. voidMyFont:PrintGDIText(GLintx,GLinty,CStringstr)55. 56. glLoadIdentity();57. glPushAttrib(GL_CURRENT_BIT|GL_LIGHTING_BIT);58. 59. glDisable(GL_TEXTURE_2D);60. glDisable(GL_LIGHTING);61. 62. glColor4f(mColor0,mColor1,mColor2,mColor3);63.

22、64. PrintfChtext(x,y,str);65. 66. glPopAttrib();67. glPushAttrib和glWindowPos2i的意義不多說了??粗黧w函數(shù)PrintfChtext。幾個GDI函數(shù): GetTextExtentPoint32用當(dāng)前所選字體來計算字符串尺寸,按邏輯單位計算的高和寬都沒有考慮裁剪取的情況。 CreateBitmap創(chuàng)建單位色位圖。函數(shù)所做的是依據(jù)字符串大小建立一張單色位圖,把該位圖信息存入UCHAR數(shù)組Bits內(nèi)。類似的操作在認(rèn)識HBITMAP與Bmp操作(整內(nèi)存拷貝版) 也談過,所以細(xì)節(jié)部分譬如為什么要取寬度位8倍數(shù)等等就略過。重點是要把

23、數(shù)組Bits交給誰。恩,glBitmap函數(shù)道出了一切。OpenGL里除了幾何對象(點、線、多邊形)和紋理圖像對象外,還有一種不常用的對象,位圖Bitmap。一般來說這樣的位圖是灰度的,也就是位圖矩塊內(nèi)每個像素只有1BIT的信息0 OR 1。這對文字來說正好,因為文字就是黑色(/透明)背景中的白色部分,黑白分明。顏色可以在繪制位圖后用glColor設(shè)置嘛。glBitmap函數(shù)就是用來根據(jù)數(shù)據(jù)顯示位圖的。而該位圖內(nèi)可以說是被打印了GDI文字上去(用TextOut),于是最后在屏幕上的還是位圖文字,且可以用glWindowPos2i調(diào)節(jié)起始點位置。就這樣,完成的GDI文字從基于DC的GDI環(huán)境,顯示到基于RC的OPenGL環(huán)境上??上部少R。具體應(yīng)用:1. 2. /CMAINFRAME3. MyFontmFont;4. 5. /初始化:6. mFont.BuildGDIFont(宋體,FW_NORMAL,25);7. /25是字體字高,

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論