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

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

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

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

3、并在一個開源DEMO中找到,分析代碼段后就拿來主義了,至昨不曾好好考究這就是我所知的第三種方法。三種方法都是三步曲:在初始化的時候“創建字體”Build,在渲染階段“應用字體”(顯示文字)Print,在程序結束或不再需要文字顯示的時候“銷毀字體”kill。其中前兩步比較重要,著重討論討論哈1. 常規的屏幕字體打印(NormalFont)應用得比較廣,大名鼎鼎的AZURE以前的DEMO就是用這個的。NEHE教程中作為首次出現的字體顯示方法,介紹應該比較全面,大家想仔細了解的話請務必從上面網址進入學習(當然還有因為我理解不透不敢亂講的緣由)。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函數創建字體這應該是比較常用的方法,設置了關于字體的一切并選入字體后,有一步重要的操作:wglUseFontBitmaps。1. 2. wglUseFontBitmap3. 為當前選中的GDI字體創建一組OpenGL顯示列表位圖字體4. BOOLwglUseFontBitmap(HDChDC,DWORDdwFirst,DWORDdwCount,DWORDdwListBase);5. 6. 參數7. hDC8. 設備環境句柄9. 10. dwFirst11. 用于創建顯示列表字體的第一個字符的ASCII值12. 13. d

8、wCount14. 字符數15. 16. dwListBase17. 第一個顯示列表的名稱18. 19. 返回值20. 成功返回TRUE,否則返回FALSE21. 輸入為DC,32,96以及創建的96個新顯示列表的base列表。函數繪制從ASCII碼為32-128的字符進入顯示列表,依賴OPENGL顯示列表的高速顯示能力(直接從硬件拿存儲區),可以方便進行字符的切換。在Print過程中,調用glCallLists就能調動起這些列表了,但是怎么決定具體要“調動”哪些字母呢(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. 首先看函數形式printf形式,若想有個詳細了解,可到這里看看。簡單來說,就是C時代的可變參數列。va_start - vsprintf - (va_arg)- v

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

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

13、景“里面”亂竄。在具體應用中,在初始化調用BuildGLFont.,在渲染階段調用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. /將在坐標X=530,Y=710位置開始繪制文字。對1024*768大小的渲染窗口中,即在右上角注意,OpenGL窗口坐標系的原點在窗口的左下角

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

15、空間騰訊微博人人網豆瓣0 點擊這里獲取該日志的TrackBack引用地址 相關文章: 亂彈OpenGL選擇-拾取機制(下)(2009-6-14 23:3:8)亂彈OpenGL選擇-拾取機制(上)(2009-6-13 16:54:2)子類調用父類的純虛函數之問題(2009-6-8 23:18:32)視錐類CFrustum .zwqxin ver(2009-6-2 22:39:52)標準MFC在OpenGL(2009-5-31 17:46:47)QuickSort 快速排序的實現(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)一年前,首次獻給OpenGL之夜.雷達追蹤(2009-4-5 22:18:52)在OpenGL上設置字體和顯示文字(下)2009-8-6 10:22:27 | 發布:zwqxin本篇緊隨上篇,繼續說一下鄙人所了解的在OpenGL進行文字顯示的方法,也方便不知從哪個次元來到這里的學習者提供一點這方面的信息。上一篇見:在OpenGL上設置字體和顯示文字(上) ZwqX本文來源于ZwqXin( 轉載請注明原文地址:2. 紋理字體最近接觸Irrlicht引擎,里面的GUI模塊涉及的字體設置就是用了這種紋

17、理字體的方法。事實上,上篇的方法最后多少了涉及到了位圖字體,但是這里所說的,是直接從一張“寫著各個英文字符和其他常用字符”的紋理上,按對此紋理上的圖案“結構”的先驗知識而獲取字符對應的“紋理部分”,顯示到屏幕上。換句話來說,這就是真正的紋理貼圖了,因此必須結合一張特定設計的“字體紋理”。要顯示一個字符,需要你繪制一個一定大小的矩形(這個長度值相當于之前的字體高度它控制最后出來的文字的大小),然后找到你所需字符在該紋理上的紋理坐標,作為索引檢索出紋理上的對應字符部分的小紋理,貼到該矩形上。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的意義不多說了。看主體函數PrintfChtext。幾個GDI函數: GetTextExtentPoint32用當前所選字體來計算字符串尺寸,按邏輯單位計算的高和寬都沒有考慮裁剪取的情況。 CreateBitmap創建單位色位圖。函數所做的是依據字符串大小建立一張單色位圖,把該位圖信息存入UCHAR數組Bits內。類似的操作在認識HBITMAP與Bmp操作(整內存拷貝版) 也談過,所以細節部分譬如為什么要取寬度位8倍數等等就略過。重點是要把

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

溫馨提示

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

評論

0/150

提交評論